[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH 7/7] Perform terminations before unmounting filesystems on shutdown.



We switched to doing umounts beforehand and also to using lazy
umount to prevent hangs due to having killed NetworkManager prior
to unmounting NFS media. (commit a1c759a9524e003)

With this we perform terminations first, but we use killall5's
ability to omit certain pids from the list of processes to kill.
We kill everything except mdmon (this bug), NetworkManager, and
dhclient (for the NFS unmount thing, bz#463959). We don't need
to do lazy unmounting anymore, either.

Resolves: rhbz#604614
---
 loader/shutdown.c   |   51 +++++++++++++++++++++++++++++++++++++++------------
 loader/undomounts.c |    2 +-
 2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/loader/shutdown.c b/loader/shutdown.c
index cc8a85f..b07817d 100644
--- a/loader/shutdown.c
+++ b/loader/shutdown.c
@@ -38,16 +38,43 @@ void disableSwap(void);
 void unmountFilesystems(void);
 
 static void performTerminations(void) {
-	sync();
-	printf("sending termination signals...");
-	kill(-1, 15);
-	sleep(2);
-	printf("done\n");
-
-	printf("sending kill signals...");
-	kill(-1, 9);
-	sleep(2);
-	printf("done\n");
+    int status;
+    FILE *f;
+    char *donotkill[] = {"mdmon", "NetworkManager", "dhclient", NULL};
+    char buf[256], omit[256], oarg[64];
+    char **procname, *pid;
+
+    /* find some pids so we can omit them from killall5 */
+    *omit = '\0';
+    for (procname=donotkill; *procname; procname++) {
+        sprintf(buf, "/usr/sbin/pidof %s", *procname);
+        if ((f = popen(buf, "r")) != NULL) {
+            if (fgets(buf, sizeof(buf), f) != NULL) {
+                buf[strcspn(buf,"\n")] = '\0';
+                pid = strtok(buf, " ");
+                while (pid) {
+                    sprintf(oarg, " -o %s", pid);
+                    strcat(omit, oarg);
+                    pid = strtok(NULL, " ");
+                }
+            }
+
+            fclose(f);
+        }
+    }
+
+    sync();
+    printf("sending termination signals...");
+    sprintf(buf, "/usr/sbin/killall5 -15%s", omit);
+    status = system(buf);
+    sleep(2);
+    printf("done\n");
+
+    printf("sending kill signals...");
+    sprintf(buf, "/usr/sbin/killall5 -9%s", omit);
+    status = system(buf);
+    sleep(2);
+    printf("done\n");
 }
 
 static void performUnmounts(void) {
@@ -119,14 +146,14 @@ void shutDown(int doKill, reboot_action rebootAction)
     static int reentered = 0;
     
     if (reentered) {
-        performUnmounts();
         performTerminations();
+        performUnmounts();
         performReboot(rebootAction);
     }
     reentered = 1;
     if (rebootAction != DELAYED_REBOOT && doKill) {
-        performUnmounts();
         performTerminations();
+        performUnmounts();
         performReboot(rebootAction);
     } else {
         performDelayedReboot();
diff --git a/loader/undomounts.c b/loader/undomounts.c
index efb7d37..23e6f4b 100644
--- a/loader/undomounts.c
+++ b/loader/undomounts.c
@@ -78,7 +78,7 @@ void undoMount(struct unmountInfo * fs, int numFs, int this) {
 
     printf("\t%s", fs[this].name);
     /* don't need to unmount /tmp.  it is busy anyway. */
-    if (umount2(fs[this].name, MNT_DETACH) < 0) {
+    if (umount(fs[this].name) < 0) {
         printf(" umount failed (%d)", errno);
     } else {
         printf(" done");
-- 
1.7.3.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]