The number of rounds used for Miller-Rabin testing of the prime
provided as input parameter to DH_check() is evaluated when the
lsvcgssd daemon starts. This speed test takes between 5 and 10 seconds
so it makes sense to run it in the background.
Any prime tested before the right number of rounds has been determined
would use the default from OpenSSL. This can lead to longer request
processing time, but this is only for a temporary and short period of
time.
Lustre-change: https://review.whamcloud.com/54088
Lustre-commit:
d753dc75ad2a919e5fff3bc51c20b4569cd86a86
Test-Parameters: trivial
Test-Parameters: testgroup=review-dne-selinux-ssk-part-1
Test-Parameters: testgroup=review-dne-selinux-ssk-part-2
Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: If77f4374c5af463fdadd15979a594af1786af1df
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/54278
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
local ret
dname=$(basename "$dname" | awk '{print $1}')
- do_nodesv $list "num=\\\$(ps -o cmd -C $dname | grep $dname | wc -l);
+ do_nodesv $list "num=0;
+for proc in \\\$(pgrep $dname); do
+[ \\\$(ps -o ppid= -p \\\$proc) -ne 1 ] || ((num++))
+done;
if [ \\\"\\\$num\\\" -ne 1 ]; then
- echo \\\$num instance of $dname;
- exit 1;
+ echo \\\$num instance of $dname;
+ exit 1;
fi; "
ret=$?
(( $ret == 0 )) || return $ret
#include <sys/stat.h>
#include <libcfs/util/string.h>
#include <sys/time.h>
+#include <signal.h>
#include "sk_utils.h"
#include "write_bytes.h"
* \retval max number of rounds to keep prime testing under usec_check_max
* return 0 if we should use the default DH_check rounds
*/
-int sk_speedtest_dh_valid(unsigned int usec_check_max)
+int sk_speedtest_dh_valid(unsigned int usec_check_max, pid_t *child)
{
DH *dh;
BIGNUM *p, *g;
+ struct sigaction sa;
int num_rounds, prev_rounds = 0;
+ /* Set SIGCHLD disposition so that child that terminates
+ * does not become a zombie.
+ */
+ sa.sa_handler = NULL;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_NOCLDWAIT;
+ if (sigaction(SIGCHLD, &sa, NULL) == -1)
+ printerr(2, "SIGCHLD sigaction failed\n");
+
+ *child = fork();
+ if (*child == -1) {
+ printerr(0, "cannot fork child for speedtest: %s\n",
+ strerror(errno));
+ /* in this case the speedtest cannot be run, so return 0
+ * to use default num rounds for prime testing
+ */
+ return 0;
+ } else if (*child != 0) {
+ /* parent returns immediately,
+ * 0 means num rounds is not determined yet
+ */
+ return 0;
+ }
+
+ /* now in forked child process, start speed test */
+
dh = DH_new();
if (!dh)
return 0;
struct sk_cred *sk_create_cred(const char *fsname, const char *cluster,
const uint32_t flags);
#ifndef HAVE_OPENSSL_EVP_PKEY
-int sk_speedtest_dh_valid(unsigned int usec_check_max);
+int sk_speedtest_dh_valid(unsigned int usec_check_max, pid_t *child);
#endif
uint32_t sk_gen_params(struct sk_cred *skc, int num_rounds);
int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs,
extern int null_enabled;
extern int krb_enabled;
extern int sk_enabled;
-extern int sk_dh_checks;
+extern int *sk_dh_checks;
#define GSSD_SERVICE_NAME "lustre"
#include <unistd.h>
/* For nanosleep() */
#include <time.h>
+#include <sys/mman.h>
#include "cacheio.h"
#include "svcgssd.h"
/* max allowed time for prime testing: 400 ms */
#define MAX_ALLOWED_TIME_FOR_PRIME 400000
-int sk_dh_checks;
+int *sk_dh_checks;
void svcgssd_run(void)
{
- int local_socket, remote_socket;
+ int local_socket = -1, remote_socket;
struct sockaddr_un addr;
bool retried = false;
- int ret = 0;
+#if !defined(HAVE_OPENSSL_EVP_PKEY) && OPENSSL_VERSION_NUMBER >= 0x1010103fL
+ pid_t child = 1;
+#endif
+ int ret = EXIT_SUCCESS;
if (sk_enabled) {
+ sk_dh_checks = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ if (sk_dh_checks == MAP_FAILED) {
+ printerr(LL_ERR,
+ "cannot mmap memory for sk_dh_checks: %s\n",
+ strerror(errno));
+ ret = EXIT_FAILURE;
+ goto out_close;
+ }
+
#if !defined(HAVE_OPENSSL_EVP_PKEY) && OPENSSL_VERSION_NUMBER >= 0x1010103fL
- sk_dh_checks =
- sk_speedtest_dh_valid(MAX_ALLOWED_TIME_FOR_PRIME);
- if (sk_dh_checks)
+ /* child will run asynchronously, parent will not wait for it */
+ *sk_dh_checks =
+ sk_speedtest_dh_valid(MAX_ALLOWED_TIME_FOR_PRIME,
+ &child);
+ if (*sk_dh_checks)
printerr(LL_WARN,
"will use %d rounds for prime testing\n",
- sk_dh_checks);
+ *sk_dh_checks);
+ else
+ printerr(LL_WARN,
+ "will use default number of rounds for prime testing\n");
+ if (child == 0)
+ /* job done for child */
+ exit(EXIT_SUCCESS);
#else
- sk_dh_checks = 0;
+ *sk_dh_checks = 0;
+ printerr(LL_WARN,
+ "will use default number of rounds for prime testing\n");
#endif
} else {
/* For krb, preload mapping table if any */
local_socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (local_socket == -1) {
printerr(LL_ERR, "unable to create socket: %d\n", -errno);
- ret = 1;
+ ret = EXIT_FAILURE;
goto out_close;
}
goto again;
}
printerr(LL_ERR, "unable to bind socket: %d\n", -errno);
- ret = 1;
+ ret = EXIT_FAILURE;
goto out_close;
}
if (listen(local_socket, 10) == -1) {
printerr(LL_ERR, "unable to listen on socket: %d\n", -errno);
- ret = 1;
+ ret = EXIT_FAILURE;
goto out;
}
out_close:
if (local_socket >= 0)
close(local_socket);
+ if (munmap(sk_dh_checks, sizeof(int)) == -1) {
+ printerr(LL_ERR, "cannot munmap memory for sk_dh_checks: %s\n",
+ strerror(errno));
+ ret = EXIT_FAILURE;
+ }
exit(ret);
}
}
redo:
- rc = sk_gen_params(skc, sk_dh_checks);
+ rc = sk_gen_params(skc, *sk_dh_checks);
if (rc != GSS_S_COMPLETE) {
printerr(LL_ERR,
"Failed to generate DH params for responder\n");