]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
mount: add support for x-mount.mkdir[=<mode>] option
authorOndrej Oprala <ooprala@redhat.com>
Fri, 21 Dec 2012 13:45:46 +0000 (14:45 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 9 Jan 2013 17:52:32 +0000 (18:52 +0100)
If the target directory (mountpoint) does not exist then mount(8) will create
it before mount.<type> is executed or mount(2) syscall is called.

Co-Author: Karel Zak <kzak@redhat.com>
Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
Documentation/TODO
libmount/src/context.c
sys-utils/mount.8
tests/expected/libmount/context-x-mount.mkdir [new file with mode: 0644]
tests/ts/libmount/context

index 694e9a7d6aebc9eb02abf749fb1f44b222adafdb..50c95191e450d10653277b30c9ffabefd69befc4 100644 (file)
@@ -26,8 +26,6 @@ libmount (mount/umount)
 
    (all this already supported by libmount)
 
- - add x-mount-mkdir mount option to libmount to allow "mkdir /mountpoint"
-
  - support MS_PROPAGATION flags in fstab -- note that kernel assumes that
    these flags are not mixed with another mount flags, it means that:
 
index 3269b0beb8feb7ca0b018ba24e181e00c0718505..35c2f04b08c2ca48756f598c8d1c05c4bf69b3f3 100644 (file)
@@ -1368,6 +1368,47 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt)
        return 0;
 }
 
+/* create a mountpoint if x-mount.mkdir[=<mode>] specified */
+static int mkdir_target(const char *tgt, struct libmnt_fs *fs)
+{
+       char *mstr = NULL;
+       size_t mstr_sz = 0;
+       mode_t mode = 0;
+       struct stat st;
+       int rc;
+
+       assert(tgt);
+       assert(fs);
+
+       if (mnt_optstr_get_option(fs->user_optstr, "x-mount.mkdir", &mstr, &mstr_sz) != 0)
+               return 0;
+       if (stat(tgt, &st) == 0)
+               return 0;
+
+       if (mstr && mstr_sz) {
+               char *end = NULL;
+
+               errno = 0;
+               mode = strtol(mstr, &end, 8);
+
+               if (errno || !end || mstr + mstr_sz != end) {
+                       DBG(CXT, mnt_debug("failed to parse mkdir mode '%s'", mstr));
+                       return -MNT_ERR_MOUNTOPT;
+               }
+       }
+
+       if (!mode)
+               mode = S_IRWXU |                        /* 0755 */
+                      S_IRGRP | S_IXGRP |
+                      S_IROTH | S_IXOTH;
+
+       rc = mkdir_p(tgt, mode);
+       if (rc)
+               DBG(CXT, mnt_debug("mkdir %s failed: %m", tgt));
+
+       return rc;
+}
+
 int mnt_context_prepare_target(struct libmnt_context *cxt)
 {
        const char *tgt;
@@ -1387,6 +1428,17 @@ int mnt_context_prepare_target(struct libmnt_context *cxt)
        if (!tgt)
                return 0;
 
+       /* mkdir target */
+       if (cxt->action == MNT_ACT_MOUNT
+           && !mnt_context_is_restricted(cxt)
+           && cxt->user_mountflags & MNT_MS_XCOMMENT) {
+
+               rc = mkdir_target(tgt, cxt->fs);
+               if (rc)
+                       return rc;      /* mkdir or parse error */
+       }
+
+       /* canonicalize the path */
        cache = mnt_context_get_cache(cxt);
        if (cache) {
                char *path = mnt_resolve_path(tgt, cache);
index 5f77f18364e5d06e8f5161fc46d7e1155e74c858..add9818fab52994f64c2191d09fdc8530ad2dfcc 100644 (file)
@@ -1105,6 +1105,13 @@ applications specific options. These options are not stored to mtab file, send
 to mount.<type> helpers or
 .B mount(2)
 system call. The suggested format is x-<appname>.<option> (e.g. x-systemd.automount).
+.TP
+.B x-mount.mkdir[=<mode>]
+Allow to make a target directory (mountpoint). The optional argument <mode>
+specifies the file system access mode used for
+.B mkdir (2)
+in octal notation. The default mode is 0755. This functionality is supported
+only for root users.
 
 .SH "FILESYSTEM SPECIFIC MOUNT OPTIONS"
 The following options apply only to certain filesystems.
diff --git a/tests/expected/libmount/context-x-mount.mkdir b/tests/expected/libmount/context-x-mount.mkdir
new file mode 100644 (file)
index 0000000..7504a7e
--- /dev/null
@@ -0,0 +1 @@
+successfully mounted
index c8f2850a85b0443951e3be7d4ec9d06e86e1c74d..c3b0b6dea9b4df82ce9d2cb35ce11f2060e7cdef 100755 (executable)
@@ -13,6 +13,8 @@ TESTPROG="$TS_HELPER_LIBMOUNT_CONTEXT"
 LABEL=libmount-test
 UUID=$(uuidgen)
 MOUNTPOINT="$TS_MOUNTPOINT"
+TS_NOEXIST="$TS_OUTDIR/${TS_TESTNAME}-${TS_SUBNAME}-noex"
+[ -d $TS_NOEXIST ] && rmdir $TS_NOEXIST
 
 #set -x
 
@@ -128,6 +130,14 @@ grep -q $MOUNTPOINT $LIBMOUNT_MTAB &&
        echo "umount failed: found $MOUNTPOINT in $LIBMOUNT_MTAB" >> $TS_OUTPUT 2>&1
 ts_finalize_subtest
 
+ts_init_subtest "x-mount.mkdir"
+$TS_CMD_MOUNT -o x-mount.mkdir --bind $MOUNTPOINT $TS_NOEXIST >> $TS_OUTPUT 2>&1 &&
+  echo "successfully mounted" >> $TS_OUTPUT
+ts_finalize_subtest
+
+$TS_CMD_UMOUNT $TS_NOEXIST
+rmdir $TS_NOEXIST
+
 ts_log "...done."
 rmmod scsi_debug
 ts_finalize