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;
#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");