Esempio n. 1
0
static int
lofs_mount(am_node *am, mntfs *mf)
{
  int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
  int error;

  error = mount_lofs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
  if (error) {
    errno = error;
    plog(XLOG_ERROR, "mount_lofs: %m");
    return error;
  }
  return 0;
}
Esempio n. 2
0
int
autofs_mount_fs(am_node *mp, mntfs *mf)
{
  char *target, *target2 = NULL;
  int err = 0;

  if (mf->mf_flags & MFF_ON_AUTOFS) {
    if ((err = mkdir(mp->am_path, 0555)))
      return errno;
  }

  /*
   * 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(mp->am_path);
    return err;
  }

  if (mf->mf_flags & MFF_ON_AUTOFS)
    /* Nothing else to do */
    return 0;

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

#ifdef MNT2_GEN_OPT_BIND
  if (bind_works && gopt.flags & CFM_AUTOFS_USE_LOFS) {
    struct stat buf;

    /*
     * HACK ALERT!
     *
     * Since the bind mount mechanism doesn't allow mountpoint crossing,
     * we _must_ use symlinks for the host mount case. Otherwise we end up
     * with a bunch of empty mountpoints...
     */
    if (mf->mf_ops == &amfs_host_ops)
      goto use_symlink;

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

    /*
     * We need to stat() the destination, because the bind mount does not
     * follow symlinks and/or allow for non-existent destinations.
     * We fall back to symlinks if there are problems.
     *
     * We also need to temporarily change pgrp, otherwise our stat() won't
     * trigger whatever cascading mounts are needed.
     *
     * 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) {
      pid_t pgrp = getpgrp();
      setpgrp();
      err = stat(target2, &buf);
      if ((err = setpgid(0, pgrp))) {
	plog(XLOG_ERROR, "autofs: cannot restore pgrp: %s", strerror(errno));
	plog(XLOG_ERROR, "autofs: aborting the mount");
	goto out;
      }
      if (err)
	goto use_symlink;
    }
    if ((err = lstat(target2, &buf)))
      goto use_symlink;
    if (S_ISLNK(buf.st_mode))
      goto use_symlink;

    plog(XLOG_INFO, "autofs: bind-mounting %s -> %s", mp->am_path, target2);
    mkdir(mp->am_path, 0555);
    err = mount_lofs(mp->am_path, target2, mf->mf_mopts, 1);
    if (err) {
      rmdir(mp->am_path);
      plog(XLOG_INFO, "autofs: bind-mounting %s -> %s failed", mp->am_path, target2);
      goto use_symlink;
    }
    goto out;
  }
#endif /* MNT2_GEN_OPT_BIND */
 use_symlink:
  plog(XLOG_INFO, "autofs: symlinking %s -> %s", mp->am_path, target);
  err = symlink(target, mp->am_path);

 out:
  if (target2)
    XFREE(target2);

  if (err)
    return errno;
  return 0;
}
Esempio n. 3
0
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;
}