From: wchang kim Date: Fri, 9 Dec 2016 07:02:55 +0000 (+0900) Subject: Add the directory for system session and user session to share. X-Git-Tag: submit/tizen_3.0/20161212.042035^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4d75e390f11c074529e93b4497c2fdc1320a2c4a;p=platform%2Fadaptation%2Fsystem-plugin.git Add the directory for system session and user session to share. Making the directory of /run/user_ext/. Mounting tmpfs to it with smackfstransmute System::Run. Unmounting directories which systemd_user_helper made when service is stopped. Change-Id: Ia749ba8ec291018c29216c65a0d47ee7ab385dbc Signed-off-by: Woochang Kim --- diff --git a/packaging/system-plugin.spec b/packaging/system-plugin.spec index fe80dd9..ec8a348 100644 --- a/packaging/system-plugin.spec +++ b/packaging/system-plugin.spec @@ -320,9 +320,12 @@ mv %{_sysconfdir}/fstab_lazymnt %{_sysconfdir}/fstab %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=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 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper start %i/' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/ExecStart=\(.*\)/ a ExecStop=\/usr\/bin\/systemd_user_helper stop %i' /usr/lib/systemd/system/user\@.service /usr/bin/sed -i -e '/PIDFile=\(.*\)/d' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/XDG_RUNTIME_DIR/ a Environment=XDG_RUNTIME_EXT_DIR=/run/user_ext/%i' /usr/lib/systemd/system/user\@.service echo 'PIDFile=/run/user/%i/.systemd.pid' >> /usr/lib/systemd/system/user\@.service +echo "d /run/user_ext 0755 root root -" >> /usr/lib/tmpfiles.d/systemd.conf %files profile_ivi %{_prefix}/lib/udev/rules.d/99-usb-ethernet.rules diff --git a/packaging/systemd-user-helper.manifest b/packaging/systemd-user-helper.manifest index 2a0cec5..bcde152 100644 --- a/packaging/systemd-user-helper.manifest +++ b/packaging/systemd-user-helper.manifest @@ -2,4 +2,7 @@ + + + diff --git a/src/systemd-user-helper/systemd-user-helper.c b/src/systemd-user-helper/systemd-user-helper.c index 6ffe977..a8145fa 100644 --- a/src/systemd-user-helper/systemd-user-helper.c +++ b/src/systemd-user-helper/systemd-user-helper.c @@ -29,6 +29,10 @@ #include +#include +#include +#include + #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) #define PIDFILE_PATH ".systemd.pid" @@ -49,6 +53,10 @@ } \ } while (0); +#define MOUNT_SIZE "10000k" +#define MAX_GRP_BUF_SIZE (1024 * 4) +#define GRP_NAME_SYSTEM_SHARE "system_share" + static void *container_handle = NULL; static const char *systemd_arg[] = { @@ -57,9 +65,117 @@ static const char *systemd_arg[] = { NULL }; +int mac_smack_use(void) { + static int cached_use = -1; + + if (cached_use < 0) + cached_use = access("/sys/fs/smackfs/", F_OK) >= 0; + + return cached_use; +} + +static int mount_user_ext(char *username) +{ + char *mount_point = NULL; + char *mount_option = NULL; + uid_t mnt_uid; + gid_t mnt_gid; + struct group *p_grp = NULL, grp_buf; + char buf[MAX_GRP_BUF_SIZE]; + int r; + + mnt_uid = atoi(username); + if(mnt_uid <= 0) + return -1; + + r = asprintf(&mount_point, "/run/user_ext/%s", username); + if (r < 0) { + fprintf(stderr, "Failed to set mount point for user_ext\n"); + return r; + } + + (void) mkdir(mount_point, 0750); + + r = getgrnam_r(GRP_NAME_SYSTEM_SHARE, &grp_buf, buf, sizeof(buf), &p_grp); + if( r == 0 && p_grp != NULL) + { + mnt_gid = p_grp->gr_gid; + } + else + { + free(mount_point); + return -2; + } + + if (mac_smack_use()) + r = asprintf(&mount_option, "mode=0750,smackfstransmute=System::Run,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE); + else + r = asprintf(&mount_option, "mode=0750,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE); + + if (r < 0) { + fprintf(stderr, "Failed to set mount option for user_ext\n"); + free(mount_point); + return r; + } + + r = mount("tmpfs", mount_point, "tmpfs", MS_NODEV|MS_NOSUID|MS_NOEXEC, mount_option); + free(mount_point); + free(mount_option); + + if (r < 0) { + fprintf(stderr, "Failed to mount user_ext\n"); + return r; + } + return 0; +} + +static int umount_user_ext(char *username) +{ + int r; + char *mount_point = NULL; + + r = asprintf(&mount_point, "/run/user_ext/%s", username); + if (r < 0) { + fprintf(stderr, "Failed to set mount point for user_ext\n"); + return r; + } + r = umount2(mount_point, MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Failed to umount user_ext\n"); + free(mount_point); + return r; + } + r = rmdir(mount_point); + if (r < 0) { + fprintf(stderr, "Failed to rmdir user_ext\n"); + free(mount_point); + return r; + } + free(mount_point); + return 0; +} + +static int stop_process(char *username) +{ + int r; + + (void)umount_user_ext(username); + r = umount2(tzplatform_getenv(TZ_USER_CONTENT), MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Warning : Failed to umount user content\n"); + } + + r = umount2(tzplatform_getenv(TZ_USER_APP), MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Warning : Failed to umount application content\n"); + } + return 0; +} + static int normal_user_preprocess(char *username) { int r; + r = unshare(CLONE_NEWNS); if (r < 0) { fprintf(stderr, "unshare failed\n"); @@ -198,6 +314,30 @@ static int make_pid_file(int pid, char* user_id) return r; } +static int change_smack_for_user_session() +{ + FILE *fp; + int r = 0; + + fp = fopen("/proc/self/attr/current", "w"); + + if(fp == NULL) + { + r = -errno; + return r; + } + r = fputs("User", fp); + if(r == EOF) + { + fclose(fp); + r = -errno; + return r; + } + fclose(fp); + + return 0; +} + int run_child(int argc, const char *argv[], char* user_id) { pid_t pid; @@ -230,14 +370,38 @@ int main(int argc, char *argv[]) { int r = 0; int support_container = 0; + char *operation; + char *username; - if (argc < 2) { + if (argc < 3) { fprintf(stderr, "require user argument\n"); return -1; } + operation = argv[1]; + username = argv[2]; + + if (strcmp(operation,"stop") == 0) { + return stop_process(username); + } else if (strcmp(operation, "start") == 0) { + } else { + fprintf(stderr, "option is invalid(%s)\n", operation); + return -2; + } + + r = mount_user_ext(username); + if (r < 0) { + fprintf(stderr, "mount user_ext failed\n"); + return r; + } + r = change_smack_for_user_session(); + if(r != 0) + { + fprintf(stderr, "failed to change smack\n"); + return r; + } /* pre-processing */ - r = normal_user_preprocess(argv[1]); + r = normal_user_preprocess(username); if (r < 0) { fprintf(stderr, "normal user preprocess failed\n"); return r; @@ -246,14 +410,14 @@ int main(int argc, char *argv[]) /* If container supports below funcs, below line should be enabled. */ support_container = (access(CONTAINER_LIB, F_OK) == 0) ? 1 : 0; if (support_container) { - r = container_preprocess(argv[1]); + r = container_preprocess(username); if (r < 0) { fprintf(stderr, "container preprocess failed\n"); return r; } } - r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, argv[1]); + r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, username); if (r < 0) { fprintf(stderr, "systemd user execution failed\n"); return r; @@ -265,14 +429,14 @@ int main(int argc, char *argv[]) wait_condition(); /* post-processing */ - r = normal_user_postprocess(argv[1]); + r = normal_user_postprocess(username); if (r < 0) { fprintf(stderr, "normal user postprocess failed\n"); return r; } if (support_container) { - r = container_postprocess(argv[1]); + r = container_postprocess(username); if (r < 0) { fprintf(stderr, "container postprocess failed\n"); return r;