*/
#include "mountP.h"
-#include "fileutils.h"
#include "strutils.h"
#include "namespace.h"
return rc;
}
-static int is_subdir_required(struct libmnt_context *cxt, int *rc)
-{
- char *dir;
- size_t sz;
-
- assert(cxt);
- assert(rc);
-
- *rc = 0;
-
- if (!cxt->fs
- || !cxt->fs->user_optstr
- || mnt_optstr_get_option(cxt->fs->user_optstr,
- "X-mount.subdir", &dir, &sz) != 0)
- return 0;
-
- if (dir && *dir == '"')
- dir++, sz-=2;
-
- if (!dir || sz < 1) {
- DBG(CXT, ul_debug("failed to parse X-mount.subdir '%s'", dir));
- *rc = -MNT_ERR_MOUNTOPT;
- } else {
- cxt->subdir = strndup(dir, sz);
- if (!cxt->subdir)
- *rc = -ENOMEM;
-
- DBG(CXT, ul_debug("subdir %s wanted", dir));
- }
-
- return *rc == 0;
-}
-
-static int is_mkdir_required(const char *tgt, struct libmnt_fs *fs, mode_t *mode, int *rc)
-{
- char *mstr = NULL;
- size_t mstr_sz = 0;
- struct stat st;
-
- assert(tgt);
- assert(fs);
- assert(mode);
- assert(rc);
-
- *mode = 0;
- *rc = 0;
-
- if (mnt_optstr_get_option(fs->user_optstr, "X-mount.mkdir", &mstr, &mstr_sz) != 0 &&
- mnt_optstr_get_option(fs->user_optstr, "x-mount.mkdir", &mstr, &mstr_sz) != 0) /* obsolete */
- return 0;
-
- if (mnt_stat_mountpoint(tgt, &st) == 0)
- return 0;
-
- DBG(CXT, ul_debug("mkdir %s (%s) wanted", tgt, mstr));
-
- if (mstr && mstr_sz) {
- char *end = NULL;
-
- if (*mstr == '"')
- mstr++, mstr_sz-=2;
-
- errno = 0;
- *mode = strtol(mstr, &end, 8);
-
- if (errno || !end || mstr + mstr_sz != end) {
- DBG(CXT, ul_debug("failed to parse mkdir mode '%s'", mstr));
- *rc = -MNT_ERR_MOUNTOPT;
- return 0;
- }
- }
-
- if (!*mode)
- *mode = S_IRWXU | /* 0755 */
- S_IRGRP | S_IXGRP |
- S_IROTH | S_IXOTH;
-
- return 1;
-}
-
-int mnt_context_prepare_target(struct libmnt_context *cxt)
-{
- const char *tgt, *prefix;
- int rc = 0;
- struct libmnt_ns *ns_old;
- mode_t mode = 0;
-
- assert(cxt);
- assert(cxt->fs);
- assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
-
- DBG(CXT, ul_debugobj(cxt, "--> preparing target path"));
-
- tgt = mnt_fs_get_target(cxt->fs);
- if (!tgt)
- return 0;
-
- /* apply prefix */
- prefix = mnt_context_get_target_prefix(cxt);
- if (prefix) {
- const char *p = *tgt == '/' ? tgt + 1 : tgt;
-
- if (!*p)
- /* target is "/", use "/prefix" */
- rc = mnt_fs_set_target(cxt->fs, prefix);
- else {
- char *path = NULL;
-
- if (asprintf(&path, "%s/%s", prefix, p) <= 0)
- rc = -ENOMEM;
- else {
- rc = mnt_fs_set_target(cxt->fs, path);
- free(path);
- }
- }
- if (rc)
- return rc;
- tgt = mnt_fs_get_target(cxt->fs);
- }
-
- ns_old = mnt_context_switch_target_ns(cxt);
- if (!ns_old)
- return -MNT_ERR_NAMESPACE;
-
- /* X-mount.mkdir target */
- if (cxt->action == MNT_ACT_MOUNT
- && (cxt->user_mountflags & MNT_MS_XCOMMENT ||
- cxt->user_mountflags & MNT_MS_XFSTABCOMM)
- && is_mkdir_required(tgt, cxt->fs, &mode, &rc)) {
-
- /* supported only for root or non-suid mount(8) */
- if (!mnt_context_is_restricted(cxt)) {
- rc = ul_mkdir_p(tgt, mode);
- if (rc)
- DBG(CXT, ul_debug("mkdir %s failed: %m", tgt));
- } else
- rc = -EPERM;
- }
-
- /* canonicalize the path */
- if (rc == 0) {
- struct libmnt_cache *cache = mnt_context_get_cache(cxt);
-
- if (cache) {
- char *path = mnt_resolve_path(tgt, cache);
- if (path && strcmp(path, tgt) != 0)
- rc = mnt_fs_set_target(cxt->fs, path);
- }
- }
-
- /* X-mount.subdir= target */
- if (rc == 0
- && cxt->action == MNT_ACT_MOUNT
- && (cxt->user_mountflags & MNT_MS_XFSTABCOMM)
- && is_subdir_required(cxt, &rc)) {
-
- DBG(CXT, ul_debugobj(cxt, "subdir %s required", cxt->subdir));
- }
-
-
- if (!mnt_context_switch_ns(cxt, ns_old))
- return -MNT_ERR_NAMESPACE;
-
- DBG(CXT, ul_debugobj(cxt, "final target '%s' [rc=%d]",
- mnt_fs_get_target(cxt->fs), rc));
- return rc;
-}
-
/* Guess type, but not set to cxt->fs, always use free() for the result. It's
* no error when we're not able to guess a filesystem type. Note that error
* does not mean that result in @type is NULL.
#include "linux_version.h"
#include "mountP.h"
#include "strutils.h"
+#include "fileutils.h"
#if defined(HAVE_LIBSELINUX) || defined(HAVE_SMACK)
struct libmnt_optname {
return 0;
}
+static int is_subdir_required(struct libmnt_context *cxt, int *rc)
+{
+ char *dir;
+ size_t sz;
+
+ assert(cxt);
+ assert(rc);
+
+ *rc = 0;
+
+ if (!cxt->fs
+ || !cxt->fs->user_optstr
+ || mnt_optstr_get_option(cxt->fs->user_optstr,
+ "X-mount.subdir", &dir, &sz) != 0)
+ return 0;
+
+ if (dir && *dir == '"')
+ dir++, sz-=2;
+
+ if (!dir || sz < 1) {
+ DBG(CXT, ul_debug("failed to parse X-mount.subdir '%s'", dir));
+ *rc = -MNT_ERR_MOUNTOPT;
+ } else {
+ cxt->subdir = strndup(dir, sz);
+ if (!cxt->subdir)
+ *rc = -ENOMEM;
+
+ DBG(CXT, ul_debug("subdir %s wanted", dir));
+ }
+
+ return *rc == 0;
+}
+
+static int is_mkdir_required(const char *tgt, struct libmnt_fs *fs, mode_t *mode, int *rc)
+{
+ char *mstr = NULL;
+ size_t mstr_sz = 0;
+ struct stat st;
+
+ assert(tgt);
+ assert(fs);
+ assert(mode);
+ assert(rc);
+
+ *mode = 0;
+ *rc = 0;
+
+ if (mnt_optstr_get_option(fs->user_optstr, "X-mount.mkdir", &mstr, &mstr_sz) != 0 &&
+ mnt_optstr_get_option(fs->user_optstr, "x-mount.mkdir", &mstr, &mstr_sz) != 0) /* obsolete */
+ return 0;
+
+ if (mnt_stat_mountpoint(tgt, &st) == 0)
+ return 0;
+
+ DBG(CXT, ul_debug("mkdir %s (%s) wanted", tgt, mstr));
+
+ if (mstr && mstr_sz) {
+ char *end = NULL;
+
+ if (*mstr == '"')
+ mstr++, mstr_sz-=2;
+
+ errno = 0;
+ *mode = strtol(mstr, &end, 8);
+
+ if (errno || !end || mstr + mstr_sz != end) {
+ DBG(CXT, ul_debug("failed to parse mkdir mode '%s'", mstr));
+ *rc = -MNT_ERR_MOUNTOPT;
+ return 0;
+ }
+ }
+
+ if (!*mode)
+ *mode = S_IRWXU | /* 0755 */
+ S_IRGRP | S_IXGRP |
+ S_IROTH | S_IXOTH;
+
+ return 1;
+}
+
+
+static int prepare_target(struct libmnt_context *cxt)
+{
+ const char *tgt, *prefix;
+ int rc = 0;
+ struct libmnt_ns *ns_old;
+ mode_t mode = 0;
+
+ assert(cxt);
+ assert(cxt->fs);
+ assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
+
+ DBG(CXT, ul_debugobj(cxt, "--> preparing target path"));
+
+ tgt = mnt_fs_get_target(cxt->fs);
+ if (!tgt)
+ return 0;
+
+ /* apply prefix */
+ prefix = mnt_context_get_target_prefix(cxt);
+ if (prefix) {
+ const char *p = *tgt == '/' ? tgt + 1 : tgt;
+
+ if (!*p)
+ /* target is "/", use "/prefix" */
+ rc = mnt_fs_set_target(cxt->fs, prefix);
+ else {
+ char *path = NULL;
+
+ if (asprintf(&path, "%s/%s", prefix, p) <= 0)
+ rc = -ENOMEM;
+ else {
+ rc = mnt_fs_set_target(cxt->fs, path);
+ free(path);
+ }
+ }
+ if (rc)
+ return rc;
+ tgt = mnt_fs_get_target(cxt->fs);
+ }
+
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
+ /* X-mount.mkdir target */
+ if (cxt->action == MNT_ACT_MOUNT
+ && (cxt->user_mountflags & MNT_MS_XCOMMENT ||
+ cxt->user_mountflags & MNT_MS_XFSTABCOMM)
+ && is_mkdir_required(tgt, cxt->fs, &mode, &rc)) {
+
+ /* supported only for root or non-suid mount(8) */
+ if (!mnt_context_is_restricted(cxt)) {
+ rc = ul_mkdir_p(tgt, mode);
+ if (rc)
+ DBG(CXT, ul_debug("mkdir %s failed: %m", tgt));
+ } else
+ rc = -EPERM;
+ }
+
+ /* canonicalize the path */
+ if (rc == 0) {
+ struct libmnt_cache *cache = mnt_context_get_cache(cxt);
+
+ if (cache) {
+ char *path = mnt_resolve_path(tgt, cache);
+ if (path && strcmp(path, tgt) != 0)
+ rc = mnt_fs_set_target(cxt->fs, path);
+ }
+ }
+
+ /* X-mount.subdir= target */
+ if (rc == 0
+ && cxt->action == MNT_ACT_MOUNT
+ && (cxt->user_mountflags & MNT_MS_XFSTABCOMM)
+ && is_subdir_required(cxt, &rc)) {
+
+ DBG(CXT, ul_debugobj(cxt, "subdir %s required", cxt->subdir));
+ }
+
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
+ DBG(CXT, ul_debugobj(cxt, "final target '%s' [rc=%d]",
+ mnt_fs_get_target(cxt->fs), rc));
+ return rc;
+}
+
/**
* mnt_context_prepare_mount:
* @cxt: context
if (!rc)
rc = mnt_context_guess_fstype(cxt);
if (!rc)
- rc = mnt_context_prepare_target(cxt);
+ rc = prepare_target(cxt);
if (!rc)
rc = parse_ownership_mode(cxt);
if (!rc)
struct libmnt_table **mountinfo, const char *tgt);
extern int mnt_context_prepare_srcpath(struct libmnt_context *cxt);
-extern int mnt_context_prepare_target(struct libmnt_context *cxt);
extern int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type);
extern int mnt_context_guess_fstype(struct libmnt_context *cxt);
extern int mnt_context_prepare_helper(struct libmnt_context *cxt,