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_umount.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_umount.c')
-rw-r--r-- | libmount/src/context_umount.c | 80 |
1 files changed, 80 insertions, 0 deletions
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; +} |