[Pkg-sysvinit-commits] r1450 - in sysvinit-upstream/trunk: doc src

Petter Reinholdtsen pere at alioth.debian.org
Sun Jul 12 14:59:06 UTC 2009


Author: pere
Date: 2009-07-12 14:59:06 +0000 (Sun, 12 Jul 2009)
New Revision: 1450

Modified:
   sysvinit-upstream/trunk/doc/Changelog
   sysvinit-upstream/trunk/src/killall5.c
Log:
Modify killall to work better with user space file system, by
changing cwd to /proc when stopping and killing processes, and
avoiding stat() when the value isn't used.  Also, lock process
pages in memory to avoid paging when user processes are stopped.
Patch from Debian and Goswin von Brederlow with changes by Kel
Modderman.


Modified: sysvinit-upstream/trunk/doc/Changelog
===================================================================
--- sysvinit-upstream/trunk/doc/Changelog	2009-07-12 14:48:54 UTC (rev 1449)
+++ sysvinit-upstream/trunk/doc/Changelog	2009-07-12 14:59:06 UTC (rev 1450)
@@ -71,6 +71,12 @@
     some pids during shutdown.  Based on patch from Colin Watson and
     Ubuntu.
   * Add references between killall5 and pidof manual pages.  Patch from Debian.
+  * Modify killall to work better with user space file system, by
+    changing cwd to /proc when stopping and killing processes, and
+    avoiding stat() when the value isn't used.  Also, lock process
+    pages in memory to avoid paging when user processes are stopped.
+    Patch from Debian and Goswin von Brederlow with changes by Kel
+    Modderman.
 
  -- Petter Reinholdtsen <pere at debian.org>  Fri, 30 Jul 2004 14:14:58 +0200
 

Modified: sysvinit-upstream/trunk/src/killall5.c
===================================================================
--- sysvinit-upstream/trunk/src/killall5.c	2009-07-12 14:48:54 UTC (rev 1449)
+++ sysvinit-upstream/trunk/src/killall5.c	2009-07-12 14:59:06 UTC (rev 1450)
@@ -40,10 +40,13 @@
 #include <syslog.h>
 #include <getopt.h>
 #include <stdarg.h>
+#include <sys/mman.h>
 
 char *Version = "@(#)killall5 2.86 31-Jul-2004 miquels at cistron.nl";
 
 #define STATNAMELEN	15
+#define DO_STAT 1
+#define NO_STAT 0
 
 /* Info about a process. */
 typedef struct proc {
@@ -165,8 +168,9 @@
 
 /*
  *	Read the proc filesystem.
+ *	CWD must be /proc to avoid problems if / is affected by the killing (ie depend on fuse).
  */
-int readproc()
+int readproc(int do_stat)
 {
 	DIR		*dir;
 	FILE		*fp;
@@ -180,7 +184,11 @@
 	int		pid, f;
 
 	/* Open the /proc directory. */
-	if ((dir = opendir("/proc")) == NULL) {
+	if (chdir("/proc") == -1) {
+		nsyslog(LOG_ERR, "chdir /proc failed");
+		return -1;
+	}
+	if ((dir = opendir(".")) == NULL) {
 		nsyslog(LOG_ERR, "cannot opendir(/proc)");
 		return -1;
 	}
@@ -206,10 +214,10 @@
 		memset(p, 0, sizeof(PROC));
 
 		/* Open the status file. */
-		snprintf(path, sizeof(path), "/proc/%s/stat", d->d_name);
+		snprintf(path, sizeof(path), "%s/stat", d->d_name);
 
 		/* Read SID & statname from it. */
- 		if ((fp = fopen(path, "r")) != NULL) {
+		if ((fp = fopen(path, "r")) != NULL) {
 			buf[0] = 0;
 			fgets(buf, sizeof(buf), fp);
 
@@ -223,7 +231,7 @@
 				if (q == NULL) {
 					p->sid = 0;
 					nsyslog(LOG_ERR,
-					"can't get program name from %s\n",
+					"can't get program name from /proc/%s\n",
 						path);
 					free(p);
 					continue;
@@ -260,7 +268,7 @@
 			continue;
 		}
 
-		snprintf(path, sizeof(path), "/proc/%s/cmdline", d->d_name);
+		snprintf(path, sizeof(path), "%s/cmdline", d->d_name);
 		if ((fp = fopen(path, "r")) != NULL) {
 
 			/* Now read argv[0] */
@@ -306,7 +314,7 @@
 
 		/* Try to stat the executable. */
 		snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
-		if (stat(path, &st) == 0) {
+		if (do_stat && stat(path, &st) == 0) {
 			p->dev = st.st_dev;
 			p->ino = st.st_ino;
 		}
@@ -562,7 +570,7 @@
 	}
 
 	/* Print out process-ID's one by one. */
-	readproc();
+	readproc(DO_STAT);
 	for(f = 0; f < argc; f++) {
 		if ((q = pidof(argv[f])) != NULL) {
 			spid = 0;
@@ -680,12 +688,15 @@
 	signal(SIGSTOP, SIG_IGN);
 	signal(SIGKILL, SIG_IGN);
 
+	/* lock us into memory */
+	mlockall(MCL_CURRENT | MCL_FUTURE);
+
 	/* Now stop all processes. */
 	kill(-1, SIGSTOP);
 	sent_sigstop = 1;
 
 	/* Read /proc filesystem */
-	if (readproc() < 0) {
+	if (readproc(NO_STAT) < 0) {
 		kill(-1, SIGCONT);
 		return(1);
 	}




More information about the Pkg-sysvinit-commits mailing list