From f73e7b9f69835d483cee95e6a20b6307b9d16b77 Mon Sep 17 00:00:00 2001 From: neilbrown Date: Thu, 6 Oct 2005 05:20:19 +0000 Subject: [PATCH] Assorted changes from Steve Dickson --- ChangeLog | 32 +++++++++++++++++++++ support/include/nfslib.h | 2 ++ support/nfs/Makefile | 2 +- support/nfs/closeall.c | 31 +++++++++++++++++++++ support/nfs/exports.c | 2 +- support/nfs/xlog.c | 2 +- utils/idmapd/Makefile | 2 +- utils/idmapd/idmapd.c | 21 ++++++-------- utils/mountd/mountd.c | 29 +++++++++---------- utils/nfsd/nfsd.c | 4 +-- utils/statd/monitor.c | 3 +- utils/statd/rmtcall.c | 60 ++++++++++++++++++++++++++++++++++++++-- utils/statd/statd.c | 20 ++++++++------ utils/statd/statd.h | 1 + utils/statd/svc_run.c | 3 +- utils/svcgssd/svcgssd.c | 11 +++----- 16 files changed, 172 insertions(+), 53 deletions(-) create mode 100644 support/nfs/closeall.c diff --git a/ChangeLog b/ChangeLog index ddb0082..df3ae49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2005-10-06 Steve Dickson NeilBrown + * support/nfs/export.c: don't warn about sync/async for readonly + exports + * support/nfs/closeall.c: new file with function to close all + file descriptors from a give minimum upwards. + * nfsd/mountd/statd/idmapd/gsssvcd: use closeall. + * utils/mountd/mountd.c: Eliminate 3 syslog message that are + logged for successful events. + * utils/mountd/mountd.c: make sure the correct hostname is used in + the SM_NOTIFY message that is sent from a rebooted server which + has multiple network interfaces. (bz 139101) + + Details can be found in: + https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=139101 + + *utils/idmapd/idmapd.c:Fixed subscripting problem in idmapd (bz + 158188) This fixes the following problem: + rpc.idmapd: nfsdreopen: Opening '' failed: errno 2 (No such file or directory) + + Details can be found in: + https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=158188 + + *utils/statd/statd.c(drop_privs): clear st_gid as well as st_uid + of stat fails. + *utils/statd/svc_run.c(my_svc_run): remove usage of undocumented + %m format specifier. + *utils/statd/montor.c(sm_mon_1_svc): as above + *support/nfs/xlog.c(xlog): Changed xlog to use LOG_INFO instead of + LOG_DEBUG so debug messages will appear w/out any config changes + to syslog.conf. + + 2005-09-02 Mike Frysinger * utils/rquotad/rquota_server.c(getquotainfo): use explicit struture-member copying rather than memcpy, as the element diff --git a/support/include/nfslib.h b/support/include/nfslib.h index 2fbd0f5..a1932a5 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -137,6 +137,8 @@ int qword_get_int(char **bpp, int *anint); void cache_flush(int force); int check_new_cache(void); +void closeall(int min); + /* lockd. */ int lockdsvc(); diff --git a/support/nfs/Makefile b/support/nfs/Makefile index fb8f508..7740224 100644 --- a/support/nfs/Makefile +++ b/support/nfs/Makefile @@ -6,7 +6,7 @@ LIBNAME = libnfs.a OBJS = exports.o rmtab.o xio.o \ rpcmisc.o rpcdispatch.o xlog.o xmalloc.o wildmat.o \ nfssvc.o nfsclient.o nfsexport.o getfh.o nfsctl.o \ - lockdsvc.o svc_socket.o cacheio.o + lockdsvc.o svc_socket.o cacheio.o closeall.o include $(TOP)rules.mk diff --git a/support/nfs/closeall.c b/support/nfs/closeall.c new file mode 100644 index 0000000..cc7fb3b --- /dev/null +++ b/support/nfs/closeall.c @@ -0,0 +1,31 @@ +/* + * support/nfs/closeall.c + * Close all file descriptors greater than some limit, + * Use readdir "/proc/self/fd" to avoid excess close(2) calls. + */ + +#include +#include +#include + +void +closeall(int min) +{ + DIR *dir = opendir("/proc/self/fd"); + if (dir != NULL) { + int dfd = dirfd(dir); + struct dirent *d; + + while ((d = readdir(dir)) != NULL) { + char *endp; + long n = strtol(d->d_name, &endp, 10); + if (*endp != '\0' && n >= min && n != dfd) + (void) close(n); + } + closedir(dir); + } else { + int fd = sysconf(_SC_OPEN_MAX); + while (--fd >= min) + (void) close(fd); + } +} diff --git a/support/nfs/exports.c b/support/nfs/exports.c index 43e68b1..1048c80 100644 --- a/support/nfs/exports.c +++ b/support/nfs/exports.c @@ -448,7 +448,7 @@ bad_option: ep->e_nsqgids = nsqgids; out: - if (warn && !had_sync_opt) + if (warn && !had_sync_opt && !(ep->e_flags & NFSEXP_READONLY)) xlog(L_WARNING, "%s [%d]: No 'sync' or 'async' option specified for export \"%s:%s\".\n" " Assuming default behaviour ('sync').\n" " NOTE: this default has changed from previous versions\n", diff --git a/support/nfs/xlog.c b/support/nfs/xlog.c index e1e4c3f..d59f27f 100644 --- a/support/nfs/xlog.c +++ b/support/nfs/xlog.c @@ -161,7 +161,7 @@ xlog(int kind, const char *fmt, ...) break; default: if (!log_stderr) - syslog(LOG_DEBUG, "%s", buff); + syslog(LOG_INFO, "%s", buff); break; } } diff --git a/utils/idmapd/Makefile b/utils/idmapd/Makefile index 41314ef..4e432ad 100644 --- a/utils/idmapd/Makefile +++ b/utils/idmapd/Makefile @@ -6,7 +6,7 @@ TOP = ../../ PROGRAM = idmapd PREFIX = rpc. OBJS = atomicio.o cfg.o idmapd.o setproctitle.o strlcat.o strlcpy.o -LIBS = -levent -lnfsidmap +LIBS = -levent -lnfsidmap -lnfs MAN8 = idmapd MAN5 = idmapd.conf diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c index 80819d4..3be8148 100644 --- a/utils/idmapd/idmapd.c +++ b/utils/idmapd/idmapd.c @@ -91,8 +91,8 @@ (w) = p; \ } while (0) -#define IC_IDNAME 1 -#define IC_NAMEID 2 +#define IC_IDNAME 0 +#define IC_NAMEID 1 struct idmap_client { int ic_fd; int ic_dirfd; @@ -622,8 +622,8 @@ nfsdreopen() static int nfsdopen(char *path) { - return ((nfsdopenone(&nfsd_ic[0], IC_NAMEID, path) == 0 && - nfsdopenone(&nfsd_ic[1], IC_IDNAME, path) == 0) ? 0 : -1); + return ((nfsdopenone(&nfsd_ic[IC_NAMEID], IC_NAMEID, path) == 0 && + nfsdopenone(&nfsd_ic[IC_IDNAME], IC_IDNAME, path) == 0) ? 0 : -1); } static int @@ -846,7 +846,7 @@ int pipefds[2] = { -1, -1}; void mydaemon(int nochdir, int noclose) { - int pid, status, tempfd, fdmax, filedes; + int pid, status, tempfd; if (pipe(pipefds) < 0) err(1, "mydaemon: pipe() failed: errno %d (%s)\n", errno, strerror(errno)); @@ -879,13 +879,10 @@ mydaemon(int nochdir, int noclose) if (noclose == 0) { 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); + closeall(3); } return; diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 7325b25..a9ec1c7 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -104,10 +104,11 @@ mount_dump_1_svc(struct svc_req *rqstp, void *argp, mountlist *res) { struct sockaddr_in *addr = (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); - xlog(L_NOTICE, "dump request from %s", - inet_ntoa(addr->sin_addr)); - *res = mountlist_list(); + if ((*res = mountlist_list()) == NULL) + xlog(L_WARNING, "dump request from %s failed.", + inet_ntoa(addr->sin_addr)); + return 1; } @@ -157,9 +158,11 @@ mount_export_1_svc(struct svc_req *rqstp, void *argp, exports *resp) { struct sockaddr_in *addr = (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); - xlog(L_NOTICE, "export request from %s", - inet_ntoa(addr->sin_addr)); - *resp = get_exportlist(); + + if ((*resp = get_exportlist()) == NULL) + xlog(L_WARNING, "export request from %s failed.", + inet_ntoa(addr->sin_addr)); + return 1; } @@ -168,9 +171,10 @@ mount_exportall_1_svc(struct svc_req *rqstp, void *argp, exports *resp) { struct sockaddr_in *addr = (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); - xlog(L_NOTICE, "exportall request from %s", - inet_ntoa(addr->sin_addr)); - *resp = get_exportlist(); + + if ((*resp = get_exportlist()) == NULL) + xlog(L_WARNING, "exportall request from %s failed.", + inet_ntoa(addr->sin_addr)); return 1; } @@ -557,11 +561,8 @@ main(int argc, char **argv) sigaction(SIGCHLD, &sa, NULL); /* Daemons should close all extra filehandles ... *before* RPC init. */ - if (!foreground) { - int fd = sysconf (_SC_OPEN_MAX); - while (--fd > 2) - (void) close(fd); - } + if (!foreground) + closeall(3); new_cache = check_new_cache(); if (new_cache) diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c index 86e8094..78143ed 100644 --- a/utils/nfsd/nfsd.c +++ b/utils/nfsd/nfsd.c @@ -80,9 +80,7 @@ main(int argc, char **argv) (void) dup2(fd, 1); (void) dup2(fd, 2); } - fd = sysconf(_SC_OPEN_MAX); - while (--fd > 2) - (void) close(fd); + closeall(3); if ((error = nfssvc(port, count)) < 0) { int e = errno; 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 #include #include +#include #include #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 #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #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 #include "statd.h" #include "version.h" +#include "nfslib.h" /* Socket operations */ #include @@ -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: diff --git a/utils/svcgssd/svcgssd.c b/utils/svcgssd/svcgssd.c index 3b5a981..3059253 100644 --- a/utils/svcgssd/svcgssd.c +++ b/utils/svcgssd/svcgssd.c @@ -113,13 +113,10 @@ mydaemon(int nochdir, int noclose) if (noclose == 0) { 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); + closeall(3); } return; -- 2.39.2