static int reboot_system(void) { /* Query PID file, and send USR1 to the running daemon */ int pid = readpidfile(); if (pid > 0) { printf("Rebooting system\n"); kill(pid, SIGHUP); } else { reboot_now(); /*notreached*/ return 1; } return 0; }
static void reset_config_fs(void) { int rc; block_sig(1); printf("Resetting configuration\n"); #ifdef LOGGING system("/bin/logd resetconfig"); #endif /* * Don't actually clean out the filesystem. * That will be done when we reboot */ if ((rc = flat_clean(0)) < 0) { syslog(LOG_ERR, "Failed to prepare flatfs for reset (%d): %m", rc); exit(1); } save_config_to_flash(); reboot_now(); block_sig(0); }
int main(int argc, char *argv[]) { struct sigaction act; int rc, rc1, rc2, readonly, clobbercfg; clobbercfg = readonly = 0; openlog("flatfsd", LOG_PERROR, LOG_DAEMON); while ((rc = getopt(argc, argv, "vcnribwH123hs?")) != EOF) { switch (rc) { case 'w': clobbercfg++; readonly++; break; case 'r': readonly++; break; case 'n': nowrite = 1; break; case 'c': #if !defined(USING_FLASH_FILESYSTEM) rc = flat_check(); if (rc < 0) { #ifdef LOGGING char ecmd[64]; sprintf(ecmd, "/bin/logd chksum-bad %d", -rc); system(ecmd); #endif printf("Flash filesystem is invalid %d - check syslog\n", rc); } else { printf("Flash filesystem is valid\n"); #ifdef LOGGING system("/bin/logd chksum-good"); #endif } exit(rc); #else exit(0); #endif break; case 'v': version(); exit(0); break; case 's': log_caller("/bin/logd flatfsd-s"); exit(saveconfig()); break; case 'b': log_caller("/bin/logd flatfsd-b"); exit(reboot_system()); break; case 'H': log_caller("/bin/logd flatfsd-h"); exit(halt_system()); break; case 'i': log_caller("/bin/logd flatfsd-i"); exit(reset_config()); break; case '1': fsver = 1; break; case '2': fsver = 2; break; case '3': fsver = 3; break; case 'h': case '?': usage(0); break; default: usage(1); break; } } if (readonly) { rc1 = rc2 = 0; if (clobbercfg || #if !defined(USING_FLASH_FILESYSTEM) ((rc = flat_restorefs()) < 0) || #endif (rc1 = flat_filecount()) <= 0 || (rc2 = flat_needinit()) ) { #ifdef LOGGING char ecmd[64]; /* log the reason we have for killing the flatfs */ if (clobbercfg) sprintf(ecmd, "/bin/logd newflatfs clobbered"); else if (rc < 0) sprintf(ecmd, "/bin/logd newflatfs recreate=%d", rc); else if (rc1 <= 0) sprintf(ecmd, "/bin/logd newflatfs filecount=%d", rc1); else if (rc2) sprintf(ecmd, "/bin/logd newflatfs needinit"); else sprintf(ecmd, "/bin/logd newflatfs unknown"); system(ecmd); #endif syslog(LOG_ERR, "Nonexistent or bad flatfs (%d), creating new one...", rc); flat_clean(1); if ((rc = flat_new(DEFAULTDIR)) < 0) { syslog(LOG_ERR, "Failed to create new flatfs, err=%d errno=%d", rc, errno); exit(1); } save_config_to_flash(); } syslog(LOG_INFO, "Created %d configuration files (%d bytes)", numfiles, numbytes); exit(0); } creatpidfile(); act.sa_handler = sighup; memset(&act.sa_mask, 0, sizeof(act.sa_mask)); act.sa_flags = SA_RESTART; act.sa_restorer = 0; sigaction(SIGHUP, &act, NULL); act.sa_handler = sigusr1; memset(&act.sa_mask, 0, sizeof(act.sa_mask)); act.sa_flags = SA_RESTART; act.sa_restorer = 0; sigaction(SIGUSR1, &act, NULL); act.sa_handler = sigusr2; memset(&act.sa_mask, 0, sizeof(act.sa_mask)); act.sa_flags = SA_RESTART; act.sa_restorer = 0; sigaction(SIGUSR2, &act, NULL); act.sa_handler = sigpwr; memset(&act.sa_mask, 0, sizeof(act.sa_mask)); act.sa_flags = SA_RESTART; act.sa_restorer = 0; sigaction(SIGPWR, &act, NULL); /* Make sure we don't suddenly exit while we are writing */ act.sa_handler = sigexit; memset(&act.sa_mask, 0, sizeof(act.sa_mask)); act.sa_flags = SA_RESTART; act.sa_restorer = 0; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); sigaction(SIGQUIT, &act, NULL); register_resetpid(); /* * Spin forever, waiting for a signal to write... */ for (;;) { if (recv_usr1) { struct stat st_buf; recv_usr1 = 0; /* Don't write out config if temp file exists. */ if (stat(IGNORE_FLASH_WRITE_FILE, &st_buf) == 0) { syslog(LOG_INFO, "Not writing to flash " "because %s exists", IGNORE_FLASH_WRITE_FILE); continue; } save_config_to_flash(); continue; } if (recv_hup) { /* * Make sure we do the check above first so that we * commit to flash before rebooting. */ recv_hup = 0; reboot_now(); /*notreached*/ exit(1); } if (recv_pwr) { /* * Ditto for halt */ recv_pwr = 0; halt_now(); /*notreached*/ exit(1); } if (recv_usr2) { #ifdef LOGGING system("/bin/logd button"); #endif recv_usr2 = 0; current_cmd++; if (cmd_list[current_cmd].action == NULL) /* wrap */ current_cmd = 0; } if (exit_flatfsd) break; if (current_cmd) led_pause(); else if (!recv_hup && !recv_usr1 && !recv_usr2 && !recv_pwr) pause(); } return 0; }
// For some reason printf generally doesn't work here void dump_info(unsigned int *context, int offset, char *type) { unsigned int *addr; unsigned int *reg; unsigned int flags; int i; int rstlow; int led; // Make sure we avoid unaligned accesses context = (unsigned int *)(((unsigned int) context) & ~3); // context point into the exception stack, at flags, followed by registers 0 .. 13 reg = context + 1; dump_string(type); dump_string(" at "); // The stacked LR points one or two words afer the exception address addr = (unsigned int *)((reg[13] & ~3) - offset); dump_hex((unsigned int)addr); #ifdef HAS_MULTICORE dump_string(" on core "); dump_digit(_get_core()); #endif dump_string("\r\n"); dump_string("Registers:\r\n"); for (i = 0; i <= 13; i++) { dump_string(" r["); RPI_AuxMiniUartWrite('0' + (i / 10)); RPI_AuxMiniUartWrite('0' + (i % 10)); dump_string("]="); dump_hex(reg[i]); dump_string("\r\n"); } dump_string("Memory:\r\n"); for (i = -4; i <= 4; i++) { dump_string(" "); dump_hex((unsigned int) (addr + i)); RPI_AuxMiniUartWrite('='); dump_hex(*(addr + i)); if (i == 0) { dump_string(" <<<<<< \r\n"); } else { dump_string("\r\n"); } } // The flags are pointed to by context, before the registers flags = *context; dump_string("Flags: \r\n NZCV--------------------IFTMMMMM\r\n "); dump_binary(flags); dump_string(" ("); // The last 5 bits of the flags are the mode switch (flags & 0x1f) { case 0x10: dump_string("User"); break; case 0x11: dump_string("FIQ"); break; case 0x12: dump_string("IRQ"); break; case 0x13: dump_string("Supervisor"); break; case 0x17: dump_string("Abort"); break; case 0x1B: dump_string("Undefined"); break; case 0x1F: dump_string("System"); break; default: dump_string("Illegal"); break; }; dump_string(" Mode)\r\n"); dump_string("Halted waiting for reset\r\n"); rstlow = 0; led = 0; while (1) { for (i = 0; i < 1000000; i++) { // look for reset being low if (tube_is_rst_active()) { rstlow = 1; } // then reset on the next rising edge if (rstlow && (!tube_is_rst_active())) { reboot_now(); } } if (led) { LED_OFF(); } else { LED_ON(); } led = ~led; } }