summaryrefslogtreecommitdiffstats
path: root/libmount/src/context.c
diff options
context:
space:
mode:
authorKarel Zak2017-04-27 14:01:26 +0200
committerKarel Zak2017-04-27 14:10:23 +0200
commitea848180dd344ec2859b5ca329d9b1375ddde1ac (patch)
tree3891525fa351a694f83fc19d17c048d0771f0722 /libmount/src/context.c
parentlibmount: support MS_RDONLY on write-protected devices (diff)
downloadkernel-qcow2-util-linux-ea848180dd344ec2859b5ca329d9b1375ddde1ac.tar.gz
kernel-qcow2-util-linux-ea848180dd344ec2859b5ca329d9b1375ddde1ac.tar.xz
kernel-qcow2-util-linux-ea848180dd344ec2859b5ca329d9b1375ddde1ac.zip
libmount: add mnt_context_get_excode()
It's pretty complex task to make mount(8) and umount(8) return code and generate error message. It seems better to do that in the libmount rather than force all library users to duplicate mount(8) mk_exit_code() functions. It also means that all the messages will be translated only once. Changes: * all error messages are printed by warn() * no more multi-line messages * all messages prefixed by mount target (mountpoint) * library provides mount(8) compatible MNT_EX_* codes Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1429531 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src/context.c')
-rw-r--r--libmount/src/context.c97
1 files changed, 96 insertions, 1 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c
index 6a7c7d351..a370cea09 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -175,6 +175,7 @@ int mnt_reset_context(struct libmnt_context *cxt)
cxt->flags |= (fl & MNT_FL_RWONLY_MOUNT);
cxt->flags |= (fl & MNT_FL_NOSWAPMATCH);
cxt->flags |= (fl & MNT_FL_TABPATHS_CHECKED);
+
return 0;
}
@@ -2261,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.
*/
@@ -2273,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, "return code: %d [%s]", rc,
+ buf ? buf : "<no-message>"));
+ return rc;
+}
+
+
/**
* mnt_context_init_helper
* @cxt: mount context