shutdown: exclude processes with argv[0][0] from killing
This commit is contained in:
parent
6bd9fe5a73
commit
7e4ab3c5a6
|
@ -47,29 +47,45 @@
|
|||
#define FINALIZE_ATTEMPTS 50
|
||||
|
||||
static bool ignore_proc(pid_t pid) {
|
||||
if (pid == 1)
|
||||
return true;
|
||||
|
||||
/* TODO: add more ignore rules here: device-mapper, etc */
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_kernel_thread(pid_t pid)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
FILE *f;
|
||||
char c;
|
||||
size_t count;
|
||||
uid_t uid;
|
||||
int r;
|
||||
|
||||
/* We are PID 1, let's not commit suicide */
|
||||
if (pid == 1)
|
||||
return true;
|
||||
|
||||
r = get_process_uid(pid, &uid);
|
||||
if (r < 0)
|
||||
return true; /* not really, but better safe than sorry */
|
||||
|
||||
/* Non-root processes otherwise are always subject to be killed */
|
||||
if (uid != 0)
|
||||
return false;
|
||||
|
||||
snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid);
|
||||
char_array_0(buf);
|
||||
|
||||
snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long)pid);
|
||||
f = fopen(buf, "re");
|
||||
if (!f)
|
||||
return true; /* not really, but has the desired effect */
|
||||
|
||||
count = fread(&c, 1, 1, f);
|
||||
fclose(f);
|
||||
return count != 1;
|
||||
|
||||
/* Kernel threads have an empty cmdline */
|
||||
if (count <= 0)
|
||||
return true;
|
||||
|
||||
/* Processes with argv[0][0] = '@' we ignore from the killing
|
||||
* spree. */
|
||||
if (count == 1 && c == '@')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int killall(int sign) {
|
||||
|
@ -77,7 +93,8 @@ static int killall(int sign) {
|
|||
struct dirent *d;
|
||||
unsigned int n_processes = 0;
|
||||
|
||||
if ((dir = opendir("/proc")) == NULL)
|
||||
dir = opendir("/proc");
|
||||
if (!dir)
|
||||
return -errno;
|
||||
|
||||
while ((d = readdir(dir))) {
|
||||
|
@ -86,9 +103,6 @@ static int killall(int sign) {
|
|||
if (parse_pid(d->d_name, &pid) < 0)
|
||||
continue;
|
||||
|
||||
if (is_kernel_thread(pid))
|
||||
continue;
|
||||
|
||||
if (ignore_proc(pid))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
* - accelerate looking for "all hostnames" and suchlike.
|
||||
* - handle incomplete header
|
||||
*
|
||||
* - kann NTP nicht finden?
|
||||
* - in unit.c check ob syslog.socket wegen logging reconnect is kaputt
|
||||
*
|
||||
*
|
||||
* - local deserializer
|
||||
* - http server
|
||||
* - message catalog
|
||||
|
|
51
src/util.c
51
src/util.c
|
@ -1119,6 +1119,57 @@ int get_process_exe(pid_t pid, char **name) {
|
|||
return r;
|
||||
}
|
||||
|
||||
int get_process_uid(pid_t pid, uid_t *uid) {
|
||||
char *p;
|
||||
FILE *f;
|
||||
int r;
|
||||
|
||||
assert(uid);
|
||||
|
||||
if (pid == 0)
|
||||
return getuid();
|
||||
|
||||
if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
f = fopen(p, "re");
|
||||
free(p);
|
||||
|
||||
if (!f)
|
||||
return -errno;
|
||||
|
||||
while (!feof(f)) {
|
||||
char line[LINE_MAX], *l;
|
||||
|
||||
if (!fgets(line, sizeof(line), f)) {
|
||||
if (feof(f))
|
||||
break;
|
||||
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
l = strstrip(line);
|
||||
|
||||
if (startswith(l, "Uid:")) {
|
||||
l += 4;
|
||||
l += strspn(l, WHITESPACE);
|
||||
|
||||
l[strcspn(l, WHITESPACE)] = 0;
|
||||
|
||||
r = parse_uid(l, uid);
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
r = -EIO;
|
||||
|
||||
finish:
|
||||
fclose(f);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
char *strnappend(const char *s, const char *suffix, size_t b) {
|
||||
size_t a;
|
||||
char *r;
|
||||
|
|
|
@ -251,6 +251,7 @@ int rmdir_parents(const char *path, const char *stop);
|
|||
int get_process_comm(pid_t pid, char **name);
|
||||
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
|
||||
int get_process_exe(pid_t pid, char **name);
|
||||
int get_process_uid(pid_t pid, uid_t *uid);
|
||||
|
||||
char hexchar(int x);
|
||||
int unhexchar(char c);
|
||||
|
|
Loading…
Reference in New Issue