Fix wait-target-done.c
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 6 Jul 2020 23:22:57 +0000 (08:22 +0900)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Wed, 20 Mar 2024 15:28:49 +0000 (16:28 +0100)
1. Change inotify fd to nonblock.
2. Change timeout to use alarm(). And make it encompass
   the whole process, which now includes wd allocation.
3. Add dependency with tlm.service to
   system-delayed-target-trigger.service
4. Add journal log.

Change-Id: Ibec5e4f4030e26235dbba6610a5142d0e29e423f
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
packaging/systemd.spec
packaging/wait-target-done.c
units/system-delayed-target-trigger.service

index 3f5e38b..81ebfa7 100644 (file)
@@ -219,7 +219,7 @@ cp %{SOURCE8} .
 # compile test-runner for 'dbus-integration-test' framework
 %__cc %{_builddir}/%{name}-%{version}/test-runner.c -o %{_builddir}/%{name}-%{version}/systemd-tests
 %__cc -fPIE -pie %{_builddir}/%{name}-%{version}/send-booting-done.c -o %{_builddir}/%{name}-%{version}/send-booting-done -Isrc -L%{_builddir}/%{name}-%{version}/%{build_dir} -lsystemd
-%__cc -fPIE -pie %{_builddir}/%{name}-%{version}/wait-target-done.c -o %{_builddir}/%{name}-%{version}/wait-target-done -Isrc/basic -DRELATIVE_SOURCE_PATH="" -DSIZEOF_TIME_T=4
+%__cc -fPIE -pie %{_builddir}/%{name}-%{version}/wait-target-done.c -o %{_builddir}/%{name}-%{version}/wait-target-done -DRELATIVE_SOURCE_PATH="" -DSIZEOF_TIME_T=4 -Isrc/basic -Isrc/systemd -L%{_builddir}/%{name}-%{version}/%{build_dir} -lsystemd
 
 %install
 %meson_install
index c8bcbbc..794c2b2 100644 (file)
@@ -5,9 +5,11 @@
 #include <poll.h>
 #include <unistd.h>
 #include <time.h>
+#include <signal.h>
 #include <sys/inotify.h>
 
 #include <fs-util.h>
+#include <sd-journal.h>
 
 #define PATH_SYSTEM                                                    "/run/systemd/system/"
 #define PATH_USER                                                      "/run/user/5001/systemd/"
 #define GRAPHICAL_TARGET_DONE                          "graphical.target.done"
 #define DEFAULT_TARGET_DONE                                    "default.target.done"
 
-#define WAIT_TIMEOUT_MS                30000 /* 30 seconds */
+#define WAIT_TIMEOUT           30 /* 30 seconds */
 
 static int wd[2];
 static unsigned char remains;
 
+static struct sigaction sa;
+
 static long get_current_monotonic_ms(void)
 {
        struct timespec current;
@@ -29,32 +33,74 @@ static long get_current_monotonic_ms(void)
        return (current.tv_sec * 1000) + (current.tv_nsec / 1000000);
 }
 
-static void handle_events(int fd)
+static void exit_failure_error(const char *format, ...)
+{
+       va_list ap;
+
+       alarm(0); /* cancel alarm */
+
+       va_start(ap, format);
+       sd_journal_printv(LOG_ERR, format, ap);
+       va_end(ap);
+
+       exit(EXIT_FAILURE);
+}
+
+static void exit_failure_timeout(int signum)
+{
+       exit_failure_error("30s timeout expired, Remains: %#x", remains);
+}
+
+static void exit_success(void)
+{
+       alarm(0); /* cancel alarm */
+       exit(EXIT_SUCCESS);
+}
+
+static void init_timer(void)
+{
+       sa.sa_handler = exit_failure_timeout;
+       sigaction(SIGALRM, &sa, NULL);
+
+       /* timer for 30s timeout, raise SIGALRM on expire */
+       alarm(WAIT_TIMEOUT);
+}
+
+static void handle_file_event(int fd)
 {
        union inotify_event_buffer buffer;
        struct inotify_event *e;
        ssize_t l;
+       long current_ms;
 
        while (1) {
                l = read(fd, &buffer, sizeof(buffer));
-               if (l== -1 && errno != EAGAIN) {
-                       perror("read");
-                       exit(EXIT_FAILURE);
-               }
+               if (l== -1 && errno != EAGAIN)
+                       exit_failure_error("Failed to read.");
 
                if (l <= 0)
                        break;
 
                FOREACH_INOTIFY_EVENT(e, buffer, l) {
                        if (e->mask & IN_CREATE) {
-                               if (e->wd == wd[0] && strstr(e->name, GRAPHICAL_TARGET_DONE))
+                               current_ms = get_current_monotonic_ms();
+                               if (e->wd == wd[0] && !strcmp(e->name, GRAPHICAL_TARGET_DONE)) {
+                                       sd_journal_print(LOG_DEBUG, "%s%s is created. (%ld)",
+                                                       PATH_SYSTEM, GRAPHICAL_TARGET_DONE, current_ms);
                                        remains &= ~(1 << 0);
-                               else if (e->wd == wd[1] && strstr(e->name, DEFAULT_TARGET_DONE))
+                               } else if (e->wd == wd[1] && !strcmp(e->name, DEFAULT_TARGET_DONE)) {
+                                       sd_journal_print(LOG_DEBUG, "%s%s is created. (%ld)",
+                                                       PATH_USER, DEFAULT_TARGET_DONE, current_ms);
                                        remains &= ~(1 << 1);
-                               else if (e->wd == wd[0] && strstr(e->name, DELAYED_TARGET_DONE))
+                               } else if (e->wd == wd[0] && !strcmp(e->name, DELAYED_TARGET_DONE)) {
+                                       sd_journal_print(LOG_DEBUG, "%s%s is created. (%ld)",
+                                                       PATH_SYSTEM, DELAYED_TARGET_DONE, current_ms);
                                        remains &= ~(1 << 2);
-                               else if (e->wd == wd[1] && strstr(e->name, DELAYED_TARGET_DONE))
+                               } else if (e->wd == wd[1] && !strcmp(e->name, DELAYED_TARGET_DONE)) {
+                                       sd_journal_print(LOG_DEBUG, "%s%s is created. (%ld)",
+                                                       PATH_USER, DELAYED_TARGET_DONE, current_ms);
                                        remains &= ~(1 << 3);
+                               }
                        }
                }
 
@@ -68,24 +114,34 @@ int main(int argc, char **argv)
        int fd, poll_num;
        nfds_t nfds;
        struct pollfd fds[1];
-       long current_ms, timeout_ms;
+
+       sd_journal_print(LOG_DEBUG, "Start main.");
+
+       init_timer();
 
        remains = 0;
 
-       fd = inotify_init();
-       if (fd < 0) {
-               perror("inotify_init");
-               exit(EXIT_FAILURE);
-       }
+       fd = inotify_init1(IN_NONBLOCK);
+       if (fd < 0)
+               exit_failure_error("Failed to inotify_init.");
 
-       wd[0] = inotify_add_watch(fd, PATH_SYSTEM, IN_CREATE);
-       while (wd[0] < 0)
-               wd[0] = inotify_add_watch(fd, PATH_SYSTEM, IN_CREATE);
+       /* add watch descriptor for directory PATH_SYSTEM */
+       while (access(PATH_SYSTEM, F_OK) != 0) {
+               sleep(1);
+       }
+       wd[0] = inotify_add_watch(fd, PATH_SYSTEM, IN_ALL_EVENTS);
+       if (wd[0] < 0)
+               exit_failure_error("Failed to add wd to %s: %s", PATH_SYSTEM, strerror(errno));
 
-       wd[1] = inotify_add_watch(fd, PATH_USER, IN_CREATE);
-       while (wd[1] < 0)
-               wd[1] = inotify_add_watch(fd, PATH_USER, IN_CREATE);
+       /* watch descriptor for directory PATH_USER */
+       while (access(PATH_USER, F_OK) != 0) {
+               sleep(1);
+       }
+       wd[1] = inotify_add_watch(fd, PATH_USER, IN_ALL_EVENTS);
+       if (wd[1] < 0)
+               exit_failure_error("Failed to add wd to %s: %s", PATH_USER, strerror(errno));
 
+       /* setting files to be waited */
        if (access(PATH_SYSTEM GRAPHICAL_TARGET_DONE, F_OK) == -1)
                remains |= (1 << 0);
        if (access(PATH_USER DEFAULT_TARGET_DONE, F_OK) == -1)
@@ -97,34 +153,31 @@ int main(int argc, char **argv)
                        remains |= (1 << 3);
        }
 
+       sd_journal_print(LOG_DEBUG, "wd(%s): %d, wd(%s): %d, Remains: %#x",
+                       PATH_SYSTEM, wd[0], PATH_USER, wd[1], remains);
+
        nfds = 1;
 
        fds[0].fd = fd;
        fds[0].events = POLLIN;
 
-       current_ms = get_current_monotonic_ms();
-       timeout_ms = current_ms + WAIT_TIMEOUT_MS;
-
-       while (remains && current_ms < timeout_ms) {
-               poll_num = poll(fds, nfds, timeout_ms - current_ms);
+       /* polling filesystem events */
+       while (remains) {
+               poll_num = poll(fds, nfds, WAIT_TIMEOUT * 1000);
                if (poll_num == -1) {
-                       if (errno == EINTR) {
-                               current_ms = get_current_monotonic_ms();
+                       if (errno == EINTR)
                                continue;
-                       }
-                       exit(EXIT_FAILURE);
+                       exit_failure_error("Failed to poll.");
                }
 
                if (poll_num > 0 && fds[0].revents & POLLIN)
-                       handle_events(fd);
-
-               current_ms = get_current_monotonic_ms();
+                       handle_file_event(fd);
        }
 
        close(fd);
 
        if (remains)
-               exit(EXIT_FAILURE);
+               exit_failure_error("Failed to wait target, Remains: %#x", remains);
        else
-               exit(EXIT_SUCCESS);
+               exit_success();
 }
index e98808e..0412201 100644 (file)
@@ -2,7 +2,7 @@
 Description=System Delayed Target Trigger Service
 After=basic.target
 Wants=wait-mount@opt-usr.service
-After=wait-mount@opt-usr.service
+After=wait-mount@opt-usr.service tlm.service
 DefaultDependencies=no
 RefuseManualStart=yes
 RefuseManualStop=yes