/** System shutdown thread. * @param _action Action to perform once the system has been shut down. * @param arg2 Unused. */ static void shutdown_thread_entry(void *_action, void *arg2) { int action = (int)((ptr_t)_action); thread_wire(curr_thread); thread_disable_preempt(); kprintf(LOG_NOTICE, "system: terminating all processes...\n"); process_shutdown(); kprintf(LOG_NOTICE, "system: unmounting filesystems...\n"); fs_shutdown(); #if CONFIG_SMP kprintf(LOG_NOTICE, "system: shutting down other CPUs...\n"); smp_call_broadcast(shutdown_call_func, NULL, 0); #endif switch(action) { case SHUTDOWN_REBOOT: kprintf(LOG_NOTICE, "system: rebooting...\n"); platform_reboot(); break; case SHUTDOWN_POWEROFF: kprintf(LOG_NOTICE, "system: powering off...\n"); platform_poweroff(); break; } kprintf(LOG_NOTICE, "system: halted.\n"); arch_cpu_halt(); }
/* * On gecko style machines (e.g. 712/xx and 715/xx) * the power switch status is stored in Bit 0 ("the highest bit") * of CPU diagnose register 25. * */ static void gecko_tasklet_func(unsigned long unused) { if (!pwrsw_enabled) return; if (__getDIAG(25) & 0x80000000) { /* power switch button not pressed or released again */ /* Warning: Some machines do never reset this DIAG flag! */ shutdown_timer = 0; } else { process_shutdown(); } }
static void polling_tasklet_func(unsigned long soft_power_reg) { unsigned long current_status; if (!pwrsw_enabled) return; current_status = gsc_readl(soft_power_reg); if (current_status & 0x1) { /* power switch button not pressed */ shutdown_timer = 0; } else { process_shutdown(); } }
/* main kernel thread worker. It polls the button state */ static int kpowerswd(void *param) { __set_current_state(TASK_RUNNING); do { int button_not_pressed; unsigned long soft_power_reg = (unsigned long) param; schedule_timeout_interruptible(pwrsw_enabled ? HZ : HZ/POWERSWITCH_POLL_PER_SEC); __set_current_state(TASK_RUNNING); if (unlikely(!pwrsw_enabled)) continue; if (soft_power_reg) { /* * Non-Gecko-style machines: * Check the power switch status which is read from the * real I/O location at soft_power_reg. * Bit 31 ("the lowest bit) is the status of the power switch. * This bit is "1" if the button is NOT pressed. */ button_not_pressed = (gsc_readl(soft_power_reg) & 0x1); } else { /* * On gecko style machines (e.g. 712/xx and 715/xx) * the power switch status is stored in Bit 0 ("the highest bit") * of CPU diagnose register 25. * Warning: Some machines never reset the DIAG flag, even if * the button has been released again. */ button_not_pressed = (__getDIAG(25) & 0x80000000); } if (likely(button_not_pressed)) { if (unlikely(shutdown_timer && /* avoid writing if not necessary */ shutdown_timer < (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC))) { shutdown_timer = 0; printk(KERN_INFO KTHREAD_NAME ": Shutdown request aborted.\n"); } } else process_shutdown(); } while (!kthread_should_stop()); return 0; }
static int kpowerswd(void *param) { __set_current_state(TASK_RUNNING); do { int button_not_pressed; unsigned long soft_power_reg = (unsigned long) param; schedule_timeout_interruptible(pwrsw_enabled ? HZ : HZ/POWERSWITCH_POLL_PER_SEC); __set_current_state(TASK_RUNNING); if (unlikely(!pwrsw_enabled)) continue; if (soft_power_reg) { /* */ button_not_pressed = (gsc_readl(soft_power_reg) & 0x1); } else { /* */ button_not_pressed = (__getDIAG(25) & 0x80000000); } if (likely(button_not_pressed)) { if (unlikely(shutdown_timer && /* */ shutdown_timer < (POWERSWITCH_DOWN_SEC*POWERSWITCH_POLL_PER_SEC))) { shutdown_timer = 0; printk(KERN_INFO KTHREAD_NAME ": Shutdown request aborted.\n"); } } else process_shutdown(); } while (!kthread_should_stop()); return 0; }
/* * Shutdown sequence. Opposite to boot(). */ static void shutdown(void) { kprintf("Shutting down.\n"); vmstats_print(); process_shutdown(); swap_shutdown(); vfs_clearbootfs(); vfs_clearcurdir(); vfs_unmountall(); splhigh(); scheduler_shutdown(); thread_shutdown(); }
int main(int argc, char *argv[]) { int i, use_stdin = 0; char *user = NULL, *file = NULL; struct passwd *p; auparse_state_t *au; setlocale (LC_ALL, ""); for (i=1; i<argc; i++) { if (argv[i][0] != '-') { //take input and lookup as if it were a user name //if that fails assume its a tty if (user == NULL) { p = getpwnam(argv[i]); if (p) { cuid = p->pw_uid; user = argv[i]; continue; } } if (cterm == NULL) { cterm = argv[i]; } else { usage(); return 1; } } else { if (strcmp(argv[i], "-f") == 0) { if (use_stdin == 0) { i++; file = argv[i]; } else { fprintf(stderr,"stdin already given\n"); return 1; } } else if (strcmp(argv[i], "--bad") == 0) { bad = 1; } else if (strcmp(argv[i], "--proof") == 0) { proof = 1; } else if (strcmp(argv[i], "--extract") == 0) { f = fopen("aulast.log", "wt"); } else if (strcmp(argv[i], "--stdin") == 0) { if (file == NULL) use_stdin = 1; else { fprintf(stderr, "file already given\n"); return 1; } } else if (strcmp(argv[i], "--debug") == 0) { debug = 1; } else { usage(); return 1; } } } list_create(&l); // Search for successful user logins if (file) au = auparse_init(AUSOURCE_FILE, file); else if (use_stdin) au = auparse_init(AUSOURCE_FILE_POINTER, stdin); else { if (getuid()) { fprintf(stderr, "You probably need to be root for this to work\n"); } au = auparse_init(AUSOURCE_LOGS, NULL); } if (au == NULL) { fprintf(stderr, "Error - %s\n", strerror(errno)); goto error_exit_1; } // The theory: iterate though events // 1) when LOGIN is found, create a new session node // 2) if that session number exists, close out the old one // 3) when USER_LOGIN is found, update session node // 4) When USER_END is found update session node and close it out // 5) When BOOT record found make new record and check for previous // 6) If previous boot found, set status to crash and logout everyone // 7) When SHUTDOWN found, close out reboot record while (auparse_next_event(au) > 0) { // We will take advantage of the fact that all events // of interest are one record long int type = auparse_get_type(au); if (type < 0) continue; switch (type) { case AUDIT_LOGIN: create_new_session(au); extract_record(au); break; case AUDIT_USER_LOGIN: update_session_login(au); extract_record(au); break; case AUDIT_USER_END: update_session_logout(au); extract_record(au); break; case AUDIT_SYSTEM_BOOT: process_bootup(au); extract_record(au); break; case AUDIT_SYSTEM_SHUTDOWN: process_shutdown(au); extract_record(au); break; case AUDIT_DAEMON_START: process_kernel(au); extract_record(au); break; } } auparse_destroy(au); // Now output the leftovers list_first(&l); do { lnode *cur = list_get_cur(&l); report_session(cur); } while (list_next(&l)); free(kernel); list_clear(&l); if (f) fclose(f); return 0; error_exit_1: list_clear(&l); if (f) fclose(f); return 1; }
int main(int argc, char **argv) { int rc = 0; auparse_state_t *au = NULL; setlocale(LC_ALL, ""); if (parse_args(argc, argv)) goto error; if (help_flag) { usage(stdout); goto exit; } /* Initialize event list*/ events = list_new((list_free_data_fn*) event_free); if (events == NULL) goto unexpected_error; /* Initialize auparse */ au = init_auparse(); if (au == NULL) goto error; if (create_search_criteria(au)) goto error; while (ausearch_next_event(au) > 0) { int err = 0; switch(auparse_get_type(au)) { case AUDIT_VIRT_MACHINE_ID: err = process_machine_id_event(au); break; case AUDIT_VIRT_CONTROL: err = process_control_event(au); break; case AUDIT_VIRT_RESOURCE: err = process_resource_event(au); break; case AUDIT_AVC: err = process_avc(au); break; case AUDIT_FIRST_ANOM_MSG ... AUDIT_LAST_ANOM_MSG: case AUDIT_FIRST_KERN_ANOM_MSG ... AUDIT_LAST_KERN_ANOM_MSG: err = process_anom(au); break; case AUDIT_SYSTEM_SHUTDOWN: err = process_shutdown(au); break; } if (err) { goto unexpected_error; } auparse_next_event(au); } /* Show results */ if (summary_flag) { print_summary(); } else { print_events(); } /* success */ goto exit; unexpected_error: fprintf(stderr, "Unexpected error\n"); error: rc = 1; exit: if (au) auparse_destroy(au); list_free(events); if (debug) fprintf(stdout, "Exit code: %d\n", rc); return rc; }