Change MainPID of user@service 07/98407/3 accepted/tizen/3.0/common/20161122.195027 accepted/tizen/3.0/ivi/20161122.124236 accepted/tizen/3.0/mobile/20161122.124143 accepted/tizen/3.0/tv/20161122.124213 accepted/tizen/3.0/wearable/20161122.124227 submit/tizen_3.0/20161118.041243
authorKunhoon Baik <knhoon.baik@samsung.com>
Thu, 17 Nov 2016 07:26:34 +0000 (16:26 +0900)
committerKunhoon Baik <knhoon.baik@samsung.com>
Fri, 18 Nov 2016 04:32:19 +0000 (13:32 +0900)
systemd-user-helper helps to launch systemd user session.
Thus, MainPID should be changed to systemd user session for keeping original behavior like stop operation.
This patch changes the MainPID to systemd user session by using pidfile and forking type.

Change-Id: Id8dc3daa71c18914b79e218043705fe5e167d14f

packaging/system-plugin.spec
src/systemd-user-helper/systemd-user-helper.c

index 3622003..13684a2 100644 (file)
@@ -308,12 +308,13 @@ mv %{_sysconfdir}/fstab_lazymnt %{_sysconfdir}/fstab
 %manifest systemd-user-helper.manifest
 %caps(cap_sys_admin,cap_mac_admin,cap_mac_override,cap_dac_override,cap_setgid=ei) %{_bindir}/systemd_user_helper
 
+#TODO: when uninstalling, it should be restored to original file
 %posttrans -n systemd-user-helper
 cp -a /usr/lib/systemd/system/user\@.service /usr/lib/systemd/system/__user@.service
-/usr/bin/sed -i -e 's/Type=\(.*\)/Type=simple/' /usr/lib/systemd/system/user\@.service
+/usr/bin/sed -i -e 's/Type=\(.*\)/Type=forking/' /usr/lib/systemd/system/user\@.service
 /usr/bin/sed -i -e 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper %i/' /usr/lib/systemd/system/user\@.service
-/usr/bin/sed -i -e '/RemainAfterExit=\(.*\)/d' /usr/lib/systemd/system/user\@.service
-echo 'RemainAfterExit=yes' >> /usr/lib/systemd/system/user\@.service
+/usr/bin/sed -i -e '/PIDFile=\(.*\)/d' /usr/lib/systemd/system/user\@.service
+echo 'PIDFile=/run/user/%i/.systemd.pid' >> /usr/lib/systemd/system/user\@.service
 
 %files profile_ivi
 %{_prefix}/lib/udev/rules.d/99-usb-ethernet.rules
index a5e22e0..a61a90d 100644 (file)
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <signal.h>
 #include <errno.h>
+#include <limits.h>
+#include <sys/stat.h>
 
 #include <sched.h>
 #include <sys/mount.h>
 
 #include <tzplatform_config.h>
 
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+#define PIDFILE_PATH ".systemd.pid"
+
 // For compatibility, Using hard-coded path
 #define LEGACY_CONTENTS_DIR "/opt/usr/media"
 #define LEGACY_APPS_DIR "/opt/usr/apps"
@@ -34,7 +40,7 @@
 #define CONTAINER_LIB "/usr/lib/security/pam_krate.so"
 
 #define LOAD_SYMBOL(handle, sym, name) \
-       do{ \
+       do { \
                sym = dlsym(handle, name); \
                if (!sym) { \
                        fprintf(stderr, "dlsym %s error\n", name); \
 
 static void *container_handle = NULL;
 
+static const char *systemd_arg[] = {
+       "/usr/lib/systemd/systemd",
+       "--user",
+       NULL
+};
+
 static int normal_user_preprocess(char *username)
 {
        int r;
        r = unshare(CLONE_NEWNS);
        if (r < 0) {
-               fprintf(stderr,"unshare failed\n");
+               fprintf(stderr, "unshare failed\n");
                return r;
        }
 
        r = mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL);
        if (r < 0) {
-               fprintf(stderr,"Failed to change the propagation type of root to SLAVE\n");
+               fprintf(stderr, "Failed to change the propagation type of root to SLAVE\n");
                return r;
        }
 
@@ -69,14 +81,14 @@ static int normal_user_postprocess(char *username)
        r = mount(tzplatform_getenv(TZ_USER_CONTENT),
                        LEGACY_CONTENTS_DIR, NULL, MS_BIND, NULL);
        if (r < 0) {
-               fprintf(stderr, "user content bind mount failed - %d\n",errno);
+               fprintf(stderr, "user content bind mount failed - %d\n", errno);
                return r;
        }
 
        r = mount(tzplatform_getenv(TZ_USER_APP),
                        LEGACY_APPS_DIR, NULL, MS_BIND, NULL);
        if (r < 0) {
-               fprintf(stderr, "user app bind mount failed - %d\n",errno);
+               fprintf(stderr, "user app bind mount failed - %d\n", errno);
                return r;
        }
 
@@ -143,8 +155,8 @@ static int wait_condition(void)
 
        int (*wait_mount_user)(void);
 
-       r = access(LAZYMOUNT_LIB,F_OK);
-       if (r < 0){
+       r = access(LAZYMOUNT_LIB, F_OK);
+       if (r < 0) {
                fprintf(stderr, "cannot find lazymount module - No support lazymount\n");
                return 0;
        }
@@ -168,6 +180,52 @@ static int wait_condition(void)
        return 0;
 }
 
+static int make_pid_file(int pid, char* user_id)
+{
+       FILE *fp;
+       char pidpath[PATH_MAX];
+       int r = 0;
+
+       snprintf(pidpath, PATH_MAX, "/run/user/%s/%s", user_id, PIDFILE_PATH);
+
+       fp = fopen(pidpath, "w+");
+       if (fp != NULL) {
+               fprintf(fp, "%d", pid);
+               fclose(fp);
+       } else
+               r = -1;
+
+       return r;
+}
+
+int run_child(int argc, const char *argv[], char* user_id)
+{
+       pid_t pid;
+       int r = 0;
+       int i;
+
+       if (!argv)
+               return -EINVAL;
+
+       pid = fork();
+
+       if (pid < 0) {
+               fprintf(stderr, "failed to fork");
+               r = -errno;
+       } else if (pid == 0) {
+               for (i = 0; i < _NSIG; ++i)
+                       signal(i, SIG_DFL);
+
+               r = execv(argv[0], (char **)argv);
+               /* NOT REACH */
+       } else{
+               make_pid_file(pid, user_id);
+               r = pid;
+       }
+
+       return r;
+}
+
 int main(int argc, char *argv[])
 {
        int r = 0;
@@ -195,11 +253,12 @@ int main(int argc, char *argv[])
                }
        }
 
-       /* TODO: fork & exec */
-       r = system("/usr/lib/systemd/systemd --user &");
+       r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, argv[1]);
        if (r < 0) {
                fprintf(stderr, "systemd user execution failed\n");
                return r;
+       } else{
+               fprintf(stderr, "success = pid = %d\n", r);
        }
 
        /* sync-style since there is no need to process other signal */