Fix delayed.target 36/232536/6
authorYoungjae Cho <y0.cho@samsung.com>
Wed, 6 May 2020 06:39:03 +0000 (15:39 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Fri, 8 May 2020 04:20:51 +0000 (13:20 +0900)
Add binary wait-target-done.c for waiting creation of *.done file.

Change-Id: I0d87c574086073b28aa52dccca3e760914e2abbd
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
packaging/systemd.spec
packaging/wait-default-target.sh
packaging/wait-delayed-target.sh
packaging/wait-target-done.c [new file with mode: 0644]

index 6b4ceb5..46f8d1f 100644 (file)
@@ -63,6 +63,7 @@ Source5:        wait-delayed-target.sh
 Source6:        org.tizen.system.conf
 Source7:        sysctl-tizen-override.conf
 Source8:        send-booting-done.c
+Source9:        wait-target-done.c
 Source1001:     systemd.manifest
 BuildRequires:  gperf
 BuildRequires:  intltool >= 0.40.0
@@ -171,6 +172,7 @@ This modifies systemd to support KDBUS in Tizen.
 cp %{SOURCE1001} .
 cp %{SOURCE3} .
 cp %{SOURCE8} .
+cp %{SOURCE9} .
 
 %define _vpath_srcdir .
 %define _vpath_builddir %{build_dir}
@@ -225,6 +227,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 %{_builddir}/%{name}-%{version}/send-booting-done.c -o %{_builddir}/%{name}-%{version}/send-booting-done -Isrc -L%{_builddir}/%{name}-%{version}/%{build_dir} -lsystemd
+%__cc %{_builddir}/%{name}-%{version}/wait-target-done.c -o %{_builddir}/%{name}-%{version}/wait-target-done -Isrc/basic -DRELATIVE_SOURCE_PATH="" -DSIZEOF_TIME_T=4
 
 %install
 %meson_install
@@ -329,6 +332,7 @@ mkdir -p %{buildroot}%{_prefix}/lib/dbus-tests/test-suites/systemd-tests/
 mv %{buildroot}%{_prefix}/lib/systemd/tests/test-bus-* %{buildroot}%{_prefix}/lib/dbus-tests/test-suites/systemd-tests/
 # Install send-booting-done helper
 install -D -m 755 %{_builddir}/%{name}-%{version}/send-booting-done %{buildroot}%{_prefix}/lib/systemd/
+install -D -m 755 %{_builddir}/%{name}-%{version}/wait-target-done %{buildroot}%{_prefix}/lib/systemd/
 
 # Shell Completion
 %if ! %{?WITH_BASH_COMPLETION}
@@ -664,6 +668,7 @@ fi
 %exclude %{_prefix}/lib/systemd/system/runlevel5.target
 %exclude %{_prefix}/lib/systemd/system/runlevel6.target
 %{_prefix}/lib/systemd/send-booting-done
+%{_prefix}/lib/systemd/wait-target-done
 
 %files -n libsystemd
 %manifest %{name}.manifest
index 1c1e0f2..753172f 100644 (file)
@@ -1,24 +1,11 @@
 #!/bin/bash
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 
-for loop in {1..150}
-do
-    echo $1: ${loop}/150
-
-    if [ -f /run/systemd/system/graphical.target.done -a -f /run/user/5001/systemd/default.target.done ]
-    then
-        echo $1: "System and User Default Target Done"
-        # Do nothing, service unit do next step.
-
-        exit 0
-    fi
-
-    /usr/bin/sleep 0.2
-done
-
-# timeout
-#########################################################################################################
-echo $1: "Default Target 30 Seconds Timeout"
-# Do nothing, service unit do next step.
-
+/usr/lib/systemd/wait-target-done default
+if [ $? -eq 0 ]
+then
+       echo "System and User Default Target Done"
+else
+       echo "Default Target 30 Seconds Timeout"
+fi
 exit 0
index 7c2e08d..a2d777f 100644 (file)
@@ -1,26 +1,15 @@
 #!/bin/bash
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 
-for loop in {1..150}
-do
-    echo ${loop}/150
-
-    if [ -f /run/systemd/system/delayed.target.done -a -f /run/user/5001/systemd/delayed.target.done -a -f /run/systemd/system/graphical.target.done -a -f /run/user/5001/systemd/default.target.done ]
-    then
-        echo "System and User Delayed Target Done"
-        /usr/bin/vconftool set -t int  memory/sysman/booting_status 1 -f
-        /usr/lib/systemd/send-booting-done
-
-        exit 0
-    fi
-
-    /usr/bin/sleep 0.2
-done
-
-# timeout
-#########################################################################################################
-echo "Delayed Target 30 Seconds Timeout"
-/usr/bin/vconftool set -t int  memory/sysman/booting_status 3 -f
-/usr/lib/systemd/send-booting-done timeout
-
+/usr/lib/systemd/wait-target-done delayed
+if [ $? -eq 0 ]
+then
+       echo "System and User Delayed Target Done"
+       /usr/bin/vconftool set -t int  memory/sysman/booting_status 1 -f
+       /usr/lib/systemd/send-booting-done
+else
+       echo "Delayed Target 30 Seconds Timeout"
+       /usr/bin/vconftool set -t int  memory/sysman/booting_status 3 -f
+       /usr/lib/systemd/send-booting-done timeout
+fi
 exit 0
diff --git a/packaging/wait-target-done.c b/packaging/wait-target-done.c
new file mode 100644 (file)
index 0000000..c8bcbbc
--- /dev/null
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <poll.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/inotify.h>
+
+#include <fs-util.h>
+
+#define PATH_SYSTEM                                                    "/run/systemd/system/"
+#define PATH_USER                                                      "/run/user/5001/systemd/"
+
+#define DELAYED_TARGET_DONE                                    "delayed.target.done"
+#define GRAPHICAL_TARGET_DONE                          "graphical.target.done"
+#define DEFAULT_TARGET_DONE                                    "default.target.done"
+
+#define WAIT_TIMEOUT_MS                30000 /* 30 seconds */
+
+static int wd[2];
+static unsigned char remains;
+
+static long get_current_monotonic_ms(void)
+{
+       struct timespec current;
+       clock_gettime(CLOCK_MONOTONIC, &current);
+
+       return (current.tv_sec * 1000) + (current.tv_nsec / 1000000);
+}
+
+static void handle_events(int fd)
+{
+       union inotify_event_buffer buffer;
+       struct inotify_event *e;
+       ssize_t l;
+
+       while (1) {
+               l = read(fd, &buffer, sizeof(buffer));
+               if (l== -1 && errno != EAGAIN) {
+                       perror("read");
+                       exit(EXIT_FAILURE);
+               }
+
+               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))
+                                       remains &= ~(1 << 0);
+                               else if (e->wd == wd[1] && strstr(e->name, DEFAULT_TARGET_DONE))
+                                       remains &= ~(1 << 1);
+                               else if (e->wd == wd[0] && strstr(e->name, DELAYED_TARGET_DONE))
+                                       remains &= ~(1 << 2);
+                               else if (e->wd == wd[1] && strstr(e->name, DELAYED_TARGET_DONE))
+                                       remains &= ~(1 << 3);
+                       }
+               }
+
+               if (!remains)
+                       break;
+       }
+}
+
+int main(int argc, char **argv)
+{
+       int fd, poll_num;
+       nfds_t nfds;
+       struct pollfd fds[1];
+       long current_ms, timeout_ms;
+
+       remains = 0;
+
+       fd = inotify_init();
+       if (fd < 0) {
+               perror("inotify_init");
+               exit(EXIT_FAILURE);
+       }
+
+       wd[0] = inotify_add_watch(fd, PATH_SYSTEM, IN_CREATE);
+       while (wd[0] < 0)
+               wd[0] = inotify_add_watch(fd, PATH_SYSTEM, IN_CREATE);
+
+       wd[1] = inotify_add_watch(fd, PATH_USER, IN_CREATE);
+       while (wd[1] < 0)
+               wd[1] = inotify_add_watch(fd, PATH_USER, IN_CREATE);
+
+       if (access(PATH_SYSTEM GRAPHICAL_TARGET_DONE, F_OK) == -1)
+               remains |= (1 << 0);
+       if (access(PATH_USER DEFAULT_TARGET_DONE, F_OK) == -1)
+               remains |= (1 << 1);
+       if (argc == 2 && !strcmp(argv[1], "delayed")) {
+               if (access(PATH_SYSTEM DELAYED_TARGET_DONE, F_OK) == -1)
+                       remains |= (1 << 2);
+               if (access(PATH_USER DELAYED_TARGET_DONE, F_OK) == -1)
+                       remains |= (1 << 3);
+       }
+
+       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);
+               if (poll_num == -1) {
+                       if (errno == EINTR) {
+                               current_ms = get_current_monotonic_ms();
+                               continue;
+                       }
+                       exit(EXIT_FAILURE);
+               }
+
+               if (poll_num > 0 && fds[0].revents & POLLIN)
+                       handle_events(fd);
+
+               current_ms = get_current_monotonic_ms();
+       }
+
+       close(fd);
+
+       if (remains)
+               exit(EXIT_FAILURE);
+       else
+               exit(EXIT_SUCCESS);
+}