summaryrefslogtreecommitdiffstats
path: root/loader
diff options
context:
space:
mode:
authorDavid Lehman <dlehman@redhat.com>2011-02-08 12:30:19 -0600
committerDavid Lehman <dlehman@redhat.com>2011-02-22 09:55:21 -0600
commit8f537d923bf833b1d57504e8e3058535b347fa2f (patch)
tree6e485de59056fb3ee914a6813e3b0e709531d124 /loader
parent0bf0cf131cff4a242d5f6b6b763203cf8cd88dc6 (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.c51
-rw-r--r--loader/undomounts.c2
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");