aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmount/src/context.c2
-rw-r--r--libmount/src/context_mount.c7
-rw-r--r--libmount/src/hook_mount.c46
-rw-r--r--libmount/src/mountP.h4
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 */