*/
int mnt_context_reset_status(struct libmnt_context *cxt)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
DBG(CXT, ul_debugobj(cxt, "checking for writable tab files"));
+#ifdef USE_LIBMOUNT_FORCE_MOUNTINFO
+ cxt->mtab_writable = 0;
+#else
mnt_has_regular_mtab(&cxt->mtab_path, &cxt->mtab_writable);
+#endif
if (!cxt->mtab_writable)
/* use /run/mount/utab if /etc/mtab is useless */
*/
int mnt_context_set_optsmode(struct libmnt_context *cxt, int mode)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
cxt->optsmode = mode;
int mnt_context_get_optsmode(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->optsmode;
}
*/
struct libmnt_fs *mnt_context_get_fs(struct libmnt_context *cxt)
{
- assert(cxt);
if (!cxt)
return NULL;
if (!cxt->fs)
*/
void *mnt_context_get_fs_userdata(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->fs ? mnt_fs_get_userdata(cxt->fs) : NULL;
}
*/
void *mnt_context_get_fstab_userdata(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->fstab ? mnt_table_get_userdata(cxt->fstab) : NULL;
}
*/
void *mnt_context_get_mtab_userdata(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->mtab ? mnt_table_get_userdata(cxt->mtab) : NULL;
}
*/
int mnt_context_set_source(struct libmnt_context *cxt, const char *source)
{
- assert(cxt);
return mnt_fs_set_source(mnt_context_get_fs(cxt), source);
}
*/
const char *mnt_context_get_source(struct libmnt_context *cxt)
{
- assert(cxt);
return mnt_fs_get_source(mnt_context_get_fs(cxt));
}
*/
int mnt_context_set_target(struct libmnt_context *cxt, const char *target)
{
- assert(cxt);
return mnt_fs_set_target(mnt_context_get_fs(cxt), target);
}
*/
const char *mnt_context_get_target(struct libmnt_context *cxt)
{
- assert(cxt);
return mnt_fs_get_target(mnt_context_get_fs(cxt));
}
*/
int mnt_context_set_fstype(struct libmnt_context *cxt, const char *fstype)
{
- assert(cxt);
return mnt_fs_set_fstype(mnt_context_get_fs(cxt), fstype);
}
*/
const char *mnt_context_get_fstype(struct libmnt_context *cxt)
{
- assert(cxt);
return mnt_fs_get_fstype(mnt_context_get_fs(cxt));
}
*/
int mnt_context_set_options(struct libmnt_context *cxt, const char *optstr)
{
- assert(cxt);
return mnt_fs_set_options(mnt_context_get_fs(cxt), optstr);
}
*/
int mnt_context_append_options(struct libmnt_context *cxt, const char *optstr)
{
- assert(cxt);
return mnt_fs_append_options(mnt_context_get_fs(cxt), optstr);
}
*/
const char *mnt_context_get_options(struct libmnt_context *cxt)
{
- assert(cxt);
return mnt_fs_get_options(mnt_context_get_fs(cxt));
}
{
char *p = NULL;
- assert(cxt);
if (!cxt)
return -EINVAL;
if (pattern) {
{
char *p = NULL;
- assert(cxt);
if (!cxt)
return -EINVAL;
if (pattern) {
*/
int mnt_context_set_fstab(struct libmnt_context *cxt, struct libmnt_table *tb)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
*/
int mnt_context_get_fstab(struct libmnt_context *cxt, struct libmnt_table **tb)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
if (!cxt->fstab) {
*/
int mnt_context_get_mtab(struct libmnt_context *cxt, struct libmnt_table **tb)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
if (!cxt->mtab) {
return 0;
}
+/*
+ * Called by mtab parser to filter out entries, non-zero means that
+ * an entry has to be filtered out.
+ */
+static int mtab_filter(struct libmnt_fs *fs, void *data)
+{
+ if (!fs || !data)
+ return 0;
+ if (mnt_fs_streq_target(fs, data))
+ return 0;
+ if (mnt_fs_streq_srcpath(fs, data))
+ return 0;
+ return 1;
+}
+
+/*
+ * The same like mnt_context_get_mtab(), but does not read all mountinfo/mtab
+ * file, but only entries relevant for @tgt.
+ */
+int mnt_context_get_mtab_for_target(struct libmnt_context *cxt,
+ struct libmnt_table **mtab,
+ const char *tgt)
+{
+ struct stat st;
+ struct libmnt_cache *cache = NULL;
+ char *cn_tgt = NULL;
+ int rc;
+
+ if (stat(tgt, &st) == 0 && S_ISDIR(st.st_mode)) {
+ cache = mnt_context_get_cache(cxt);
+ cn_tgt = mnt_resolve_path(tgt, cache);
+ if (cn_tgt)
+ mnt_context_set_tabfilter(cxt, mtab_filter, cn_tgt);
+ }
+
+ rc = mnt_context_get_mtab(cxt, mtab);
+
+ if (cn_tgt) {
+ mnt_context_set_tabfilter(cxt, NULL, NULL);
+ if (!cache)
+ free(cn_tgt);
+ }
+
+ return rc;
+}
+
/*
* Allows to specify a filter for tab file entries. The filter is called by
* the table parser. Currently used for mtab and utab only.
int (*fltr)(struct libmnt_fs *, void *),
void *data)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
{
int rc;
- assert(cxt);
- assert(tb);
if (!cxt || !tb)
return -EINVAL;
int mnt_context_set_tables_errcb(struct libmnt_context *cxt,
int (*cb)(struct libmnt_table *tb, const char *filename, int line))
{
- assert(cxt);
if (!cxt)
return -EINVAL;
*/
struct libmnt_cache *mnt_context_get_cache(struct libmnt_context *cxt)
{
- assert(cxt);
if (!cxt || mnt_context_is_nocanonicalize(cxt))
return NULL;
char *(*get)(struct libmnt_context *),
void (*release)(struct libmnt_context *, char *))
{
- assert(cxt);
if (!cxt)
return -EINVAL;
cxt->pwd_get_cb = get;
*/
struct libmnt_lock *mnt_context_get_lock(struct libmnt_context *cxt)
{
- assert(cxt);
/*
* DON'T call this function within libmount, it will always allocate
* the lock. The mnt_update_* functions are able to allocate the lock
*/
int mnt_context_set_mflags(struct libmnt_context *cxt, unsigned long flags)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
int rc = 0;
struct list_head *p;
- assert(cxt);
- assert(flags);
if (!cxt || !flags)
return -EINVAL;
{
int rc = 0;
- assert(cxt);
- assert(flags);
if (!cxt || !flags)
return -EINVAL;
*/
int mnt_context_set_mountdata(struct libmnt_context *cxt, void *data)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
cxt->mountdata = data;
return 0;
}
-/* Guess type, but not set to cxt->fs, use free() for the result. It's no error
- * when we're not able to guess a filesystem type.
+/* 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.
*/
int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type)
{
assert(cxt->fs);
assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
+ DBG(CXT, ul_debugobj(cxt, "preparing fstype"));
+
if (!cxt || !cxt->fs)
return -EINVAL;
if (type)
goto done;
- if (cxt->flags & MS_REMOUNT)
+ if (cxt->mountflags & MS_REMOUNT)
goto none;
if (cxt->fstype_pattern)
goto done;
target = mnt_fs_get_target(cxt->fs);
- if (cxt->action == MNT_ACT_UMOUNT && target && !strcmp(target, "/"))
- /* Don't try to touch mtab if umounting root FS */
+ if (cxt->action == MNT_ACT_UMOUNT && target && !strcmp(target, "/")) {
+ DBG(CXT, ul_debugobj(cxt, "root umount: setting NOMTAB"));
mnt_context_disable_mtab(cxt, TRUE);
-
+ }
if (mnt_context_is_nomtab(cxt)) {
DBG(CXT, ul_debugobj(cxt, "skip update: NOMTAB flag"));
return 0;
if (!rc && !mnt_fs_get_fstype(cxt->fs))
rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs));
+ if (!rc && !mnt_fs_get_root(cxt->fs) && mnt_fs_get_root(fs))
+ rc = mnt_fs_set_root(cxt->fs, mnt_fs_get_root(fs));
+
if (rc)
return rc;
*/
int mnt_context_apply_fstab(struct libmnt_context *cxt)
{
- int rc = -1;
+ int rc = -1, isremount = 0;
struct libmnt_table *tab = NULL;
const char *src = NULL, *tgt = NULL;
+ unsigned long mflags = 0;
- assert(cxt);
- assert(cxt->fs);
-
- if (!cxt)
+ if (!cxt || !cxt->fs)
return -EINVAL;
if (mnt_context_tab_applied(cxt)) /* already applied */
cxt->optsmode &= ~MNT_OMODE_FORCE;
}
+ if (mnt_context_get_mflags(cxt, &mflags) == 0 && mflags & MS_REMOUNT)
+ isremount = 1;
+
if (cxt->fs) {
src = mnt_fs_get_source(cxt->fs);
tgt = mnt_fs_get_target(cxt->fs);
return 0;
}
- DBG(CXT, ul_debugobj(cxt,
- "trying to apply fstab (src=%s, target=%s)", src, tgt));
-
/* let's initialize cxt->fs */
ignore_result( mnt_context_get_fs(cxt) );
/* try fstab */
if (cxt->optsmode & MNT_OMODE_FSTAB) {
+ DBG(CXT, ul_debugobj(cxt, "trying to apply fstab (src=%s, target=%s)", src, tgt));
rc = mnt_context_get_fstab(cxt, &tab);
if (!rc)
rc = apply_table(cxt, tab, MNT_ITER_FORWARD);
}
/* try mtab */
- if (rc < 0 && (cxt->optsmode & MNT_OMODE_MTAB)) {
- DBG(CXT, ul_debugobj(cxt, "trying to apply from mtab"));
- rc = mnt_context_get_mtab(cxt, &tab);
+ if (rc < 0 && (cxt->optsmode & MNT_OMODE_MTAB)
+ && (isremount || cxt->action == MNT_ACT_UMOUNT)) {
+ DBG(CXT, ul_debugobj(cxt, "trying to apply mtab (src=%s, target=%s)", src, tgt));
+ if (tgt)
+ rc = mnt_context_get_mtab_for_target(cxt, &tab, tgt);
+ else
+ rc = mnt_context_get_mtab(cxt, &tab);
if (!rc)
rc = apply_table(cxt, tab, MNT_ITER_BACKWARD);
}
if (rc) {
+ if (!mnt_context_is_restricted(cxt)
+ && tgt && !src
+ && isremount) {
+ DBG(CXT, ul_debugobj(cxt, "only target; ignore missing mtab entry on remount"));
+ return 0;
+ }
+
DBG(CXT, ul_debugobj(cxt, "failed to find entry in fstab/mtab [rc=%d]: %m", rc));
/* force to "not found in fstab/mtab" error, the details why
*/
int mnt_context_tab_applied(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->flags & MNT_FL_TAB_APPLIED;
}
*/
int mnt_context_propagation_only(struct libmnt_context *cxt)
{
- assert(cxt);
- assert(cxt->fs);
-
if (cxt->action != MNT_ACT_MOUNT)
return 0;
*/
int mnt_context_get_status(struct libmnt_context *cxt)
{
- assert(cxt);
return !cxt->syscall_status || !cxt->helper_exec_status;
}
*/
int mnt_context_helper_executed(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->helper_exec_status != 1;
}
*/
int mnt_context_get_helper_status(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->helper_status;
}
*/
int mnt_context_syscall_called(struct libmnt_context *cxt)
{
- assert(cxt);
return cxt->syscall_status != 1;
}
*/
int mnt_context_get_syscall_errno(struct libmnt_context *cxt)
{
- assert(cxt);
if (cxt->syscall_status < 0)
return -cxt->syscall_status;
return 0;
*/
int mnt_context_set_syscall_status(struct libmnt_context *cxt, int status)
{
- assert(cxt);
if (!cxt)
return -EINVAL;
{
int rc;
- assert(cxt);
+ if (!cxt)
+ return -EINVAL;
rc = mnt_context_disable_helpers(cxt, TRUE);
if (!rc)
struct libmnt_table *mtab;
int rc;
- assert(cxt);
if (!cxt || !fs || !mounted)
return -EINVAL;
{
pid_t *pids;
- assert(cxt);
if (!cxt)
return -EINVAL;
{
int i;
- assert(cxt);
if (!cxt)
return -EINVAL;