diff options
author | Karel Zak | 2017-04-27 14:01:26 +0200 |
---|---|---|
committer | Karel Zak | 2017-04-27 14:10:23 +0200 |
commit | ea848180dd344ec2859b5ca329d9b1375ddde1ac (patch) | |
tree | 3891525fa351a694f83fc19d17c048d0771f0722 /libmount/src/context.c | |
parent | libmount: support MS_RDONLY on write-protected devices (diff) | |
download | kernel-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.c | 97 |
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 |