]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_shutdown.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / kern / kern_shutdown.c
index 3bd774db5e2dbc530ba01bd8ae1d0cdc8938f1e3..e723f89a26af56dc60c7936586a3407bd0cfd911 100644 (file)
@@ -67,6 +67,7 @@
 #include <kern/clock.h>                 /* for delay_for_interval() */
 #include <libkern/OSAtomic.h>
 #include <IOKit/IOPlatformExpert.h>
+#include <IOKit/IOMessage.h>
 
 #include <sys/kdebug.h>
 
@@ -82,7 +83,7 @@ unsigned int proc_shutdown_exitcount = 0;
 static int  sd_openlog(vfs_context_t);
 static int  sd_closelog(vfs_context_t);
 static void sd_log(vfs_context_t, const char *, ...);
-static void proc_shutdown(void);
+static void proc_shutdown(int only_non_dext);
 static void zprint_panic_info(void);
 extern void halt_log_enter(const char * what, const void * pc, uint64_t time);
 
@@ -93,6 +94,7 @@ extern boolean_t kdp_has_polled_corefile(void);
 struct sd_filterargs {
        int delayterm;
        int shutdownstate;
+       int only_non_dext;
 };
 
 
@@ -113,7 +115,7 @@ static int sd_callback1(proc_t p, void * arg);
 static int sd_callback2(proc_t p, void * arg);
 static int sd_callback3(proc_t p, void * arg);
 
-extern boolean_t panic_include_zprint;
+extern bool panic_include_zprint;
 extern mach_memory_info_t *panic_kext_memory_info;
 extern vm_size_t panic_kext_memory_size;
 
@@ -217,7 +219,7 @@ reboot_kernel(int howto, char *message)
                /* handle live procs (deallocate their root and current directories), suspend initproc */
 
                startTime = mach_absolute_time();
-               proc_shutdown();
+               proc_shutdown(TRUE);
                halt_log_enter("proc_shutdown", 0, mach_absolute_time() - startTime);
 
 #if CONFIG_AUDIT
@@ -252,10 +254,27 @@ reboot_kernel(int howto, char *message)
 #endif /* DEVELOPMENT || DEBUG */
                {
                        startTime = mach_absolute_time();
-                       vfs_unmountall();
+                       vfs_unmountall(TRUE);
                        halt_log_enter("vfs_unmountall", 0, mach_absolute_time() - startTime);
                }
 
+               IOSystemShutdownNotification(kIOSystemShutdownNotificationTerminateDEXTs);
+
+               startTime = mach_absolute_time();
+               proc_shutdown(FALSE);
+               halt_log_enter("proc_shutdown", 0, mach_absolute_time() - startTime);
+
+#if DEVELOPMENT || DEBUG
+               if (!(howto & RB_PANIC) || !kdp_has_polled_corefile())
+#endif /* DEVELOPMENT || DEBUG */
+               {
+                       startTime = mach_absolute_time();
+                       vfs_unmountall(FALSE);
+                       halt_log_enter("vfs_unmountall", 0, mach_absolute_time() - startTime);
+               }
+
+
+
                /* Wait for the buffer cache to clean remaining dirty buffers */
                startTime = mach_absolute_time();
                for (iter = 0; iter < 100; iter++) {
@@ -334,6 +353,7 @@ sd_closelog(vfs_context_t ctx)
        if (sd_logvp != NULLVP) {
                VNOP_FSYNC(sd_logvp, MNT_WAIT, ctx);
                error = vnode_close(sd_logvp, FWRITE, ctx);
+               sd_logvp = NULLVP;
        }
 
        return error;
@@ -365,6 +385,8 @@ sd_log(vfs_context_t ctx, const char *fmt, ...)
        va_end(arglist);
 }
 
+#define proc_is_driver(p) (task_is_driver((p)->task))
+
 static int
 sd_filt1(proc_t p, void * args)
 {
@@ -373,6 +395,10 @@ sd_filt1(proc_t p, void * args)
        int delayterm = sf->delayterm;
        int shutdownstate = sf->shutdownstate;
 
+       if (sf->only_non_dext && proc_is_driver(p)) {
+               return 0;
+       }
+
        if (((p->p_flag & P_SYSTEM) != 0) || (p->p_ppid == 0)
            || (p == self) || (p->p_stat == SZOMB)
            || (p->p_shutdownstate != shutdownstate)
@@ -403,7 +429,9 @@ sd_callback1(proc_t p, void * args)
                        proc_shutdown_exitcount++;
                        proc_list_unlock();
                }
-
+               if (proc_is_driver(p)) {
+                       printf("lingering dext %s signal(%d)\n", p->p_name, signo);
+               }
                psignal(p, signo);
                if (countproc != 0) {
                        sd->activecount++;
@@ -423,6 +451,10 @@ sd_filt2(proc_t p, void * args)
        int delayterm = sf->delayterm;
        int shutdownstate = sf->shutdownstate;
 
+       if (sf->only_non_dext && proc_is_driver(p)) {
+               return 0;
+       }
+
        if (((p->p_flag & P_SYSTEM) != 0) || (p->p_ppid == 0)
            || (p == self) || (p->p_stat == SZOMB)
            || (p->p_shutdownstate == shutdownstate)
@@ -451,6 +483,9 @@ sd_callback2(proc_t p, void * args)
                        proc_shutdown_exitcount++;
                        proc_list_unlock();
                }
+               if (proc_is_driver(p)) {
+                       printf("lingering dext %s signal(%d)\n", p->p_name, signo);
+               }
                psignal(p, signo);
                if (countproc != 0) {
                        sd->activecount++;
@@ -517,7 +552,7 @@ sd_callback3(proc_t p, void * args)
  */
 
 static void
-proc_shutdown(void)
+proc_shutdown(int only_non_dext)
 {
        vfs_context_t ctx = vfs_context_current();
        struct proc *p, *self;
@@ -550,6 +585,7 @@ sigterm_loop:
         */
        sfargs.delayterm = delayterm;
        sfargs.shutdownstate = 0;
+       sfargs.only_non_dext = only_non_dext;
        sdargs.signo = SIGTERM;
        sdargs.setsdstate = 1;
        sdargs.countproc = 1;
@@ -569,7 +605,7 @@ sigterm_loop:
                         */
                        ts.tv_sec = 3;
                        ts.tv_nsec = 0;
-                       error = msleep(&proc_shutdown_exitcount, proc_list_mlock, PWAIT, "shutdownwait", &ts);
+                       error = msleep(&proc_shutdown_exitcount, &proc_list_mlock, PWAIT, "shutdownwait", &ts);
                        if (error != 0) {
                                for (p = allproc.lh_first; p; p = p->p_list.le_next) {
                                        if ((p->p_listflag & P_LIST_EXITCOUNT) == P_LIST_EXITCOUNT) {
@@ -628,7 +664,7 @@ sigterm_loop:
                         */
                        ts.tv_sec = 10;
                        ts.tv_nsec = 0;
-                       error = msleep(&proc_shutdown_exitcount, proc_list_mlock, PWAIT, "shutdownwait", &ts);
+                       error = msleep(&proc_shutdown_exitcount, &proc_list_mlock, PWAIT, "shutdownwait", &ts);
                        if (error != 0) {
                                for (p = allproc.lh_first; p; p = p->p_list.le_next) {
                                        if ((p->p_listflag & P_LIST_EXITCOUNT) == P_LIST_EXITCOUNT) {
@@ -686,6 +722,10 @@ sigterm_loop:
 
        sd_closelog(ctx);
 
+       if (only_non_dext) {
+               return;
+       }
+
        /*
         * Now that all other processes have been terminated, suspend init
         */