[Replicant] [libsamsung-ipc] [PATCH 14/26] tools: ipc-modem: Add syslog support

Denis 'GNUtoo' Carikli GNUtoo at cyberdimension.org
Mon Mar 28 20:20:28 UTC 2022


There is ongoing work to make libsamsung-ipc and the modem drivers of
the Galaxy SIII (GT-I9300) work on top of an upstream kernel instead
of kernels derived from the vendor kernels.

For that work it's convenient to be able to store the kernel the
kernel logs in systemd-journald along with the output of ipc-modem.

If the kernel is built with CONFIG_LOCALVERSION_AUTO, we can track the
exact kernel revision used. And if the modem driver crashed, we can
still have the logs in journald at the next reboot. It also enables us
to store logs over a long period of time and get back to old logs.

However when running ipc-modem through a systemd service unit, the
output is piped to systemd, and we only get the following output with
journalctl -u <service> .service:
    Started [Service Unit Description].

This is because when a program is piped, line buffering changes from
line buffered (the default when outputing to stdout on a terminal
according to setbuf(3)) to fully buffered.

To fix that we add a syslog log-target. Several programs already have
a --syslog (like OpenVPN) or --log-target= (like PulseAudio) command
line argument.

Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo at cyberdimension.org>
---
 tools/ipc-modem.c | 59 ++++++++++++++++++++++++++++++++---------------
 tools/ipc-modem.h |  6 ++++-
 2 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/tools/ipc-modem.c b/tools/ipc-modem.c
index d882400..5977a7e 100644
--- a/tools/ipc-modem.c
+++ b/tools/ipc-modem.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <strings.h>
+#include <syslog.h>
 #include <termios.h>
 #include <unistd.h>
 #include <string.h>
@@ -40,6 +41,8 @@
 
 #include "ipc-modem.h"
 
+enum log_target log_target;
+
 int state = MODEM_STATE_LPM;
 int seq;
 int in_call;
@@ -478,10 +481,15 @@ void modem_log_handler(void *user_data, const char *msg)
 				break;
 		}
 
-		if (user_data)
+		if (log_target == LOG_TO_STDOUT && user_data)
 			printf("[%s] %s\n", (char *)user_data, message);
-		else
+		else if (log_target == LOG_TO_STDOUT)
 			printf("[%s] %s\n", MODEM_LOG_DEBUG, message);
+		else if (log_target == LOG_TO_SYSLOG && user_data)
+			syslog(LOG_INFO,
+			       "[%s] %s\n", (char *)user_data, message);
+		else if (log_target == LOG_TO_SYSLOG)
+			syslog(LOG_INFO, "[%s] %s\n", MODEM_LOG_DEBUG, message);
 	}
 
 	free(message);
@@ -539,17 +547,20 @@ void print_help(void)
 {
 	printf("usage: ipc-modem <command>\n"
 	       "commands:\n"
-	       "\tboot                  boot modem only\n"
-	       "\tpower-on              power on the modem only\n"
-	       "\tpower-off             power off the modem only\n"
-	       "\tstart                 boot modem and start read loop\n"
+	       "\tboot                          boot modem only\n"
+	       "\tpower-on                      power on the modem only\n"
+	       "\tpower-off                     power off the modem only\n"
+	       "\tstart                         "
+	       "boot modem and start read loop\n"
 	       "arguments:\n"
-	       "\t--call=[NUMBER]       call NUMBER\n"
-	       "\t--debug               enable debug messages\n"
-	       "\t--dry-run             "
+	       "\t--call=[NUMBER]               call NUMBER\n"
+	       "\t--debug                       enable debug messages\n"
+	       "\t--dry-run                     "
 	       "Test the ipc-modem program without talking to the modem.\n"
-	       "\t--help                print this help message\n"
-	       "\t--pin=[PIN]           provide SIM card PIN\n");
+	       "\t--help                        print this help message\n"
+	       "\t--log-target=[stdout|syslog]  "
+	       "direct logs to stdout or syslog\n"
+	       "\t--pin=[PIN]                   provide SIM card PIN\n");
 }
 
 int handle_command(struct ipc_client *client,
@@ -654,12 +665,13 @@ int main(int argc, char *argv[])
 	int opt_i = 0;
 
 	struct option opt_l[] = {
-		{"call",    required_argument,  0,  0 },
-		{"debug",   no_argument,        0,  0 },
-		{"dry-run", no_argument,        0,  0 },
-		{"help",    no_argument,        0,  0 },
-		{"pin",     required_argument,  0,  0 },
-		{0,         0,                  0,  0 }
+		{"call",       required_argument,  0,  0 },
+		{"debug",      no_argument,        0,  0 },
+		{"dry-run",    no_argument,        0,  0 },
+		{"help",       no_argument,        0,  0 },
+		{"log-target", required_argument,  0,  0 },
+		{"pin",        required_argument,  0,  0 },
+		{0,            0,                  0,  0 }
 	};
 
 	bzero((void *)&cmdline_opts, sizeof(cmdline_opts));
@@ -687,6 +699,13 @@ int main(int argc, char *argv[])
 					return 1;
 				}
 			}
+		} else if ((strcmp(opt_l[opt_i].name, "log-target") == 0)) {
+			if (optarg && !strcmp(optarg, "syslog")) {
+				log_target = LOG_TO_SYSLOG;
+			} else if (optarg && strcmp(optarg, "stdout")) {
+				printf("[E] Invalid log target '%s'\n", optarg);
+				return 1;
+			}
 		} else if (strcmp(opt_l[opt_i].name, "debug") == 0) {
 			cmdline_opts.debug = true;
 		} else if (strcmp(opt_l[opt_i].name, "dry-run") == 0) {
@@ -721,9 +740,11 @@ int main(int argc, char *argv[])
 
 	if (cmdline_opts.debug == 0)
 		ipc_client_log_callback_register(client,
-						 modem_log_handler_quiet, NULL);
+						 modem_log_handler_quiet,
+						 NULL);
 	else
-		ipc_client_log_callback_register(client, modem_log_handler,
+		ipc_client_log_callback_register(client,
+						 modem_log_handler,
 						 NULL);
 
 	while (optind < argc) {
diff --git a/tools/ipc-modem.h b/tools/ipc-modem.h
index 69b9f64..0b31d83 100644
--- a/tools/ipc-modem.h
+++ b/tools/ipc-modem.h
@@ -37,13 +37,17 @@ enum command {
 	CMD_POWER_OFF,
 };
 
+enum log_target {
+	LOG_TO_STDOUT,
+	LOG_TO_SYSLOG,
+};
+
 struct cmdline_opts {
 	enum command command;
 	bool debug;
 	bool dry_run;
 };
 
-
 void ipc_modem_log(struct ipc_client *client,
 		   char *prefix, const char *message, ...);
 
-- 
2.35.1



More information about the Replicant mailing list