Пример #1
0
/**
 * mnt_context_umount:
 * @cxt: umount context
 *
 * High-level, umounts filesystem by umount(2) or fork()+exec(/sbin/umount.type).
 *
 * This is similar to:
 *
 *	mnt_context_prepare_umount(cxt);
 *	mnt_context_do_umount(cxt);
 *	mnt_context_finalize_umount(cxt);
 *
 * See also mnt_context_disable_helpers().
 *
 * WARNING: non-zero return code does not mean that umount(2) syscall or
 *          umount.type helper wasn't successfully called.
 *
 *          Check mnt_context_get_status() after error!
 *
 * Returns: 0 on success;
 *         >0 in case of umount(2) error (returns syscall errno),
 *         <0 in case of other errors.
 */
int mnt_context_umount(struct libmnt_context *cxt)
{
	int rc;

	assert(cxt);
	assert(cxt->fs);
	assert(cxt->helper_exec_status == 1);
	assert(cxt->syscall_status == 1);

	DBG(CXT, mnt_debug_h(cxt, "umount: %s", mnt_context_get_target(cxt)));

	rc = mnt_context_prepare_umount(cxt);
	if (!rc)
		rc = mnt_context_prepare_update(cxt);
	if (!rc)
		rc = mnt_context_do_umount(cxt);
	if (!rc)
		rc = mnt_context_update_tabs(cxt);
	return rc;
}
Пример #2
0
static int umount_main(struct libmnt_context *cxt, int argc, char **argv)
{
    int rc, c;
    char *spec = NULL, *opts = NULL;

    static const struct option longopts[] = {
        { "force", 0, 0, 'f' },
        { "help", 0, 0, 'h' },
        { "no-mtab", 0, 0, 'n' },
        { "verbose", 0, 0, 'v' },
        { "read-only", 0, 0, 'r' },
        { "lazy", 0, 0, 'l' },
        { "types", 1, 0, 't' },
        { NULL, 0, 0, 0 }
    };

    mnt_context_init_helper(cxt, MNT_ACT_UMOUNT, 0);

    while ((c = getopt_long (argc, argv, "fvnrlh", longopts, NULL)) != -1) {

        rc = mnt_context_helper_setopt(cxt, c, optarg);
        if (rc == 0)		/* valid option */
            continue;
        if (rc < 0)		/* error (probably ENOMEM) */
            goto err;
        /* rc==1 means unknow option */
        umount_usage();
        return EX_USAGE;
    }

    if (optind < argc)
        spec = argv[optind++];

    if (!spec || (*spec != '/' && strchr(spec,':') == NULL)) {
        nfs_error(_("%s: no mount point provided"), progname);
        return EX_USAGE;
    }

    if (mnt_context_set_target(cxt, spec))
        goto err;
    if (mnt_context_set_fstype_pattern(cxt, "nfs,nfs4"))	/* restrict filesystems */
        goto err;

    /* read mtab/fstab, evaluate permissions, etc. */
    rc = mnt_context_prepare_umount(cxt);
    if (rc) {
        nfs_error(_("%s: failed to prepare umount: %s\n"),
                  progname, strerror(-rc));
        goto err;
    }

    opts = retrieve_mount_options(mnt_context_get_fs(cxt));

    if (!mnt_context_is_lazy(cxt)) {
        if (opts) {
            /* we have full FS description (e.g. from mtab or /proc) */
            switch (is_vers4(cxt)) {
            case 0:
                /* We ignore the error from nfs_umount23.
                 * If the actual umount succeeds (in del_mtab),
                 * we don't want to signal an error, as that
                 * could cause /sbin/mount to retry!
                 */
                nfs_umount23(mnt_context_get_source(cxt), opts);
                break;
            case 1:			/* unknown */
                break;
            default:		/* error */
                goto err;
            }
        } else
            /* strange, no entry in mtab or /proc not mounted */
            nfs_umount23(spec, "tcp,v3");
    }

    rc = mnt_context_do_umount(cxt);	/* call umount(2) syscall */
    mnt_context_finalize_mount(cxt);	/* mtab update */

    if (rc && !mnt_context_get_status(cxt)) {
        /* mnt_context_do_umount() returns errno if umount(2) failed */
        umount_error(rc, spec);
        goto err;
    }

    free(opts);
    return EX_SUCCESS;
err:
    free(opts);
    return EX_FAIL;
}