mirror of
https://github.com/systemd/systemd.git
synced 2025-09-16 17:45:36 +03:00
Merge pull request #3858 from jfilak/coredump-containers-v2
Coredump: save information useful for debuging crashes in containers - v2
This commit is contained in:
@@ -558,6 +558,89 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_process_ns(pid_t pid, const char *namespace, ino_t *ns) {
|
||||||
|
const char *p;
|
||||||
|
struct stat stbuf;
|
||||||
|
_cleanup_close_ int proc_ns_dir_fd;
|
||||||
|
|
||||||
|
p = procfs_file_alloca(pid, "ns");
|
||||||
|
|
||||||
|
proc_ns_dir_fd = open(p, O_DIRECTORY | O_CLOEXEC | O_RDONLY);
|
||||||
|
if (proc_ns_dir_fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (fstatat(proc_ns_dir_fd, namespace, &stbuf, /* flags */0) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
*ns = stbuf.st_ino;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) {
|
||||||
|
pid_t cpid = pid, ppid = 0;
|
||||||
|
ino_t proc_mntns;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
r = get_process_ns(pid, "mnt", &proc_mntns);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ino_t parent_mntns;
|
||||||
|
|
||||||
|
r = get_process_ppid(cpid, &ppid);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = get_process_ns(ppid, "mnt", &parent_mntns);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (proc_mntns != parent_mntns)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ppid == 1)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
cpid = ppid;
|
||||||
|
}
|
||||||
|
|
||||||
|
*container_pid = ppid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 1 if the parent was found.
|
||||||
|
* Returns 0 if there is not a process we can call the pid's
|
||||||
|
* container parent (the pid's process isn't 'containerized').
|
||||||
|
* Returns a negative number on errors.
|
||||||
|
*/
|
||||||
|
static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) {
|
||||||
|
int r = 0;
|
||||||
|
pid_t container_pid;
|
||||||
|
const char *proc_root_path;
|
||||||
|
struct stat root_stat, proc_root_stat;
|
||||||
|
|
||||||
|
/* To compare inodes of / and /proc/[pid]/root */
|
||||||
|
if (stat("/", &root_stat) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
proc_root_path = procfs_file_alloca(pid, "root");
|
||||||
|
if (stat(proc_root_path, &proc_root_stat) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
/* The process uses system root. */
|
||||||
|
if (proc_root_stat.st_ino == root_stat.st_ino) {
|
||||||
|
*cmdline = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = get_mount_namespace_leader(pid, &container_pid);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return get_process_cmdline(container_pid, 0, false, cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
static int change_uid_gid(const char *context[]) {
|
static int change_uid_gid(const char *context[]) {
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
@@ -933,11 +1016,13 @@ static int process_kernel(int argc, char* argv[]) {
|
|||||||
/* The larger ones we allocate on the heap */
|
/* The larger ones we allocate on the heap */
|
||||||
_cleanup_free_ char
|
_cleanup_free_ char
|
||||||
*core_owner_uid = NULL, *core_open_fds = NULL, *core_proc_status = NULL,
|
*core_owner_uid = NULL, *core_open_fds = NULL, *core_proc_status = NULL,
|
||||||
*core_proc_maps = NULL, *core_proc_limits = NULL, *core_proc_cgroup = NULL, *core_environ = NULL;
|
*core_proc_maps = NULL, *core_proc_limits = NULL, *core_proc_cgroup = NULL, *core_environ = NULL,
|
||||||
|
*core_proc_mountinfo = NULL, *core_container_cmdline = NULL;
|
||||||
|
|
||||||
_cleanup_free_ char *exe = NULL, *comm = NULL;
|
_cleanup_free_ char *exe = NULL, *comm = NULL;
|
||||||
const char *context[_CONTEXT_MAX];
|
const char *context[_CONTEXT_MAX];
|
||||||
struct iovec iovec[25];
|
bool proc_self_root_is_slash;
|
||||||
|
struct iovec iovec[27];
|
||||||
size_t n_iovec = 0;
|
size_t n_iovec = 0;
|
||||||
uid_t owner_uid;
|
uid_t owner_uid;
|
||||||
const char *p;
|
const char *p;
|
||||||
@@ -1110,6 +1195,15 @@ static int process_kernel(int argc, char* argv[]) {
|
|||||||
IOVEC_SET_STRING(iovec[n_iovec++], core_proc_cgroup);
|
IOVEC_SET_STRING(iovec[n_iovec++], core_proc_cgroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = procfs_file_alloca(pid, "mountinfo");
|
||||||
|
if (read_full_file(p, &t, NULL) >=0) {
|
||||||
|
core_proc_mountinfo = strappend("COREDUMP_PROC_MOUNTINFO=", t);
|
||||||
|
free(t);
|
||||||
|
|
||||||
|
if (core_proc_mountinfo)
|
||||||
|
IOVEC_SET_STRING(iovec[n_iovec++], core_proc_mountinfo);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_process_cwd(pid, &t) >= 0) {
|
if (get_process_cwd(pid, &t) >= 0) {
|
||||||
core_cwd = strjoina("COREDUMP_CWD=", t);
|
core_cwd = strjoina("COREDUMP_CWD=", t);
|
||||||
free(t);
|
free(t);
|
||||||
@@ -1119,9 +1213,20 @@ static int process_kernel(int argc, char* argv[]) {
|
|||||||
|
|
||||||
if (get_process_root(pid, &t) >= 0) {
|
if (get_process_root(pid, &t) >= 0) {
|
||||||
core_root = strjoina("COREDUMP_ROOT=", t);
|
core_root = strjoina("COREDUMP_ROOT=", t);
|
||||||
free(t);
|
|
||||||
|
|
||||||
IOVEC_SET_STRING(iovec[n_iovec++], core_root);
|
IOVEC_SET_STRING(iovec[n_iovec++], core_root);
|
||||||
|
|
||||||
|
/* If the process' root is "/", then there is a chance it has
|
||||||
|
* mounted own root and hence being containerized. */
|
||||||
|
proc_self_root_is_slash = strcmp(t, "/") == 0;
|
||||||
|
free(t);
|
||||||
|
if (proc_self_root_is_slash && get_process_container_parent_cmdline(pid, &t) > 0) {
|
||||||
|
core_container_cmdline = strappend("COREDUMP_CONTAINER_CMDLINE=", t);
|
||||||
|
free(t);
|
||||||
|
|
||||||
|
if (core_container_cmdline)
|
||||||
|
IOVEC_SET_STRING(iovec[n_iovec++], core_container_cmdline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_process_environ(pid, &t) >= 0) {
|
if (get_process_environ(pid, &t) >= 0) {
|
||||||
|
Reference in New Issue
Block a user