Пример #1
0
/**
 * mnt_context_do_mount
 * @cxt: context
 *
 * Call mount(2) or mount.type helper. Unnecessary for mnt_context_mount().
 *
 * Note that this function could be called only once. If you want to mount
 * another source or target than you have to call mnt_reset_context().
 *
 * If you want to call mount(2) for the same source and target with a diffrent
 * mount flags or fstype then call mnt_context_reset_status() and then try
 * again mnt_context_do_mount().
 *
 * WARNING: non-zero return code does not mean that mount(2) syscall or
 *          mount.type helper wasn't successfully called.
 *
 *          Check mnt_context_get_status() after error!
*
 * Returns: 0 on success;
 *         >0 in case of mount(2) error (returns syscall errno),
 *         <0 in case of other errors.
 */
int mnt_context_do_mount(struct libmnt_context *cxt)
{
	const char *type;
	int res;

	assert(cxt);
	assert(cxt->fs);
	assert(cxt->helper_exec_status == 1);
	assert(cxt->syscall_status == 1);
	assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
	assert((cxt->flags & MNT_FL_PREPARED));
	assert((cxt->action == MNT_ACT_MOUNT));

	DBG(CXT, mnt_debug_h(cxt, "mount: do mount"));

	if (!(cxt->flags & MNT_FL_MOUNTDATA))
		cxt->mountdata = (char *) mnt_fs_get_fs_options(cxt->fs);

	type = mnt_fs_get_fstype(cxt->fs);
	if (type)
		res = do_mount(cxt, NULL);
	else
		res = do_mount_by_pattern(cxt, cxt->fstype_pattern);

	if (mnt_context_get_status(cxt)
	    && !mnt_context_is_fake(cxt)
	    && !cxt->helper) {
		/*
		 * Mounted by mount(2), do some post-mount checks
		 *
		 * Kernel allows to use MS_RDONLY for bind mounts, but the
		 * read-only request could be silently ignored. Check it to
		 * avoid 'ro' in mtab and 'rw' in /proc/mounts.
		 */
		if ((cxt->mountflags & MS_BIND)
		    && (cxt->mountflags & MS_RDONLY)
		    && !mnt_is_readonly(mnt_context_get_target(cxt)))

			mnt_context_set_mflags(cxt,
					cxt->mountflags & ~MS_RDONLY);


		/* Kernel can silently add MS_RDONLY flag when mounting file
		 * system that does not have write support. Check this to avoid
		 * 'ro' in /proc/mounts and 'rw' in mtab.
		 */
		if (!(cxt->mountflags & (MS_RDONLY | MS_PROPAGATION | MS_MOVE))
		    && mnt_is_readonly(mnt_context_get_target(cxt)))

			mnt_context_set_mflags(cxt,
					cxt->mountflags | MS_RDONLY);
	}

	return res;
}
Пример #2
0
static int try_mount(struct libmnt_context *cxt, int bg)
{
    struct libmnt_fs *fs;
    const char *p;
    char *src = NULL, *tgt = NULL, *type = NULL, *opts = NULL;
    unsigned long flags = 0;
    int fake, ret = 0;

    fs = mnt_context_get_fs(cxt);

    /* libmount returns read-only pointers (const char)
     * so, reallocate for nfsmount() functions.
     */
    if ((p = mnt_fs_get_source(fs)))	/* spec */
        src = strdup(p);
    if ((p = mnt_fs_get_target(fs)))	/* mountpoint */
        tgt = strdup(p);
    if ((p = mnt_fs_get_fstype(fs)))	/* FS type */
        type = strdup(p);
    if ((p = mnt_fs_get_fs_options(fs)))	/* mount options */
        opts = strdup(p);

    mnt_context_get_mflags(cxt, &flags);	/* mount(2) flags */
    fake = mnt_context_is_fake(cxt);

    if (string)
        ret = nfsmount_string(src, tgt, type, flags, &opts, fake, bg);

    else if (strcmp(type, "nfs4") == 0)
        ret = nfs4mount(src, tgt, flags, &opts, fake, bg);
    else
        ret = nfsmount(src, tgt, flags, &opts, fake, bg);

    /* Store mount options if not called with mount --no-mtab */
    if (!ret && !mnt_context_is_nomtab(cxt))
        store_mount_options(fs, opts);

    free(src);
    free(tgt);
    free(type);
    free(opts);

    return ret;
}