1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +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:
Zbigniew Jędrzejewski-Szmek 2016-08-02 13:38:00 -04:00 committed by GitHub
commit 87edd2b116

View File

@ -558,6 +558,89 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
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[]) {
uid_t uid;
gid_t gid;
@ -933,11 +1016,13 @@ static int process_kernel(int argc, char* argv[]) {
/* The larger ones we allocate on the heap */
_cleanup_free_ char
*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;
const char *context[_CONTEXT_MAX];
struct iovec iovec[25];
bool proc_self_root_is_slash;
struct iovec iovec[27];
size_t n_iovec = 0;
uid_t owner_uid;
const char *p;
@ -1110,6 +1195,15 @@ static int process_kernel(int argc, char* argv[]) {
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) {
core_cwd = strjoina("COREDUMP_CWD=", t);
free(t);
@ -1119,9 +1213,20 @@ static int process_kernel(int argc, char* argv[]) {
if (get_process_root(pid, &t) >= 0) {
core_root = strjoina("COREDUMP_ROOT=", t);
free(t);
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) {