예제 #1
0
/*
 * Mount the top-level
 */
int
amfs_toplvl_mount(am_node *mp, mntfs *mf)
{
  struct stat stb;
  char opts[SIZEOF_OPTS], preopts[SIZEOF_OPTS], toplvl_opts[40];
  int error;

  /*
   * Mounting the automounter.
   * Make sure the mount directory exists, construct
   * the mount options and call the mount_amfs_toplvl routine.
   */

  if (stat(mp->am_path, &stb) < 0) {
    return errno;
  } else if ((stb.st_mode & S_IFMT) != S_IFDIR) {
    plog(XLOG_WARNING, "%s is not a directory", mp->am_path);
    return ENOTDIR;
  }

  /*
   * Construct some mount options:
   *
   * Tack on magic map=<mapname> option in mtab to emulate
   * SunOS automounter behavior.
   */

#ifdef HAVE_FS_AUTOFS
  if (mf->mf_flags & MFF_IS_AUTOFS) {
    autofs_get_opts(opts, sizeof(opts), mp->am_autofs_fh);
  } else
#endif /* HAVE_FS_AUTOFS */
  {
    preopts[0] = '\0';
#ifdef MNTTAB_OPT_INTR
    xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts));
    xstrlcat(preopts, ",", sizeof(preopts));
#endif /* MNTTAB_OPT_INTR */
#ifdef MNTTAB_OPT_IGNORE
    xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts));
    xstrlcat(preopts, ",", sizeof(preopts));
#endif /* MNTTAB_OPT_IGNORE */
    /* write most of the initial options + preopts */
    xsnprintf(opts, sizeof(opts), "%s%s,%s=%d,%s,map=%s",
	      preopts,
	      MNTTAB_OPT_RW,
	      MNTTAB_OPT_PORT, nfs_port,
	      mf->mf_ops->fs_type, mf->mf_info);

    /* process toplvl timeo/retrans options, if any */
    if (gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL] > 0) {
      xsnprintf(toplvl_opts, sizeof(toplvl_opts), ",%s=%d",
		MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL]);
      xstrlcat(opts, toplvl_opts, sizeof(opts));
    }
    if (gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL] > 0) {
      xsnprintf(toplvl_opts, sizeof(toplvl_opts), ",%s=%d",
		MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL]);
      xstrlcat(opts, toplvl_opts, sizeof(opts));
    }

#ifdef MNTTAB_OPT_NOLOCK
    xstrlcat(opts, ",", sizeof(opts));
    xstrlcat(opts, MNTTAB_OPT_NOLOCK, sizeof(opts));
#endif /* MNTTAB_OPT_NOLOCK */

#ifdef MNTTAB_OPT_NOAC
    if (gopt.auto_attrcache == 0) {
      xstrlcat(opts, ",", sizeof(opts));
      xstrlcat(opts, MNTTAB_OPT_NOAC, sizeof(opts));
    } else
#endif /* MNTTAB_OPT_NOAC */
      set_auto_attrcache_timeout(preopts, opts, sizeof(preopts));
  }

  /* now do the mount */
  error = amfs_mount(mp, mf, opts);
  if (error) {
    errno = error;
    plog(XLOG_FATAL, "amfs_toplvl_mount: amfs_mount failed: %m");
    return error;
  }
  return 0;
}
예제 #2
0
/*
 * Mount a sub-mount
 */
static int
amfs_auto_mount(am_node *mp, mntfs *mf)
{
  /*
   * Pseudo-directories are used to provide some structure
   * to the automounted directories instead
   * of putting them all in the top-level automount directory.
   *
   * Here, just increment the parent's link count.
   */
  mp->am_parent->am_fattr.na_nlink++;

  /*
   * Info field of . means use parent's info field.
   * Historical - not documented.
   */
  if (mf->mf_info[0] == '.' && mf->mf_info[1] == '\0')
    mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_mnt->mf_info);

  /*
   * Compute prefix:
   *
   * If there is an option prefix then use that else
   * If the parent had a prefix then use that with name
   *      of this node appended else
   * Use the name of this node.
   *
   * That means if you want no prefix you must say so
   * in the map.
   */
  if (mf->mf_fo->opt_pref) {
    /* allow pref:=null to set a real null prefix */
    if (STREQ(mf->mf_fo->opt_pref, "null")) {
      mp->am_pref = strdup("");
    } else {
      /*
       * the prefix specified as an option
       */
      mp->am_pref = strdup(mf->mf_fo->opt_pref);
    }
  } else {
    /*
     * else the parent's prefix
     * followed by the name
     * followed by /
     */
    char *ppref = mp->am_parent->am_pref;
    if (ppref == 0)
      ppref = "";
    mp->am_pref = str3cat((char *) 0, ppref, mp->am_name, "/");
  }

#ifdef HAVE_FS_AUTOFS
  if (mf->mf_flags & MFF_IS_AUTOFS) {
    char opts[SIZEOF_OPTS];
    int error;

    autofs_get_opts(opts, sizeof(opts), mp->am_autofs_fh);

    /* now do the mount */
    error = amfs_mount(mp, mf, opts);
    if (error) {
      errno = error;
      plog(XLOG_FATAL, "amfs_auto_mount: amfs_mount failed: %m");
      return error;
    }
  }
#endif /* HAVE_FS_AUTOFS */

  /*
   * Attach a map cache
   */
  amfs_mkcacheref(mf);

  return 0;
}