+2005-01-17 Ion Badulescu <ionut@moisil.badula.org>
+
+ * NEWS: document the ability to restart old mount points
+
+ * amd/map.c (mount_auto_node): force the fileid of the
+ root to be 1, so that it won't change between restarts; use the
+ root filesystem's own methods instead of hard-coding the use of
+ the default methods
+
+ * conf/transp/transp_tli.c (create_nfs_service): better cleanup on
+ error conditions.
+ (bind_resv_port2): allow the caller to request a certain port.
+
+ * conf/transp/transp_sockets.c (bind_resv_port): allow the caller
+ to request a certain port.
+ (create_nfs_service): better cleanup on error conditions.
+
+ * amd/restart.c (restart_automounter_nodes): new function, takes
+ care of restarting automounter NFS mount points (autofs will come
+ later).
+ (restart): skip all automounter mount points.
+
+ * amd/nfs_subr.c (fh_to_mp3, mp_to_fh): new filehandle
+ implementation: if the path to the node is shorter than sizeof(fh)
+ chars (currently 32 chars for a NFSv2 fh), simply store it inside
+ the fh. For longer paths, keep the old implementation.
+
+ * amd/nfs_start.c (mount_automounter): reorder things so that
+ restarting the toplvl filesystems occurs before anything else (so
+ that we can grab all the ports we need before we accidentally use
+ them for something else).
+
+ * amd/mntfs.c (locate_mntfs): remove dead code; add special
+ handling of restarted toplvl filesystems.
+
+ * amd/mapc.c (root_keyiter): fix up a comment.
+
+ * amd/map.c (path_to_exported_ap): new function, searches for and
+ returns a node by the path to it.
+ (get_root_nfs_fh): remove unnecessary fiddling with the root fh.
+
+ * config.guess.long: support Red Hat Enterprise Linux
+
2005-01-17 Erez Zadok <ezk@cs.sunysb.edu>
* libamu/util.c (rmdirs): prevent amd from logging 'Read-only
value, and you get ESTALE errors on your particular OS, then set this
value back to 0 seconds.
+- support restarting the automounter's own mount points (only over NFS,
+ for now).
+
- fully support WebNFS as per RFC 2054. It now tries v3/TCP first, falling
back to v2/UDP if this doesn't work. The "webnfs" pseudo-mount options
has been renamed (again) to "public" to match Solaris 2.
- restructured the restarting of already-mounted filesystems, in the process
- also fixing a problem with restarting nfsx components
+ also fixing a problem with restarting nfsx components.
- support escaped slashes, needed for SMB mounts. Use '\\\/\\\/' in a
string to get a double slash.
* SUCH DAMAGE.
*
*
- * $Id: amd.c,v 1.30 2005/01/14 01:14:00 ezk Exp $
+ * $Id: amd.c,v 1.31 2005/01/18 03:01:24 ib42 Exp $
*
*/
if (gopt.flags & CFM_PROCESS_LOCK) {
do_memory_locking();
}
- sprintf(pid_fsname, "%s:(pid%ld)", am_get_hostname(), (long) am_mypid);
do_mapc_reload = clocktime() + gopt.map_reload_interval;
* SUCH DAMAGE.
*
*
- * $Id: amd.h,v 1.55 2005/01/14 01:14:00 ezk Exp $
+ * $Id: amd.h,v 1.56 2005/01/18 03:01:24 ib42 Exp $
*
*/
* when transmitted.
*/
struct am_fh {
+ int fhh_type; /* old or new am_fh */
int fhh_pid; /* process id */
int fhh_id; /* map id */
u_int fhh_gen; /* generation number */
extern am_node *get_exported_ap(int index);
extern am_node *get_first_exported_ap(int *index);
extern am_node *get_next_exported_ap(int *index);
+extern am_node *path_to_exported_ap(char *path);
extern am_node *exported_ap_alloc(void);
extern am_node *find_mf(mntfs *);
extern am_node *next_map(int *);
extern void rem_que(qelem *);
extern void reschedule_timeout_mp(void);
extern void restart(void);
+extern void restart_automounter_nodes(void);
extern int root_keyiter(key_fun *, opaque_t);
extern void root_newmap(const char *, const char *, const char *, const cf_map_t *);
extern void run_task(task_fun *, opaque_t, cb_fun *, opaque_t);
* SUCH DAMAGE.
*
*
- * $Id: amfs_generic.c,v 1.27 2005/01/03 20:56:45 ezk Exp $
+ * $Id: amfs_generic.c,v 1.28 2005/01/18 03:01:24 ib42 Exp $
*
*/
if (mf->mf_fo && mf->mf_fo->opt_sublink)
mp->am_link = strdup(mf->mf_fo->opt_sublink);
- if (mf->mf_flags & MFF_MOUNTED) {
- dlog("duplicate mount of \"%s\" ...", mf->mf_info);
- /*
- * Skip initial processing of the mountpoint if already mounted.
- * This could happen if we have multiple sublinks into the same f/s.
- */
- goto already_mounted;
- }
-
- if (mf->mf_fo->fs_mtab) {
- plog(XLOG_MAP, "Trying mount of %s on %s fstype %s mount_type %s",
- mf->mf_fo->fs_mtab, mf->mf_mount, p->fs_type,
- mp->am_flags & AMF_AUTOFS ? "autofs" : "non-autofs");
- }
-
/*
* Will usually need to play around with the mount nodes
* file attribute structure. This must be done here.
else
mk_fattr(&mp->am_fattr, NFLNK);
+ if (mf->mf_flags & MFF_MOUNTED) {
+ dlog("duplicate mount of \"%s\" ...", mf->mf_info);
+ /*
+ * Skip initial processing of the mountpoint if already mounted.
+ * This could happen if we have multiple sublinks into the same f/s,
+ * or if we are restarting an already-mounted filesystem.
+ */
+ goto already_mounted;
+ }
+
+ if (mf->mf_fo->fs_mtab) {
+ plog(XLOG_MAP, "Trying mount of %s on %s fstype %s mount_type %s",
+ mf->mf_fo->fs_mtab, mf->mf_mount, p->fs_type,
+ mp->am_flags & AMF_AUTOFS ? "autofs" : "non-autofs");
+ }
+
if (p->fs_init && !(mf->mf_flags & MFF_RESTART))
this_error = p->fs_init(mf);
* SUCH DAMAGE.
*
*
- * $Id: autil.c,v 1.47 2005/01/14 01:14:00 ezk Exp $
+ * $Id: autil.c,v 1.48 2005/01/18 03:01:24 ib42 Exp $
*
*/
/*
* Do mounted callback
*/
- if (mf->mf_ops->mounted) {
- (*mf->mf_ops->mounted) (mf);
- }
+ if (mf->mf_ops->mounted)
+ mf->mf_ops->mounted(mf);
free_opts(mf->mf_fo);
XFREE(mf->mf_fo);
* SUCH DAMAGE.
*
*
- * $Id: map.c,v 1.50 2005/01/03 20:56:45 ezk Exp $
+ * $Id: map.c,v 1.51 2005/01/18 03:01:24 ib42 Exp $
*
*/
}
+/*
+ * Get exported_ap by path
+ */
+am_node *
+path_to_exported_ap(char *path)
+{
+ int index;
+ am_node *mp;
+
+ mp = get_first_exported_ap(&index);
+ while (mp != NULL) {
+ if (STREQ(mp->am_path, path))
+ break;
+ mp = get_next_exported_ap(&index);
+ }
+ return mp;
+}
+
+
/*
* Resize exported_ap map
*/
am_node *mp = get_root_ap(dir);
if (mp) {
mp_to_fh(mp, &nfh);
- /*
- * Patch up PID to match main server...
- */
- if (!foreground) {
- long pid = getppid();
- ((struct am_fh *) &nfh)->fhh_pid = pid;
- dlog("get_root_nfs_fh substitutes pid %ld", (long) pid);
- }
return &nfh;
}
{
int error = 0;
am_node *mp = (am_node *) arg;
- am_node *am;
+ am_node *new_mp;
+
+ new_mp = mp->am_mnt->mf_ops->lookup_child(mp, dir, &error, VLOOK_CREATE);
+ if (new_mp && error < 0) {
+ /*
+ * We can't allow the fileid of the root node to change.
+ * Should be ok to force it to 1, always.
+ */
+ new_mp->am_gen = new_mp->am_fattr.na_fileid = 1;
+
+ new_mp = mp->am_mnt->mf_ops->mount_child(new_mp, &error);
+ }
- /*
- * this should be:
- * mp->am_mnt->mf_opts->lookup_child(.....);
- *
- * as it is, it uses the generic methods regardless
- * of the parent filesystem's type
- */
- am = amfs_generic_lookup_child(mp, dir, &error, VLOOK_CREATE);
- if (am && error < 0)
- am = amfs_generic_mount_child(am, &error);
if (error > 0) {
errno = error; /* XXX */
plog(XLOG_ERROR, "Could not mount %s: %m", dir);
* SUCH DAMAGE.
*
*
- * $Id: mapc.c,v 1.21 2005/01/03 20:56:45 ezk Exp $
+ * $Id: mapc.c,v 1.22 2005/01/18 03:01:24 ib42 Exp $
*
*/
/*
* Iterate on the root map and call (*fn)() on the key of all the nodes.
- * Finally throw away the root map.
+ * Returns the number of entries in the root map.
*/
int
root_keyiter(key_fun *fn, opaque_t arg)
* SUCH DAMAGE.
*
*
- * $Id: mntfs.c,v 1.35 2005/01/03 20:56:45 ezk Exp $
+ * $Id: mntfs.c,v 1.36 2005/01/18 03:01:24 ib42 Exp $
*
*/
*/
if (mf->mf_ops != &amfs_error_ops)
continue;
- else
- return dup_mntfs(mf);
+ return dup_mntfs(mf);
}
-#if 0
- if ((mf->mf_flags & MFF_RESTART) && amd_state == Run) {
+ dlog("mf->mf_flags = %#x", mf->mf_flags);
+ mf->mf_fo = mo;
+ if ((mf->mf_flags & MFF_RESTART) && amd_state < Finishing) {
/*
* Restart a previously mounted filesystem.
*/
- mntfs *mf2 = alloc_mntfs(&amfs_inherit_ops, mo, mp, info, auto_opts, mopts, remopts);
dlog("Restarting filesystem %s", mf->mf_mount);
/*
- * Remember who we are restarting
+ * If we are restarting an amd internal filesystem,
+ * we need to initialize it a bit.
+ *
+ * We know it's internal because it is marked as toplvl.
*/
- mf2->mf_private = (voidp) dup_mntfs(mf);
- mf2->mf_prfree = free_mntfs;
- return mf2;
- }
+ if (mf->mf_ops == &amfs_toplvl_ops) {
+ mf->mf_ops = ops;
+ mf->mf_info = strealloc(mf->mf_info, info);
+ ops->mounted(mf); /* XXX: not right, but will do for now */
+ }
- mf->mf_fo = mo;
-#else
- mf->mf_fo = mo;
- if ((mf->mf_flags & MFF_RESTART) && amd_state == Run) {
- /*
- * Restart a previously mounted filesystem.
- */
- dlog("Restarting filesystem %s", mf->mf_mount);
return mf;
}
-#endif
if (!(mf->mf_flags & (MFF_MOUNTED | MFF_MOUNTING | MFF_UNMOUNTING))) {
fserver *fs;
* SUCH DAMAGE.
*
*
- * $Id: nfs_start.c,v 1.22 2005/01/03 20:56:45 ezk Exp $
+ * $Id: nfs_start.c,v 1.23 2005/01/18 03:01:24 ib42 Exp $
*
*/
#endif /* not SELECT_MAXWAIT */
SVCXPRT *nfsxprt;
-u_short nfs_port;
+u_short nfs_port = 0;
#ifndef HAVE_SIGACTION
# define MASKED_SIGS (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGCHLD)|sigmask(SIGHUP))
struct timeval tvv;
int nsel;
time_t now;
-#ifdef HAVE_SVC_GETREQSET
fd_set readfds;
+#ifdef HAVE_SVC_GETREQSET
memmove(&readfds, &svc_fdset, sizeof(svc_fdset));
- FD_SET(fwd_sock, &readfds);
#else /* not HAVE_SVC_GETREQSET */
- fd_set readfds;
FD_ZERO(&readfds);
# ifdef HAVE_FD_SET_FDS_BITS
readfds.fds_bits[0] = svc_fds;
# else /* not HAVE_FD_SET_FDS_BITS */
readfds = svc_fds;
# endif /* not HAVE_FD_SET_FDS_BITS */
- FD_SET(fwd_sock, &readfds);
#endif /* not HAVE_SVC_GETREQSET */
+ FD_SET(fwd_sock, &readfds);
checkup();
int udp_soAMQ, tcp_soAMQ;
struct netconfig *udp_amqncp, *tcp_amqncp;
+ /*
+ * This must be done first, because it attempts to bind
+ * to various UDP ports and we don't want anything else
+ * potentially taking over those ports before we get a chance
+ * to reserve them.
+ */
+ if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS)
+ restart_automounter_nodes();
+
+ /*
+ * Start RPC forwarding
+ */
+ if (fwd_init() != 0)
+ return 3;
+
+ /*
+ * Construct the root automount node
+ */
+ make_root_node();
+
+ /*
+ * Pick up the pieces from a previous run
+ * This is likely to (indirectly) need the rpc_fwd package
+ * so it *must* come after the call to fwd_init().
+ */
+ if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS)
+ restart();
+
/*
* Create the nfs service for amd
+ * If nfs_port is already initialized, it means we
+ * already created the service during restart_automounter_nodes().
*/
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
- if (ret != 0)
- return ret;
+ if (nfs_port == 0) {
+ ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
+ if (ret != 0)
+ return ret;
+ }
+ sprintf(pid_fsname, "%s:(pid%ld,port%u)", am_get_hostname(), (long) am_mypid, nfs_port);
+
/* security: if user sets -D amq, don't even create listening socket */
if (!amuDebug(D_AMQ)) {
ret = create_amq_service(&udp_soAMQ, &udp_amqp, &udp_amqncp, &tcp_soAMQ, &tcp_amqp, &tcp_amqncp);
}
#endif /* HAVE_FS_AUTOFS */
- /*
- * Start RPC forwarding
- */
- if (fwd_init() != 0)
- return 3;
-
- /*
- * Construct the root automount node
- */
- make_root_node();
-
- /*
- * Pick up the pieces from a previous run
- * This is likely to (indirectly) need the rpc_fwd package
- * so it *must* come after the call to fwd_init().
- */
- if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS)
- restart();
-
/*
* Mount the top-level auto-mountpoints
*/
* SUCH DAMAGE.
*
*
- * $Id: nfs_subr.c,v 1.21 2005/01/03 20:56:45 ezk Exp $
+ * $Id: nfs_subr.c,v 1.22 2005/01/18 03:01:24 ib42 Exp $
*
*/
struct am_fh *fp = (struct am_fh *) fhp;
am_node *ap = 0;
- /*
- * Check process id matches
- * If it doesn't then it is probably
- * from an old kernel cached filehandle
- * which is now out of date.
- */
- if (fp->fhh_pid != am_mypid)
- goto drop;
+ if (fp->fhh_type != 0) {
+ /* New filehandle type */
+ char *path = xmalloc(sizeof(*fhp) + 1);
+ memset(path, 0, sizeof(fhp) + 1);
+ strncpy(path, (char *) fhp, sizeof(*fhp));
+ /* dlog("fh_to_mp3: new filehandle: %s", path); */
- /*
- * Get hold of the supposed mount node
- */
- ap = get_exported_ap(fp->fhh_id);
+ ap = path_to_exported_ap(path);
+ XFREE(path);
+ } else {
+ /* dlog("fh_to_mp3: old filehandle: %d", fp->fhh_id); */
+ /*
+ * Check process id matches
+ * If it doesn't then it is probably
+ * from an old kernel cached filehandle
+ * which is now out of date.
+ */
+ if (fp->fhh_pid != am_mypid)
+ goto drop;
+
+ /*
+ * Get hold of the supposed mount node
+ */
+ ap = get_exported_ap(fp->fhh_id);
+ /*
+ * Check the generation number in the node
+ * matches the one from the kernel. If not
+ * then the old node has been timed out and
+ * a new one allocated.
+ */
+ if (ap->am_gen != fp->fhh_gen)
+ ap = 0;
+ }
/*
* If it doesn't exists then drop the request
if (!ap)
goto drop;
- /*
- * Check the generation number in the node
- * matches the one from the kernel. If not
- * then the old node has been timed out and
- * a new one allocated.
- */
- if (ap->am_gen != fp->fhh_gen) {
- ap = 0;
- goto drop;
- }
-
#if 0
/*
* If the node is hung then locate a new node
void
mp_to_fh(am_node *mp, am_nfs_fh *fhp)
{
- struct am_fh *fp = (struct am_fh *) fhp;
+ int pathlen;
memset((char *) fhp, 0, sizeof(am_nfs_fh));
- /*
- * Take the process id
- */
- fp->fhh_pid = am_mypid;
+ pathlen = strlen(mp->am_path);
+ if (pathlen <= sizeof(*fhp)) {
+ /* dlog("mp_to_fh: new filehandle: %s", mp->am_path); */
+ strncpy((char *) fhp, mp->am_path, pathlen);
+ } else {
+ struct am_fh *fp = (struct am_fh *) fhp;
- /*
- * ... the map number
- */
- fp->fhh_id = mp->am_mapno;
+ /*
+ * Take the process id
+ */
+ fp->fhh_pid = am_mypid;
- /*
- * ... and the generation number
- */
- fp->fhh_gen = mp->am_gen;
+ /*
+ * ... the map number
+ */
+ fp->fhh_id = mp->am_mapno;
- /*
- * ... to make a "unique" triple that will never
- * be reallocated except across reboots (which doesn't matter)
- * or if we are unlucky enough to be given the same
- * pid as a previous amd (very unlikely).
- */
+ /*
+ * ... and the generation number
+ */
+ fp->fhh_gen = mp->am_gen;
+
+ /*
+ * ... to make a "unique" triple that will never
+ * be reallocated except across reboots (which doesn't matter)
+ * or if we are unlucky enough to be given the same
+ * pid as a previous amd (very unlikely).
+ */
+ /* dlog("mp_to_fh: old filehandle: %d", fp->fhh_id); */
+ }
}
* SUCH DAMAGE.
*
*
- * $Id: restart.c,v 1.11 2005/01/03 20:56:45 ezk Exp $
+ * $Id: restart.c,v 1.12 2005/01/18 03:01:24 ib42 Exp $
*
*/
*
* Scan through the mount list finding all "interesting" mount points.
* Next hack up partial data structures and add the mounted file
- * system to the list of known filesystems. This will leave a
- * dangling reference to that filesystems, so when the filesystem is
- * finally inherited, an extra "free" must be done on it.
+ * system to the list of known filesystems.
*
* This module relies on internal details of other components. If
* you change something else make *sure* restart() still works.
mntent_t *me = mlp->mnt;
am_ops *fs_ops = 0;
+ if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
+ /*
+ * NFS entry, or possibly an Amd entry...
+ * The mnt_fsname for daemon mount points is
+ * host:(pidXXX)
+ * or (seen on Solaris)
+ * host:daemon(pidXXX)
+ */
+ char *colon = strchr(me->mnt_fsname, ':');
+ if (colon && strstr(colon, "(pid"))
+ continue;
+ }
+
/* Search for the correct filesystem ops */
fs_ops = ops_search(me->mnt_type);
if (!fs_ops)
fs_ops = &amfs_link_ops;
+ restart_fake_mntfs(me, fs_ops);
+ }
+
+ /*
+ * Free the mount list
+ */
+ free_mntlist(ml);
+}
+
+
+/*
+ * Handle an amd restart for amd's own mount points.
+ *
+ * Scan through the mount list finding all daemon mount points
+ * (determined by the presence of a pid inside the mount info).
+ * Next hack up partial data structures and add the mounted file
+ * system to the list of known filesystems.
+ *
+ * This module relies on internal details of other components. If
+ * you change something else make *sure* restart() still works.
+ */
+void
+restart_automounter_nodes(void)
+{
+ /*
+ * Read the existing mount table
+ */
+ mntlist *ml, *mlp;
+
+ /* Reasonably sized list of restarted nfs ports */
+ u_short old_ports[256];
+ {
+ int i;
+ for (i = 0; i < 256; i++)
+ old_ports[i] = 0;
+ }
+
+ /*
+ * For each entry, find nfs, ufs or auto mounts
+ * and create a partial am_node to represent it.
+ */
+ for (mlp = ml = read_mtab("restart", mnttab_file_name);
+ mlp;
+ mlp = mlp->mnext) {
+ mntent_t *me = mlp->mnt;
+ am_ops *fs_ops = 0;
+
if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
/*
* NFS entry, or possibly an Amd entry...
* host:daemon(pidXXX)
*/
char *colon = strchr(me->mnt_fsname, ':');
-
if (colon && strstr(colon, "(pid")) {
+ long pid;
+ u_short port;
+ int err = 1;
+
plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
- fs_ops = &amfs_link_ops;
+
+ /* Is the old automounter still alive? */
+ if (sscanf(colon, "%*[^(](pid%ld%*[,)]", &pid) != 1) {
+ plog(XLOG_WARNING, "Can't parse pid in %s", me->mnt_fsname);
+ goto give_up;
+ }
+ if (kill(pid, 0) != -1 || errno != ESRCH) {
+ plog(XLOG_WARNING, "Automounter (pid: %ld) still alive", pid);
+ goto give_up;
+ }
+
+ /*
+ * Do we have a map for this mount point?
+ * Who cares, we'll restart anyway -- getting ESTALE
+ * is way better than hanging.
+ */
+
+ /* Can we restart it? Only if it tells us what port it was using... */
+ if (sscanf(colon, "%*[^,],port%hu)", &port) != 1) {
+ plog(XLOG_WARNING, "No port specified for %s", me->mnt_fsname);
+ goto give_up;
+ }
+
+ /* Maybe we already own that port... */
+ if (port != nfs_port) {
+ int i;
+ for (i = 0; i < 256; i++) {
+ if (old_ports[i] == port ||
+ old_ports[i] == 0)
+ break;
+ }
+ if (i == 256) {
+ plog(XLOG_WARNING, "Too many open ports (256)");
+ goto give_up;
+ }
+
+ if (old_ports[i] == 0) {
+ int soNFS;
+ SVCXPRT *nfsxprt;
+ if (create_nfs_service(&soNFS, &port, &nfsxprt, nfs_program_2) != 0) {
+ plog(XLOG_WARNING, "Can't bind to port %u", port);
+ goto give_up;
+ }
+ old_ports[i] = nfs_port = port;
+ }
+ }
+ err = 0;
+
+ give_up:
+ if (err) {
+ plog(XLOG_WARNING, "Can't restart %s, leaving it alone", me->mnt_dir);
+ fs_ops = &amfs_link_ops;
+ } else {
+ fs_ops = &amfs_toplvl_ops;
+ }
+
+ restart_fake_mntfs(me, fs_ops);
}
}
-
- restart_fake_mntfs(me, fs_ops);
}
/*
* SUCH DAMAGE.
*
*
- * $Id: transp_sockets.c,v 1.30 2005/01/14 03:29:45 ezk Exp $
+ * $Id: transp_sockets.c,v 1.31 2005/01/18 03:01:24 ib42 Exp $
*
* Socket specific utilities.
* -Erez Zadok <ezk@cs.columbia.edu>
memset((voidp) &sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- port = IPPORT_RESERVED;
-
- do {
- --port;
- sin.sin_port = htons(port);
+ if (pp && *pp > 0) {
+ sin.sin_port = htons(*pp);
rc = bind(so, (struct sockaddr *) &sin, sizeof(sin));
- } while (rc < 0 && (int) port > IPPORT_RESERVED / 2);
+ } else {
+ port = IPPORT_RESERVED;
- if (pp && rc == 0)
- *pp = port;
+ do {
+ --port;
+ sin.sin_port = htons(port);
+ rc = bind(so, (struct sockaddr *) &sin, sizeof(sin));
+ } while (rc < 0 && (int) port > IPPORT_RESERVED / 2);
+
+ if (pp && rc == 0)
+ *pp = port;
+ }
return rc;
}
*soNFSp = socket(AF_INET, SOCK_DGRAM, 0);
- if (*soNFSp < 0 || bind_resv_port(*soNFSp, NULL) < 0) {
+ if (*soNFSp < 0 || bind_resv_port(*soNFSp, nfs_portp) < 0) {
plog(XLOG_FATAL, "Can't create privileged nfs port (socket)");
+ if (*soNFSp >= 0)
+ close(*soNFSp);
return 1;
}
if ((*nfs_xprtp = svcudp_create(*soNFSp)) == NULL) {
plog(XLOG_FATAL, "cannot create rpc/udp service");
+ close(*soNFSp);
return 2;
}
if ((*nfs_portp = (*nfs_xprtp)->xp_port) >= IPPORT_RESERVED) {
plog(XLOG_FATAL, "Can't create privileged nfs port");
+ svc_destroy(*nfs_xprtp);
+ close(*soNFSp);
return 1;
}
if (!svc_register(*nfs_xprtp, NFS_PROGRAM, NFS_VERSION, dispatch_fxn, 0)) {
plog(XLOG_FATAL, "unable to register (%ld, %ld, 0)",
(u_long) NFS_PROGRAM, (u_long) NFS_VERSION);
+ svc_destroy(*nfs_xprtp);
+ close(*soNFSp);
return 3;
}
* SUCH DAMAGE.
*
*
- * $Id: transp_tli.c,v 1.25 2005/01/14 03:29:45 ezk Exp $
+ * $Id: transp_tli.c,v 1.26 2005/01/18 03:01:24 ib42 Exp $
*
* TLI specific utilities.
* -Erez Zadok <ezk@cs.columbia.edu>
* How to bind to reserved ports.
* (port-only) version.
*/
-int
+static int
bind_resv_port2(u_short *pp)
{
int td, rc = -1, port;
treq->qlen = 0;
treq->addr.len = treq->addr.maxlen;
errno = EADDRINUSE;
- port = IPPORT_RESERVED;
- do {
- --port;
- sin->sin_port = htons(port);
+ if (pp && *pp > 0) {
+ sin->sin_port = htons(*pp);
rc = t_bind(td, treq, tret);
- if (rc < 0) {
- plog(XLOG_ERROR, "t_bind for port %d: %s", port, t_errlist[t_errno]);
- } else {
- if (memcmp(treq->addr.buf, tret->addr.buf, tret->addr.len) == 0)
- break;
- else
- t_unbind(td);
- }
- } while ((rc < 0 || errno == EADDRINUSE) && (int) port > IPPORT_RESERVED / 2);
+ } else {
+ port = IPPORT_RESERVED;
+
+ do {
+ --port;
+ sin->sin_port = htons(port);
+ rc = t_bind(td, treq, tret);
+ if (rc < 0) {
+ plog(XLOG_ERROR, "t_bind for port %d: %s", port, t_errlist[t_errno]);
+ } else {
+ if (memcmp(treq->addr.buf, tret->addr.buf, tret->addr.len) == 0)
+ break;
+ else
+ t_unbind(td);
+ }
+ } while ((rc < 0 || errno == EADDRINUSE) && (int) port > IPPORT_RESERVED / 2);
+
+ if (pp && rc == 0)
+ *pp = port;
+ }
- if (pp && rc == 0)
- *pp = port;
t_free((char *) tret, T_BIND);
t_free((char *) treq, T_BIND);
return rc;
*soNFSp = (*nfs_xprtp)->xp_fd;
if (*soNFSp < 0 || bindnfs_port(*soNFSp, nfs_portp) < 0) {
plog(XLOG_ERROR, "Can't create privileged nfs port (TLI)");
+ svc_destroy(*nfs_xprtp);
return 1;
}
if (svc_reg(*nfs_xprtp, NFS_PROGRAM, NFS_VERSION, dispatch_fxn, NULL) != 1) {
plog(XLOG_ERROR, "could not register amd NFS service");
+ svc_destroy(*nfs_xprtp);
return 1;
}
GCONFIG=`echo ${GCONFIG} | sed -e 's/i.86/i386/' -e 's/linux-gnu/linux/'`
if test -f /etc/redhat-release ; then
long=`getver /etc/redhat-release`
- # determine if it's Red Hat or Fedora
- if grep -qi fedora /etc/redhat-release ; then
+ if grep -q 'Red Hat Enterprise Linux' /etc/redhat-release; then
+ echo ${GCONFIG}-rhel${long}
+ elif grep -q 'Fedora Core' /etc/redhat-release; then
echo ${GCONFIG}-fc${long}
else
echo ${GCONFIG}-rh${long}