summaryrefslogtreecommitdiffstats
path: root/utils/statd
diff options
context:
space:
mode:
Diffstat (limited to 'utils/statd')
-rw-r--r--utils/statd/monitor.c3
-rw-r--r--utils/statd/rmtcall.c60
-rw-r--r--utils/statd/statd.c20
-rw-r--r--utils/statd/statd.h1
-rw-r--r--utils/statd/svc_run.c3
5 files changed, 74 insertions, 13 deletions
diff --git a/utils/statd/monitor.c b/utils/statd/monitor.c
index 88b33db..40e8f49 100644
--- a/utils/statd/monitor.c
+++ b/utils/statd/monitor.c
@@ -15,6 +15,7 @@
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <errno.h>
#include <arpa/inet.h>
#include "misc.h"
#include "statd.h"
@@ -172,7 +173,7 @@ sm_mon_1_svc(struct mon *argp, struct svc_req *rqstp)
sprintf(path, "%s/%s", SM_DIR, mon_name);
if ((fd = open(path, O_WRONLY|O_SYNC|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
/* Didn't fly. We won't monitor. */
- note(N_ERROR, "creat(%s) failed: %m", path);
+ note(N_ERROR, "creat(%s) failed: %s", path, strerror (errno));
nlist_free(NULL, clnt);
free(path);
goto failure;
diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c
index 474bbb4..a45705b 100644
--- a/utils/statd/rmtcall.c
+++ b/utils/statd/rmtcall.c
@@ -26,6 +26,7 @@
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
+#include <net/if.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
@@ -34,6 +35,7 @@
#include <netdb.h>
#include <string.h>
#include <unistd.h>
+#include <ifaddrs.h>
#include "sm_inter.h"
#include "statd.h"
#include "notlist.h"
@@ -90,7 +92,50 @@ statd_get_socket(int port)
out_success:
return sockfd;
}
-
+/*
+ * Using the NL_ADDR(lp), reset (if needed) the hostname
+ * that will be put in the SM_NOTIFY to the hostname
+ * that is associated with the network interface
+ * that was monitored
+ */
+static void
+reset_my_name(notify_list *lp)
+{
+ struct ifaddrs *ifa = NULL, *ifap;
+ struct in_addr netaddr, tmp;
+ struct sockaddr_in *sin, *nsin;
+ struct hostent *hp;
+
+ netaddr.s_addr = inet_netof(NL_ADDR(lp));
+ if (getifaddrs(&ifa) >= 0) {
+ for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
+ if (!(ifap->ifa_flags & IFF_UP))
+ continue;
+
+ note(N_DEBUG, "ifa_name %s\n", ifap->ifa_name);
+ if (ifap->ifa_addr == NULL)
+ continue;
+ if (ifap->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ sin = (struct sockaddr_in *)ifap->ifa_addr;
+ nsin = (struct sockaddr_in *)ifap->ifa_netmask;
+ tmp.s_addr = sin->sin_addr.s_addr & nsin->sin_addr.s_addr;
+ if (memcmp(&tmp.s_addr, &netaddr.s_addr, sizeof(netaddr.s_addr)))
+ continue;
+ hp = gethostbyaddr((char *)&sin->sin_addr,
+ sizeof(sin->sin_addr), AF_INET);
+ if (hp == NULL)
+ continue;
+ if (strcmp(NL_MY_NAME(lp), hp->h_name)) {
+ free(NL_MY_NAME(lp));
+ NL_MY_NAME(lp)= strdup(hp->h_name);
+ note(N_DEBUG, "NL_MY_NAME %s\n", NL_MY_NAME(lp));
+ }
+ }
+ }
+ return;
+}
/*
* Try to resolve host name for notify/callback request
*
@@ -300,6 +345,7 @@ process_entry(int sockfd, notify_list *lp)
{
struct sockaddr_in sin;
struct status new_status;
+ stat_chge new_stat;
xdrproc_t func;
void *objp;
u_int32_t proc, vers, prog;
@@ -326,9 +372,19 @@ process_entry(int sockfd, notify_list *lp)
/* Use source address for notify replies */
sin.sin_addr = lp->addr;
+ /*
+ * Unless a static hostname has been defined
+ * set the NL_MY_NAME(lp) hostname to the
+ * one associated with the network interface
+ */
+ if (!(run_mode & STATIC_HOSTNAME))
+ reset_my_name(lp);
func = (xdrproc_t) xdr_stat_chge;
- objp = &SM_stat_chge;
+ new_stat.state = MY_STATE;
+ new_stat.mon_name = NL_MY_NAME(lp);
+
+ objp = &new_stat;
break;
case NOTIFY_CALLBACK:
prog = NL_MY_PROG(lp);
diff --git a/utils/statd/statd.c b/utils/statd/statd.c
index 48362c0..f61914d 100644
--- a/utils/statd/statd.c
+++ b/utils/statd/statd.c
@@ -22,6 +22,7 @@
#include <grp.h>
#include "statd.h"
#include "version.h"
+#include "nfslib.h"
/* Socket operations */
#include <sys/types.h>
@@ -194,8 +195,10 @@ static void drop_privs(void)
struct stat st;
if (stat(SM_DIR, &st) == -1 &&
- stat(DIR_BASE, &st) == -1)
+ stat(DIR_BASE, &st) == -1) {
st.st_uid = 0;
+ st.st_gid = 0;
+ }
if (st.st_uid == 0) {
note(N_WARNING, "statd running as root. chown %s to choose different user\n",
@@ -285,6 +288,7 @@ int main (int argc, char **argv)
}
break;
case 'n': /* Specify local hostname */
+ run_mode |= STATIC_HOSTNAME;
MY_NAME = xstrdup(optarg);
break;
case 'P':
@@ -400,14 +404,12 @@ int main (int argc, char **argv)
}
}
tempfd = open("/dev/null", O_RDWR);
- close(0); dup2(tempfd, 0);
- close(1); dup2(tempfd, 1);
- close(2); dup2(tempfd, 2);
- fdmax = sysconf (_SC_OPEN_MAX);
- for (filedes = 3; filedes < fdmax; filedes++)
- if (filedes != pipefds[1])
- close (filedes);
-
+ dup2(tempfd, 0);
+ dup2(tempfd, 1);
+ dup2(tempfd, 2);
+ dup2(pipefds[1], 3);
+ pipefds[1] = 3;
+ closeall(4);
}
/* Child. */
diff --git a/utils/statd/statd.h b/utils/statd/statd.h
index e782972..d9d5d3d 100644
--- a/utils/statd/statd.h
+++ b/utils/statd/statd.h
@@ -78,6 +78,7 @@ extern int run_mode;
/* LH - notify_only mode would be for notifying hosts on an IP alias
* that just came back up, for ex, when failing over a HA service to
* another host.... */
+#define STATIC_HOSTNAME 8 /* Always use the hostname set by -n */
/*
* Program name and version pointers -- See statd.c for the reasoning
diff --git a/utils/statd/svc_run.c b/utils/statd/svc_run.c
index f6bcbb9..597b68d 100644
--- a/utils/statd/svc_run.c
+++ b/utils/statd/svc_run.c
@@ -123,7 +123,8 @@ my_svc_run(void)
if (errno == EINTR || errno == ECONNREFUSED
|| errno == ENETUNREACH || errno == EHOSTUNREACH)
continue;
- note(N_ERROR, "my_svc_run() - select: %m");
+ note(N_ERROR, "my_svc_run() - select: %s",
+ strerror (errno));
return;
case 0: