mon_name, my_name);
/* But we'll let you pass anyway. */
- result.res_stat = STAT_SUCC;
- result.state = MY_STATE;
- return (&result);
+ goto success;
}
clnt = NL_NEXT(clnt);
}
ha_callout("add-client", mon_name, my_name, -1);
nlist_insert(&rtnl, clnt);
close(fd);
-
+ dprintf(N_DEBUG, "MONITORING %s for %s", mon_name, my_name);
+ success:
result.res_stat = STAT_SUCC;
+ /* SUN's sm_inter.x says this should be "state number of local site".
+ * X/Open says '"state" will be contain the state of the remote NSM.'
+ * href=http://www.opengroup.org/onlinepubs/9629799/SM_MON.htm
+ * Linux lockd currently (2.6.21 and prior) ignores whatever is
+ * returned, and given the above contraction, it probably always will..
+ * So we just return what we always returned. If possible, we
+ * have already told lockd about our state number via a sysctl.
+ * If lockd wants the remote state, it will need to
+ * use SM_STAT (and prayer).
+ */
result.state = MY_STATE;
- dprintf(N_DEBUG, "MONITORING %s for %s", mon_name, my_name);
return (&result);
failure:
void nsm_log(int fac, const char *fmt, ...);
static int record_pid();
static void drop_privs(void);
+static void set_kernel_nsm_state(int state);
static struct nsm_host * hosts = NULL;
backup_hosts(_SM_DIR_PATH, _SM_BAK_PATH);
get_hosts(_SM_BAK_PATH);
+ /* Get and update the NSM state. This will call sync() */
+ nsm_state = nsm_get_state(opt_update_state);
+ set_kernel_nsm_state(nsm_state);
+
if (!opt_debug) {
if (!opt_quiet)
printf("Backgrounding to notify hosts...\n");
close(2);
}
- /* Get and update the NSM state. This will call sync() */
- nsm_state = nsm_get_state(opt_update_state);
-
notify();
if (hosts) {
exit(1);
}
}
+
+static void set_kernel_nsm_state(int state)
+{
+ int fd;
+
+ fd = open("/proc/sys/fs/nfs/nsm_local_state",O_WRONLY);
+ if (fd >= 0) {
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%d", state);
+ write(fd, buf, strlen(buf));
+ close(fd);
+ }
+}
* status." My implementation is operative; it returns 'STAT_SUCC'
* whenever it can resolve the hostname that it's being asked to
* monitor, and returns 'STAT_FAIL' otherwise.
+ *
+ * sm_inter.x says the 'state' returned should be
+ * "state number of site sm_name". It is not clear how to get this.
+ * X/Open says:
+ * STAT_SUCC
+ * The NSM will monitor the given host. "sm_stat_res.state" contains
+ * the state of the NSM.
+ * Which implies that 'state' is the state number of the *local* NSM.
+ * href=http://www.opengroup.org/onlinepubs/9629799/SM_STAT.htm
+ *
+ * We return the *local* state as
+ * 1/ We have easy access to it.
+ * 2/ It might be useful to a remote client who needs it and has no
+ * other way to get it.
+ * 3/ That's what we always did in the past.
*/
struct sm_stat_res *
sm_stat_1_svc (struct sm_name *argp, struct svc_req *rqstp)
extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
extern int statd_get_socket(void);
+static void load_state_number(void);
#ifdef SIMULATIONS
extern void simulator (int, char **);
* pass on any SM_NOTIFY that arrives
*/
load_state();
-
+ load_state_number();
pmap_unset (SM_PROG, SM_VERS);
/* this registers both UDP and TCP services */
}
return 0;
}
+
+static void
+load_state_number(void)
+{
+ int fd;
+
+ if ((fd = open(SM_STAT_PATH, O_RDONLY)) == -1)
+ return;
+
+ read(fd, &MY_STATE, sizeof(MY_STATE));
+ close(fd);
+ fd = open("/proc/sys/fs/nfs/nsm_local_state",O_WRONLY);
+ if (fd >= 0) {
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%d", MY_STATE);
+ write(fd, buf, strlen(buf));
+ close(fd);
+ }
+
+}