/* * Called by monitor threads to update message buffer and alerts in monitor * structure, where main thread will act upon them. */ void fcd_lib_set_mon_status(struct fcd_monitor *mon, const char *buf, int warn, int fail, const int *disks) { unsigned i, led; int ret; ret = pthread_mutex_lock(&mon->mutex); if (ret != 0) FCD_PT_ABRT("pthread_mutex_lock", ret); memcpy(mon->buf + 45, buf, 20); fcd_alert_update(warn ? FCD_ALERT_SET_REQ : FCD_ALERT_CLR_REQ, &mon->sys_warn); fcd_alert_update(fail ? FCD_ALERT_SET_REQ : FCD_ALERT_CLR_REQ, &mon->sys_fail); if (disks != NULL) { for (i = 0; i < fcd_conf_disk_count; ++i) { led = fcd_conf_disks[i].port_no - 2; fcd_alert_update(disks[i] ? FCD_ALERT_SET_REQ : FCD_ALERT_CLR_REQ, &mon->disk_alerts[led]); } } ret = pthread_mutex_unlock(&mon->mutex); if (ret != 0) FCD_PT_ABRT("pthread_mutex_unlock", ret); }
static void fcd_main_sigmask(sigset_t *mask, ...) { va_list ap; int i; if (sigemptyset(mask) == -1) FCD_PABORT("sigemptyset"); i = pthread_sigmask(0, NULL, mask); if (i != 0) FCD_PT_ABRT("pthread_sigmask", i); va_start(ap, mask); while (1) { i = va_arg(ap, int); if (i == 0) break; if (i > 0) { if (sigaddset(mask, i) == -1) FCD_PABORT("sigaddset"); } else { if (sigdelset(mask, -i) == -1) FCD_PABORT("sigdelset"); } } va_end(ap); }
/* * Unlocks the disk mutex */ void fcd_lib_disk_mutex_unlock(void) { int ret; ret = pthread_mutex_unlock(&fcd_lib_disk_mutex); if (ret != 0) FCD_PT_ABRT("pthread_mutex_unlock", ret); }
static void fcd_lib_disable(struct fcd_monitor *const mon) { static const char disabled_msg[20] = "ERROR: NOT AVAILABLE"; int ret; FCD_WARN("Disabling %s monitor\n", mon->name); ret = pthread_mutex_lock(&mon->mutex); if (ret != 0) FCD_PT_ABRT("pthread_mutex_lock", ret); fcd_alert_update(FCD_ALERT_SET_REQ, &mon->sys_fail); memcpy(mon->buf + 45, disabled_msg, 20); ret = pthread_mutex_unlock(&mon->mutex); if (ret != 0) FCD_PT_ABRT("pthread_mutex_unlock", ret); }
static void fcd_main_read_monitor(int tty_fd, struct fcd_monitor *mon) { int ret; if (mon->enabled) { if (mon->monitor_fn != 0) { ret = pthread_mutex_lock(&mon->mutex); if (ret != 0) FCD_PT_ABRT("pthread_mutex_lock", ret); } fcd_tty_write_msg(tty_fd, mon); if (mon->monitor_fn != 0) { fcd_alert_read_monitor(mon); ret = pthread_mutex_unlock(&mon->mutex); if (ret != 0) FCD_PT_ABRT("pthread_mutex_unlock", ret); } } }
static void fcd_main_start_mon_threads(void) { struct fcd_monitor *mon, **m; int ret; for (m = fcd_monitors; mon = *m, mon != NULL; ++m) { if (mon->monitor_fn != 0 && mon->enabled) { ret = pthread_create(&mon->tid, NULL, mon->monitor_fn, mon); if (ret != 0) FCD_PT_ABRT("pthread_create", ret); } } }
int main(int argc, char *argv[]) { sigset_t worker_sigmask, main_sigmask; struct fcd_monitor **mon; pthread_t reaper_thread; int tty_fd, ret; fcd_main_parse_args(argc, argv); if (fcd_err_foreground) { fcd_main_enable_coredump(); } else { openlog("freecusd", LOG_PID, LOG_DAEMON); fcd_main_child_log_open(); if (daemon(0, 0) == -1) FCD_PABORT("daemon"); } fcd_conf_parse(); setlocale(LC_NUMERIC, ""); fcd_main_sigmask(&worker_sigmask, SIGINT, SIGTERM, SIGCHLD, SIGUSR1, 0); fcd_main_sigmask(&main_sigmask, -SIGINT, -SIGTERM, SIGCHLD, SIGUSR1, 0); fcd_main_sigmask(&fcd_mon_ppoll_sigmask, SIGINT, SIGTERM, SIGCHLD, -SIGUSR1, 0); fcd_main_sigmask(&fcd_proc_ppoll_sigmask, SIGINT, SIGTERM, -SIGCHLD, -SIGUSR1, 0); ret = pthread_sigmask(SIG_SETMASK, &worker_sigmask, NULL); if (ret != 0) FCD_PT_ABRT("pthread_sigmask", ret); fcd_main_set_sig_handler(); ret = pthread_create(&reaper_thread, NULL, fcd_proc_fn, NULL); if (ret != 0) FCD_PT_ABRT("pthread_create", ret); fcd_main_start_mon_threads(); ret = pthread_sigmask(SIG_SETMASK, &main_sigmask, NULL); if (ret != 0) FCD_PT_ABRT("pthread_sigmask", ret); fcd_pic_setup_gpio(); fcd_pic_reset(); tty_fd = fcd_tty_open("/dev/ttyS0"); fcd_alert_leds_open(); while (!fcd_main_got_exit_signal) { for (mon = fcd_monitors; *mon != NULL; ++mon) { fcd_main_read_monitor(tty_fd, *mon); ret = nanosleep(&fcd_main_sleep, NULL); if (ret == -1 && errno != EINTR) FCD_PABORT("nanosleep"); if (fcd_main_got_exit_signal) break; } } fcd_alert_leds_close(); if (close(tty_fd) == -1) FCD_PERROR("close"); fcd_main_stop_mon_threads(); fcd_main_stop_thread(reaper_thread); if (!fcd_err_foreground && close(fcd_err_child_errfd) == -1) FCD_PERROR(fcd_main_log_addr.sun_path); FCD_INFO("Exiting\n"); return 0; }