summaryrefslogtreecommitdiffstats
path: root/libmount/src/context.c
diff options
context:
space:
mode:
authorOndrej Oprala2012-12-21 14:45:46 +0100
committerKarel Zak2013-01-09 18:52:32 +0100
commit701c69617e50ed8c15bc2c5bc7bf6eee1cb04b23 (patch)
treed979ddb7a6757d3ab5f2900d460ab721f7025a8e /libmount/src/context.c
parentlibmount; add recursive mkdir (diff)
downloadkernel-qcow2-util-linux-701c69617e50ed8c15bc2c5bc7bf6eee1cb04b23.tar.gz
kernel-qcow2-util-linux-701c69617e50ed8c15bc2c5bc7bf6eee1cb04b23.tar.xz
kernel-qcow2-util-linux-701c69617e50ed8c15bc2c5bc7bf6eee1cb04b23.zip
mount: add support for x-mount.mkdir[=<mode>] option
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>
Diffstat (limited to 'libmount/src/context.c')
-rw-r--r--libmount/src/context.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c
index 3269b0beb..35c2f04b0 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -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);