Whamcloud - gitweb
LU-17175 gss: background speedtest for Miller-Rabin rounds 88/54088/5
authorSebastien Buisson <sbuisson@ddn.com>
Sat, 17 Feb 2024 12:27:15 +0000 (13:27 +0100)
committerOleg Drokin <green@whamcloud.com>
Mon, 4 Mar 2024 20:03:02 +0000 (20:03 +0000)
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.

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-on: https://review.whamcloud.com/c/fs/lustre-release/+/54088
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Aurelien Degremont <adegremont@nvidia.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/tests/test-framework.sh
lustre/utils/gss/sk_utils.c
lustre/utils/gss/sk_utils.h
lustre/utils/gss/svcgssd.h
lustre/utils/gss/svcgssd_main_loop.c
lustre/utils/gss/svcgssd_proc.c

index 067add1..660d20c 100755 (executable)
@@ -1194,7 +1194,10 @@ check_gss_daemon_nodes() {
        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;
index 0dc46dd..1aeef05 100644 (file)
@@ -44,6 +44,7 @@
 #include <sys/stat.h>
 #include <libcfs/util/string.h>
 #include <sys/time.h>
+#include <signal.h>
 
 #include "sk_utils.h"
 #include "write_bytes.h"
@@ -838,12 +839,39 @@ static unsigned char test_prime[VALUE_LENGTH] =
  * \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;
index 0fb3af3..4de88e9 100644 (file)
@@ -380,7 +380,7 @@ uint32_t sk_verify_hash(const char *string, const EVP_MD *hash_alg,
 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,
index 36e8b95..2ca95f2 100644 (file)
@@ -48,7 +48,7 @@ extern char *oss_local_realm;
 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"
 
index b0d9f89..c3a0a4c 100644 (file)
@@ -45,6 +45,7 @@
 #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 */
@@ -83,7 +107,7 @@ again:
        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;
        }
 
@@ -99,13 +123,13 @@ again:
                        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;
        }
 
@@ -126,5 +150,10 @@ 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);
 }
index 0595469..3009d61 100644 (file)
@@ -601,7 +601,7 @@ static int handle_sk(struct svc_nego_data *snd)
        }
 
 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");