コード例 #1
0
ファイル: autofs_solaris_v1.c プロジェクト: ryo/netbsd-src
void
autofs_mount_succeeded(am_node *mp)
{
    SVCXPRT *transp = mp->am_transp;
    struct stat stb;
    char *space_hack;

    if (transp) {
        /* this was a mount request */
        mntres res;
        res.status = 0;

        if (!svc_sendreply(transp,
                           (XDRPROC_T_TYPE) xdr_mntres,
                           (SVC_IN_ARG_TYPE) &res))
            svcerr_systemerr(transp);

        dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
        XFREE(transp);
        mp->am_transp = NULL;
    }

    space_hack = autofs_strdup_space_hack(mp->am_path);
    if (!lstat(space_hack, &stb)) {
        mp->am_dev = stb.st_dev;
        mp->am_rdev = stb.st_rdev;
    }
    XFREE(space_hack);
    /* don't expire the entries -- the kernel will do it for us */
    mp->am_flags |= AMF_NOTIMEOUT;

    plog(XLOG_INFO, "autofs: mounting %s succeeded", mp->am_path);
}
コード例 #2
0
ファイル: autofs_solaris_v1.c プロジェクト: ryo/netbsd-src
int
autofs_umount_fs(am_node *mp, mntfs *mf)
{
    int err = 0;
    char *space_hack = autofs_strdup_space_hack(mp->am_path);

    /*
     * Autofs v1 doesn't support symlinks,
     * so we ignore the CFM_AUTOFS_USE_LOFS flag
     */
    if (!(mf->mf_flags & MFF_ON_AUTOFS)) {
        err = UMOUNT_FS(mp->am_path, mnttab_file_name, 1);
        if (err)
            goto out;
        rmdir(space_hack);
    }

    /*
     * Multiple sublinks could reference this f/s.
     * Don't actually unmount it unless we're holding the last reference.
     */
    if (mf->mf_refc == 1) {
        if ((err = mf->mf_ops->umount_fs(mp, mf)))
            goto out;

        if (mf->mf_flags & MFF_ON_AUTOFS)
            rmdir(space_hack);
    }

out:
    XFREE(space_hack);
    return err;
}
コード例 #3
0
ファイル: umount_aix.c プロジェクト: raven-au/am-utils-6.2
int
umount_fs(char *mntdir, const char *mnttabname, u_int unmount_flags)
{
  mntlist *mlist, *mp, *mp_save = NULL;
  int error = 0;

  mp = mlist = read_mtab(mntdir, mnttabname);

  /*
   * Search the mount table looking for
   * the correct (ie last) matching entry
   */
  while (mp) {
    if (STREQ(mp->mnt->mnt_dir, mntdir))
      mp_save = mp;
    mp = mp->mnext;
  }

  if (mp_save) {
    dlog("Trying unmount(%s)", mp_save->mnt->mnt_dir);

#ifdef MOUNT_TABLE_ON_FILE
    /*
     * This unmount may hang leaving this process with an exclusive lock on
     * /etc/mtab. Therefore it is necessary to unlock mtab, do the unmount,
     * then lock mtab (again) and reread it and finally update it.
     */
    unlock_mntlist();
#endif /* MOUNT_TABLE_ON_FILE */

#ifdef NEED_AUTOFS_SPACE_HACK
    if (unmount_flags & AMU_UMOUNT_AUTOFS) {
      char *mnt_dir_save = mp_save->mnt->mnt_dir;
      mp_save->mnt->mnt_dir = autofs_strdup_space_hack(mnt_dir_save);
      error = UNMOUNT_TRAP(mp_save->mnt);
      XFREE(mp_save->mnt->mnt_dir);
      mp_save->mnt->mnt_dir = mnt_dir_save;
    } else
#endif /* NEED_AUTOFS_SPACE_HACK */
      error = UNMOUNT_TRAP(mp_save->mnt);
    if (error < 0) {
      switch ((error = errno)) {
      case EINVAL:
      case ENOTBLK:
	plog(XLOG_WARNING, "unmount: %s is not mounted", mp_save->mnt->mnt_dir);
	error = 0;		/* Not really an error */
	break;

      case ENOENT:
	/*
	 * This could happen if the kernel insists on following symlinks
	 * when we try to unmount a direct mountpoint. We need to propagate
	 * the error up so that the top layers know it failed and don't
	 * try to rmdir() the mountpoint or other silly things.
	 */
	plog(XLOG_ERROR, "mount point %s: %m", mp_save->mnt->mnt_dir);
	break;

#if defined(MNT2_GEN_OPT_FORCE) && defined(HAVE_UVMOUNT)
      case EBUSY:
      case EIO:
      case ESTALE:
	/* caller determines if forced unmounts should be used */
	if (unmount_flags & AMU_UMOUNT_FORCE) {
	  error = umount2_fs(mntdir, unmount_flags);
	  if (error < 0)
	    error = errno;
	  else
	    break;		/* all is OK */
	}
	/* fallthrough */
#endif /* MNT2_GEN_OPT_FORCE && HAVE_UVMOUNT */
      default:
	dlog("%s: unmount: %m", mp_save->mnt->mnt_dir);
	break;
      }
    }
    dlog("Finished unmount(%s)", mp_save->mnt->mnt_dir);

    if (!error) {
#ifdef MOUNT_TABLE_ON_FILE
      free_mntlist(mlist);
      mp = mlist = read_mtab(mntdir, mnttabname);

      /*
       * Search the mount table looking for
       * the correct (ie last) matching entry
       */
      mp_save = NULL;
      while (mp) {
	if (STREQ(mp->mnt->mnt_dir, mntdir))
	  mp_save = mp;
	mp = mp->mnext;
      }

      if (mp_save) {
	mnt_free(mp_save->mnt);
	mp_save->mnt = NULL;
	rewrite_mtab(mlist, mnttabname);
      }
#endif /* MOUNT_TABLE_ON_FILE */
    }

  } else {

    plog(XLOG_ERROR, "Couldn't find how to unmount %s", mntdir);
    /*
     * Assume it is already unmounted
     */
    error = 0;
  } /* end of "if (mp_save)" statement */

  free_mntlist(mlist);

  return error;
}
コード例 #4
0
ファイル: autofs_solaris_v1.c プロジェクト: ryo/netbsd-src
int
autofs_mount_fs(am_node *mp, mntfs *mf)
{
    int err = 0;
    char *target, *target2 = NULL;
    char *space_hack = autofs_strdup_space_hack(mp->am_path);
    struct stat buf;

    if (mf->mf_flags & MFF_ON_AUTOFS) {
        if ((err = mkdir(space_hack, 0555)))
            goto out;
    }

    /*
     * For sublinks, we could end up here with an already mounted f/s.
     * Don't do anything in that case.
     */
    if (!(mf->mf_flags & MFF_MOUNTED))
        err = mf->mf_ops->mount_fs(mp, mf);

    if (err) {
        if (mf->mf_flags & MFF_ON_AUTOFS)
            rmdir(space_hack);
        errno = err;
        goto out;
    }

    /*
     * Autofs v1 doesn't support symlinks,
     * so we ignore the CFM_AUTOFS_USE_LOFS flag
     */
    if (mf->mf_flags & MFF_ON_AUTOFS)
        /* Nothing to do */
        goto out;

    if (mp->am_link)
        target = mp->am_link;
    else
        target = mf->mf_mount;

    if (target[0] != '/')
        target2 = str3cat(NULL, mp->am_parent->am_path, "/", target);
    else
        target2 = xstrdup(target);

    plog(XLOG_INFO, "autofs: converting from link to lofs (%s -> %s)", mp->am_path, target2);
    /*
     * we need to stat() the destination, because the bind mount does not
     * follow symlinks and/or allow for non-existent destinations.
     *
     * WARNING: we will deadlock if this function is called from the master
     * amd process and it happens to trigger another auto mount. Therefore,
     * this function should be called only from a child amd process, or
     * at the very least it should not be called from the parent unless we
     * know for sure that it won't cause a recursive mount. We refuse to
     * cause the recursive mount anyway if called from the parent amd.
     */
    if (!foreground) {
        if ((err = stat(target2, &buf)))
            goto out;
    }
    if ((err = lstat(target2, &buf)))
        goto out;

    if ((err = mkdir(space_hack, 0555)))
        goto out;

    if ((err = mount_lofs(mp->am_path, target2, mf->mf_mopts, 1))) {
        errno = err;
        goto out;
    }

out:
    XFREE(space_hack);
    if (target2)
        XFREE(target2);

    if (err)
        return errno;
    return 0;
}
コード例 #5
0
ファイル: mount_fs.c プロジェクト: enukane/netbsd-src
int
mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, u_long nfs_version, const char *nfs_proto, const char *mnttabname, int on_autofs)
{
  int error = 0;
#ifdef MOUNT_TABLE_ON_FILE
  char *zopts = NULL, *xopts = NULL;
  size_t l;
#endif /* MOUNT_TABLE_ON_FILE */
  char *mnt_dir = NULL;

#ifdef NEED_AUTOFS_SPACE_HACK
  char *old_mnt_dir = NULL;
  /* perform space hack */
  if (on_autofs) {
    old_mnt_dir = mnt->mnt_dir;
    mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir);
  } else
#endif /* NEED_AUTOFS_SPACE_HACK */
    mnt_dir = strdup(mnt->mnt_dir);

  dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)",
       mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);

again:
  error = MOUNT_TRAP(type, mnt, flags, mnt_data);

  if (error < 0) {
    plog(XLOG_ERROR, "'%s': mount: %m", mnt_dir);
    /*
     * The following code handles conditions which shouldn't
     * occur.  They are possible either because amd screws up
     * in preparing for the mount, or because some human
     * messed with the mount point.  Both have been known to
     * happen. -- stolcke 2/22/95
     */
    if (errno == EBUSY) {
      /*
       * Also, sometimes unmount isn't called, e.g., because
       * our mountlist is garbled.  This leaves old mount
       * points around which need to be removed before we
       * can mount something new in their place.
       */
      errno = umount_fs(mnt_dir, mnttabname, on_autofs);
      if (errno != 0)
	plog(XLOG_ERROR, "'%s': umount: %m", mnt_dir);
      else {
	plog(XLOG_WARNING, "extra umount required for '%s'", mnt_dir);
	error = MOUNT_TRAP(type, mnt, flags, mnt_data);
      }
    }
  }

  if (error < 0 && --retry > 0) {
    sleep(1);
    goto again;
  }

#ifdef NEED_AUTOFS_SPACE_HACK
  /* Undo space hack */
  if (on_autofs)
    mnt->mnt_dir = old_mnt_dir;
#endif /* NEED_AUTOFS_SPACE_HACK */

  if (error < 0) {
    error = errno;
    goto out;
  }

#ifdef MOUNT_TABLE_ON_FILE
  /*
   * Allocate memory for options:
   *        dev=..., vers={2,3}, proto={tcp,udp}
   */
  l = strlen(mnt->mnt_opts) + 48;
  zopts = (char *) xmalloc(l);

  /* copy standard options */
  xopts = mnt->mnt_opts;

  xstrlcpy(zopts, xopts, l);

# ifdef MNTTAB_OPT_DEV
  {
    /* add the extra dev= field to the mount table */
    struct stat stb;
    if (lstat(mnt_dir, &stb) == 0) {
      char optsbuf[48];
      if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */
	xsnprintf(optsbuf, sizeof(optsbuf), "%s=%04lx",
		  MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff);
      else			/* e.g. System Vr4 */
	xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx",
		  MNTTAB_OPT_DEV, (u_long) stb.st_dev);
      append_opts(zopts, l, optsbuf);
    }
  }
# endif /* MNTTAB_OPT_DEV */

# if defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)
  /*
   * add the extra vers={2,3} field to the mount table,
   * unless already specified by user
   */
   if (nfs_version == NFS_VERSION3 &&
       hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) {
     char optsbuf[48];
     xsnprintf(optsbuf, sizeof(optsbuf),
	       "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3);
     append_opts(zopts, l, optsbuf);
   }
# endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */

# ifdef MNTTAB_OPT_PROTO
  /*
   * add the extra proto={tcp,udp} field to the mount table,
   * unless already specified by user.
   */
  if (nfs_proto && !amu_hasmntopt(mnt, MNTTAB_OPT_PROTO)) {
    char optsbuf[48];
    xsnprintf(optsbuf, sizeof(optsbuf), "%s=%s", MNTTAB_OPT_PROTO, nfs_proto);
    append_opts(zopts, l, optsbuf);
  }
# endif /* MNTTAB_OPT_PROTO */

  /* finally, store the options into the mount table structure */
  mnt->mnt_opts = zopts;

  /*
   * Additional fields in mntent_t
   * are fixed up here
   */
# ifdef HAVE_MNTENT_T_MNT_CNODE
  mnt->mnt_cnode = 0;
# endif /* HAVE_MNTENT_T_MNT_CNODE */

# ifdef HAVE_MNTENT_T_MNT_RO
  mnt->mnt_ro = (amu_hasmntopt(mnt, MNTTAB_OPT_RO) != NULL);
# endif /* HAVE_MNTENT_T_MNT_RO */

# ifdef HAVE_MNTENT_T_MNT_TIME
#  ifdef HAVE_MNTENT_T_MNT_TIME_STRING
  {				/* allocate enough space for a long */
    size_t l = 13 * sizeof(char);
    char *str = (char *) xmalloc(l);
    xsnprintf(str, l, "%ld", time((time_t *) NULL));
    mnt->mnt_time = str;
  }
#  else /* not HAVE_MNTENT_T_MNT_TIME_STRING */
  mnt->mnt_time = time((time_t *) NULL);
#  endif /* not HAVE_MNTENT_T_MNT_TIME_STRING */
# endif /* HAVE_MNTENT_T_MNT_TIME */

  write_mntent(mnt, mnttabname);

# ifdef MNTTAB_OPT_DEV
  if (xopts) {
    XFREE(mnt->mnt_opts);
    mnt->mnt_opts = xopts;
  }
# endif /* MNTTAB_OPT_DEV */
#endif /* MOUNT_TABLE_ON_FILE */

 out:
  XFREE(mnt_dir);
  return error;
}