From 3c33ecb61bffc644cb6b1eea6e08e13eb88986d4 Mon Sep 17 00:00:00 2001 From: "Mark A. Grondona" Date: Sat, 2 Nov 2024 22:49:55 +0000 Subject: [PATCH] imp: remove pidinfo abstraction Problem: The `struct pidinfo` abstraction was only required by the IMP kill subcommand, which has been removed. Remove pidinfo related code and tests. --- src/imp/pidinfo.c | 227 ----------------------------------------- src/imp/pidinfo.h | 11 -- src/imp/test/pidinfo.c | 26 ----- 3 files changed, 264 deletions(-) diff --git a/src/imp/pidinfo.c b/src/imp/pidinfo.c index 10771f7e..60122b93 100644 --- a/src/imp/pidinfo.c +++ b/src/imp/pidinfo.c @@ -25,203 +25,12 @@ #include #include -#include -#ifdef HAVE_LINUX_MAGIC_H -#include -#endif -#ifndef TMPFS_MAGIC -#define TMPFS_MAGIC 0x01021994 /* from linux/magic.h */ -#endif -#ifndef CGROUP_SUPER_MAGIC -#define CGROUP_SUPER_MAGIC 0x27e0eb -#endif - #include #include -#include "src/libutil/strlcpy.h" - #include "pidinfo.h" #include "imp_log.h" -struct cgroup_info { - char mount_dir[PATH_MAX + 1]; - bool unified; -}; - -/* Determine if this system is using the unified (v2) or legacy (v1) - * cgroups hierarchy (See https://systemd.io/CGROUP_DELEGATION/) - * and mount point for systemd managed cgroups. - */ -static int cgroup_info_init (struct cgroup_info *cg) -{ - struct statfs fs; - - (void) strlcpy (cg->mount_dir, "/sys/fs/cgroup", sizeof (cg->mount_dir)); - cg->unified = true; - - if (statfs (cg->mount_dir, &fs) < 0) - return -1; - -#ifdef CGROUP2_SUPER_MAGIC - /* if cgroup2 fs mounted: unified hierarchy for all users of cgroupfs - */ - if (fs.f_type == CGROUP2_SUPER_MAGIC) - return 0; -#endif /* CGROUP2_SUPER_MAGIC */ - - /* O/w, if /sys/fs/cgroup is mounted as tmpfs, we need to check - * for /sys/fs/cgroup/systemd mounted as cgroupfs (legacy). - * We do not support hybrid mode (/sys/fs/cgroup/systemd or - * /sys/fs/cgroup/unified mounted as cgroup2fs), since there were - * no systems on which to test this configuration. - */ - if (fs.f_type == TMPFS_MAGIC) { - - (void) strlcpy (cg->mount_dir, - "/sys/fs/cgroup/systemd", - sizeof (cg->mount_dir)); - if (statfs (cg->mount_dir, &fs) == 0 - && fs.f_type == CGROUP_SUPER_MAGIC) { - cg->unified = false; - return 0; - } - } - - /* Unable to determine cgroup mount point and/or unified vs legacy */ - return -1; -} - - -/* Store the command name from /proc/PID/comm into buffer 'buf' of size 'len'. - */ -static int pid_command (pid_t pid, char *buf, int len) -{ - int rc = -1; - FILE *fp = NULL; - int n; - size_t size = 0; - char *line = NULL; - char file [64]; - int saved_errno; - - if (buf == NULL || len <= 0) { - errno = EINVAL; - return -1; - } - - /* 64 bytes is guaranteed to hold /proc/%ju/comm, assuming largest - * unsigned integer pid would be 21 characters (2^64-1) + 11 characters - * for "/proc/" + "/comm" + some slack. - */ - (void) snprintf (file, sizeof (file), "/proc/%ju/comm", (uintmax_t) pid); - - if (!(fp = fopen (file, "r"))) - return -1; - if (getline (&line, &size, fp) < 0) - goto out; - if ((n = strlen (line)) > len) { - errno = ENOSPC; - goto out; - } - /* - * Remove trailing newline and copy command into destination buffer. - * No need to check return code since size of destination was already - * checked above. - */ - if (line[n-1] == '\n') - line[n-1] = '\0'; - (void) strlcpy (buf, line, len); - - rc = 0; -out: - saved_errno = errno; - free (line); - fclose (fp); - errno = saved_errno; - return rc; -} - -/* - * Looks up the 'name=systemd'[*] subsystem relative cgroup path in - * /proc/PID/cgroups and prepends `cgroup_mount_dir` to get the - * full path. - * - * [*] perhaps could also use the "pids" cgroup. - */ -static int pid_systemd_cgroup_path (pid_t pid, char *buf, int len) -{ - int rc = -1; - FILE *fp; - size_t size = 0; - int n; - char file [64]; - char *line = NULL; - struct cgroup_info cgroup; - int saved_errno; - - if (cgroup_info_init (&cgroup) < 0) - return -1; - - /* 64 bytes is guaranteed to hold /proc/%ju/comm, assuming largest - * unsigned integer pid would be 21 characters (2^64-1) + 13 characters - * for "/proc/" + "/cgroup" + some slack. - */ - (void) snprintf (file, sizeof (file), "/proc/%ju/cgroup", (uintmax_t) pid); - if (!(fp = fopen (file, "r"))) - return -1; - - while ((n = getline (&line, &size, fp)) >= 0) { - char *nl; - char *relpath = NULL; - char *subsys = strchr (line, ':'); - if ((nl = strchr (line, '\n'))) - *nl = '\0'; - if (subsys == NULL || *(++subsys) == '\0' - || !(relpath = strchr (subsys, ':'))) - continue; - /* Nullify subsys, relpath is already nul-terminated at newline */ - *(relpath++) = '\0'; - if (cgroup.unified || strcmp (subsys, "name=systemd") == 0) { - n = snprintf (buf, len, "%s%s", cgroup.mount_dir, relpath); - if ((n > 0) && (n < len)) - rc = 0; - break; - } - } - - if (rc < 0) - errno = ENOENT; - - saved_errno = errno; - free (line); - fclose (fp); - errno = saved_errno; - return rc; -} - -/* return the file owner of 'path' - */ -static uid_t path_owner (const char *path) -{ - struct stat st; - if (stat (path, &st) < 0) - return ((uid_t) -1); - return st.st_uid; -} - -/* return the owner of pid. -1 on failure. - */ -static uid_t pid_owner (pid_t pid) -{ - char path [64]; - - /* /proc/%ju is guaranteed to fit in 64 bytes: - */ - (void) snprintf (path, sizeof (path), "/proc/%ju", (uintmax_t) pid); - return path_owner (path); -} - static int parse_pid (const char *s, pid_t *ppid) { unsigned long val; @@ -281,42 +90,6 @@ static pid_t pid_ppid (pid_t pid) return ppid; } -void pid_info_destroy (struct pid_info *pi) -{ - if (pi) { - int saved_errno = errno; - free (pi); - errno = saved_errno; - } -} - -struct pid_info *pid_info_create (pid_t pid) -{ - struct pid_info *pi; - - if (pid == 0) { - errno = EINVAL; - return NULL; - } - if (!(pi = calloc (1, sizeof (*pi)))) - return NULL; - if (pid < 0) - pid = -pid; - pi->pid = pid; - if ((pi->pid_owner = pid_owner (pid)) == (uid_t) -1) - goto err; - if (pid_systemd_cgroup_path (pid, pi->cg_path, sizeof (pi->cg_path)) < 0) - goto err; - if ((pi->cg_owner = path_owner (pi->cg_path)) == (uid_t) -1) - goto err; - if (pid_command (pid, pi->command, sizeof (pi->command)) < 0) - goto err; - return pi; -err: - pid_info_destroy (pi); - return NULL; -} - int pid_kill_children_fallback (pid_t parent, int sig) { int count = 0; diff --git a/src/imp/pidinfo.h b/src/imp/pidinfo.h index 57d73c01..ef273e2a 100644 --- a/src/imp/pidinfo.h +++ b/src/imp/pidinfo.h @@ -11,17 +11,6 @@ #ifndef HAVE_PIDINFO_H #define HAVE_PIDINFO_H 1 -struct pid_info { - pid_t pid; - char command [64]; - uid_t pid_owner; - char cg_path [4096]; - uid_t cg_owner; -}; - -struct pid_info *pid_info_create (pid_t pid); -void pid_info_destroy (struct pid_info *pi); - /* Send signal to any children of pid. * Returns the number of children signaled or -1 if an error occurred. */ diff --git a/src/imp/test/pidinfo.c b/src/imp/test/pidinfo.c index 74d021a4..84b1f894 100644 --- a/src/imp/test/pidinfo.c +++ b/src/imp/test/pidinfo.c @@ -149,33 +149,7 @@ static void pid_kill_tests (void) int main (void) { - struct pid_info *p; - - ok (pid_info_create (0) == NULL && errno == EINVAL, - "pid_info_create (0) fails with EINVAL"); - - ok ((p = pid_info_create (getpid ())) != NULL, - "pid_info_create (getpid ()) works"); - ok (p->pid == getpid (), - "p->pid is expected"); - ok (p->pid_owner == getuid (), - "p->pid_owner is expected"); - diag ("p->cg_path = %s", p->cg_path); - diag ("p->cg_owner = %d", (int) p->cg_owner); - pid_info_destroy (p); - - ok ((p = pid_info_create (-getpid ())) != NULL, - "pid_info_create (-getpid ()) works"); - ok (p->pid == getpid (), - "p->pid is expected"); - ok (p->pid_owner == getuid (), - "p->pid_owner is expected"); - diag ("p->cg_path = %s", p->cg_path); - diag ("p->cg_owner = %d", (int) p->cg_owner); - pid_info_destroy (p); - pid_kill_tests (); - done_testing (); }