* NEWS: document the ability to restart old mount points
authorIon Badulescu <ib42@cs.columbia.edu>
Tue, 18 Jan 2005 03:01:24 +0000 (03:01 +0000)
committerIon Badulescu <ib42@cs.columbia.edu>
Tue, 18 Jan 2005 03:01:24 +0000 (03:01 +0000)
* 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

15 files changed:
ChangeLog
NEWS
amd/amd.c
amd/amd.h
amd/amfs_generic.c
amd/autil.c
amd/map.c
amd/mapc.c
amd/mntfs.c
amd/nfs_start.c
amd/nfs_subr.c
amd/restart.c
conf/transp/transp_sockets.c
conf/transp/transp_tli.c
config.guess.long

index 5a0e3855a6dcbd56f1538d02218969f0239a1264..3e449a8bbeb5b7ecca61bb13acdb2f3ecc00a46a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+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
diff --git a/NEWS b/NEWS
index 3f26c827ac2a233b6d7f091e0fec37f751dd3537..b888d24b437ac30399d2adf3deb0c5af5cb11c35 100644 (file)
--- a/NEWS
+++ b/NEWS
   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.
index e88eaea03bb085c1a96f3dc1977d59fe949d0238..e50a47fcba582773021f7e1a719a693a613ba8df 100644 (file)
--- a/amd/amd.c
+++ b/amd/amd.c
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -571,7 +571,6 @@ main(int argc, char *argv[])
   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;
 
index 8ca31effb32870d3f792046811403c50a7bbbb1e..653e6ad6fd04f5637fae3742fcaa7cefc6c6235f 100644 (file)
--- a/amd/amd.h
+++ b/amd/amd.h
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -485,6 +485,7 @@ struct am_node {
  * 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 */
@@ -533,6 +534,7 @@ extern void am_unmounted(am_node *);
 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 *);
@@ -594,6 +596,7 @@ extern void ops_showfstypes(char *outbuf);
 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);
index e7d793501c43407608f5fd156efd4cd8917615c7..f232d9d4039dfdab21fb76308629500c8cbea588 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -727,21 +727,6 @@ amfs_bgmount(struct continuation *cp)
     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.
@@ -758,6 +743,22 @@ amfs_bgmount(struct continuation *cp)
     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);
 
index 414591e0c888215c8db5824c39509767aa8d1e7d..4efd9b92e67252dd90b862199d85762e609286f6 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -268,9 +268,8 @@ mf_mounted(mntfs *mf)
     /*
      * 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);
index c0bbfdb1b483db0a7c9f3e84fdcf99f62ee87e28..ed128036a714d0a9d73a166733cf7903f785b97d 100644 (file)
--- a/amd/map.c
+++ b/amd/map.c
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -143,6 +143,25 @@ get_exported_ap(int index)
 }
 
 
+/*
+ * 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
  */
@@ -529,14 +548,6 @@ get_root_nfs_fh(char *dir)
   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;
   }
 
@@ -595,18 +606,19 @@ mount_auto_node(char *dir, opaque_t arg)
 {
   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);
index 3b5584cacccc11fa3f05dbd31ed4d0caf8ce1c3f..be1173532fee6dd51593a96676a18232dac1d5ac 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -1042,7 +1042,7 @@ mapc_keyiter(mnt_map *m, key_fun *fn, opaque_t arg)
 
 /*
  * 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)
index 8d0b595206209fa19cc5cbbb50d08353da29ec05..dfa94902a17eec99cea05398bc1c1d63b52a7efb 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -134,37 +134,31 @@ locate_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, ch
         */
        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;
index d4c3471e0b4d75aba8f070e3f23c6dc12393783a..61fe39eed91a9d5f6cd6e2769f00781a173a9a29 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -52,7 +52,7 @@
 #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))
@@ -208,21 +208,19 @@ run_rpc(void)
     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();
 
@@ -337,12 +335,46 @@ mount_automounter(int ppid)
   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);
@@ -364,25 +396,6 @@ mount_automounter(int ppid)
   }
 #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
    */
index 37741ca0d1f13234eaeedaafd9f1095c01f31fa5..55b7dd06cedf26d36f97cc95ba68abca2a50b833 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -612,19 +612,39 @@ fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
   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
@@ -632,17 +652,6 @@ fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
   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
@@ -747,29 +756,38 @@ fh_to_mp(am_nfs_fh *fhp)
 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); */
+  }
 }
index ad71d8bb6b8adbca4642db2cdab5ddf433f4161d..e1811718e4f8f754c320ffea47f8f8da1ab73ad6 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  */
 
@@ -122,9 +122,7 @@ restart_fake_mntfs(mntent_t *me, am_ops *fs_ops)
  *
  * 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.
@@ -147,6 +145,19 @@ restart(void)
     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);
 
@@ -157,6 +168,53 @@ restart(void)
     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...
@@ -166,14 +224,71 @@ restart(void)
        *        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);
   }
 
   /*
index c7eb9fd29d62174e0fd7a171a275c46371633932..ab260b4b335d4ce3b740a423d78b551c97b9d8b2 100644 (file)
@@ -37,7 +37,7 @@
  * 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>
@@ -129,16 +129,21 @@ bind_resv_port(int so, u_short *pp)
   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;
 }
@@ -249,21 +254,28 @@ create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*
 
   *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;
   }
 
index 4488f953c33a62c2c11e240bff2fa0933de62dde..7e0851efdaba817b5f41bda673f5ed235a3b2a0a 100644 (file)
@@ -37,7 +37,7 @@
  * 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>
@@ -154,7 +154,7 @@ bind_resv_port(int td, u_short *pp)
  * How to bind to reserved ports.
  * (port-only) version.
  */
-int
+static int
 bind_resv_port2(u_short *pp)
 {
   int td, rc = -1, port;
@@ -216,24 +216,31 @@ bind_resv_port2(u_short *pp)
   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;
@@ -436,10 +443,12 @@ create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*
   *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;
   }
 
index 03275502390ed83d1d859c1a0106a01377482b93..1c4614bccb34b202f38ae9f04a13be1d0a7927dc 100755 (executable)
@@ -31,8 +31,9 @@ case "${GCONFIG}" in
        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}