diff options
| author | David Lehman <dlehman@redhat.com> | 2011-02-08 12:30:19 -0600 |
|---|---|---|
| committer | David Lehman <dlehman@redhat.com> | 2011-02-22 09:55:21 -0600 |
| commit | 8f537d923bf833b1d57504e8e3058535b347fa2f (patch) | |
| tree | 6e485de59056fb3ee914a6813e3b0e709531d124 /loader | |
| parent | 0bf0cf131cff4a242d5f6b6b763203cf8cd88dc6 (diff) | |
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
Diffstat (limited to 'loader')
| -rw-r--r-- | loader/shutdown.c | 51 | ||||
| -rw-r--r-- | loader/undomounts.c | 2 |
2 files changed, 40 insertions, 13 deletions
diff --git a/loader/shutdown.c b/loader/shutdown.c index b36077736..c56e44209 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 5445a18cb..189572b06 100644 --- a/loader/undomounts.c +++ b/loader/undomounts.c @@ -76,7 +76,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"); |
