void linux_bootchart_switch () { struct cfgnode *node = cfg_getnode ("configuration-bootchart-active", NULL); if (node && node->flag) { if ((node = cfg_getnode ("configuration-bootchart-polling-interval", NULL)) && node->value) { linux_bootchart_sleep_time = node->value; } else { linux_bootchart_sleep_time = 200; } if ((node = cfg_getnode ("configuration-bootchart-process-accounting", NULL)) && node->flag) { linux_bootchart_process_accounting = 1; } if (!linux_bootchart_have_thread) { linux_bootchart_have_thread = 1; ethread_spawn_detached ((void *(*)(void *))linux_bootchart_thread, (void *)NULL); } } linux_bootchart_in_switch++; }
void einit_feedback_visual_fbsplash_boot_event_handler(struct einit_event *ev) { /* preinit */ if ((ev->type == einit_boot_devices_available) && !(coremode & einit_mode_ipconly)) { if (einit_initial_environment) { /* check for kernel params */ uint32_t i = 0; char start_splash = 0, *ttypatch = NULL, *splashargs = NULL; for (; einit_initial_environment[i]; i++) { if (strstr (einit_initial_environment[i], "splash=") == einit_initial_environment[i]) { start_splash = 1; splashargs = einit_initial_environment[i]+7; if (!ttypatch) ttypatch = "tty1"; } else if ((strstr (einit_initial_environment[i], "console=") == einit_initial_environment[i]) || (strstr (einit_initial_environment[i], "einitty=") == einit_initial_environment[i])) { ttypatch = einit_initial_environment[i]+8; } } if (splashargs && *splashargs) { char *fbtheme = NULL/*, *fbmode = NULL*/; if (splashargs) { char **p = str2set (',', splashargs); if (p) { for (i = 0; p[i]; i++) { char *sep = strchr (p[i], ':'); if (sep) { *sep = 0; sep++; if (strmatch (p[i], "theme")) { fbtheme = estrdup (sep); } }/* else { fbmode = estrdup(p[i]); }*/ } free (p); } } if (fbtheme) { struct cfgnode *node = cfg_getnode ("configuration-feedback-visual-fbsplash-theme", NULL); if (node && node->arbattrs) { uint32_t u = 0; for (; node->arbattrs[u]; u+=2) { if (strmatch(node->arbattrs[u], "s")) { notice (4, "patching fbsplash theme to %s", fbtheme); node->arbattrs[u+1] = fbtheme; node->svalue = fbtheme; } } } } /* if (fbmode) { }*/ } else fbsplash_disabled = 1; if (ttypatch && *ttypatch) { struct cfgnode *node = cfg_getnode ("configuration-feedback-visual-std-io", NULL); /* patch console */ if (node && node->arbattrs) { uint32_t ri = 0; for (; node->arbattrs[ri]; ri+=2) { if (strmatch (node->arbattrs[ri], "stdio")) { char tx[BUFFERSIZE]; if (ttypatch[0] == '/') esprintf (tx, BUFFERSIZE, "%s", ttypatch); else esprintf (tx, BUFFERSIZE, "/dev/%s", ttypatch); notice (4, "patching stdio output to go to %s", tx); node->arbattrs[ri+1] = estrdup(tx); } else if (strmatch (node->arbattrs[ri], "activate-vt")) { notice (4, "removing activate-vt= instruction"); node->arbattrs = (char **)setdel ((void **)node->arbattrs, node->arbattrs[ri]); node->arbattrs = (char **)setdel ((void **)node->arbattrs, node->arbattrs[ri]); } } } } if (start_splash) { struct einit_event ee = evstaticinit(einit_core_change_service_status); ee.argv = (char **)setadd ((void **)ee.set, "splashd", SET_TYPE_STRING); ee.argv = (char **)setadd ((void **)ee.set, "enable", SET_TYPE_STRING); event_emit (&ee, einit_event_flag_broadcast); evstaticdestroy(ee); notice (4, "enabling feedack (fbsplash)"); einit_feedback_visual_fbsplash_enable(); } } } }
void core_einit_event_handler (struct einit_event *ev) { if (ev->type == einit_core_configuration_update) { struct cfgnode *node; char *str; ev->chain_type = einit_core_update_modules; if ((node = cfg_getnode ("core-mortality-bad-malloc", NULL))) mortality[bitch_emalloc] = node->value; if ((node = cfg_getnode ("core-mortality-bad-stdio", NULL))) mortality[bitch_stdio] = node->value; if ((node = cfg_getnode ("core-mortality-bad-regex", NULL))) mortality[bitch_regex] = node->value; if ((node = cfg_getnode ("core-mortality-bad-expat", NULL))) mortality[bitch_expat] = node->value; if ((node = cfg_getnode ("core-mortality-bad-dl", NULL))) mortality[bitch_dl] = node->value; if ((node = cfg_getnode ("core-mortality-bad-lookup", NULL))) mortality[bitch_lookup] = node->value; if ((node = cfg_getnode ("core-mortality-bad-pthreads", NULL))) mortality[bitch_epthreads] = node->value; if ((node = cfg_getnode ("core-settings-allow-code-unloading", NULL))) einit_allow_code_unloading = node->flag; if ((str = cfg_getstring ("core-scheduler-niceness/core", NULL))) einit_core_niceness_increment = parse_integer (str); if ((str = cfg_getstring ("core-scheduler-niceness/tasks", NULL))) einit_task_niceness_increment = parse_integer (str); } else if (ev->type == einit_core_update_modules) { struct lmodule *lm; repeat: lm = mlist; einit_new_node = 0; while (lm) { if (lm->source && strmatch(lm->source, "core")) { lm = mod_update (lm); // tell module to scan for changes if it's a module-loader if (lm->module && (lm->module->mode & einit_module_loader) && (lm->scanmodules != NULL)) { notice (8, "updating modules (%s)", lm->module->rid ? lm->module->rid : "unknown"); lm->scanmodules (mlist); /* if an actual new node has been added to the configuration, repeat this step */ if (einit_new_node) goto repeat; } } lm = lm->next; } /* give the module-logic code and others a chance at processing the current list */ struct einit_event update_event = evstaticinit(einit_core_module_list_update); update_event.para = mlist; event_emit (&update_event, einit_event_flag_broadcast); evstaticdestroy(update_event); } else if (ev->type == einit_core_recover) { // call everyone's recover-function (if defined) struct lmodule *lm = mlist; while (lm) { if (lm->recover) { lm->recover (lm); } lm = lm->next; } } else if (ev->type == einit_core_suspend_all) { // suspend everyone (if possible) struct lmodule *lm = mlist; int ok = 0; while (lm) { ok += (mod (einit_module_suspend, lm, NULL) == status_ok) ? 1 : 0; lm = lm->next; } if (ok) notice (4, "%i modules suspended", ok); event_snooze_time = event_timer_register_timeout(60); } else if (ev->type == einit_core_resume_all) { // resume everyone (if necessary) struct lmodule *lm = mlist; int ok = 0; while (lm) { ok += (mod (einit_module_resume, lm, NULL) == status_ok) ? 1 : 0; lm = lm->next; } if (ok) notice (4, "%i available", ok); } }
void linux_hotplug_hotplug_event_handler (struct einit_event *ev) { if (ev->stringset) { char *subsystem = NULL; char *firmware = NULL; char *devpath = NULL; int i = 0; struct cfgnode *node = cfg_getnode ("configuration-system-hotplug-support-legacy-hotplug-scripts", NULL); for (; ev->stringset[i]; i+=2) { if (strmatch (ev->stringset[i], "SUBSYSTEM")) { subsystem = ev->stringset[i+1]; } else if (strmatch (ev->stringset[i], "FIRMWARE")) { firmware = ev->stringset[i+1]; } else if (strmatch (ev->stringset[i], "DEVPATH")) { devpath = ev->stringset[i+1]; } } if (node && node->flag) { char **commands = NULL; if (subsystem) { char n = 0; for (; n < 2; n++) { char buffer[BUFFERSIZE]; char *tbuffer = (n == 1) ? "/etc/einit/hotplug.d/default/" : NULL; switch (n) { case 0: esprintf(buffer, BUFFERSIZE, "/etc/einit/hotplug.d/%s/", subsystem); tbuffer = buffer; break; case 1: break; default: tbuffer = NULL; break; } if (tbuffer) { struct stat st; if (!stat (tbuffer, &st) && S_ISDIR(st.st_mode)) { char **cm = readdirfilter (NULL, tbuffer, "\\.hotplug$", NULL, 0); if (cm) { commands = (char **)setcombine_nc ((void **)commands, (const void **)cm, SET_TYPE_STRING); efree (cm); } } } } } if (commands) { char **env = NULL; char *command; ssize_t blen = strlen (subsystem) + 2; char **cd = NULL; for (i = 0; ev->stringset[i]; i+=2) { env = straddtoenviron (env, ev->stringset[i], ev->stringset[i+1]); } for (i = 0; commands[i]; i++) { int len = blen + strlen (commands[i]); char *t = emalloc (len); esprintf (t, len, "%s %s", commands[i], subsystem); cd = set_str_add (cd, t); efree (t); } if (cd) { command = set2str (';', (const char **)cd); pexec(command, NULL, 0, 0, NULL, NULL, env, NULL); efree (cd); efree (command); } efree (env); efree (commands); } } if (firmware && (ev->type == einit_hotplug_add)) { char buffer[BUFFERSIZE]; int tblen = sizeof(SYS_DIR) + strlen (devpath) + 11; FILE *f; struct stat st; char *targetbuffer = emalloc (tblen); notice (2, "need firmware: %s", firmware); esprintf (buffer, BUFFERSIZE, FIRMWARE_DIR "/%s", firmware); if (stat (buffer, &st)) { esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("-1\n", f); fclose (f); } notice (3, "can't locate firmware: %s", buffer); } else { esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("1\n", f); fclose (f); } esprintf (targetbuffer, tblen, SYS_DIR "/%s/data", devpath); ssize_t ll = 0; char *firmware_data = readfile_l (buffer, &ll); if (firmware_data && ll) { if ((f = fopen (targetbuffer, "w"))) { int rembytes = ll; while (rembytes > 0) { size_t bw = fwrite (firmware_data +ll -rembytes, rembytes, 1, f); if (bw == 1) break; if (bw < 0) { notice (3, "error writing firmware: %s", buffer); } } fclose (f); } esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("0\n", f); fclose (f); } notice (3, "firmware loaded okay: %s", buffer); } else { esprintf (targetbuffer, tblen, SYS_DIR "/%s/loading", devpath); if ((f = fopen (targetbuffer, "w"))) { fputs ("-1\n", f); fclose (f); } notice (3, "can't load firmware: %s", buffer); } } notice (3, "done loading firmware: %s", buffer); efree (targetbuffer); } } }
void *linux_bootchart_thread (void *ignored) { struct cfgnode *node; char *save_to = "/var/log/bootchart.tgz"; FILE *f; char try_acct = 1; signed int extra_wait = 0; if ((node = cfg_getnode ("configuration-bootchart-extra-waiting-time", NULL)) && node->value) { extra_wait = node->value; } char *buffer_ds = NULL; char *buffer_ps = NULL; char *buffer_st = NULL; while (!shutting_down && (linux_bootchart_have_thread || (extra_wait > 0))) { char *uptime = linux_bootchart_get_uptime(); if (linux_bootchart_process_accounting && try_acct) { if (acct ("/dev/kernel_pacct") == -1) try_acct = 1; } if (uptime) { buffer_ds = linux_bootchart_update_ds (buffer_ds, uptime); buffer_ps = linux_bootchart_update_ps (buffer_ps, uptime); buffer_st = linux_bootchart_update_st (buffer_st, uptime); free (uptime); uptime = NULL; } usleep (linux_bootchart_sleep_time); if (!linux_bootchart_have_thread) extra_wait -= linux_bootchart_sleep_time; } if ((node = cfg_getnode ("configuration-bootchart-save-to", NULL)) && node->svalue) { save_to = node->svalue; } if (coremode & einit_mode_sandbox) { save_to = "bootchart.tgz"; } mkdir ("/tmp/bootchart.einit", 0755); if (buffer_ds) { if ((f = fopen ("/tmp/bootchart.einit/proc_diskstats.log", "w"))) { fputs (buffer_ds, f); fclose (f); } free (buffer_ds); buffer_ds = NULL; } if (buffer_ps) { if ((f = fopen ("/tmp/bootchart.einit/proc_ps.log", "w"))) { fputs (buffer_ps, f); fclose (f); } free (buffer_ps); buffer_ps = NULL; } if (buffer_st) { if ((f = fopen ("/tmp/bootchart.einit/proc_stat.log", "w"))) { fputs (buffer_st, f); fclose (f); } free (buffer_st); buffer_st = NULL; } if (linux_bootchart_process_accounting) { char *r = readfile ("/dev/kernel_pacct"); if (r) { if ((f = fopen ("/tmp/bootchart.einit/kernel_pacct", "w"))) { fputs (r, f); fclose (f); } unlink ("/dev/kernel_pacct"); } acct(NULL); } if ((f = fopen ("/tmp/bootchart.einit/header", "w"))) { char *t, buffer[BUFFERSIZE]; time_t ti = time(NULL); /* we're emulating bootchartd-0.8/0.9's format... */ eputs ("version = 0.8\n", f); if (gethostname (buffer, BUFFERSIZE) == 0) { eprintf (f, "title = eINIT Boot Chart for %s, %s", buffer, ctime(&ti)); } else { eprintf (f, "title = eINIT Boot Chart, %s", ctime(&ti)); } fprintf (f, "system.uname = %s %s %s %s\n", osinfo.sysname, osinfo.release, osinfo.version, osinfo.machine); if ((t = readfile ("/etc/gentoo-release"))) { strtrim (t); eprintf (f, "system.release = %s\n", t); free (t); } else { eputs ("system.release = unknown\n", f); } if ((t = readfile ("/proc/cpuinfo"))) { char **r = str2set ('\n', t); char *n = NULL; int i; if (r) { for (i = 0; r[i]; i++) { if (strstr (r[i], "model name") == r[i]) { n = r[i]; break; } } if (n) eprintf (f, "system.cpu = %s\n", n); else eputs ("system.cpu = unknown\n", f); } free (t); } else { eputs ("system.cpu = unknown\n", f); } if ((t = readfile ("/proc/cmdline"))) { eprintf (f, "system.kernel.options = %s\n", t); free (t); } fclose (f); } char buffer[BUFFERSIZE]; if (coremode & einit_mode_sandbox) { esprintf (buffer, BUFFERSIZE, "export pwx=`pwd`; cd /tmp/bootchart.einit; tar czf \"${pwx}/%s\" *", save_to); } else { esprintf (buffer, BUFFERSIZE, "cd /tmp/bootchart.einit; tar czf %s *", save_to); } system (buffer); unlink_recursive ("/tmp/bootchart.einit/", 1); char *di = cfg_getstring ("configuration-bootchart-chart-directory", NULL); char *fo = cfg_getstring ("configuration-bootchart-chart-format", NULL); esprintf (buffer, BUFFERSIZE, "bootchart -o %s -f %s %s", di, fo, save_to); return NULL; }