summaryrefslogtreecommitdiffstats
path: root/utils/statd/statd.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/statd/statd.c')
-rw-r--r--utils/statd/statd.c97
1 files changed, 62 insertions, 35 deletions
diff --git a/utils/statd/statd.c b/utils/statd/statd.c
index c92e12f..6200911 100644
--- a/utils/statd/statd.c
+++ b/utils/statd/statd.c
@@ -23,6 +23,7 @@
#include <rpc/pmap_clnt.h>
#include <rpcmisc.h>
#include <sys/resource.h>
+#include <sys/wait.h>
#include <grp.h>
#include "statd.h"
#include "version.h"
@@ -44,7 +45,6 @@ char * SM_STAT_PATH = DEFAULT_SM_STAT_PATH;
/* ----- end of state directory path stuff ------- */
-short int restart = 0;
int run_mode = 0; /* foreground logging mode */
/* LH - I had these local to main, but it seemed silly to have
@@ -74,7 +74,7 @@ static struct option longopts[] =
};
extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
-extern int statd_get_socket(int port);
+extern int statd_get_socket(void);
#ifdef SIMULATIONS
extern void simulator (int, char **);
@@ -107,8 +107,7 @@ static void
killer (int sig)
{
note (N_FATAL, "Caught signal %d, un-registering and exiting.", sig);
- if (!(run_mode & MODE_NOTIFY_ONLY))
- pmap_unset (SM_PROG, SM_VERS);
+ pmap_unset (SM_PROG, SM_VERS);
exit (0);
}
@@ -116,9 +115,10 @@ killer (int sig)
static void
sigusr (int sig)
{
+ extern void my_svc_exit (void);
dprintf (N_DEBUG, "Caught signal %d, re-notifying (state %d).", sig,
MY_STATE);
- re_notify = 1;
+ my_svc_exit();
}
/*
@@ -138,16 +138,7 @@ static void log_modes(void)
if (run_mode & MODE_LOG_STDERR)
strcat(buf,"Log-STDERR ");
- if (run_mode & MODE_NOTIFY_ONLY)
- {
- strcat(buf,"Notify-Only ");
- }
note(N_WARNING,buf);
- /* future: IP aliasing
- if (run_mode & MODE_NOTIFY_ONLY)
- {
- dprintf(N_DEBUG,"Notify IP: %s",svr_addr);
- } */
}
/*
@@ -223,6 +214,31 @@ static void drop_privs(void)
}
}
+static void run_sm_notify(int outport)
+{
+ char op[20];
+ char *av[6];
+ int ac = 0;
+
+ av[ac++] = "/usr/sbin/sm-notify";
+ if (run_mode & MODE_NODAEMON)
+ av[ac++] = "-d";
+ if (outport) {
+ sprintf(op, "-p%d", outport);
+ av[ac++] = op;
+ }
+ if (run_mode & STATIC_HOSTNAME) {
+ av[ac++] = "-N";
+ av[ac++] = MY_NAME;
+ }
+ av[ac] = NULL;
+ fprintf(stderr, "%s: -N deprecated, consider using /usr/sbin/sm-notify directly\n",
+ name_p);
+ execv(av[0], av);
+ fprintf(stderr, "%s: failed to run %s\n", name_p, av[0]);
+ exit(2);
+
+}
/*
* Entry routine/main loop.
*/
@@ -347,6 +363,10 @@ int main (int argc, char **argv)
exit(-1);
}
+ if (run_mode & MODE_NOTIFY_ONLY)
+ run_sm_notify(out_port);
+
+
if (!(run_mode & MODE_NODAEMON)) {
run_mode &= ~MODE_LOG_STDERR; /* Never log to console in
daemon mode. */
@@ -435,24 +455,23 @@ int main (int argc, char **argv)
*/
signal(SIGPIPE, SIG_IGN);
- /* initialize out_port */
- statd_get_socket(out_port);
-
create_pidfile();
atexit(truncate_pidfile);
+
+ switch (pid = fork()) {
+ case 0:
+ run_sm_notify(out_port);
+ break;
+ case -1:
+ break;
+ default:
+ waitpid(pid, NULL, 0);
+ }
+
drop_privs();
for (;;) {
- if (!(run_mode & MODE_NOTIFY_ONLY)) {
- /* Do not do pmap_unset() when running in notify mode.
- * We may clear the portmapper record for a statd not
- * running in notify mode disabling it.
- * Juan C. Gomez j_carlos_gomez@yahoo.com
- */
- pmap_unset (SM_PROG, SM_VERS);
- }
- change_state ();
- shuffle_dirs (); /* Move directory names around */
+ pmap_unset (SM_PROG, SM_VERS);
/* If we got this far, we have successfully started, so notify parent */
if (pipefds[1] > 0) {
@@ -462,13 +481,8 @@ int main (int argc, char **argv)
pipefds[1] = -1;
}
- notify_hosts (); /* Send out notify requests */
- ++restart;
-
/* this registers both UDP and TCP services */
- if (!(run_mode & MODE_NOTIFY_ONLY)) {
- rpc_init("statd", SM_PROG, SM_VERS, sm_prog_1, port);
- }
+ rpc_init("statd", SM_PROG, SM_VERS, sm_prog_1, port);
/*
* Handle incoming requests: SM_NOTIFY socket requests, as
@@ -476,8 +490,21 @@ int main (int argc, char **argv)
*/
my_svc_run(); /* I rolled my own, Olaf made it better... */
- if ((run_mode & MODE_NOTIFY_ONLY))
- break;
+ /* Only get here when simulating a crash so we should probably
+ * start sm-notify running again. As we have already dropped
+ * privileges, this might not work, but I don't think
+ * responding to SM_SIMU_CRASH is an important use cases to
+ * get perfect.
+ */
+ switch (pid = fork()) {
+ case 0:
+ run_sm_notify(out_port);
+ break;
+ case -1:
+ break;
+ default:
+ waitpid(pid, NULL, 0);
+ }
}
return 0;
}