summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKunhoon Baik <knhoon.baik@samsung.com>2016-11-17 16:26:34 +0900
committerKunhoon Baik <knhoon.baik@samsung.com>2016-11-18 13:32:19 +0900
commit5054878c415b21ba818869394aea9fbe0bcdfdf3 (patch)
treee8fa26fda40d7bc9aca47baff4d8d2c029a4874f
parent863335a0dec22abbc9d2444e9031db15b6822707 (diff)
downloadsystem-plugin-5054878c415b21ba818869394aea9fbe0bcdfdf3.tar.gz
system-plugin-5054878c415b21ba818869394aea9fbe0bcdfdf3.tar.bz2
system-plugin-5054878c415b21ba818869394aea9fbe0bcdfdf3.zip
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
-rw-r--r--packaging/system-plugin.spec7
-rw-r--r--src/systemd-user-helper/systemd-user-helper.c77
2 files changed, 72 insertions, 12 deletions
diff --git a/packaging/system-plugin.spec b/packaging/system-plugin.spec
index 3622003..13684a2 100644
--- a/packaging/system-plugin.spec
+++ b/packaging/system-plugin.spec
@@ -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
diff --git a/src/systemd-user-helper/systemd-user-helper.c b/src/systemd-user-helper/systemd-user-helper.c
index a5e22e0..a61a90d 100644
--- a/src/systemd-user-helper/systemd-user-helper.c
+++ b/src/systemd-user-helper/systemd-user-helper.c
@@ -19,13 +19,19 @@
#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); \
@@ -45,18 +51,24 @@
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 */