summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/exitcodes.h10
-rw-r--r--lib/timer.c29
-rw-r--r--libmount/docs/libmount-sections.txt14
-rw-r--r--libmount/src/context.c144
-rw-r--r--libmount/src/context_mount.c358
-rw-r--r--libmount/src/context_umount.c80
-rw-r--r--libmount/src/libmount.h.in78
-rw-r--r--libmount/src/libmount.sym7
-rw-r--r--libmount/src/mountP.h20
-rw-r--r--sys-utils/fstrim.c8
-rw-r--r--sys-utils/mount.86
-rw-r--r--sys-utils/mount.c435
-rw-r--r--sys-utils/umount.c180
-rw-r--r--tests/expected/libmount/loop-conflict2
-rw-r--r--tests/expected/libmount/loop-o-loop-val-conflict2
-rw-r--r--tests/expected/libmount/loop-o-loop-val-initialized2
-rw-r--r--tests/expected/libmount/loop-overlay6
-rwxr-xr-xtests/ts/libmount/loop9
-rwxr-xr-xtests/ts/libmount/loop-overlay10
19 files changed, 831 insertions, 569 deletions
diff --git a/include/exitcodes.h b/include/exitcodes.h
index 24ee12364..f28f68e45 100644
--- a/include/exitcodes.h
+++ b/include/exitcodes.h
@@ -22,14 +22,4 @@
#define FSCK_EX_USAGE 16 /* Usage or syntax error */
#define FSCK_EX_LIBRARY 128 /* Shared library error */
-/* Exit codes used by mount-line programs */
-#define MOUNT_EX_SUCCESS 0 /* No errors */
-#define MOUNT_EX_USAGE 1 /* incorrect invocation or permission */
-#define MOUNT_EX_SYSERR 2 /* out of memory, cannot fork, ... */
-#define MOUNT_EX_SOFTWARE 4 /* internal mount bug or wrong version */
-#define MOUNT_EX_USER 8 /* user interrupt */
-#define MOUNT_EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */
-#define MOUNT_EX_FAIL 32 /* mount failure */
-#define MOUNT_EX_SOMEOK 64 /* some mount succeeded */
-
#endif /* UTIL_LINUX_EXITCODES_H */
diff --git a/lib/timer.c b/lib/timer.c
index 05fbd92f5..210c726cb 100644
--- a/lib/timer.c
+++ b/lib/timer.c
@@ -10,19 +10,38 @@
#include "c.h"
#include "timer.h"
+/*
+ * Note the timeout is used for the first signal, then the signal is send
+ * repeatedly in interval ~1% of the original timeout to avoid race in signal
+ * handling -- for example you want to use timer to define timeout for a
+ * syscall:
+ *
+ * setup_timer()
+ * syscall()
+ * cancel_timer()
+ *
+ * if the timeout is too short than it's possible that the signal is delivered
+ * before application enter the syscall function. For this reason timer send
+ * the signal repeatedly.
+ *
+ * The applications need to ensure that they can tolerate multiple signal
+ * deliveries.
+ */
int setup_timer(timer_t * t_id, struct itimerval *timeout,
void (*timeout_handler)(int, siginfo_t *, void *))
{
+ time_t sec = timeout->it_value.tv_sec;
+ long usec = timeout->it_value.tv_usec;
struct sigaction sig_a;
static struct sigevent sig_e = {
.sigev_notify = SIGEV_SIGNAL,
.sigev_signo = SIGALRM
};
struct itimerspec val = {
- .it_value.tv_sec = timeout->it_value.tv_sec,
- .it_value.tv_nsec = timeout->it_value.tv_usec * 1000,
- .it_interval.tv_sec = 0,
- .it_interval.tv_nsec = 0
+ .it_value.tv_sec = sec,
+ .it_value.tv_nsec = usec * 1000,
+ .it_interval.tv_sec = sec / 100,
+ .it_interval.tv_nsec = (sec ? sec % 100 : 1) * 10*1000*1000
};
if (sigemptyset(&sig_a.sa_mask))
@@ -35,7 +54,7 @@ int setup_timer(timer_t * t_id, struct itimerval *timeout,
return 1;
if (timer_create(CLOCK_MONOTONIC, &sig_e, t_id))
return 1;
- if (timer_settime(*t_id, SA_SIGINFO, &val, NULL))
+ if (timer_settime(*t_id, 0, &val, NULL))
return 1;
return 0;
}
diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt
index 78d89cae7..9c6ff2463 100644
--- a/libmount/docs/libmount-sections.txt
+++ b/libmount/docs/libmount-sections.txt
@@ -35,9 +35,12 @@ mnt_context_enable_fork
mnt_context_enable_lazy
mnt_context_enable_loopdel
mnt_context_enable_rdonly_umount
+mnt_context_enable_rwonly_mount
mnt_context_enable_sloppy
mnt_context_enable_verbose
+mnt_context_forced_rdonly
mnt_context_get_cache
+mnt_context_get_excode
mnt_context_get_fs
mnt_context_get_fstab
mnt_context_get_fstab_userdata
@@ -72,6 +75,7 @@ mnt_context_is_nomtab
mnt_context_is_parent
mnt_context_is_rdonly_umount
mnt_context_is_restricted
+mnt_context_is_rwonly_mount
mnt_context_is_sloppy
mnt_context_is_swapmatch
mnt_context_is_verbose
@@ -105,6 +109,15 @@ MNT_ERR_NOFSTAB
MNT_ERR_NOFSTYPE
MNT_ERR_NOSOURCE
MNT_ERR_LOOPOVERLAP
+<SUBSECTION>
+MNT_EX_SUCCESS
+MNT_EX_USAGE
+MNT_EX_SYSERR
+MNT_EX_SOFTWARE
+MNT_EX_USER
+MNT_EX_FILEIO
+MNT_EX_FAIL
+MNT_EX_SOMEOK
</SECTION>
<SECTION>
@@ -130,6 +143,7 @@ MNT_MS_UHELPER
MNT_MS_USER
MNT_MS_USERS
MNT_MS_XCOMMENT
+MNT_MS_XFSTABCOMM
<SUBSECTION>
MS_BIND
MS_DIRSYNC
diff --git a/libmount/src/context.c b/libmount/src/context.c
index e731749b4..38e036330 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -172,8 +172,10 @@ int mnt_reset_context(struct libmnt_context *cxt)
cxt->flags |= (fl & MNT_FL_FORCE);
cxt->flags |= (fl & MNT_FL_NOCANONICALIZE);
cxt->flags |= (fl & MNT_FL_RDONLY_UMOUNT);
+ cxt->flags |= (fl & MNT_FL_RWONLY_MOUNT);
cxt->flags |= (fl & MNT_FL_NOSWAPMATCH);
cxt->flags |= (fl & MNT_FL_TABPATHS_CHECKED);
+
return 0;
}
@@ -478,6 +480,48 @@ int mnt_context_is_rdonly_umount(struct libmnt_context *cxt)
}
/**
+ * mnt_context_enable_rwonly_mount:
+ * @cxt: mount context
+ * @enable: TRUE or FALSE
+ *
+ * Force read-write mount; if enabled libmount will never try MS_RDONLY
+ * after failed mount(2) EROFS. (See mount(8) man page, option -w).
+ *
+ * Returns: 0 on success, negative number in case of error.
+ */
+int mnt_context_enable_rwonly_mount(struct libmnt_context *cxt, int enable)
+{
+ return set_flag(cxt, MNT_FL_RWONLY_MOUNT, enable);
+}
+
+/**
+ * mnt_context_is_rwonly_mount
+ * @cxt: mount context
+ *
+ * See also mnt_context_enable_rwonly_mount() and mount(8) man page,
+ * option -w.
+ *
+ * Returns: 1 if only read-write mount is allowed.
+ */
+int mnt_context_is_rwonly_mount(struct libmnt_context *cxt)
+{
+ return cxt->flags & MNT_FL_RWONLY_MOUNT ? 1 : 0;
+}
+
+/**
+ * mnt_context_forced_rdonly:
+ * @cxt: mount context
+ *
+ * See also mnt_context_enable_rwonly_mount().
+ *
+ * Returns: 1 if mounted read-only on write-protected device.
+ */
+int mnt_context_forced_rdonly(struct libmnt_context *cxt)
+{
+ return cxt->flags & MNT_FL_FORCED_RDONLY ? 1 : 0;
+}
+
+/**
* mnt_context_disable_helpers:
* @cxt: mount context
* @disable: TRUE or FALSE
@@ -2002,8 +2046,10 @@ int mnt_context_apply_fstab(struct libmnt_context *cxt)
if (!cxt || !cxt->fs)
return -EINVAL;
- if (mnt_context_tab_applied(cxt)) /* already applied */
+ if (mnt_context_tab_applied(cxt)) { /* already applied */
+ DBG(CXT, ul_debugobj(cxt, "fstab already applied -- skip"));
return 0;
+ }
if (mnt_context_is_restricted(cxt)) {
DBG(CXT, ul_debugobj(cxt, "force fstab usage for non-root users!"));
@@ -2216,7 +2262,7 @@ int mnt_context_set_syscall_status(struct libmnt_context *cxt, int status)
* @buf: buffer
* @bufsiz: size of the buffer
*
- * Not implemented yet.
+ * Not implemented, deprecated in favor or mnt_context_get_excode().
*
* Returns: 0 or negative number in case of error.
*/
@@ -2228,6 +2274,100 @@ int mnt_context_strerror(struct libmnt_context *cxt __attribute__((__unused__)),
return 0;
}
+
+int mnt_context_get_generic_excode(int rc, char *buf, size_t bufsz, char *fmt, ...)
+{
+ va_list va;
+
+ if (rc == 0)
+ return MNT_EX_SUCCESS;
+
+ va_start(va, fmt);
+
+ /* we need to support "%m" */
+ errno = rc < 0 ? -rc : rc;
+
+ if (buf)
+ vsnprintf(buf, bufsz, fmt, va);
+
+ switch (errno) {
+ case EINVAL:
+ case EPERM:
+ rc = MNT_EX_USAGE;
+ break;
+ case ENOMEM:
+ rc = MNT_EX_SYSERR;
+ break;
+ default:
+ rc = MNT_EX_FAIL;
+ break;
+ }
+ va_end(va);
+ return rc;
+}
+
+/**
+ * mnt_context_get_excode:
+ * @cxt: context
+ * @rc: return code of the previous operation
+ * @buf: buffer to print error message (optional)
+ * @bufsz: size of the buffer
+ *
+ * This function analyzes context, [u]mount syscall and external helper status
+ * and @mntrc and generates unified return code (see MNT_EX_*) as expected
+ * from mount(8) or umount(8).
+ *
+ * If the external helper (e.g. /sbin/mount.type) has been executed than it
+ * returns status from wait() of the helper. It's not libmount fail if helper
+ * returns some crazy undocumented codes... See mnt_context_helper_executed()
+ * and mnt_context_get_helper_status(). Note that mount(8) and umount(8) utils
+ * always return code from helper without extra care about it.
+ *
+ * If the argument @buf is not NULL then error message is generated (if
+ * anything failed).
+ *
+ * The @mntrc is usually return code from mnt_context_mount(),
+ * mnt_context_umount(), or 'mntrc' as returned by mnt_context_next_mount().
+ *
+ * Returns: MNT_EX_* codes.
+ */
+int mnt_context_get_excode(
+ struct libmnt_context *cxt,
+ int rc,
+ char *buf,
+ size_t bufsz)
+{
+ if (buf) {
+ *buf = '\0'; /* for sure */
+
+ if (!cxt->enabled_textdomain) {
+ bindtextdomain(LIBMOUNT_TEXTDOMAIN, LOCALEDIR);
+ cxt->enabled_textdomain = 1;
+ }
+ }
+
+ switch (cxt->action) {
+ case MNT_ACT_MOUNT:
+ rc = mnt_context_get_mount_excode(cxt, rc, buf, bufsz);
+ break;
+ case MNT_ACT_UMOUNT:
+ rc = mnt_context_get_umount_excode(cxt, rc, buf, bufsz);
+ break;
+ default:
+ if (rc)
+ rc = mnt_context_get_generic_excode(rc, buf, bufsz,
+ _("operation failed: %m"));
+ else
+ rc = MNT_EX_SUCCESS;
+ break;
+ }
+
+ DBG(CXT, ul_debugobj(cxt, "excode: rc=%d message=\"%s\"", rc,
+ buf ? buf : "<no-message>"));
+ return rc;
+}
+
+
/**
* mnt_context_init_helper
* @cxt: mount context
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index 6368e9ba8..9caee70e5 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -1083,6 +1083,7 @@ int mnt_context_mount(struct libmnt_context *cxt)
assert(cxt->helper_exec_status == 1);
assert(cxt->syscall_status == 1);
+again:
rc = mnt_context_prepare_mount(cxt);
if (!rc)
rc = mnt_context_prepare_update(cxt);
@@ -1090,6 +1091,32 @@ int mnt_context_mount(struct libmnt_context *cxt)
rc = mnt_context_do_mount(cxt);
if (!rc)
rc = mnt_context_update_tabs(cxt);
+
+ /*
+ * Read-only device; try mount filesystem read-only
+ */
+ if ((rc == -EROFS && !mnt_context_syscall_called(cxt)) /* before syscall; rdonly loopdev */
+ || mnt_context_get_syscall_errno(cxt) == EROFS /* syscall failed with EROFS */
+ || mnt_context_get_syscall_errno(cxt) == EACCES) /* syscall failed with EACCES */
+ {
+ unsigned long mflags = 0;
+
+ mnt_context_get_mflags(cxt, &mflags);
+
+ if (!(mflags & MS_RDONLY) /* not yet RDONLY */
+ && !(mflags & MS_REMOUNT) /* not remount */
+ && !(mflags & MS_BIND) /* not bin mount */
+ && !mnt_context_is_rwonly_mount(cxt)) { /* no explicit read-write */
+
+ assert(!(cxt->flags & MNT_FL_FORCED_RDONLY));
+ DBG(CXT, ul_debugobj(cxt, "write-protected source, trying RDONLY."));
+
+ mnt_context_reset_status(cxt);
+ mnt_context_set_mflags(cxt, mflags | MS_RDONLY);
+ cxt->flags |= MNT_FL_FORCED_RDONLY;
+ goto again;
+ }
+ }
return rc;
}
@@ -1222,3 +1249,334 @@ int mnt_context_next_mount(struct libmnt_context *cxt,
return 0;
}
+/*
+ * Returns 1 if @dir parent is shared
+ */
+static int is_shared_tree(struct libmnt_context *cxt, const char *dir)
+{
+ struct libmnt_table *tb = NULL;
+ struct libmnt_fs *fs;
+ unsigned long mflags = 0;
+ char *mnt = NULL, *p;
+ int rc = 0;
+
+ if (!dir)
+ return 0;
+ if (mnt_context_get_mtab(cxt, &tb) || !tb)
+ goto done;
+
+ mnt = strdup(dir);
+ if (!mnt)
+ goto done;
+ p = strrchr(mnt, '/');
+ if (!p)
+ goto done;
+ if (p > mnt)
+ *p = '\0';
+ fs = mnt_table_find_mountpoint(tb, mnt, MNT_ITER_BACKWARD);
+
+ rc = fs && mnt_fs_is_kernel(fs)
+ && mnt_fs_get_propagation(fs, &mflags) == 0
+ && (mflags & MS_SHARED);
+done:
+ free(mnt);
+ return rc;
+}
+
+int mnt_context_get_mount_excode(
+ struct libmnt_context *cxt,
+ int rc,
+ char *buf,
+ size_t bufsz)
+{
+ int syserr;
+ struct stat st;
+ unsigned long uflags = 0, mflags = 0;
+
+ int restricted = mnt_context_is_restricted(cxt);
+ const char *tgt = mnt_context_get_target(cxt);
+ const char *src = mnt_context_get_source(cxt);
+
+ if (mnt_context_helper_executed(cxt)) {
+ /*
+ * /sbin/mount.<type> called, return status
+ */
+ if (rc == -MNT_ERR_APPLYFLAGS && buf)
+ snprintf(buf, bufsz, _("WARNING: failed to apply propagation flags"));
+
+ return mnt_context_get_helper_status(cxt);
+ }
+
+ if (rc == 0 && mnt_context_get_status(cxt) == 1) {
+ /*
+ * Libmount success && syscall success.
+ */
+ if (buf && mnt_context_forced_rdonly(cxt))
+ snprintf(buf, bufsz, _("WARNING: device write-protected, mounted read-only"));
+ return MNT_EX_SUCCESS;
+ }
+
+ mnt_context_get_mflags(cxt, &mflags); /* mount(2) flags */
+ mnt_context_get_user_mflags(cxt, &uflags); /* userspace flags */
+
+ if (!mnt_context_syscall_called(cxt)) {
+ /*
+ * libmount errors (extra library checks)
+ */
+ switch (rc) {
+ case -EPERM:
+ if (buf)
+ snprintf(buf, bufsz, _("operation permitted for root only"));
+ return MNT_EX_USAGE;
+ case -EBUSY:
+ if (buf)
+ snprintf(buf, bufsz, _("%s is already mounted"), src);
+ return MNT_EX_USAGE;
+ case -MNT_ERR_NOFSTAB:
+ if (!buf)
+ return MNT_EX_USAGE;
+ if (mnt_context_is_swapmatch(cxt))
+ snprintf(buf, bufsz, _("can't find in %s"),
+ mnt_get_fstab_path());
+ else if (tgt)
+ snprintf(buf, bufsz, _("can't find mount point in %s"),
+ mnt_get_fstab_path());
+ else if (src)
+ snprintf(buf, bufsz, _("can't find mount source %s in %s"),
+ src, mnt_get_fstab_path());
+ return MNT_EX_USAGE;
+ case -MNT_ERR_AMBIFS:
+ if (buf)
+ snprintf(buf, bufsz, _("more filesystems detected on %s; use -t <type> or wipefs(8)"), src);
+ return MNT_EX_USAGE;
+ case -MNT_ERR_NOFSTYPE:
+ if (buf)
+ snprintf(buf, bufsz, restricted ?
+ _("failed to determine filesystem type") :
+ _("no filesystem type specified"));
+ return MNT_EX_USAGE;
+ case -MNT_ERR_NOSOURCE:
+ if (uflags & MNT_MS_NOFAIL)
+ return MNT_EX_SUCCESS;
+ if (buf) {
+ if (src)
+ snprintf(buf, bufsz, _("can't find %s"), src);
+ else
+ snprintf(buf, bufsz, _("no mount source specified"));
+ }
+ return MNT_EX_USAGE;
+ case -MNT_ERR_MOUNTOPT:
+ if (buf)
+ snprintf(buf, bufsz, errno ?
+ _("failed to parse mount options: %m") :
+ _("failed to parse mount options"));
+ return MNT_EX_USAGE;
+ case -MNT_ERR_LOOPDEV:
+ if (buf)
+ snprintf(buf, bufsz, _("failed to setup loop device for %s"), src);
+ return MNT_EX_FAIL;
+ case -MNT_ERR_LOOPOVERLAP:
+ if (buf)
+ snprintf(buf, bufsz, _("overlapping loop device exists for %s"), src);
+ return MNT_EX_FAIL;
+ default:
+ return mnt_context_get_generic_excode(rc, buf, bufsz, _("mount failed: %m"));
+ }
+
+ } else if (mnt_context_get_syscall_errno(cxt) == 0) {
+ /*
+ * mount(2) syscall success, but something else failed
+ * (probably error in mtab processing).
+ */
+ if (rc < 0)
+ return mnt_context_get_generic_excode(rc, buf, bufsz,
+ _("filesystem was mounted, but any subsequent operation failed: %m"));
+
+ return MNT_EX_SOFTWARE; /* internal error */
+
+ }
+
+ /*
+ * mount(2) errors
+ */
+ syserr = mnt_context_get_syscall_errno(cxt);
+
+
+ switch(syserr) {
+ case EPERM:
+ if (!buf)
+ break;
+ if (geteuid() == 0) {
+ if (stat(tgt, &st) || !S_ISDIR(st.st_mode))
+ snprintf(buf, bufsz, _("mount point is not a directory"));
+ else
+ snprintf(buf, bufsz, _("permission denied"));
+ } else
+ snprintf(buf, bufsz, _("must be superuser to use mount"));
+ break;
+
+ case EBUSY:
+ {
+ struct libmnt_table *tb;
+
+ if (!buf)
+ break;
+ if (mflags & MS_REMOUNT) {
+ snprintf(buf, bufsz, _("mount point is busy"));
+ break;
+ }
+ if (src && mnt_context_get_mtab(cxt, &tb) == 0) {
+ struct libmnt_iter itr;
+ struct libmnt_fs *fs;
+
+ mnt_reset_iter(&itr, MNT_ITER_FORWARD);
+ while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
+ const char *s = mnt_fs_get_srcpath(fs),
+ *t = mnt_fs_get_target(fs);
+
+ if (t && s && mnt_fs_streq_srcpath(fs, src)) {
+ snprintf(buf, bufsz, _("%s already mounted on %s"), s, t);
+ break;
+ }
+ }
+ }
+ if (!*buf)
+ snprintf(buf, bufsz, _("%s already mounted or mount point busy"), src);
+ break;
+ }
+ case ENOENT:
+ if (tgt && lstat(tgt, &st)) {
+ if (buf)
+ snprintf(buf, bufsz, _("mount point does not exist"));
+ } else if (tgt && stat(tgt, &st)) {
+ if (buf)
+ snprintf(buf, bufsz, _("mount point is a symbolic link to nowhere"));
+ } else if (src && stat(src, &st)) {
+ if (uflags & MNT_MS_NOFAIL)
+ return MNT_EX_SUCCESS;
+ if (buf)
+ snprintf(buf, bufsz, _("special device %s does not exist"), src);
+ } else if (buf) {
+ errno = syserr;
+ snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
+ }
+ break;
+
+ case ENOTDIR:
+ if (stat(tgt, &st) || ! S_ISDIR(st.st_mode)) {
+ if (buf)
+ snprintf(buf, bufsz, _("mount point is not a directory"));
+ } else if (src && stat(src, &st) && errno == ENOTDIR) {
+ if (uflags & MNT_MS_NOFAIL)
+ return MNT_EX_SUCCESS;
+ if (buf)
+ snprintf(buf, bufsz, _("special device %s does not exist "
+ "(a path prefix is not a directory)"), src);
+ } else if (buf) {
+ errno = syserr;
+ snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
+ }
+ break;
+
+ case EINVAL:
+ if (!buf)
+ break;
+ if (mflags & MS_REMOUNT)
+ snprintf(buf, bufsz, _("mount point not mounted or bad option"));
+ else if (rc == -MNT_ERR_APPLYFLAGS)
+ snprintf(buf, bufsz, _("not mount point or bad option"));
+ else if ((mflags & MS_MOVE) && is_shared_tree(cxt, src))
+ snprintf(buf, bufsz,
+ _("bad option; moving a mount "
+ "residing under a shared mount is unsupported"));
+ else if (mnt_fs_is_netfs(mnt_context_get_fs(cxt)))
+ snprintf(buf, bufsz,
+ _("bad option; for several filesystems (e.g. nfs, cifs) "
+ "you might need a /sbin/mount.<type> helper program"));
+ else
+ snprintf(buf, bufsz,
+ _("wrong fs type, bad option, bad superblock on %s, "
+ "missing codepage or helper program, or other error"),
+ src);
+ break;
+
+ case EMFILE:
+ if (buf)
+ snprintf(buf, bufsz, _("mount table full"));
+ break;
+
+ case EIO:
+ if (buf)
+ snprintf(buf, bufsz, _("can't read superblock on %s"), src);
+ break;
+
+ case ENODEV:
+ if (!buf)
+ break;
+ if (mnt_context_get_fstype(cxt))
+ snprintf(buf, bufsz, _("unknown filesystem type '%s'"),
+ mnt_context_get_fstype(cxt));
+ else
+ snprintf(buf, bufsz, _("unknown filesystem type"));
+ break;
+
+ case ENOTBLK:
+ if (uflags & MNT_MS_NOFAIL)
+ return MNT_EX_SUCCESS;
+ if (!buf)
+ break;
+ if (stat(src, &st))
+ snprintf(buf, bufsz, _("%s is not a block device, and stat(2) fails?"), src);
+ else if (S_ISBLK(st.st_mode))
+ snprintf(buf, bufsz,
+ _("the kernel does not recognize %s as a block device; "
+ "maybe \"modprobe driver\" is necessary"), src);
+ else if (S_ISREG(st.st_mode))
+ snprintf(buf, bufsz, _("%s is not a block device; try \"-o loop\""), src);
+ else
+ snprintf(buf, bufsz, _("%s is not a block device"), src);
+ break;
+
+ case ENXIO:
+ if (uflags & MNT_MS_NOFAIL)
+ return MNT_EX_SUCCESS;
+ if (buf)
+ snprintf(buf, bufsz, _("%s is not a valid block device"), src);
+ break;
+
+ case EACCES:
+ case EROFS:
+ if (!buf)
+ break;
+ if (mflags & MS_RDONLY)
+ snprintf(buf, bufsz, _("cannot mount %s read-only"), src);
+ else if (mnt_context_is_rwonly_mount(cxt))
+ snprintf(buf, bufsz, _("%s is write-protected but explicit read-write mode requested"), src);
+ else if (mflags & MS_REMOUNT)
+ snprintf(buf, bufsz, _("cannot remount %s read-write, is write-protected"), src);
+ else if (mflags & MS_BIND)
+ snprintf(buf, bufsz, _("bind %s failed"), src);
+ else {
+ errno = syserr;
+ snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
+ }
+ break;
+
+ case ENOMEDIUM:
+ if (uflags & MNT_MS_NOFAIL)
+ return MNT_EX_SUCCESS;
+ if (buf)
+ snprintf(buf, bufsz, _("no medium found on %s"), src);
+ break;
+
+ default:
+ if (buf) {
+ errno = syserr;
+ snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
+ }
+ break;
+ }
+
+ return MNT_EX_FAIL;
+}
+
diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c
index 28787dab1..a2bba8060 100644
--- a/libmount/src/context_umount.c
+++ b/libmount/src/context_umount.c
@@ -1016,3 +1016,83 @@ int mnt_context_next_umount(struct libmnt_context *cxt,
*mntrc = rc;
return 0;
}
+
+
+int mnt_context_get_umount_excode(
+ struct libmnt_context *cxt,
+ int rc,
+ char *buf,
+ size_t bufsz)
+{
+ if (mnt_context_helper_executed(cxt))
+ /*
+ * /sbin/umount.<type> called, return status
+ */
+ return mnt_context_get_helper_status(cxt);
+
+ if (rc == 0 && mnt_context_get_status(cxt) == 1)
+ /*
+ * Libmount success && syscall success.
+ */
+ return MNT_EX_SUCCESS;
+
+ if (!mnt_context_syscall_called(cxt)) {
+ /*
+ * libmount errors (extra library checks)
+ */
+ if (rc == -EPERM && !mnt_context_tab_applied(cxt)) {
+ /* failed to evaluate permissions because not found
+ * relevant entry in mtab */
+ if (buf)
+ snprintf(buf, bufsz, _("not mounted"));
+ return MNT_EX_USAGE;
+ }
+ return mnt_context_get_generic_excode(rc, buf, bufsz,
+ _("umount failed: %m"));
+
+ } else if (mnt_context_get_syscall_errno(cxt) == 0) {
+ /*
+ * umount(2) syscall success, but something else failed
+ * (probably error in mtab processing).
+ */
+ if (rc < 0)
+ return mnt_context_get_generic_excode(rc, buf, bufsz,
+ _("filesystem was unmounted, but any subsequent operation failed: %m"));
+
+ return MNT_EX_SOFTWARE; /* internal error */
+ }
+
+ /*
+ * umount(2) errors
+ */
+ if (buf) {
+ int syserr = mnt_context_get_syscall_errno(cxt);
+
+ switch (syserr) {
+ case ENXIO:
+ snprintf(buf, bufsz, _("invalid block device")); /* ??? */
+ break;
+ case EINVAL:
+ snprintf(buf, bufsz, _("not mounted"));
+ break;
+ case EIO:
+ snprintf(buf, bufsz, _("can't write superblock"));
+ break;
+ case EBUSY:
+ snprintf(buf, bufsz, _("target is busy"));
+ break;
+ case ENOENT:
+ snprintf(buf, bufsz, _("no mount point specified"));
+ break;
+ case EPERM:
+ snprintf(buf, bufsz, _("must be superuser to unmount"));
+ break;
+ case EACCES:
+ snprintf(buf, bufsz, _("block devices are not permitted on filesystem"));
+ break;
+ default:
+ return mnt_context_get_generic_excode(syserr, buf, bufsz,_("umount(2) system call failed: %m"));
+ }
+ }
+ return MNT_EX_FAIL;
+}
diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in
index f191a52fe..123145fc4 100644
--- a/libmount/src/libmount.h.in
+++ b/libmount/src/libmount.h.in
@@ -185,6 +185,72 @@ enum {
*/
#define MNT_ERR_LOOPOVERLAP 5007
+
+/*
+ * Overall return codes -- based on mount(8) and umount(8) return codes.
+ * See mnt_context_get_excode() for more details.
+ */
+
+/**
+ * MNT_EX_SUCCESS:
+ *
+ * [u]mount(8) exit code: no errors
+ */
+#define MNT_EX_SUCCESS 0
+
+/**
+ * MNT_EX_USAGE:
+ *
+ * [u]mount(8) exit code: incorrect invocation or permission
+ */
+#define MNT_EX_USAGE 1
+
+/**
+ * MNT_EX_SYSERR:
+ *
+ * [u]mount(8) exit code: out of memory, cannot fork, ...
+ */
+
+#define MNT_EX_SYSERR 2
+
+/**
+ * MNT_EX_SOFTWARE:
+ *
+ * [u]mount(8) exit code: internal mount bug or wrong version
+ */
+#define MNT_EX_SOFTWARE 4
+
+/**
+ * MNT_EX_USER:
+ *
+ * [u]mount(8) exit code: user interrupt
+ */
+#define MNT_EX_USER 8
+
+/**
+ * MNT_EX_FILEIO:
+ *
+ * [u]mount(8) exit code: problems writing, locking, ... mtab/fstab
+ */
+#define MNT_EX_FILEIO 16
+
+/**
+ * MNT_EX_FAIL:
+ *
+ * [u]mount(8) exit code: mount failure
+ */
+#define MNT_EX_FAIL 32
+
+/**
+ * MNT_EX_SOMEOK:
+ *
+ * [u]mount(8) exit code: some mount succeeded; usually when executed with
+ * --all options. Never returned by libmount.
+ */
+#define MNT_EX_SOMEOK 64
+
+
+
#ifndef __GNUC_PREREQ
# if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
@@ -610,6 +676,7 @@ extern int mnt_context_set_optsmode(struct libmnt_context *cxt, int mode);
extern int mnt_context_disable_canonicalize(struct libmnt_context *cxt, int disable);
extern int mnt_context_enable_lazy(struct libmnt_context *cxt, int enable);
extern int mnt_context_enable_rdonly_umount(struct libmnt_context *cxt, int enable);
+extern int mnt_context_enable_rwonly_mount(struct libmnt_context *cxt, int enable);
extern int mnt_context_disable_helpers(struct libmnt_context *cxt, int disable);
extern int mnt_context_enable_sloppy(struct libmnt_context *cxt, int enable);
extern int mnt_context_enable_fake(struct libmnt_context *cxt, int enable);
@@ -626,6 +693,8 @@ extern int mnt_context_is_lazy(struct libmnt_context *cxt)
__ul_attribute__((nonnull));
extern int mnt_context_is_rdonly_umount(struct libmnt_context *cxt)
__ul_attribute__((nonnull));
+extern int mnt_context_is_rwonly_mount(struct libmnt_context *cxt)
+ __ul_attribute__((nonnull));
extern int mnt_context_is_sloppy(struct libmnt_context *cxt)
__ul_attribute__((nonnull));
extern int mnt_context_is_fake(struct libmnt_context *cxt)
@@ -644,6 +713,8 @@ extern int mnt_context_is_nocanonicalize(struct libmnt_context *cxt)
__ul_attribute__((nonnull));
extern int mnt_context_is_swapmatch(struct libmnt_context *cxt)
__ul_attribute__((nonnull));
+extern int mnt_context_forced_rdonly(struct libmnt_context *cxt)
+ __ul_attribute__((nonnull));
extern int mnt_context_is_fork(struct libmnt_context *cxt)
__ul_attribute__((nonnull));
@@ -724,7 +795,12 @@ extern int mnt_context_syscall_called(struct libmnt_context *cxt);
extern int mnt_context_get_syscall_errno(struct libmnt_context *cxt);
extern int mnt_context_strerror(struct libmnt_context *cxt, char *buf,
- size_t bufsiz);
+ size_t bufsiz)
+ __ul_attribute__((deprecated));
+
+extern int mnt_context_get_excode(struct libmnt_context *cxt,
+ int rc, char *buf, size_t bufsz);
+
/* context_mount.c */
extern int mnt_context_mount(struct libmnt_context *cxt);
diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym
index f0210c240..ca16cafa1 100644
--- a/libmount/src/libmount.sym
+++ b/libmount/src/libmount.sym
@@ -315,3 +315,10 @@ MOUNT_2.28 {
mnt_table_find_target_with_option;
mnt_fs_set_priority;
} MOUNT_2.26;
+
+MOUNT_2.30 {
+ mnt_context_is_rwonly_mount;
+ mnt_context_forced_rdonly;
+ mnt_context_enable_rwonly_mount;
+ mnt_context_get_excode;
+} MOUNT_2.28;
diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
index 2baab55de..e01de337d 100644
--- a/libmount/src/mountP.h
+++ b/libmount/src/mountP.h
@@ -50,6 +50,18 @@ UL_DEBUG_DECLARE_MASK(libmount);
#define ON_DBG(m, x) __UL_DBG_CALL(libmount, MNT_DEBUG_, m, x)
#define DBG_FLUSH __UL_DBG_FLUSH(libmount, MNT_DEBUG_)
+/*
+ * NLS -- the library has to be independent on main program, so define
+ * UL_TEXTDOMAIN_EXPLICIT before you include nls.h.
+ *
+ * Now we use util-linux.po (=PACKAGE), rather than maintain the texts
+ * in the separate libmount.po file.
+ */
+#define LIBMOUNT_TEXTDOMAIN PACKAGE
+#define UL_TEXTDOMAIN_EXPLICIT LIBMOUNT_TEXTDOMAIN
+#include "nls.h"
+
+
/* extension for files in the directory */
#define MNT_MNTTABDIR_EXT ".fstab"
@@ -313,6 +325,8 @@ struct libmnt_context
int syscall_status; /* 1: not called yet, 0: success, <0: -errno */
+
+ unsigned int enabled_textdomain : 1; /* bindtextdomain() called */
};
/* flags */
@@ -328,6 +342,7 @@ struct libmnt_context
#define MNT_FL_RDONLY_UMOUNT (1 << 11) /* remount,ro after EBUSY umount(2) */
#define MNT_FL_FORK (1 << 12)
#define MNT_FL_NOSWAPMATCH (1 << 13)
+#define MNT_FL_RWONLY_MOUNT (1 << 14) /* explicit mount -w; never try read-only */
#define MNT_FL_MOUNTDATA (1 << 20)
#define MNT_FL_TAB_APPLIED (1 << 21) /* mtab/fstab merged to cxt->fs */
@@ -338,6 +353,7 @@ struct libmnt_context
#define MNT_FL_LOOPDEV_READY (1 << 26) /* /dev/loop<N> initialized by the library */
#define MNT_FL_MOUNTOPTS_FIXED (1 << 27)
#define MNT_FL_TABPATHS_CHECKED (1 << 28)
+#define MNT_FL_FORCED_RDONLY (1 << 29) /* mounted read-only on write-protected device */
/* default flags */
#define MNT_FL_DEFAULT 0
@@ -408,6 +424,10 @@ extern int mnt_context_set_tabfilter(struct libmnt_context *cxt,
int (*fltr)(struct libmnt_fs *, void *),
void *data);
+extern int mnt_context_get_generic_excode(int rc, char *buf, size_t bufsz, char *fmt, ...);
+extern int mnt_context_get_mount_excode(struct libmnt_context *cxt, int mntrc, char *buf, size_t bufsz);
+extern int mnt_context_get_umount_excode(struct libmnt_context *cxt, int mntrc, char *buf, size_t bufsz);
+
/* tab_update.c */
extern int mnt_update_set_filename(struct libmnt_update *upd,
const char *filename, int userspace_only);
diff --git a/sys-utils/fstrim.c b/sys-utils/fstrim.c
index f42ebe77a..b884af6d0 100644
--- a/sys-utils/fstrim.c
+++ b/sys-utils/fstrim.c
@@ -184,11 +184,11 @@ static int fstrim_all(struct fstrim_range *rangetpl, int verbose)
itr = mnt_new_iter(MNT_ITER_BACKWARD);
if (!itr)
- err(MOUNT_EX_FAIL, _("failed to initialize libmount iterator"));
+ err(MNT_EX_FAIL, _("failed to initialize libmount iterator"));
tab = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
if (!tab)
- err(MOUNT_EX_FAIL, _("failed to parse %s"), _PATH_PROC_MOUNTINFO);
+ err(MNT_EX_FAIL, _("failed to parse %s"), _PATH_PROC_MOUNTINFO);
/* de-duplicate by mountpoints */
mnt_table_uniq_fs(tab, 0, uniq_fs_target_cmp);
@@ -237,9 +237,9 @@ static int fstrim_all(struct fstrim_range *rangetpl, int verbose)
mnt_free_iter(itr);
if (cnt && cnt == cnt_err)
- return MOUNT_EX_FAIL; /* all failed */
+ return MNT_EX_FAIL; /* all failed */
if (cnt && cnt_err)
- return MOUNT_EX_SOMEOK; /* some ok */
+ return MNT_EX_SOMEOK; /* some ok */
return EXIT_SUCCESS;
}
diff --git a/sys-utils/mount.8 b/sys-utils/mount.8
index 56ccbbd35..bbfe71b75 100644
--- a/sys-utils/mount.8
+++ b/sys-utils/mount.8
@@ -807,8 +807,12 @@ Mount the partition that has the specified
Verbose mode.
.TP
.BR \-w , " \-\-rw" , " \-\-read\-write"
-Mount the filesystem read/write. This is the default. A synonym is
+Mount the filesystem read/write. The read-write is kernel default. A synonym is
.BR "\-o rw" .
+
+Note that specify \fB\-w\fR on command line forces \fBmount\fR command
+to never try read-only mount on write-protected devices. The default is
+try read-only if the previous mount syscall with read-write flags failed.
.TP
.BR \-V , " \-\-version"
Display version information and exit.
diff --git a/sys-utils/mount.c b/sys-utils/mount.c
index b09e77616..4d7a5fc73 100644
--- a/sys-utils/mount.c
+++ b/sys-utils/mount.c
@@ -36,12 +36,11 @@
#include "c.h"
#include "env.h"
#include "strutils.h"
-#include "exitcodes.h"
#include "xalloc.h"
#include "closestream.h"
#include "canonicalize.h"
-#define OPTUTILS_EXIT_CODE MOUNT_EX_USAGE
+#define OPTUTILS_EXIT_CODE MNT_EX_USAGE
#include "optutils.h"
/*** TODO: DOCS:
@@ -51,8 +50,6 @@
* --options-source-force MNT_OMODE_FORCE
*/
-static int readwrite;
-
static int mk_exit_code(struct libmnt_context *cxt, int rc);
static void __attribute__((__noreturn__)) exit_non_root(const char *option)
@@ -63,15 +60,15 @@ static void __attribute__((__noreturn__)) exit_non_root(const char *option)
if (ruid == 0 && euid != 0) {
/* user is root, but setuid to non-root */
if (option)
- errx(MOUNT_EX_USAGE, _("only root can use \"--%s\" option "
+ errx(MNT_EX_USAGE, _("only root can use \"--%s\" option "
"(effective UID is %u)"),
option, euid);
- errx(MOUNT_EX_USAGE, _("only root can do that "
+ errx(MNT_EX_USAGE, _("only root can do that "
"(effective UID is %u)"), euid);
}
if (option)
- errx(MOUNT_EX_USAGE, _("only root can use \"--%s\" option"), option);
- errx(MOUNT_EX_USAGE, _("only root can do that"));
+ errx(MNT_EX_USAGE, _("only root can use \"--%s\" option"), option);
+ errx(MNT_EX_USAGE, _("only root can do that"));
}
static void __attribute__((__noreturn__)) print_version(void)
@@ -92,7 +89,7 @@ static void __attribute__((__noreturn__)) print_version(void)
fputs(*p++, stdout);
}
fputs(")\n", stdout);
- exit(MOUNT_EX_SUCCESS);
+ exit(MNT_EX_SUCCESS);
}
static int table_parser_errcb(struct libmnt_table *tb __attribute__((__unused__)),
@@ -127,11 +124,11 @@ static void print_all(struct libmnt_context *cxt, char *pattern, int show_label)
struct libmnt_cache *cache = NULL;
if (mnt_context_get_mtab(cxt, &tb))
- err(MOUNT_EX_SYSERR, _("failed to read mtab"));
+ err(MNT_EX_SYSERR, _("failed to read mtab"));
itr = mnt_new_iter(MNT_ITER_FORWARD);
if (!itr)
- err(MOUNT_EX_SYSERR, _("failed to initialize libmount iterator"));
+ err(MNT_EX_SYSERR, _("failed to initialize libmount iterator"));
if (show_label)
cache = mnt_new_cache();
@@ -173,14 +170,14 @@ static int mount_all(struct libmnt_context *cxt)
{
struct libmnt_iter *itr;
struct libmnt_fs *fs;
- int mntrc, ignored, rc = MOUNT_EX_SUCCESS;
+ int mntrc, ignored, rc = MNT_EX_SUCCESS;
int nsucc = 0, nerrs = 0;
itr = mnt_new_iter(MNT_ITER_FORWARD);
if (!itr) {
warn(_("failed to initialize libmount iterator"));
- return MOUNT_EX_SYSERR;
+ return MNT_EX_SYSERR;
}
while (mnt_context_next_mount(cxt, itr, &fs, &mntrc, &ignored) == 0) {
@@ -196,10 +193,10 @@ static int mount_all(struct libmnt_context *cxt)
if (mnt_context_is_verbose(cxt))
printf("%-25s: mount successfully forked\n", tgt);
} else {
- if (mk_exit_code(cxt, mntrc) == MOUNT_EX_SUCCESS) {
+ if (mk_exit_code(cxt, mntrc) == MNT_EX_SUCCESS) {
nsucc++;
- /* Note that MOUNT_EX_SUCCESS return code does
+ /* Note that MNT_EX_SUCCESS return code does
* not mean that FS has been really mounted
* (e.g. nofail option) */
if (mnt_context_get_status(cxt)
@@ -222,11 +219,11 @@ static int mount_all(struct libmnt_context *cxt)
}
if (nerrs == 0)
- rc = MOUNT_EX_SUCCESS; /* all success */
+ rc = MNT_EX_SUCCESS; /* all success */
else if (nsucc == 0)
- rc = MOUNT_EX_FAIL; /* all failed */
+ rc = MNT_EX_FAIL; /* all failed */
else
- rc = MOUNT_EX_SOMEOK; /* some success, some failed */
+ rc = MNT_EX_SOMEOK; /* some success, some failed */
mnt_free_iter(itr);
return rc;
@@ -258,40 +255,6 @@ static void success_message(struct libmnt_context *cxt)
printf(_("%s: %s mounted on %s.\n"), pr, src, tgt);
}
-/*
- * Handles generic errors like ENOMEM, ...
- *
- * rc = 0 success
- * <0 error (usually -errno)
- *
- * Returns exit status (MOUNT_EX_*) and prints error message.
- */
-static int handle_generic_errors(int rc, const char *msg, ...)
-{
- va_list va;
-
- va_start(va, msg);
- errno = -rc;
-
- switch(errno) {
- case EINVAL:
- case EPERM:
- vwarn(msg, va);
- rc = MOUNT_EX_USAGE;
- break;
- case ENOMEM:
- vwarn(msg, va);
- rc = MOUNT_EX_SYSERR;
- break;
- default:
- vwarn(msg, va);
- rc = MOUNT_EX_FAIL;
- break;
- }
- va_end(va);
- return rc;
-}
-
#if defined(HAVE_LIBSELINUX) && defined(HAVE_SECURITY_GET_INITIAL_CONTEXT)
#include <selinux/selinux.h>
#include <selinux/context.h>
@@ -323,339 +286,29 @@ static void selinux_warning(struct libmnt_context *cxt, const char *tgt)
#endif
/*
- * Returns 1 if @dir parent is shared
- */
-static int is_shared_tree(struct libmnt_context *cxt, const char *dir)
-{
- struct libmnt_table *tb = NULL;
- struct libmnt_fs *fs;
- unsigned long mflags = 0;
- char *mnt = NULL, *p;
- int rc = 0;
-
- if (!dir)
- return 0;
- if (mnt_context_get_mtab(cxt, &tb) || !tb)
- goto done;
- mnt = xstrdup(dir);
- p = strrchr(mnt, '/');
- if (!p)
- goto done;
- if (p > mnt)
- *p = '\0';
- fs = mnt_table_find_mountpoint(tb, mnt, MNT_ITER_BACKWARD);
-
- rc = fs && mnt_fs_is_kernel(fs)
- && mnt_fs_get_propagation(fs, &mflags) == 0
- && (mflags & MS_SHARED);
-done:
- free(mnt);
- return rc;
-}
-
-/*
- * rc = 0 success
- * <0 error (usually -errno or -1)
- *
- * Returns exit status (MOUNT_EX_*) and/or prints error message.
+ * Returns exit status (MNT_EX_*) and/or prints error message.
*/
static int mk_exit_code(struct libmnt_context *cxt, int rc)
{
- int syserr;
- struct stat st;
- unsigned long uflags = 0, mflags = 0;
+ const char *tgt;
+ char buf[BUFSIZ] = { 0 };
- int restricted = mnt_context_is_restricted(cxt);
- const char *tgt = mnt_context_get_target(cxt);
- const char *src = mnt_context_get_source(cxt);
+ rc = mnt_context_get_excode(cxt, rc, buf, sizeof(buf));
+ tgt = mnt_context_get_target(cxt);
-try_readonly:
- if (mnt_context_helper_executed(cxt)) {
- /*
- * /sbin/mount.<type> called, return status
- */
- if (rc == -MNT_ERR_APPLYFLAGS)
- warnx(_("WARNING: failed to apply propagation flags"));
- return mnt_context_get_helper_status(cxt);
+ if (*buf) {
+ const char *spec = tgt;
+ if (!spec)
+ spec = mnt_context_get_source(cxt);
+ if (!spec)
+ spec = "???";
+ warnx(_("%s: %s."), spec, buf);
}
- if (rc == 0 && mnt_context_get_status(cxt) == 1) {
- /*
- * Libmount success && syscall success.
- */
+ if (rc == MNT_EX_SUCCESS && mnt_context_get_status(cxt) == 1) {
selinux_warning(cxt, tgt);
-
- return MOUNT_EX_SUCCESS; /* mount(2) success */
- }
-
- mnt_context_get_mflags(cxt, &mflags); /* mount(2) flags */
- mnt_context_get_user_mflags(cxt, &uflags); /* userspace flags */
-
- if (!mnt_context_syscall_called(cxt)) {
- /*
- * libmount errors (extra library checks)
- */
- switch (rc) {
- case -EPERM:
- warnx(_("only root can mount %s on %s"), src, tgt);
- return MOUNT_EX_USAGE;
- case -EBUSY:
- warnx(_("%s is already mounted"), src);
- return MOUNT_EX_USAGE;
- /* -EROFS before syscall can happen only for loop mount */
- case -EROFS:
- warnx(_("%s is used as read only loop, mounting read-only"), src);
- mnt_context_reset_status(cxt);
- mnt_context_set_mflags(cxt, mflags | MS_RDONLY);
- rc = mnt_context_mount(cxt);
- if (!rc)
- rc = mnt_context_finalize_mount(cxt);
- goto try_readonly;
- case -MNT_ERR_NOFSTAB:
- if (mnt_context_is_swapmatch(cxt)) {
- warnx(_("can't find %s in %s"),
- src ? src : tgt,
- mnt_get_fstab_path());
- return MOUNT_EX_USAGE;
- }
- /* source/target explicitly defined */
- if (tgt)
- warnx(_("can't find mountpoint %s in %s"),
- tgt, mnt_get_fstab_path());
- else
- warnx(_("can't find mount source %s in %s"),
- src, mnt_get_fstab_path());
- return MOUNT_EX_USAGE;
- case -MNT_ERR_AMBIFS:
- warnx(_("%s: more filesystems detected. This should not happen,\n"
- " use -t <type> to explicitly specify the filesystem type or\n"
- " use wipefs(8) to clean up the device."), src);
- return MOUNT_EX_USAGE;
- case -MNT_ERR_NOFSTYPE:
- if (restricted)
- warnx(_("I could not determine the filesystem type, "
- "and none was specified"));
- else
- warnx(_("you must specify the filesystem type"));
- return MOUNT_EX_USAGE;
- case -MNT_ERR_NOSOURCE:
- if (uflags & MNT_MS_NOFAIL)
- return MOUNT_EX_SUCCESS;
- if (src)
- warnx(_("can't find %s"), src);
- else
- warnx(_("mount source not defined"));
- return MOUNT_EX_USAGE;
- case -MNT_ERR_MOUNTOPT:
- if (errno)
- warn(_("failed to parse mount options"));
- else
- warnx(_("failed to parse mount options"));
- return MOUNT_EX_USAGE;
- case -MNT_ERR_LOOPDEV:
- warn(_("%s: failed to setup loop device"), src);
- return MOUNT_EX_FAIL;
- case -MNT_ERR_LOOPOVERLAP:
- warnx(_("%s: overlapping loop device exists"), src);
- return MOUNT_EX_FAIL;
- default:
- return handle_generic_errors(rc, _("%s: mount failed"),
- tgt ? tgt : src);
- }
- } else if (mnt_context_get_syscall_errno(cxt) == 0) {
- /*
- * mount(2) syscall success, but something else failed
- * (probably error in mtab processing).
- */
- if (rc < 0)
- return handle_generic_errors(rc,
- _("%s: filesystem mounted, but mount(8) failed"),
- tgt ? tgt : src);
-
- return MOUNT_EX_SOFTWARE; /* internal error */
-
- }
-
- /*
- * mount(2) errors
- */
- syserr = mnt_context_get_syscall_errno(cxt);
-
-
- switch(syserr) {
- case EPERM:
- if (geteuid() == 0) {
- if (stat(tgt, &st) || !S_ISDIR(st.st_mode))
- warnx(_("mount point %s is not a directory"), tgt);
- else
- warnx(_("permission denied"));
- } else
- warnx(_("must be superuser to use mount"));
- break;
-
- case EBUSY:
- {
- struct libmnt_table *tb;
-
- if (mflags & MS_REMOUNT) {
- warnx(_("%s is busy"), tgt);
- break;
- }
-
- warnx(_("%s is already mounted or %s busy"), src, tgt);
-
- if (src && mnt_context_get_mtab(cxt, &tb) == 0) {
- struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_FORWARD);
- struct libmnt_fs *fs;
-
- while(mnt_table_next_fs(tb, itr, &fs) == 0) {
- const char *s = mnt_fs_get_srcpath(fs),
- *t = mnt_fs_get_target(fs);
-
- if (t && s && mnt_fs_streq_srcpath(fs, src))
- fprintf(stderr, _(
- " %s is already mounted on %s\n"), s, t);
- }
- mnt_free_iter(itr);
- }
- break;
- }
- case ENOENT:
- if (tgt && lstat(tgt, &st))
- warnx(_("mount point %s does not exist"), tgt);
- else if (tgt && stat(tgt, &st))
- warnx(_("mount point %s is a symbolic link to nowhere"), tgt);
- else if (src && stat(src, &st)) {
- if (uflags & MNT_MS_NOFAIL)
- return MOUNT_EX_SUCCESS;
-
- warnx(_("special device %s does not exist"), src);
- } else {
- errno = syserr;
- if (tgt)
- warn("%s: %s", _("mount(2) failed"), tgt);
- else if (src)
- warn("%s: %s", _("mount(2) failed"), src);
- else
- warn(_("mount(2) failed"));
- }
- break;
-
- case ENOTDIR:
- if (stat(tgt, &st) || ! S_ISDIR(st.st_mode))
- warnx(_("mount point %s is not a directory"), tgt);
- else if (src && stat(src, &st) && errno == ENOTDIR) {
- if (uflags & MNT_MS_NOFAIL)
- return MOUNT_EX_SUCCESS;
-
- warnx(_("special device %s does not exist "
- "(a path prefix is not a directory)"), src);
- } else {
- errno = syserr;
- warn("%s: %s", _("mount(2) failed"), tgt);
- }
- break;
-
- case EINVAL:
- if (mflags & MS_REMOUNT)
- warnx(_("%s not mounted or bad option"), tgt);
- else if (rc == -MNT_ERR_APPLYFLAGS)
- warnx(_("%s is not mountpoint or bad option"), tgt);
- else if ((mflags & MS_MOVE) && is_shared_tree(cxt, src))
- warnx(_("bad option. Note that moving a mount residing under a shared\n"
- " mount is unsupported."));
- else
- warnx(_("wrong fs type, bad option, bad superblock on %s,\n"
- " missing codepage or helper program, or other error"),
- src);
-
- if (mnt_fs_is_netfs(mnt_context_get_fs(cxt)))
- fprintf(stderr, _(
- " (for several filesystems (e.g. nfs, cifs) you might\n"
- " need a /sbin/mount.<type> helper program)\n"));
-
- fprintf(stderr, _("\n"
- " In some cases useful info is found in syslog - try\n"
- " dmesg | tail or so.\n"));
- break;
-
- case EMFILE:
- warnx(_("mount table full"));
- break;
-
- case EIO:
- warnx(_("%s: can't read superblock"), src);
- break;
-
- case ENODEV:
- if (mnt_context_get_fstype(cxt))
- warnx(_("unknown filesystem type '%s'"), mnt_context_get_fstype(cxt));
- else
- warnx(_("unknown filesystem type"));
- break;
-
- case ENOTBLK:
- if (uflags & MNT_MS_NOFAIL)
- return MOUNT_EX_SUCCESS;
-
- if (stat(src, &st))
- warnx(_("%s is not a block device, and stat(2) fails?"), src);
- else if (S_ISBLK(st.st_mode))
- warnx(_("the kernel does not recognize %s as a block device\n"
- " (maybe `modprobe driver'?)"), src);
- else if (S_ISREG(st.st_mode))
- warnx(_("%s is not a block device (maybe try `-o loop'?)"), src);
- else
- warnx(_(" %s is not a block device"), src);
- break;
-
- case ENXIO:
- if (uflags & MNT_MS_NOFAIL)
- return MOUNT_EX_SUCCESS;
-
- warnx(_("%s is not a valid block device"), src);
- break;
-
- case EACCES:
- case EROFS:
- if (mflags & MS_RDONLY)
- warnx(_("cannot mount %s read-only"), src);
-
- else if (readwrite)
- warnx(_("%s is write-protected but explicit `-w' flag given"), src);
-
- else if (mflags & MS_REMOUNT)
- warnx(_("cannot remount %s read-write, is write-protected"), src);
-
- else if (mflags & MS_BIND)
- warn(_("mount %s on %s failed"), src, tgt);
-
- else {
- warnx(_("%s is write-protected, mounting read-only"), src);
-
- mnt_context_reset_status(cxt);
- mnt_context_set_mflags(cxt, mflags | MS_RDONLY);
- rc = mnt_context_do_mount(cxt);
- if (!rc)
- rc = mnt_context_finalize_mount(cxt);
-
- goto try_readonly;
- }
- break;
-
- case ENOMEDIUM:
- if (uflags & MNT_MS_NOFAIL)
- return MOUNT_EX_SUCCESS;
-
- warnx(_("no medium found on %s"), src);
- break;
-
- default:
- warn(_("mount %s on %s failed"), src, tgt);
- break;
}
-
- return MOUNT_EX_FAIL;
+ return rc;
}
static struct libmnt_table *append_fstab(struct libmnt_context *cxt,
@@ -666,7 +319,7 @@ static struct libmnt_table *append_fstab(struct libmnt_context *cxt,
if (!fstab) {
fstab = mnt_new_table();
if (!fstab)
- err(MOUNT_EX_SYSERR, _("failed to initialize libmount table"));
+ err(MNT_EX_SYSERR, _("failed to initialize libmount table"));
mnt_table_set_parser_errcb(fstab, table_parser_errcb);
mnt_context_set_fstab(cxt, fstab);
@@ -675,7 +328,7 @@ static struct libmnt_table *append_fstab(struct libmnt_context *cxt,
}
if (mnt_table_parse_fstab(fstab, path))
- errx(MOUNT_EX_USAGE,_("%s: failed to parse"), path);
+ errx(MNT_EX_USAGE,_("%s: failed to parse"), path);
return fstab;
}
@@ -696,7 +349,7 @@ static void sanitize_paths(struct libmnt_context *cxt)
if (p) {
char *np = canonicalize_path_restricted(p);
if (!np)
- err(MOUNT_EX_USAGE, "%s", p);
+ err(MNT_EX_USAGE, "%s", p);
mnt_fs_set_target(fs, np);
free(np);
}
@@ -705,7 +358,7 @@ static void sanitize_paths(struct libmnt_context *cxt)
if (p) {
char *np = canonicalize_path_restricted(p);
if (!np)
- err(MOUNT_EX_USAGE, "%s", p);
+ err(MNT_EX_USAGE, "%s", p);
mnt_fs_set_source(fs, np);
free(np);
}
@@ -714,9 +367,9 @@ static void sanitize_paths(struct libmnt_context *cxt)
static void append_option(struct libmnt_context *cxt, const char *opt)
{
if (opt && (*opt == '=' || *opt == '\'' || *opt == '\"' || isblank(*opt)))
- errx(MOUNT_EX_USAGE, _("unsupported option format: %s"), opt);
+ errx(MNT_EX_USAGE, _("unsupported option format: %s"), opt);
if (mnt_context_append_options(cxt, opt))
- err(MOUNT_EX_SYSERR, _("failed to append option '%s'"), opt);
+ err(MNT_EX_SYSERR, _("failed to append option '%s'"), opt);
}
static int has_remount_flag(struct libmnt_context *cxt)
@@ -805,12 +458,12 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
fprintf(out, USAGE_MAN_TAIL("mount(8)"));
- exit(out == stderr ? MOUNT_EX_USAGE : MOUNT_EX_SUCCESS);
+ exit(out == stderr ? MNT_EX_USAGE : MNT_EX_SUCCESS);
}
int main(int argc, char **argv)
{
- int c, rc = MOUNT_EX_SUCCESS, all = 0, show_labels = 0;
+ int c, rc = MNT_EX_SUCCESS, all = 0, show_labels = 0;
struct libmnt_context *cxt;
struct libmnt_table *fstab = NULL;
char *srcbuf = NULL;
@@ -884,7 +537,7 @@ int main(int argc, char **argv)
mnt_init_debug(0);
cxt = mnt_new_context();
if (!cxt)
- err(MOUNT_EX_SYSERR, _("libmount context allocation failed"));
+ err(MNT_EX_SYSERR, _("libmount context allocation failed"));
mnt_context_set_tables_errcb(cxt, table_parser_errcb);
@@ -924,7 +577,7 @@ int main(int argc, char **argv)
break;
case 'r':
append_option(cxt, "ro");
- readwrite = 0;
+ mnt_context_enable_rwonly_mount(cxt, FALSE);
break;
case 'v':
mnt_context_enable_verbose(cxt, TRUE);
@@ -934,14 +587,14 @@ int main(int argc, char **argv)
break;
case 'w':
append_option(cxt, "rw");
- readwrite = 1;
+ mnt_context_enable_rwonly_mount(cxt, TRUE);
break;
case 'o':
append_option(cxt, optarg);
break;
case 'O':
if (mnt_context_set_options_pattern(cxt, optarg))
- err(MOUNT_EX_SYSERR, _("failed to set options pattern"));
+ err(MNT_EX_SYSERR, _("failed to set options pattern"));
break;
case 'L':
xasprintf(&srcbuf, "LABEL=\"%s\"", optarg);
@@ -1017,7 +670,7 @@ int main(int argc, char **argv)
mnt_context_set_source(cxt, optarg);
break;
default:
- errtryhelp(MOUNT_EX_USAGE);
+ errtryhelp(MNT_EX_USAGE);
}
}
@@ -1093,7 +746,7 @@ int main(int argc, char **argv)
if (istag && mnt_context_get_source(cxt))
/* -L, -U or --source together with LABEL= or UUID= */
- errx(MOUNT_EX_USAGE, _("source specified more than once"));
+ errx(MNT_EX_USAGE, _("source specified more than once"));
else if (istag || mnt_context_get_target(cxt))
mnt_context_set_source(cxt, argv[0]);
else
@@ -1132,7 +785,7 @@ int main(int argc, char **argv)
rc = mnt_context_mount(cxt);
rc = mk_exit_code(cxt, rc);
- if (rc == MOUNT_EX_SUCCESS && mnt_context_is_verbose(cxt))
+ if (rc == MNT_EX_SUCCESS && mnt_context_is_verbose(cxt))
success_message(cxt);
done:
mnt_free_context(cxt);
diff --git a/sys-utils/umount.c b/sys-utils/umount.c
index 21f7edfed..ed8fd4fe2 100644
--- a/sys-utils/umount.c
+++ b/sys-utils/umount.c
@@ -33,7 +33,6 @@
#include "c.h"
#include "env.h"
#include "optutils.h"
-#include "exitcodes.h"
#include "closestream.h"
#include "pathnames.h"
#include "canonicalize.h"
@@ -66,7 +65,7 @@ static void __attribute__((__noreturn__)) print_version(void)
fputs(*p++, stdout);
}
fputs(")\n", stdout);
- exit(MOUNT_EX_SUCCESS);
+ exit(MNT_EX_SUCCESS);
}
static void __attribute__((__noreturn__)) usage(FILE *out)
{
@@ -102,7 +101,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
fputs(USAGE_VERSION, out);
fprintf(out, USAGE_MAN_TAIL("umount(8)"));
- exit(out == stderr ? MOUNT_EX_USAGE : MOUNT_EX_SUCCESS);
+ exit(out == stderr ? MNT_EX_USAGE : MNT_EX_SUCCESS);
}
static void __attribute__((__noreturn__)) exit_non_root(const char *option)
@@ -113,16 +112,16 @@ static void __attribute__((__noreturn__)) exit_non_root(const char *option)
if (ruid == 0 && euid != 0) {
/* user is root, but setuid to non-root */
if (option)
- errx(MOUNT_EX_USAGE,
+ errx(MNT_EX_USAGE,
_("only root can use \"--%s\" option "
"(effective UID is %u)"),
option, euid);
- errx(MOUNT_EX_USAGE, _("only root can do that "
+ errx(MNT_EX_USAGE, _("only root can do that "
"(effective UID is %u)"), euid);
}
if (option)
- errx(MOUNT_EX_USAGE, _("only root can use \"--%s\" option"), option);
- errx(MOUNT_EX_USAGE, _("only root can do that"));
+ errx(MNT_EX_USAGE, _("only root can use \"--%s\" option"), option);
+ errx(MNT_EX_USAGE, _("only root can do that"));
}
static void success_message(struct libmnt_context *cxt)
@@ -144,123 +143,20 @@ static void success_message(struct libmnt_context *cxt)
warnx(_("%s unmounted"), tgt);
}
-/*
- * Handles generic errors like ENOMEM, ...
- *
- * rc = 0 success
- * <0 error (usually -errno)
- *
- * Returns exit status (MOUNT_EX_*) and prints error message.
- */
-static int handle_generic_errors(int rc, const char *msg, ...)
-{
- va_list va;
-
- va_start(va, msg);
- errno = -rc;
-
- switch(errno) {
- case EINVAL:
- case EPERM:
- vwarn(msg, va);
- rc = MOUNT_EX_USAGE;
- break;
- case ENOMEM:
- vwarn(msg, va);
- rc = MOUNT_EX_SYSERR;
- break;
- default:
- vwarn(msg, va);
- rc = MOUNT_EX_FAIL;
- break;
- }
- va_end(va);
- return rc;
-}
-
static int mk_exit_code(struct libmnt_context *cxt, int rc)
{
- int syserr;
- const char *tgt = mnt_context_get_target(cxt);
-
- if (mnt_context_helper_executed(cxt))
- /*
- * /sbin/umount.<type> called, return status
- */
- return mnt_context_get_helper_status(cxt);
-
- if (rc == 0 && mnt_context_get_status(cxt) == 1)
- /*
- * Libmount success && syscall success.
- */
- return MOUNT_EX_SUCCESS;
-
-
- if (!mnt_context_syscall_called(cxt)) {
- /*
- * libmount errors (extra library checks)
- */
- if (rc == -EPERM && !mnt_context_tab_applied(cxt)) {
- /* failed to evaluate permissions because not found
- * relevant entry in mtab */
- warnx(_("%s: not mounted"), tgt);
- return MOUNT_EX_USAGE;
- }
- return handle_generic_errors(rc, _("%s: umount failed"), tgt);
-
- } else if (mnt_context_get_syscall_errno(cxt) == 0) {
- /*
- * umount(2) syscall success, but something else failed
- * (probably error in mtab processing).
- */
- if (rc < 0)
- return handle_generic_errors(rc,
- _("%s: filesystem was unmounted, but mount(8) failed"),
- tgt);
-
- return MOUNT_EX_SOFTWARE; /* internal error */
-
+ char buf[BUFSIZ] = { 0 };
+
+ rc = mnt_context_get_excode(cxt, rc, buf, sizeof(buf));
+ if (*buf) {
+ const char *spec = mnt_context_get_target(cxt);
+ if (!spec)
+ spec = mnt_context_get_source(cxt);
+ if (!spec)
+ spec = "???";
+ warnx(_("%s: %s."), spec, buf);
}
-
- /*
- * umount(2) errors
- */
- syserr = mnt_context_get_syscall_errno(cxt);
-
- switch(syserr) {
- case ENXIO:
- warnx(_("%s: invalid block device"), tgt); /* ??? */
- break;
- case EINVAL:
- warnx(_("%s: not mounted"), tgt);
- break;
- case EIO:
- warnx(_("%s: can't write superblock"), tgt);
- break;
- case EBUSY:
- warnx(_("%s: target is busy\n"
- " (In some cases useful info about processes that\n"
- " use the device is found by lsof(8) or fuser(1).)"),
- tgt);
- break;
- case ENOENT:
- if (tgt && *tgt)
- warnx(_("%s: mountpoint not found"), tgt);
- else
- warnx(_("undefined mountpoint"));
- break;
- case EPERM:
- warnx(_("%s: must be superuser to unmount"), tgt);
- break;
- case EACCES:
- warnx(_("%s: block devices are not permitted on filesystem"), tgt);
- break;
- default:
- errno = syserr;
- warn("%s", tgt);
- break;
- }
- return MOUNT_EX_FAIL;
+ return rc;
}
static int umount_all(struct libmnt_context *cxt)
@@ -272,7 +168,7 @@ static int umount_all(struct libmnt_context *cxt)
itr = mnt_new_iter(MNT_ITER_BACKWARD);
if (!itr) {
warn(_("failed to initialize libmount iterator"));
- return MOUNT_EX_SYSERR;
+ return MNT_EX_SYSERR;
}
while (mnt_context_next_umount(cxt, itr, &fs, &mntrc, &ignored) == 0) {
@@ -285,7 +181,7 @@ static int umount_all(struct libmnt_context *cxt)
} else {
int xrc = mk_exit_code(cxt, mntrc);
- if (xrc == MOUNT_EX_SUCCESS
+ if (xrc == MNT_EX_SUCCESS
&& mnt_context_is_verbose(cxt))
printf("%-25s: successfully unmounted\n", tgt);
rc |= xrc;
@@ -301,15 +197,15 @@ static int umount_one(struct libmnt_context *cxt, const char *spec)
int rc;
if (!spec)
- return MOUNT_EX_SOFTWARE;
+ return MNT_EX_SOFTWARE;
if (mnt_context_set_target(cxt, spec))
- err(MOUNT_EX_SYSERR, _("failed to set umount target"));
+ err(MNT_EX_SYSERR, _("failed to set umount target"));
rc = mnt_context_umount(cxt);
rc = mk_exit_code(cxt, rc);
- if (rc == MOUNT_EX_SUCCESS && mnt_context_is_verbose(cxt))
+ if (rc == MNT_EX_SUCCESS && mnt_context_is_verbose(cxt))
success_message(cxt);
mnt_reset_context(cxt);
@@ -320,7 +216,7 @@ static struct libmnt_table *new_mountinfo(struct libmnt_context *cxt)
{
struct libmnt_table *tb = mnt_new_table();
if (!tb)
- err(MOUNT_EX_SYSERR, _("libmount table allocation failed"));
+ err(MNT_EX_SYSERR, _("libmount table allocation failed"));
mnt_table_set_parser_errcb(tb, table_parser_errcb);
mnt_table_set_cache(tb, mnt_context_get_cache(cxt));
@@ -344,7 +240,7 @@ static int umount_one_if_mounted(struct libmnt_context *cxt, const char *spec)
rc = mnt_context_find_umount_fs(cxt, spec, &fs);
if (rc == 1) {
- rc = MOUNT_EX_SUCCESS; /* already unmounted */
+ rc = MNT_EX_SUCCESS; /* already unmounted */
mnt_reset_context(cxt);
} else if (rc < 0) {
rc = mk_exit_code(cxt, rc); /* error */
@@ -363,7 +259,7 @@ static int umount_do_recurse(struct libmnt_context *cxt,
int rc;
if (!itr)
- err(MOUNT_EX_SYSERR, _("libmount iterator allocation failed"));
+ err(MNT_EX_SYSERR, _("libmount iterator allocation failed"));
/* umount all children */
for (;;) {
@@ -371,13 +267,13 @@ static int umount_do_recurse(struct libmnt_context *cxt,
if (rc < 0) {
warnx(_("failed to get child fs of %s"),
mnt_fs_get_target(fs));
- rc = MOUNT_EX_SOFTWARE;
+ rc = MNT_EX_SOFTWARE;
goto done;
} else if (rc == 1)
break; /* no more children */
rc = umount_do_recurse(cxt, tb, child);
- if (rc != MOUNT_EX_SUCCESS)
+ if (rc != MNT_EX_SUCCESS)
goto done;
}
@@ -395,7 +291,7 @@ static int umount_recursive(struct libmnt_context *cxt, const char *spec)
tb = new_mountinfo(cxt);
if (!tb)
- return MOUNT_EX_SOFTWARE;
+ return MNT_EX_SOFTWARE;
/* it's always real mountpoint, don't assume that the target maybe a device */
mnt_context_disable_swapmatch(cxt, 1);
@@ -404,7 +300,7 @@ static int umount_recursive(struct libmnt_context *cxt, const char *spec)
if (fs)
rc = umount_do_recurse(cxt, tb, fs);
else {
- rc = MOUNT_EX_USAGE;
+ rc = MNT_EX_USAGE;
warnx(access(spec, F_OK) == 0 ?
_("%s: not mounted") :
_("%s: not found"), spec);
@@ -427,7 +323,7 @@ static int umount_alltargets(struct libmnt_context *cxt, const char *spec, int r
*/
rc = mnt_context_find_umount_fs(cxt, spec, &fs);
if (rc == 1) {
- rc = MOUNT_EX_USAGE;
+ rc = MNT_EX_USAGE;
warnx(access(spec, F_OK) == 0 ?
_("%s: not mounted") :
_("%s: not found"), spec);
@@ -437,18 +333,18 @@ static int umount_alltargets(struct libmnt_context *cxt, const char *spec, int r
return mk_exit_code(cxt, rc); /* error */
if (!mnt_fs_get_srcpath(fs) || !mnt_fs_get_devno(fs))
- errx(MOUNT_EX_USAGE, _("%s: failed to determine source "
+ errx(MNT_EX_USAGE, _("%s: failed to determine source "
"(--all-targets is unsupported on systems with "
"regular mtab file)."), spec);
itr = mnt_new_iter(MNT_ITER_BACKWARD);
if (!itr)
- err(MOUNT_EX_SYSERR, _("libmount iterator allocation failed"));
+ err(MNT_EX_SYSERR, _("libmount iterator allocation failed"));
/* get on @cxt independent mountinfo */
tb = new_mountinfo(cxt);
if (!tb) {
- rc = MOUNT_EX_SOFTWARE;
+ rc = MNT_EX_SOFTWARE;
goto done;
}
@@ -468,7 +364,7 @@ static int umount_alltargets(struct libmnt_context *cxt, const char *spec, int r
else
rc = umount_one_if_mounted(cxt, mnt_fs_get_target(fs));
- if (rc != MOUNT_EX_SUCCESS)
+ if (rc != MNT_EX_SUCCESS)
break;
}
@@ -492,7 +388,7 @@ static char *sanitize_path(const char *path)
p = canonicalize_path_restricted(path);
if (!p)
- err(MOUNT_EX_USAGE, "%s", path);
+ err(MNT_EX_USAGE, "%s", path);
return p;
}
@@ -545,7 +441,7 @@ int main(int argc, char **argv)
mnt_init_debug(0);
cxt = mnt_new_context();
if (!cxt)
- err(MOUNT_EX_SYSERR, _("libmount context allocation failed"));
+ err(MNT_EX_SYSERR, _("libmount context allocation failed"));
mnt_context_set_tables_errcb(cxt, table_parser_errcb);
@@ -598,7 +494,7 @@ int main(int argc, char **argv)
break;
case 'O':
if (mnt_context_set_options_pattern(cxt, optarg))
- err(MOUNT_EX_SYSERR, _("failed to set options pattern"));
+ err(MNT_EX_SYSERR, _("failed to set options pattern"));
break;
case 't':
types = optarg;
@@ -610,7 +506,7 @@ int main(int argc, char **argv)
print_version();
break;
default:
- errtryhelp(MOUNT_EX_USAGE);
+ errtryhelp(MNT_EX_USAGE);
}
}
diff --git a/tests/expected/libmount/loop-conflict b/tests/expected/libmount/loop-conflict
index e26f99a4f..1686021f0 100644
--- a/tests/expected/libmount/loop-conflict
+++ b/tests/expected/libmount/loop-conflict
@@ -1,2 +1,2 @@
-: overlapping loop device exists
+mount: <target> overlapping loop device exists for <source>
Success
diff --git a/tests/expected/libmount/loop-o-loop-val-conflict b/tests/expected/libmount/loop-o-loop-val-conflict
index 043847449..0eb732214 100644
--- a/tests/expected/libmount/loop-o-loop-val-conflict
+++ b/tests/expected/libmount/loop-o-loop-val-conflict
@@ -1,2 +1,2 @@
-: failed to setup loop device: Device or resource busy
+mount: <target> failed to setup loop device for <source>
Success
diff --git a/tests/expected/libmount/loop-o-loop-val-initialized b/tests/expected/libmount/loop-o-loop-val-initialized
index e26f99a4f..1686021f0 100644
--- a/tests/expected/libmount/loop-o-loop-val-initialized
+++ b/tests/expected/libmount/loop-o-loop-val-initialized
@@ -1,2 +1,2 @@
-: overlapping loop device exists
+mount: <target> overlapping loop device exists for <source>
Success
diff --git a/tests/expected/libmount/loop-overlay b/tests/expected/libmount/loop-overlay
index ab6c68beb..399024471 100644
--- a/tests/expected/libmount/loop-overlay
+++ b/tests/expected/libmount/loop-overlay
@@ -1,7 +1,7 @@
second should fail
- overlapping loop device exists
+mount: <target> overlapping loop device exists for <source>
should succeed
both should fail
- overlapping loop device exists
- overlapping loop device exists
+mount: <target> overlapping loop device exists for <source>
+mount: <target> overlapping loop device exists for <source>
Success
diff --git a/tests/ts/libmount/loop b/tests/ts/libmount/loop
index 1589af1ed..ec22c9a2c 100755
--- a/tests/ts/libmount/loop
+++ b/tests/ts/libmount/loop
@@ -104,7 +104,8 @@ ts_finalize_subtest
ts_init_subtest "conflict"
[ -d "$TS_MOUNTPOINT" ] || mkdir -p $TS_MOUNTPOINT
LODEV=$( $TS_CMD_LOSETUP --find --nooverlap --show --offset=1000 "$BACKFILE" 2>> $TS_OUTPUT )
-$TS_CMD_MOUNT "$BACKFILE" "$TS_MOUNTPOINT" 2>&1 | sed 's/^.*\.img//' > $TS_OUTPUT
+$TS_CMD_MOUNT "$BACKFILE" "$TS_MOUNTPOINT" 2>&1 \
+ | sed 's/:.*:/: <target>/; s/for .*/for <source>/' > $TS_OUTPUT
$TS_CMD_LOSETUP --detach $LODEV >> $TS_OUTPUT 2>&1
udevadm settle
ts_log "Success"
@@ -114,7 +115,8 @@ ts_init_subtest "o-loop-val-initialized"
[ -d "$TS_MOUNTPOINT" ] || mkdir -p $TS_MOUNTPOINT
LODEV=$( $TS_CMD_LOSETUP --find 2>> $TS_OUTPUT )
$TS_CMD_LOSETUP $LODEV "$BACKFILE" >> $TS_OUTPUT 2>&1
-$TS_CMD_MOUNT -oloop=$LODEV "$BACKFILE" "$TS_MOUNTPOINT" 2>&1 | sed 's/^.*\.img//' > $TS_OUTPUT
+$TS_CMD_MOUNT -oloop=$LODEV "$BACKFILE" "$TS_MOUNTPOINT" 2>&1 \
+ | sed 's/:.*:/: <target>/; s/for .*/for <source>/' > $TS_OUTPUT
$TS_CMD_LOSETUP --detach $LODEV >> $TS_OUTPUT 2>&1
udevadm settle
ts_log "Success"
@@ -125,7 +127,8 @@ ts_init_subtest "o-loop-val-conflict"
cp "$BACKFILE" "$BACKFILE"-2
LODEV=$( $TS_CMD_LOSETUP --find 2>> $TS_OUTPUT )
$TS_CMD_LOSETUP $LODEV "$BACKFILE"-2 >> $TS_OUTPUT 2>&1
-$TS_CMD_MOUNT -oloop=$LODEV "$BACKFILE" "$TS_MOUNTPOINT" 2>&1 | sed 's/^.*\.img//' > $TS_OUTPUT
+$TS_CMD_MOUNT -oloop=$LODEV "$BACKFILE" "$TS_MOUNTPOINT" 2>&1 \
+ | sed 's/:.*:/: <target>/; s/for .*/for <source>/' > $TS_OUTPUT
$TS_CMD_LOSETUP --detach $LODEV >> $TS_OUTPUT 2>&1
rm "$BACKFILE"-2
udevadm settle
diff --git a/tests/ts/libmount/loop-overlay b/tests/ts/libmount/loop-overlay
index 97eb32118..dc9b73d6b 100755
--- a/tests/ts/libmount/loop-overlay
+++ b/tests/ts/libmount/loop-overlay
@@ -43,8 +43,8 @@ dd if="$IMG" of="$IMG" oflag=append bs=5MiB count=1 conv=notrunc &>/dev/null
echo "second should fail" >>$TS_OUTPUT
$TS_CMD_MOUNT -oloop "$IMG" "$TS_MOUNTPOINT-1" >> $TS_OUTPUT 2>&1
-$TS_CMD_MOUNT -oloop,offset=$OFFSET "$IMG" "$TS_MOUNTPOINT-2" 2>&1 | sed 's/.*://' >>$TS_OUTPUT
-
+$TS_CMD_MOUNT -oloop,offset=$OFFSET "$IMG" "$TS_MOUNTPOINT-2" 2>&1 \
+ | sed 's/:.*:/: <target>/; s/for .*/for <source>/' >> $TS_OUTPUT
$TS_CMD_UMOUNT "$TS_MOUNTPOINT-1" >> $TS_OUTPUT 2>&1
echo "should succeed" >>$TS_OUTPUT
@@ -56,8 +56,10 @@ $TS_CMD_UMOUNT "$TS_MOUNTPOINT-2" >> $TS_OUTPUT 2>&1
echo "both should fail" >>$TS_OUTPUT
LOOPDEV=$($TS_CMD_LOSETUP --find)
$TS_CMD_LOSETUP --offset 1 --sizelimit $OFFSET $LOOPDEV "$IMG"
-$TS_CMD_MOUNT -oloop,sizelimit=$OFFSET "$IMG" "$TS_MOUNTPOINT-1" 2>&1 | sed 's/.*://' >>$TS_OUTPUT
-$TS_CMD_MOUNT -oloop,offset=$OFFSET "$IMG" "$TS_MOUNTPOINT-2" 2>&1 | sed 's/.*://' >>$TS_OUTPUT
+$TS_CMD_MOUNT -oloop,sizelimit=$OFFSET "$IMG" "$TS_MOUNTPOINT-1" 2>&1 \
+ | sed 's/:.*:/: <target>/; s/for .*/for <source>/' >> $TS_OUTPUT
+$TS_CMD_MOUNT -oloop,offset=$OFFSET "$IMG" "$TS_MOUNTPOINT-2" 2>&1 \
+ | sed 's/:.*:/: <target>/; s/for .*/for <source>/' >> $TS_OUTPUT
$TS_CMD_LOSETUP --detach $LOOPDEV
ts_log "Success"