New audiod command: ll to change the log level at runtime. The new public daemon_get_loglevel() is needed in the zero argument case. Otherwise, the ll command handler parses the argument and calls daemon_set_loglevel(). The lopsub stanza for the subcommand is stored in a separate file which is currently only included by the lopsub suite for para_audiod, but will be included as well by the server suite. For similar reasons we implement the completer as a generic public function, i9e_ll_completer(), although it only has one caller in audioc.c. Another caller follows when the ll server command is added.
server/audiod: Don't parse loglevel argument unnecessarily. Currently the severity string (debug, info, etc.) given to --loglevel is parsed twice: Once by lopsub, which returns the loglevel as the index into the array of severity strings. We turn this index into a string and pass the string to daemon_set_loglevel() which parses the string again to turn it back into a log level value (which happens to coincide with the index value). Clean this up by letting daemon_set_loglevel() receive a log level value rather than a severity string. This also allows us to remove the now unused ENUM_STRING_VAL() macro from audiod.c.
daemon: Introduce log mutex. Currently the server processes append messages to the log file without coordination. This usually does not cause problems, but sometimes the log messages of the main server process and the afs process get interleaved due to the lack of serialization. This patch serializes access to the common log file by employing a new lock: the log_mutex. Like the mmd_mutex, it is realized as an one-element System V semaphore set. Logging is performed by the daemon subsystem implemented in daemon.c. This subsystem is also used by para_audiod which is single-threaded and thus does not need to care about serialization of log messages. To keep daemon.c working for both para_server and para_audiod, struct daemon gains two optional methods, ->pre_log_hook and ->post_log_hook. If the function pointers are not NULL, the methods are called before and after a message is logged. For para_server the methods call back to the server code to take and release the lock. para_audiod does not need to be modified because if the new function pointers are left at their default value NULL, so no hooks are called.
daemon: Fix race condition in daemonize(). If parent_waits is true, the parent process waits for a signal from the child before it exits. However, this signal can arive before the parent has set up its signal handler. This patch closes the race window by switching from signals to pipes. We now create a pipe before the new process is forked, and let the parent block on read(2) until the child exits or indicates success by writing a byte to one end of the pipe. The child process receives the file descriptor of the writing end of the pipe as the return value of daemonize(). The only user of the parent_waits feature is para_server, which is changed accordingly.
daemon: Make daemon_init_colors_or_die() independent of gengetopt. The function receives the values given to the --log-color option as a char * array, which is the type that gengetopt provides for the arguments to string options which may be given multiple times. This patch gets get rid of this implementation detail. The function no longer takes the arguments to --log-color at all and applications now must call daemon_set_log_color_or_die() themselves to set user-defined per-loglevel colors. To make this work, we let daemon_init_colors_or_die() return a boolean which indicates whether color mode should be enabled, and daemon_set_log_color_or_die() is made public. The two users of this API, para_server and para_audiod, are adjusted accordingly.
daemon: Constify argument of two functions. daemon_set_logfile() and daemon_set_loglevel() do not modify the passed string, so the type of the argument should be const char *.
daemon: New option --priority for server and audiod. On slow hardware it is useful to set the priority of the para_audiod process to avoid sound artefacts due to buffer underruns. This patch adds an option for this purpose which is available for para_server and para_audiod.
daemon: Introduce daemon_init_colors_or_die(). The log color logic is already contained in para_server and para_audiod. Let's use a single function in daemon.c for this purpose. daemon_set_default_log_colors() and daemon_set_log_color_or_die() can be made static since they are only called from daemon.c now.
daemon.c: Remove unused daemon_clear_flag(). Found by cppcheck.
daemon: Rename public functions. Let's reserve the daemon_ prefix for public functions of daemon.c to make it clear where these functions are defined.
Simplify set_server_start_time(). This function receives a pointer to a timeval structure which is supposed to contain the daemon startup time. Passing NULL means to set the daemon startup time to the current time. There are only two callers of this function, in audiod.c and in server.c. The first one passes NULL, the other one initialises the timeval structure pointed to by the global now pointer to the current time, and passes this pointer. It's easier to let set_server_start_time() always act as if NULL had been passed.
Allow switching between different log methods at runtime. Currently, para_client defines its para_log function via the INIT_STDERR_LOGGING() macro which generates a log function that writes to stderr. However, we will need to switch to a different, curses-aware logging function when operating in interactive mode. To support more than one log method the type of para_log is changed from a function to a (public) pointer variable. This variable is supposed to point to the log function currently in use so that the application can simply set para_log differently in order to switch between log functions. The patch also changes the INIT_STDERR_LOGGING() macro to receive the name of the log function to be defined and to let para_log point to the newly defined function.
daemon: Introduce parent_waits flag for daemonize(). In daemon mode, para_server should not detach from the console until it is listening on its command socket. The previous approach turned out to be buggy and has been reverted in the previous commit. This second attempt tries to get it right. It adds a boolean parameter "parent_waits" to daemonize(). After daemonize() has forked, the parent process does not exit immediately if parent_waits is true but waits until the child process sends SIGTERM to its parent, or exits. para_server makes use of the new flag in server_init(). The daemon process (child) sends SIGTERM to its parent after the command socket has been initialized. para_audiod, on the other hand, does not need this feature, so it calls daemonize() with parent_waits == false to get the old behaviour.
Overhaul the daemon uptime functions. The public interface of daemon.c offers some helpers for maintaining and printing the uptime of the service. This interface consists of the "uptime" enumeration and the public functions server_uptime() and uptime_str(). The former function takes an uptime enum which is either 'UPTIME_GET' or 'UPTIME_SET'. It is cleaner to avoid the enumeration and have two separate functions for getting and setting the uptime, so this patch replaces server_uptime() by two new functions get_server_uptime() and set_server_start_time(), renames uptime_str() to get_server_uptime_str() and gets rid of the uptime enum. All three new functions take an optional struct timeval * type argument for the common case where the caller already knows the current time, or wishes to specify another time for whatever reason. This allows to save one time() system call per scheduler loop in para_server since with this patch status_refresh() can pass the global "now" pointer (which us updated by the scheduler once per loop) to get_server_uptime().
color: Simplify color error handling. We exit on errors anyway, so get rid of the return value of color_parse() and daemon_set_log_color() and abort immediately rather than returning -1. Add the familiar "_or_die" suffix to these functions to make it clear that no error handling is necessary in the caller.
Implement --log-timing for server and audiod. This adds another option to include milliseconds in the output of each log message.
Use symbolic names for loglevels and clean up the ggo mess. We now use m4 to generate the ggo files, which allows to get rid of a lot of duplicated command line options and improves the readability of the man pages.
Move color logging code to daemon.c and use it also for para_audiod. This patch also introduces the para_log() function of daemon.c so that both para_server and para_audiod can use it.
Rename daemon_init() to daemonize().
Cosmetics: Rename some functions. Add "_or_die" suffix to functions that exit on errors.