diff options
Diffstat (limited to 'libmount/src')
| -rw-r--r-- | libmount/src/context.c | 2 | ||||
| -rw-r--r-- | libmount/src/context_mount.c | 7 | ||||
| -rw-r--r-- | libmount/src/hook_mount.c | 46 | ||||
| -rw-r--r-- | libmount/src/mountP.h | 4 |
4 files changed, 40 insertions, 19 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c index d9310c453b..6a1b995785 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -314,6 +314,8 @@ int mnt_context_reset_status(struct libmnt_context *cxt) if (!cxt) return -EINVAL; + reset_syscall_status(cxt); + cxt->syscall_status = 1; /* means not called yet */ cxt->helper_exec_status = 1; cxt->helper_status = 0; diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index b8302f9fc7..478a9fde4e 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -1571,6 +1571,13 @@ int mnt_context_get_mount_excode( */ syserr = mnt_context_get_syscall_errno(cxt); + if (buf && cxt->syscall_errmsg) { + snprintf(buf, bufsz, _("%s system call failed: %s"), + cxt->syscall_name ? : "mount", + cxt->syscall_errmsg); + return MNT_EX_FAIL; + } + switch(syserr) { case EPERM: if (!buf) diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index 961cc8745d..92438966c0 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -65,19 +65,29 @@ static void close_sysapi_fds(struct libmnt_sysapi *api) api->fd_tree = api->fd_fs = -1; } -static void debug_fs_fd_messages(int fd) +static void save_fd_messages(struct libmnt_context *cxt, int fd) { uint8_t buf[BUFSIZ]; int rc; + free(cxt->syscall_errmsg); + cxt->syscall_errmsg = NULL; + while ((rc = read(fd, buf, sizeof(buf))) != -1) { if (rc > 0 && buf[rc - 1] == '\n') buf[rc - 1] = '\0'; - DBG(CXT, ul_debug("message from kernel: %*s", rc, buf)); + DBG(CXT, ul_debug("message from kernel: \"%*s\"", rc, buf)); + + if (rc < 3 || strncmp((char *) buf, "e ", 2) != 0) + continue; + if (cxt->syscall_errmsg) + strappend(&cxt->syscall_errmsg, "; "); + + strappend(&cxt->syscall_errmsg, ((char *) buf) + 2); } } -static void set_syscall_status_cxt_log(struct libmnt_context *cxt, +static void hookset_set_syscall_status(struct libmnt_context *cxt, const char *name, int x) { struct libmnt_sysapi *api; @@ -86,13 +96,11 @@ static void set_syscall_status_cxt_log(struct libmnt_context *cxt, if (!x) { api = get_sysapi(cxt); - if (api) - debug_fs_fd_messages(api->fd_fs); + if (api && api->fd_fs >= 0) + save_fd_messages(cxt, api->fd_fs); } } -#define set_syscall_status set_syscall_status_cxt_log - /* * This hookset uses 'struct libmnt_sysapi' (mountP.h) as hookset data. */ @@ -176,7 +184,7 @@ static inline int fsconfig_set_value( } else rc = fsconfig(fd, FSCONFIG_SET_FLAG, name, NULL, 0); - set_syscall_status(cxt, "fsconfig", rc == 0); + hookset_set_syscall_status(cxt, "fsconfig", rc == 0); return rc; } @@ -241,7 +249,7 @@ static int open_fs_configuration_context(struct libmnt_context *cxt, DBG(HOOK, ul_debug(" fsopen(%s)", type)); api->fd_fs = fsopen(type, FSOPEN_CLOEXEC); - set_syscall_status(cxt, "fsopen", api->fd_fs >= 0); + hookset_set_syscall_status(cxt, "fsopen", api->fd_fs >= 0); if (api->fd_fs < 0) return -errno; api->is_new_fs = 1; @@ -280,7 +288,7 @@ static int open_mount_tree(struct libmnt_context *cxt, const char *path, unsigne oflg & OPEN_TREE_CLONE ? " clone" : "", oflg & AT_RECURSIVE ? " recursive" : "")); fd = open_tree(AT_FDCWD, path, oflg); - set_syscall_status(cxt, "open_tree", fd >= 0); + hookset_set_syscall_status(cxt, "open_tree", fd >= 0); return fd; } @@ -320,19 +328,19 @@ static int hook_create_mount(struct libmnt_context *cxt, DBG(HOOK, ul_debugobj(hs, "init FS")); rc = fsconfig(api->fd_fs, FSCONFIG_SET_STRING, "source", src, 0); - set_syscall_status(cxt, "fsconfig", rc == 0); + hookset_set_syscall_status(cxt, "fsconfig", rc == 0); if (!rc) rc = configure_superblock(cxt, hs, api->fd_fs, 0); if (!rc) { DBG(HOOK, ul_debugobj(hs, "create FS")); rc = fsconfig(api->fd_fs, FSCONFIG_CMD_CREATE, NULL, NULL, 0); - set_syscall_status(cxt, "fsconfig", rc == 0); + hookset_set_syscall_status(cxt, "fsconfig", rc == 0); } if (!rc) { api->fd_tree = fsmount(api->fd_fs, FSMOUNT_CLOEXEC, 0); - set_syscall_status(cxt, "fsmount", api->fd_tree >= 0); + hookset_set_syscall_status(cxt, "fsmount", api->fd_tree >= 0); if (api->fd_tree < 0) rc = -errno; } @@ -381,7 +389,7 @@ static int hook_reconfigure_mount(struct libmnt_context *cxt, if (api->fd_fs < 0) { api->fd_fs = fspick(api->fd_tree, "", FSPICK_EMPTY_PATH | FSPICK_NO_AUTOMOUNT); - set_syscall_status(cxt, "fspick", api->fd_fs >= 0); + hookset_set_syscall_status(cxt, "fspick", api->fd_fs >= 0); if (api->fd_fs < 0) return -errno; } @@ -390,7 +398,7 @@ static int hook_reconfigure_mount(struct libmnt_context *cxt, if (!rc) { DBG(HOOK, ul_debugobj(hs, "re-configurate FS")); rc = fsconfig(api->fd_fs, FSCONFIG_CMD_RECONFIGURE, NULL, NULL, 0); - set_syscall_status(cxt, "fsconfig", rc == 0); + hookset_set_syscall_status(cxt, "fsconfig", rc == 0); } DBG(HOOK, ul_debugobj(hs, "reconf FS done [rc=%d]", rc)); @@ -428,7 +436,7 @@ static int set_vfsflags(struct libmnt_context *cxt, errno = 0; rc = mount_setattr(api->fd_tree, "", callflags, &attr, sizeof(attr)); - set_syscall_status(cxt, "mount_setattr", rc == 0); + hookset_set_syscall_status(cxt, "mount_setattr", rc == 0); if (rc && errno == EINVAL) return -MNT_ERR_APPLYFLAGS; @@ -520,7 +528,7 @@ static int hook_set_propagation(struct libmnt_context *cxt, (uint64_t) attr.propagation)); rc = mount_setattr(api->fd_tree, "", flgs, &attr, sizeof(attr)); - set_syscall_status(cxt, "mount_setattr", rc == 0); + hookset_set_syscall_status(cxt, "mount_setattr", rc == 0); if (rc && errno == EINVAL) return -MNT_ERR_APPLYFLAGS; @@ -562,7 +570,7 @@ static int hook_attach_target(struct libmnt_context *cxt, } rc = move_mount(api->fd_tree, "", AT_FDCWD, target, MOVE_MOUNT_F_EMPTY_PATH); - set_syscall_status(cxt, "move_mount", rc == 0); + hookset_set_syscall_status(cxt, "move_mount", rc == 0); return rc == 0 ? 0 : -errno; } @@ -648,7 +656,7 @@ static int init_sysapi(struct libmnt_context *cxt, else if (!fsopen_is_supported()) { errno = ENOSYS; rc = -errno; - set_syscall_status(cxt, "fsopen", rc == 0); + hookset_set_syscall_status(cxt, "fsopen", rc == 0); } if (rc < 0) goto fail; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index 9bca4ea770..458aa1a00d 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -432,6 +432,7 @@ struct libmnt_context int syscall_status; /* 1: not called yet, 0: success, <0: -errno */ const char *syscall_name; /* failed syscall name */ + char *syscall_errmsg; /* message from kernel */ struct libmnt_ns ns_orig; /* original namespace */ struct libmnt_ns ns_tgt; /* target namespace */ @@ -496,6 +497,9 @@ static inline void reset_syscall_status(struct libmnt_context *cxt) DBG(CXT, ul_debug("reset syscall status")); cxt->syscall_status = 0; cxt->syscall_name = NULL; + + free(cxt->syscall_errmsg); + cxt->syscall_errmsg = NULL; } /* optmap.c */ |
