Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/ypbind in the case where ypbind is serving more tha...
details: https://anonhg.NetBSD.org/src/rev/21224b8d3396
branches: trunk
changeset: 748810:21224b8d3396
user: chuck <chuck%NetBSD.org@localhost>
date: Thu Nov 05 19:34:06 2009 +0000
description:
in the case where ypbind is serving more than one domain (i.e.
not just the yp_get_default_domain() domain), we must remove
any old binding files from /var/yp/binding (BINDINGDIR) from
previous runs, or the non-yp_get_default_domain()'s will not
bind properly. add a purge_bindingdir() function that basically
does "rm BINDINGDIR/*.[0-9]" at ypbind startup time.
example case of where this is an issue: bind a second (non-default)
domain. ypbind will create and flock a /var/yp/binding/xxx.2
file for it. stop and restart ypbind. the old /var/yp/binding/xxx.2
file will remain from the previous run. since it is not flock()'d
by the new instance of ypbind, libc functions like yp_master() will
fail without even bothering to talk to ypbind itself. (and ypbind
is totally unaware of the old file...)
diffstat:
usr.sbin/ypbind/ypbind.c | 54 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 50 insertions(+), 4 deletions(-)
diffs (96 lines):
diff -r 16da23622554 -r 21224b8d3396 usr.sbin/ypbind/ypbind.c
--- a/usr.sbin/ypbind/ypbind.c Thu Nov 05 19:22:57 2009 +0000
+++ b/usr.sbin/ypbind/ypbind.c Thu Nov 05 19:34:06 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ypbind.c,v 1.58 2009/01/18 10:39:17 lukem Exp $ */
+/* $NetBSD: ypbind.c,v 1.59 2009/11/05 19:34:06 chuck Exp $ */
/*
* Copyright (c) 1992, 1993 Theo de Raadt <deraadt%fsa.ca@localhost>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef LINT
-__RCSID("$NetBSD: ypbind.c,v 1.58 2009/01/18 10:39:17 lukem Exp $");
+__RCSID("$NetBSD: ypbind.c,v 1.59 2009/11/05 19:34:06 chuck Exp $");
#endif
#include <sys/param.h>
@@ -129,6 +129,7 @@
static struct _dom_binding *makebinding(const char *);
static int makelock(struct _dom_binding *);
static void removelock(struct _dom_binding *);
+static int purge_bindingdir(char *);
static void *ypbindproc_null_2(SVCXPRT *, void *);
static void *ypbindproc_domain_2(SVCXPRT *, void *);
static void *ypbindproc_setdom_2(SVCXPRT *, void *);
@@ -221,6 +222,49 @@
(void)unlink(path);
}
+/*
+ * purge_bindingdir: remove old binding files (i.e. "rm BINDINGDIR/*.[0-9]")
+ *
+ * local YP functions [e.g. yp_master()] will fail without even talking
+ * to ypbind if there is a stale (non-flock'd) binding file present.
+ * we have to scan the entire BINDINGDIR for binding files, because
+ * ypbind may bind more than just the yp_get_default_domain() domain.
+ */
+static int
+purge_bindingdir(char *dirpath) {
+ DIR *dirp;
+ int unlinkedfiles, l;
+ struct dirent *dp;
+ char pathname[MAXPATHLEN];
+
+ if ((dirp = opendir(dirpath)) == NULL)
+ return(-1); /* at this point, shouldn't ever happen */
+
+ do {
+ unlinkedfiles = 0;
+ while ((dp = readdir(dirp)) != NULL) {
+ l = dp->d_namlen;
+ /* 'rm *.[0-9]' */
+ if (l > 2 && dp->d_name[l-2] == '.' &&
+ dp->d_name[l-1] >= '0' && dp->d_name[l-1] <= '9') {
+ (void)snprintf(pathname, sizeof(pathname),
+ "%s/%s", dirpath, dp->d_name);
+ if (unlink(pathname) < 0 && errno != ENOENT)
+ return(-1);
+ unlinkedfiles++;
+ }
+ }
+
+ /* rescan dir if we removed it */
+ if (unlinkedfiles)
+ rewinddir(dirp);
+
+ } while (unlinkedfiles);
+
+ closedir(dirp);
+ return(0);
+}
+
static void *
/*ARGSUSED*/
ypbindproc_null_2(SVCXPRT *transp, void *argp)
@@ -507,8 +551,6 @@
/* initialise syslog */
openlog("ypbind", LOG_PERROR | LOG_PID, LOG_DAEMON);
- /* blow away everything in BINDINGDIR */
-
lockfd = open(_PATH_YPBIND_LOCK, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644);
if (lockfd == -1)
err(1, "Cannot create %s", _PATH_YPBIND_LOCK);
@@ -559,6 +601,10 @@
if (_yp_invalid_domain(domainname))
errx(1, "bad domainname: %s", domainname);
+ /* blow away old bindings in BINDINGDIR */
+ if (purge_bindingdir(BINDINGDIR) < 0)
+ errx(1, "unable to purge old bindings from %s", BINDINGDIR);
+
/* build initial domain binding, make it "unsuccessful" */
ypbindlist = makebinding(domainname);
ypbindlist->dom_vers = YPVERS;
Home |
Main Index |
Thread Index |
Old Index