diff options
Diffstat (limited to 'src/system/dlt-system-process-handling.c')
-rw-r--r-- | src/system/dlt-system-process-handling.c | 263 |
1 files changed, 183 insertions, 80 deletions
diff --git a/src/system/dlt-system-process-handling.c b/src/system/dlt-system-process-handling.c index eb310b0..57bd774 100644 --- a/src/system/dlt-system-process-handling.c +++ b/src/system/dlt-system-process-handling.c @@ -50,12 +50,26 @@ #include <fcntl.h> #include <signal.h> #include <sys/wait.h> -#include <pthread.h> #include <limits.h> -volatile DltSystemThreads threads; +#include <systemd/sd-journal.h> +#include <poll.h> +#include <sys/timerfd.h> +#include <time.h> DLT_IMPORT_CONTEXT(dltsystem) +DLT_IMPORT_CONTEXT(syslogContext) +DLT_IMPORT_CONTEXT(journalContext) +DLT_IMPORT_CONTEXT(watchdogContext) +DLT_IMPORT_CONTEXT(procContext) +DLT_IMPORT_CONTEXT(filetransferContext) +extern DltContext logfileContext[DLT_SYSTEM_LOG_FILE_MAX]; + +volatile uint8_t quit = 0; + +#if defined(DLT_FILETRANSFER_ENABLE) +extern s_ft_inotify ino; +#endif int daemonize() { @@ -106,105 +120,195 @@ int daemonize() return 0; } -void start_threads(DltSystemConfiguration *config) +/* Unregisters all DLT Contexts and closes all file descriptors */ +void cleanup_processes(struct pollfd *pollfd, sd_journal *j, DltSystemConfiguration *config) { - DLT_LOG(dltsystem, DLT_LOG_DEBUG, - DLT_STRING("dlt-system-process-handling, start threads")); + //Syslog cleanup + if (config->Syslog.Enable) + DLT_UNREGISTER_CONTEXT(syslogContext); + + //Journal cleanup +#if defined(DLT_SYSTEMD_JOURNAL_ENABLE) + if (config->Journal.Enable) + DLT_UNREGISTER_CONTEXT(journalContext); + if(j != NULL) + sd_journal_close(j); +#endif - int i; - threads.count = 0; - threads.shutdown = 0; + //Logfile cleanup + if (config->LogFile.Enable) { + for (int i = 0; i < config->LogFile.Count; i++) + DLT_UNREGISTER_CONTEXT(logfileContext[i]); + } - for (i = 0; i < MAX_THREADS; i++) - threads.threads[i] = 0; + //LogProcess cleanup + if (config->LogProcesses.Enable) { + DLT_UNREGISTER_CONTEXT(procContext); + } + //Watchdog cleanup #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) - start_thread(config, watchdog_thread, "systemd watchdog"); + DLT_UNREGISTER_CONTEXT(watchdogContext); #endif - if (config->Shell.Enable) - init_shell(); - - if (config->LogFile.Enable) - start_thread(config, logfile_thread, "log file"); - + //FileTransfer cleanup #if defined(DLT_FILETRANSFER_ENABLE) - if (config->Filetransfer.Enable) - start_thread(config, filetransfer_thread, "file transfer"); + if (config->Filetransfer.Enable) { + DLT_UNREGISTER_CONTEXT(filetransferContext); + } #endif - if (config->LogProcesses.Enable) - start_thread(config, logprocess_thread, "log process"); - - if (config->Syslog.Enable) - start_thread(config, syslog_thread, "syslog"); - -#if defined(DLT_SYSTEMD_JOURNAL_ENABLE) - - if (config->Journal.Enable) - start_thread(config, journal_thread, "systemd journal"); - -#endif + for (int i = 0; i < MAX_FD_NUMBER; i++) { + if(pollfd[i].fd > 0) + close(pollfd[i].fd); + } } -/** - * Start a thread and add it to the thread pool. - */ - -void start_thread(DltSystemConfiguration *conf, - void (thread)(void *), const char *name) +/* Creates timer for LogFile and LogProcess, that need to be called every second. */ +int register_timer_fd(struct pollfd *pollfd, int fdcnt) { - if (threads.count == MAX_THREADS) { - DLT_LOG(dltsystem, DLT_LOG_ERROR, - DLT_STRING("Could not create thread for "), - DLT_STRING(name), - DLT_STRING("Out of thread slots.\n")); - return; + struct itimerspec timerValue; + memset(&timerValue, '\0', sizeof(timerValue)); + timerValue.it_value.tv_sec = 1; + timerValue.it_value.tv_nsec = 0; + timerValue.it_interval.tv_sec = 1; + timerValue.it_interval.tv_nsec = 0; + + int timerfd = timerfd_create(CLOCK_MONOTONIC, 0); + if (timerfd < 0) { + DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Failed to create timer fd")); + return -1; } + pollfd[fdcnt].fd = timerfd; + pollfd[fdcnt].events = POLLIN; - DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Creating thread for "), - DLT_STRING(name), - DLT_STRING("\n")); - - pthread_t pt; + if (timerfd_settime(timerfd, 0, &timerValue, NULL) < 0) { // init timer with 1 second + DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not start timer")); + return -1; + } + return 0; +} - if (pthread_create(&pt, NULL, (void *)thread, conf) == 0) - threads.threads[threads.count++] = pt; - else - DLT_LOG(dltsystem, DLT_LOG_ERROR, - DLT_STRING("Could not create thread for "), - DLT_STRING(name), - DLT_STRING("\n")); +/* Routine for executing LogProcess and LogFile, when timer expires */ +void timer_fd_handler(int fd, DltSystemConfiguration *config) +{ + long int timersElapsed = 0; + int r = read(fd, &timersElapsed, 8); // only needed to reset fd event + if (r < 0) + DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Error while reading timer fd: "), + DLT_STRING(strerror(r))); + + if(config->LogProcesses.Enable) + logprocess_fd_handler(config); + if(config->LogFile.Enable) + logfile_fd_handler(config); } -/** - * Wait for threads to exit. - * There's not actually a condition currently - * to bail out of file transfer without a signal. - */ -void join_threads() +void start_dlt_system_processes(DltSystemConfiguration *config) { - int i; DLT_LOG(dltsystem, DLT_LOG_DEBUG, - DLT_STRING("dlt-system-process-handling, waiting for threads to exit.")); + DLT_STRING("dlt-system-process-handling, start threads")); - if (threads.count < 1) { - DLT_LOG(dltsystem, DLT_LOG_DEBUG, - DLT_STRING("dlt-system-process-handling, no threads, waiting for signal.")); - sleep(UINT_MAX); + if (config->Shell.Enable) + init_shell(); + + int fdcnt = 0; + + /* Init FDs for all activated processes*/ + struct pollfd pollfd[MAX_FD_NUMBER]; // Holds all FDs and events + uint8_t fdType[MAX_FD_NUMBER]; // Holds corresponding enum for process identification + + for(int cnt = 0 ; cnt < MAX_FD_NUMBER ; cnt++) { + pollfd[cnt].fd = 0; + pollfd[cnt].events = 0; } - else { - DLT_LOG(dltsystem, DLT_LOG_DEBUG, - DLT_STRING("dlt-system-process-handling, thread count: "), - DLT_INT(threads.count)); - - for (i = 0; i < threads.count; i++) { - pthread_join(threads.threads[i], NULL); - DLT_LOG(dltsystem, DLT_LOG_DEBUG, - DLT_STRING("dlt-system-process-handling, thread exit: "), - DLT_INT(threads.threads[i])); + + //init FD for LogFile and LogProcesses + if (config->LogProcesses.Enable || config->LogFile.Enable) { + fdType[fdcnt] = fdType_timer; + if (register_timer_fd(pollfd, fdcnt) == 0) { + if(config->LogProcesses.Enable) + logprocess_init(config); + if(config->LogFile.Enable) + logfile_init(config); + fdcnt++; } } + + //init FD for Syslog + int syslogSock = 0; + if (config->Syslog.Enable) { + fdType[fdcnt] = fdType_syslog; + syslogSock = register_syslog_fd(pollfd, fdcnt, config); + fdcnt++; + } + + //init FD for Journal + sd_journal *j = NULL; +#if defined(DLT_SYSTEMD_JOURNAL_ENABLE) + if (config->Journal.Enable) { + register_journal_fd(&j, pollfd, fdcnt, config); + fdType[fdcnt] = fdType_journal; + fdcnt++; + } +#endif + + //init FD for FileTransfer +#if defined(DLT_FILETRANSFER_ENABLE) + if (config->Filetransfer.Enable) { + init_filetransfer_dirs(config); + pollfd[fdcnt].fd = ino.handle; + pollfd[fdcnt].events = POLLIN; + fdType[fdcnt] = fdType_filetransfer; + fdcnt++; + } +#endif + + //init FD for Watchdog +#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) + fdType[fdcnt] = fdType_watchdog; + register_watchdog_fd(pollfd, fdcnt); +#endif + + while (quit == 0) + { + int ready; + ready = poll(pollfd, MAX_FD_NUMBER, -1); + if (ready == -1 && quit == 0) + DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Error while poll. Exit with: "), + DLT_STRING(strerror(ready))); + + for (int i = 0; i < MAX_FD_NUMBER; i++) { + if(pollfd[i].revents & POLLIN){ + if (fdType[i] == fdType_syslog && syslogSock > 0) { + syslog_fd_handler(syslogSock); + } + else if (fdType[i] == fdType_timer) { + timer_fd_handler(pollfd[i].fd, config); + } + #if defined(DLT_SYSTEMD_JOURNAL_ENABLE) + else if((fdType[i] == fdType_journal) && (j != NULL)) { + if(sd_journal_process(j) == SD_JOURNAL_APPEND) { + journal_fd_handler(j, config); + } + } + #endif + #if defined(DLT_FILETRANSFER_ENABLE) + else if (fdType[i] == fdType_filetransfer) { + filetransfer_fd_handler(config); + } + #endif + #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) + else if (fdType[i] == fdType_watchdog) { + watchdog_fd_handler(pollfd[i].fd); + } + #endif + } + } + } + + cleanup_processes(pollfd, j, config); + exit(0); } void dlt_system_signal_handler(int sig) @@ -220,12 +324,11 @@ void dlt_system_signal_handler(int sig) DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-process-handling, exit, signal: "), DLT_INT(sig)); - exit(0); + quit = 1; break; default: DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("dlt-system-process-handling, unknown signal!")); break; } -} - +}
\ No newline at end of file |