From dffb94a35aa3aa8500df7b15f541be9351f8a930797e9f24ac8f844e450a1bbb Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Thu, 29 Jan 2009 00:08:29 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/sysvinit?expand=0&rev=33 --- killproc-2.13.dif | 72 +++++++++++++++++++++++++------- startpar-0.52.dif | 49 ++++++++++++++++------ sysvinit-2.86-fuse-no-kill.patch | 68 ++++++++++++++++++++++-------- sysvinit.changes | 13 ++++++ sysvinit.spec | 11 ++++- 5 files changed, 167 insertions(+), 46 deletions(-) diff --git a/killproc-2.13.dif b/killproc-2.13.dif index 0135c8a..6497030 100644 --- a/killproc-2.13.dif +++ b/killproc-2.13.dif @@ -114,8 +114,8 @@ +.SH AUTHOR +Werner Fink --- mkill.c -+++ mkill.c 2008-12-12 14:30:48.817075022 +0100 -@@ -0,0 +1,684 @@ ++++ mkill.c 2009-01-28 16:36:35.524201270 +0100 +@@ -0,0 +1,728 @@ +/* + * mkill.c Send a signal to all processes accessing a mount point + * @@ -186,6 +186,7 @@ + proc_t * this, *ptr, * last; + struct dirent * dent; + int num, nsig = SIGTERM; ++ struct stat st; + boolean found; + DIR * proc; + @@ -261,7 +262,7 @@ + name[len] = '\0'; + if (check(name)) { + add_proc((pid_t)atol(dent->d_name)); -+ continue; ++ goto fuse; + } + + *slash = '\0'; @@ -274,7 +275,7 @@ + name[len] = '\0'; + if (check(name)) { + add_proc((pid_t)atol(dent->d_name)); -+ continue; ++ goto fuse; + } + + *slash = '\0'; @@ -285,9 +286,11 @@ + if ((len = readlink(path, name, PATH_MAX)) < 0) + continue; + name[len] = '\0'; ++ if (strncmp(name, "/sbin/udevd", 11) == 0) ++ continue; + if (check(name)) { + add_proc((pid_t)atol(dent->d_name)); -+ continue; ++ goto fuse; + } + + *slash = '\0'; @@ -313,9 +316,10 @@ + + if (found) { + add_proc((pid_t)atol(dent->d_name)); -+ continue; ++ goto fuse; + } + ++ fuse: + *(slash+strlen(dent->d_name)) = '\0'; + strcat(slash, "/fd"); + @@ -324,6 +328,7 @@ + strcat(slash, "/"); + flen = strlen(path); + while ((dfd = readdir(fdir)) != (struct dirent*)0) { ++ boolean isfuse = false; + + if (*dfd->d_name == '.') + continue; @@ -337,15 +342,39 @@ + continue; + name[len] = '\0'; + -+ if (check(name)) { ++ if (strcmp("/dev/fuse", name) == 0) ++ isfuse = true; ++ ++ if (found) { ++ if (isfuse) { ++ this = procs; ++ last = (proc_t*)0; ++ ++ for (ptr = procs; this; ptr = this) { ++ last = ptr->prev; ++ this = ptr->next; ++ if (ptr == procs) { ++ if (this) this->prev = (proc_t*)0; ++ procs = this; ++ } else if (last) { ++ if (this) this->prev = last; ++ last->next = this; ++ } ++ free(ptr); ++ } ++ break; ++ } ++ continue; ++ } ++ ++ if ((*name == '/') && check(name)) { ++ if (isfuse) ++ break; + found = true; -+ break; ++ add_proc((pid_t)atol(dent->d_name)); + } + } + (void)closedir(fdir); -+ -+ if (found) -+ add_proc((pid_t)atol(dent->d_name)); + } + (void)closedir(proc); + clear_mnt(); @@ -354,7 +383,7 @@ + this = procs; + last = (proc_t*)0; + found = false; -+ for(ptr = procs; this; ptr = this) { ++ for (ptr = procs; this; ptr = this) { + last = ptr->prev; + this = ptr->next; + if (nsig) { @@ -370,7 +399,11 @@ + if (num > 0) + putc('\n', stdout); + -+ num = 3000000; ++ if (stat("/fastboot", &st) < 0) ++ num = 2000000; ++ else ++ num = 6000000; ++ + if (nsig == SIGTERM) while (found) { + + if ((num <= 0) || !found) @@ -381,7 +414,7 @@ + this = procs; + last = (proc_t*)0; + found = false; -+ for(ptr = procs; this; ptr = this) { ++ for (ptr = procs; this; ptr = this) { + last = ptr->prev; + this = ptr->next; + @@ -401,6 +434,17 @@ + } + } + ++ if ((nsig == SIGTERM) && found) { ++ this = procs; ++ last = (proc_t*)0; ++ for (ptr = procs; this; ptr = this) { ++ last = ptr->prev; ++ this = ptr->next; ++ ++ kill(ptr->pid, SIGKILL); ++ } ++ } ++ + return 0; +} + diff --git a/startpar-0.52.dif b/startpar-0.52.dif index 07939ef..3864d4a 100644 --- a/startpar-0.52.dif +++ b/startpar-0.52.dif @@ -1,5 +1,5 @@ --- makeboot.c -+++ makeboot.c 2008-08-13 16:34:52.985916688 +0200 ++++ makeboot.c 2009-01-27 16:56:43.184201291 +0100 @@ -13,6 +13,12 @@ #include #include @@ -13,7 +13,30 @@ int tree_entries = 0; -@@ -158,11 +164,28 @@ void parse_makefile(const char *path) +@@ -103,6 +109,8 @@ static int check_loop(struct makenode *d + fprintf(stderr, "loop exists %s in %s!\n", dep->name, src->name); + return 1; + } ++ if (loop++ > 999) ++ return 1; + if (check_loop(s->node, src)) + return 1; + } +@@ -112,11 +120,13 @@ static int check_loop(struct makenode *d + /* + * add to the dependecy and selection lists + */ ++static int loop; + static void add_depend(struct makenode *node, const char *dst) + { + struct makenode *dep; + + dep = add_target(dst); ++ loop = 0; + if (check_loop(dep, node)) + return; + dep->select = new_list(node, dep->select); +@@ -158,11 +168,28 @@ void parse_makefile(const char *path) char *s, *strp, *p; struct makenode *node; @@ -24,9 +47,10 @@ + if (getuid() == (uid_t)0) + o_flags |= O_NOATIME; + if ((fd = open(path, o_flags)) < 0) { -+ fprintf(stderr, "Can't open %s: %s\n", path, strerror(errno)); -+ exit(1); -+ } + fprintf(stderr, "Can't open %s: %s\n", path, strerror(errno)); + exit(1); + } +- + (void)posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED); + (void)posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL); + (void)posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE); @@ -36,15 +60,14 @@ + if ((fp = fopen(path, "r")) == NULL) +#endif + { - fprintf(stderr, "Can't open %s: %s\n", path, strerror(errno)); - exit(1); - } -- ++ fprintf(stderr, "Can't open %s: %s\n", path, strerror(errno)); ++ exit(1); ++ } + while (fgets(buf, sizeof(buf), fp)) { for (s = buf; *s && isspace(*s); s++) ; -@@ -198,6 +221,11 @@ void parse_makefile(const char *path) +@@ -198,6 +225,11 @@ void parse_makefile(const char *path) } } } @@ -56,7 +79,7 @@ fclose(fp); for (node = tree_list; node; node = node->next) { -@@ -234,7 +262,17 @@ static void filter_files(const char *dir +@@ -234,7 +266,17 @@ static void filter_files(const char *dir filter_prefix = prefix; snprintf(path, sizeof(path), "/etc/init.d/%s.d", dir); @@ -74,7 +97,7 @@ /* mark all matching nodes */ for (i = 0; i < ndirs; i++) { t = lookup_target(dirlist[i]->d_name + 3); -@@ -342,6 +380,17 @@ struct makenode *pickup_task(void) +@@ -342,6 +384,17 @@ struct makenode *pickup_task(void) } } if (best) { @@ -92,7 +115,7 @@ blogger("service %s", best->name); best->status = T_RUNNING; } -@@ -359,6 +408,17 @@ void finish_task(struct makenode *node) +@@ -359,6 +412,17 @@ void finish_task(struct makenode *node) return; for (n = node->select; n; n = n->next) n->node->num_deps--; diff --git a/sysvinit-2.86-fuse-no-kill.patch b/sysvinit-2.86-fuse-no-kill.patch index 851ed16..fe27d0c 100644 --- a/sysvinit-2.86-fuse-no-kill.patch +++ b/sysvinit-2.86-fuse-no-kill.patch @@ -1,13 +1,21 @@ --- src/killall5.c -+++ src/killall5.c 2008-10-01 18:05:29.829808878 +0200 -@@ -456,6 +456,39 @@ int readproc() - return 0; ++++ src/killall5.c 2009-01-27 16:32:40.048701097 +0100 +@@ -59,6 +59,8 @@ typedef struct proc { + pid_t pid; /* Process ID. */ + int sid; /* Session ID. */ + char kernel; /* Kernel thread or zombie. */ ++ char isfuse; /* Provides FUSE filesystems */ ++ char isudev; /* Is the uevent handler */ + char nfs; /* Binary is loacted on NFS part. */ + struct proc *next; /* Pointer to next struct. */ + } PROC; +@@ -283,6 +285,38 @@ int readarg(FILE *fp, char *buf, int sz) } -+/* + /* + * Scan the filedescriptors of pid for /dev/fuse + */ -+int is_fuse(int pid) { ++int is_fuse(const char *pid) { + DIR *dir; + char path[256]; + char buf[256]; @@ -15,19 +23,18 @@ + ssize_t len; + + /* Open /proc/pid/fd/ */ -+ snprintf(path, sizeof(path), "/proc/%d/fd", pid); ++ snprintf(path, sizeof(path), "/proc/%s/fd", pid); + if ((dir = opendir(path)) != NULL) { ++ int dfd = dirfd(dir); + /* Walk through the directory. */ + while ((d = readdir(dir)) != NULL) { + if (*d->d_name == '.') + continue; + /* check for /dev/fuse */ -+ snprintf(path, sizeof(path), "/proc/%d/fd/%s", pid, d->d_name); -+ if ((len = readlink(path, buf, sizeof(buf))) > 0) { -+ if (strncmp("/dev/fuse", buf, len) == 0) { -+ /* Fuse filesystem */ -+ return 1; -+ } ++ if ((len = readlinkat(dfd, d->d_name, buf, sizeof(buf))) > 0) { ++ buf[len] = '\0'; ++ if (strcmp("/dev/fuse", buf) == 0) ++ return 1; /* Fuse filesystem */ + } + } + closedir(dir); @@ -37,10 +44,32 @@ + return 0; +} + - PIDQ_HEAD *init_pid_q(PIDQ_HEAD *q) - { - q->head = q->next = q->tail = NULL; -@@ -779,11 +812,11 @@ int main(int argc, char **argv) ++/* + * Read the proc filesystem. + */ + int readproc() +@@ -438,13 +472,19 @@ int readproc() + + /* Try to stat the executable. */ + snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name); +- if (check4nfs(path, NULL)) ++ if (check4nfs(path, buf)) + p->nfs = 1; + if ((p->nfs == 0) && (stat(path, &st) == 0)) { + p->dev = st.st_dev; + p->ino = st.st_ino; + } + ++ /* Check for uevent handler */ ++ p->isudev = (strncmp(buf, "/sbin/udevd", 11) == 0); ++ ++ /* Check for provider of FUSE filesystems */ ++ p->isfuse = is_fuse(d->d_name); ++ + /* Link it into the list. */ + p->next = plist; + plist = p; +@@ -779,14 +819,16 @@ int main(int argc, char **argv) exit(1); } @@ -50,7 +79,12 @@ pid = (int)getpid(); for (p = plist; p; p = p->next) { - if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel) { -+ if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel || is_fuse(p->pid)) { ++ if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel || p->isfuse) { kill(p->pid, SIGCONT); continue; } ++ if (((sig == SIGTERM) || (sig == SIGKILL)) && p->isudev) ++ continue; + kill(p->pid, sig); + } + diff --git a/sysvinit.changes b/sysvinit.changes index d8fb741..00c514f 100644 --- a/sysvinit.changes +++ b/sysvinit.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Tue Jan 27 16:00:03 CET 2009 - werner@suse.de + +- Do not terminate udevd with mkill(8) +- Do not terminate udevd with killall5(8) +- Avoid chrashing startpar due recursion caused by loops + +------------------------------------------------------------------- +Mon Jan 26 12:02:43 CET 2009 - werner@suse.de + +- Do not kill fuse user space processes with mkill(8) (bnc#466484) +- Minimize fuse patch for killall5(8) by using readlinkat(2) + ------------------------------------------------------------------- Wed Dec 10 14:27:34 CET 2008 - werner@suse.de diff --git a/sysvinit.spec b/sysvinit.spec index 6696e40..816a49d 100644 --- a/sysvinit.spec +++ b/sysvinit.spec @@ -1,7 +1,7 @@ # # spec file for package sysvinit (Version 2.86) # -# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -30,7 +30,7 @@ Group: System/Base PreReq: coreutils AutoReqProv: on Version: 2.86 -Release: 189 +Release: 190 Summary: SysV-Style init BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: libselinux-devel libsepol-devel @@ -321,6 +321,13 @@ rm -rf ${RPM_BUILD_ROOT} %doc %{_mandir}/man8/mkill.8.gz %changelog +* Tue Jan 27 2009 werner@suse.de +- Do not terminate udevd with mkill(8) +- Do not terminate udevd with killall5(8) +- Avoid chrashing startpar due recursion caused by loops +* Mon Jan 26 2009 werner@suse.de +- Do not kill fuse user space processes with mkill(8) (bnc#466484) +- Minimize fuse patch for killall5(8) by using readlinkat(2) * Wed Dec 10 2008 werner@suse.de - Mkill(8): add the option -0 for debugging and wait upto 3 seconds if a signal was send.