chiark / gitweb /
nspawn: introduce the new /machine/ tree in the cgroup tree and move containers there
authorLennart Poettering <lennart@poettering.net>
Tue, 16 Apr 2013 02:36:06 +0000 (04:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 16 Apr 2013 02:41:21 +0000 (04:41 +0200)
Containers will now carry a label (normally derived from the root
directory name, but configurable by the user), and the container's root
cgroup is /machine/<label>. This label is called "machine name", and can
cover both containers and VMs (as soon as libvirt also makes use of
/machine/).

libsystemd-login can be used to query the machine name from a process.

This patch also includes numerous clean-ups for the cgroup code.

20 files changed:
man/sd_pid_get_session.xml
man/systemd-nspawn.xml
src/cgls/cgls.c
src/core/cgroup.c
src/core/dbus-unit.c
src/journal/journald-server.c
src/login/libsystemd-login.sym
src/login/logind-dbus.c
src/login/logind-session.c
src/login/logind.c
src/login/sd-login.c
src/nspawn/nspawn.c
src/shared/cgroup-label.c
src/shared/cgroup-show.c
src/shared/cgroup-util.c
src/shared/cgroup-util.h
src/systemd/sd-login.h
src/test/test-cgroup-util.c
src/test/test-cgroup.c
src/udev/udevd.c

index d2b64195a6eb666f42d7527ae406547dca4ad58c..543a5c0c72d77264d30ad55cf68fb8c7edb1932c 100644 (file)
@@ -47,7 +47,8 @@
                 <refname>sd_pid_get_unit</refname>
                 <refname>sd_pid_get_user_unit</refname>
                 <refname>sd_pid_get_owner_uid</refname>
-                <refpurpose>Determine session, service or owner of a session of a specific PID</refpurpose>
+                <refname>sd_pid_get_machine_name</refname>
+                <refpurpose>Determine session, service, owner of a session or container/VM of a specific PID</refpurpose>
         </refnamediv>
 
         <refsynopsisdiv>
                                 <paramdef>pid_t <parameter>pid</parameter></paramdef>
                                 <paramdef>uid_t* <parameter>uid</parameter></paramdef>
                         </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_pid_get_machine_name</function></funcdef>
+                                <paramdef>pid_t <parameter>pid</parameter></paramdef>
+                                <paramdef>char** <parameter>name</parameter></paramdef>
+                        </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
 
                 function will fail. (More specifically: this call will
                 not work for processes that are part of user units,
                 use <function>sd_pid_get_user_unit()</function> for
-                that.)  The returned string needs to be freed with the
+                that.) The returned string needs to be freed with the
                 libc
                 <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
                 and not being a shared process of a user this function
                 will fail.</para>
 
+                <para><function>sd_pid_machine_name()</function> may
+                be used to determine the name of the VM or container
+                is a member of. The machine name is a short string,
+                suitable for usage in file system paths. The returned
+                string needs to be freed with the libc
+                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
                 <para>If the <literal>pid</literal> parameter of any
                 of these functions is passed as 0 the operation is
                 executed for the calling process.</para>
 
                 <para>The <function>sd_pid_get_session()</function>,
                 <function>sd_pid_get_unit()</function>,
-                <function>sd_pid_get_user_unit()</function>, and
-                <function>sd_pid_get_owner_uid()</function> interfaces
-                are available as shared library, which can be compiled
-                and linked to with the
+                <function>sd_pid_get_user_unit()</function>,
+                <function>sd_pid_get_owner_uid()</function> and
+                <function>sd_pid_get_machine_name()</function>
+                interfaces are available as shared library, which can
+                be compiled and linked to with the
                 <literal>libsystemd-login</literal>
                 <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
index 8adcd946b0438e6da634576eefc780a99ada068a..4d60acb3ee802efac83e7c3df0a3d9b46894860d 100644 (file)
                                 </para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><option>-M</option></term>
+                                <term><option>--machine=</option></term>
+
+                                <listitem><para>Sets the machine name
+                                for this container. This name may be
+                                used to identify this container on the
+                                host, and is used to initialize the
+                                container's hostname (which the
+                                container can choose to override,
+                                however). If not specified the last
+                                component of the root directory of the
+                                container is used.</para></listitem>
+                        </varlistentry>
+
                         <varlistentry>
                                 <term><option>--uuid=</option></term>
 
index e649b75df605b5a53bc3c38d8fa55a83c3a5150c..e01a7b13a139d535ed57356bd1a1e7bc70263ff8 100644 (file)
@@ -171,19 +171,14 @@ int main(int argc, char *argv[]) {
                                                 arg_kernel_threads, output_flags);
                 } else {
                         char _cleanup_free_ *root = NULL;
-                        const char *t = NULL;
 
-                        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root);
-                        if (r < 0)
-                                t = "/";
-                        else {
-                                if (endswith(root, "/system"))
-                                        root[strlen(root)-7] = 0;
-
-                                t = root[0] ? root : "/";
+                        r = cg_get_root_path(&root);
+                        if (r < 0) {
+                                log_error("Failed to get root path: %s", strerror(-r));
+                                goto finish;
                         }
 
-                        r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, t, NULL, 0,
+                        r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0,
                                         arg_kernel_threads, output_flags);
                 }
         }
index a248252bcdb26c1eb12000237410ae200d0587df..83df0f3c9a940130a93a6ae0181b4ac6fc0be8fd 100644 (file)
@@ -320,8 +320,9 @@ int cgroup_bonding_is_empty_list(CGroupBonding *first) {
 
 int manager_setup_cgroup(Manager *m) {
         _cleanup_free_ char *current = NULL, *path = NULL;
+        char suffix_buffer[sizeof("/systemd-") + DECIMAL_STR_MAX(pid_t)];
+        const char *suffix;
         int r;
-        char suffix[sizeof("/systemd-") + DECIMAL_STR_MAX(pid_t)];
 
         assert(m);
 
@@ -332,17 +333,17 @@ int manager_setup_cgroup(Manager *m) {
         }
 
         /* 1. Determine hierarchy */
-        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &current);
+        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &current);
         if (r < 0) {
                 log_error("Cannot determine cgroup we are running in: %s", strerror(-r));
                 return r;
         }
 
         if (m->running_as == SYSTEMD_SYSTEM)
-                strcpy(suffix, "/system");
+                suffix = "/system";
         else {
-                snprintf(suffix, sizeof(suffix), "/systemd-%lu", (unsigned long) getpid());
-                char_array_0(suffix);
+                sprintf(suffix_buffer, "/systemd-%lu", (unsigned long) getpid());
+                suffix = suffix_buffer;
         }
 
         free(m->cgroup_hierarchy);
@@ -350,11 +351,14 @@ int manager_setup_cgroup(Manager *m) {
                 /* We probably got reexecuted and can continue to use our root cgroup */
                 m->cgroup_hierarchy = current;
                 current = NULL;
-
         } else {
                 /* We need a new root cgroup */
-                m->cgroup_hierarchy = NULL;
-                if (asprintf(&m->cgroup_hierarchy, "%s%s", streq(current, "/") ? "" : current, suffix) < 0)
+                if (streq(current, "/"))
+                        m->cgroup_hierarchy = strdup(suffix);
+                else
+                        m->cgroup_hierarchy = strappend(current, suffix);
+
+                if (!m->cgroup_hierarchy)
                         return log_oom();
         }
 
@@ -509,7 +513,7 @@ Unit* cgroup_unit_by_pid(Manager *m, pid_t pid) {
         if (pid <= 1)
                 return NULL;
 
-        if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &group) < 0)
+        if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &group) < 0)
                 return NULL;
 
         l = hashmap_get(m->cgroup_bondings, group);
index 5f1b2afd5b1692def9f9e9e031807e16f6fa20bc..8c1ce61151d5aea69ccda6e13a0cf94546fd3bfd 100644 (file)
@@ -1034,7 +1034,7 @@ int bus_unit_cgroup_unset(Unit *u, DBusMessageIter *iter) {
         unit_remove_drop_in(u, runtime, controller);
 
         /* Try to migrate the old group away */
-        if (cg_get_by_pid(controller, 0, &target) >= 0)
+        if (cg_pid_get_path(controller, 0, &target) >= 0)
                 cgroup_bonding_migrate_to(u->cgroup_bondings, target, false);
 
         cgroup_bonding_free(b, true);
index be84323a6c0623446d68d404688330ed1ec4016c..a540fcb421e5d01d42db3b37c4d8796b95c3ccd0 100644 (file)
@@ -420,36 +420,6 @@ void server_vacuum(Server *s) {
         s->cached_available_space_timestamp = 0;
 }
 
-static char *shortened_cgroup_path(pid_t pid) {
-        int r;
-        char _cleanup_free_ *process_path = NULL, *init_path = NULL;
-        char *path;
-
-        assert(pid > 0);
-
-        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &process_path);
-        if (r < 0)
-                return NULL;
-
-        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &init_path);
-        if (r < 0)
-                return NULL;
-
-        if (endswith(init_path, "/system"))
-                init_path[strlen(init_path) - 7] = 0;
-        else if (streq(init_path, "/"))
-                init_path[0] = 0;
-
-        if (startswith(process_path, init_path)) {
-                path = strdup(process_path + strlen(init_path));
-        } else {
-                path = process_path;
-                process_path = NULL;
-        }
-
-        return path;
-}
-
 bool shall_try_append_again(JournalFile *f, int r) {
 
         /* -E2BIG            Hit configured limit
@@ -620,8 +590,8 @@ static void dispatch_message_real(
                                 IOVEC_SET_STRING(iovec[n++], audit_loginuid);
 #endif
 
-                t = shortened_cgroup_path(ucred->pid);
-                if (t) {
+                r = cg_pid_get_path(NULL, ucred->pid, &t);
+                if (r >= 0) {
                         cgroup = strappend("_SYSTEMD_CGROUP=", t);
                         free(t);
 
@@ -630,7 +600,8 @@ static void dispatch_message_real(
                 }
 
 #ifdef HAVE_LOGIND
-                if (sd_pid_get_session(ucred->pid, &t) >= 0) {
+                r = cg_pid_get_session(ucred->pid, &t);
+                if (r >= 0) {
                         session = strappend("_SYSTEMD_SESSION=", t);
                         free(t);
 
@@ -773,7 +744,7 @@ void server_dispatch_message(
                 const char *unit_id,
                 int priority) {
 
-        int rl;
+        int rl, r;
         char _cleanup_free_ *path = NULL;
         char *c;
 
@@ -789,8 +760,8 @@ void server_dispatch_message(
         if (!ucred)
                 goto finish;
 
-        path = shortened_cgroup_path(ucred->pid);
-        if (!path)
+        r = cg_pid_get_path_shifted(ucred->pid, NULL, &path);
+        if (r < 0)
                 goto finish;
 
         /* example: /user/lennart/3/foobar
index 9048de86a9f26841484d8ca5235ea83f2dc172f9..f4cd2097007b1159704564c13391e20216e98845 100644 (file)
@@ -68,4 +68,5 @@ global:
 LIBSYSTEMD_LOGIN_202 {
 global:
         sd_pid_get_user_unit;
+        sd_pid_get_machine_name;
 } LIBSYSTEMD_LOGIN_201;
index d957bd7de53457ffa7a2d9629f8fb1433f95c4c5..228a8389ee06b410400872e518e992e23577a58a 100644 (file)
@@ -506,7 +506,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
 
         dbus_message_iter_get_basic(&iter, &kill_processes);
 
-        r = cg_pid_get_cgroup(leader, NULL, &cgroup);
+        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, leader, &cgroup);
         if (r < 0)
                 goto fail;
 
index da7ce42015cac814cbf7e22d86ee545ae97dbce8..2f7ab3451fb806c0166f2ea46d97d569b38eab50 100644 (file)
@@ -436,7 +436,6 @@ static int session_create_one_group(Session *s, const char *controller, const ch
         int r;
 
         assert(s);
-        assert(controller);
         assert(path);
 
         if (s->leader > 0) {
index aa3e5f0914d84f9769a2feb868628540f859832f..caed149ad682ebdb9197264753de4cf4cb226f63 100644 (file)
@@ -1100,21 +1100,18 @@ int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
 }
 
 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
-        char *p;
+        _cleanup_free_ char *p = NULL;
         int r;
 
         assert(m);
         assert(pid >= 1);
         assert(session);
 
-        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
+        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
         if (r < 0)
                 return r;
 
-        r = manager_get_session_by_cgroup(m, p, session);
-        free(p);
-
-        return r;
+        return manager_get_session_by_cgroup(m, p, session);
 }
 
 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
index 4c918f2105c7b3525f61b813f1bc57fd7fbb2519..c97d75c000f5883b425b0c321a06da2aa7996c7f 100644 (file)
 #include "fileio.h"
 
 _public_ int sd_pid_get_session(pid_t pid, char **session) {
-        int r;
-        char *cgroup, *p;
-
         if (pid < 0)
                 return -EINVAL;
 
         if (!session)
                 return -EINVAL;
 
-        r = cg_pid_get_cgroup(pid, NULL, &cgroup);
-        if (r < 0)
-                return r;
-
-        if (!startswith(cgroup, "/user/")) {
-                free(cgroup);
-                return -ENOENT;
-        }
-
-        p = strchr(cgroup + 6, '/');
-        if (!p) {
-                free(cgroup);
-                return -ENOENT;
-        }
-
-        p++;
-        if (startswith(p, "shared/") || streq(p, "shared")) {
-                free(cgroup);
-                return -ENOENT;
-        }
-
-        p = strndup(p, strcspn(p, "/"));
-        free(cgroup);
-
-        if (!p)
-                return -ENOMEM;
-
-        *session = p;
-        return 0;
+        return cg_pid_get_session(pid, session);
 }
 
 _public_ int sd_pid_get_unit(pid_t pid, char **unit) {
 
         if (pid < 0)
                 return -EINVAL;
-
         if (!unit)
                 return -EINVAL;
 
@@ -88,13 +56,22 @@ _public_ int sd_pid_get_user_unit(pid_t pid, char **unit) {
 
         if (pid < 0)
                 return -EINVAL;
-
         if (!unit)
                 return -EINVAL;
 
         return cg_pid_get_user_unit(pid, unit);
 }
 
+_public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
+
+        if (pid < 0)
+                return -EINVAL;
+        if (!name)
+                return -EINVAL;
+
+        return cg_pid_get_machine_name(pid, name);
+}
+
 _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
         int r;
         char *root, *cgroup, *p, *cc;
@@ -106,7 +83,7 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
         if (!uid)
                 return -EINVAL;
 
-        r = cg_pid_get_cgroup(pid, &root, &cgroup);
+        r = cg_pid_get_path_shifted(pid, &root, &cgroup);
         if (r < 0)
                 return r;
 
index b90ccc53ef51fae8d4ffaf29cb7ce6463761a789..c25768245179cad1e2a1be819395d8ab4b65d7b5 100644 (file)
@@ -75,6 +75,7 @@ static char *arg_directory = NULL;
 static char *arg_user = NULL;
 static char **arg_controllers = NULL;
 static char *arg_uuid = NULL;
+static char *arg_machine = NULL;
 static bool arg_private_network = false;
 static bool arg_read_only = false;
 static bool arg_boot = false;
@@ -113,13 +114,14 @@ static int help(void) {
         printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
                "Spawn a minimal namespace container for debugging, testing and building.\n\n"
                "  -h --help                Show this help\n"
-               "  --version                Print version string\n"
+               "     --version             Print version string\n"
                "  -D --directory=NAME      Root directory for the container\n"
                "  -b --boot                Boot up full system (i.e. invoke init)\n"
                "  -u --user=USER           Run the command under specified user or uid\n"
                "  -C --controllers=LIST    Put the container in specified comma-separated\n"
                "                           cgroup hierarchies\n"
                "     --uuid=UUID           Set a specific machine UUID for the container\n"
+               "  -M --machine=NAME        Set the machine name for the container\n"
                "     --private-network     Disable network in container\n"
                "     --read-only           Mount the root directory read-only\n"
                "     --capability=CAP      In addition to the default, retain specified\n"
@@ -161,6 +163,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "link-journal",    required_argument, NULL, ARG_LINK_JOURNAL    },
                 { "bind",            required_argument, NULL, ARG_BIND            },
                 { "bind-ro",         required_argument, NULL, ARG_BIND_RO         },
+                { "machine",         required_argument, NULL, 'M'                 },
                 { NULL,              0,                 NULL, 0                   }
         };
 
@@ -194,22 +197,19 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case 'u':
                         free(arg_user);
-                        if (!(arg_user = strdup(optarg))) {
-                                log_error("Failed to duplicate user name.");
-                                return -ENOMEM;
-                        }
+                        arg_user = strdup(optarg);
+                        if (!arg_user)
+                                return log_oom();
 
                         break;
 
                 case 'C':
                         strv_free(arg_controllers);
                         arg_controllers = strv_split(optarg, ",");
-                        if (!arg_controllers) {
-                                log_error("Failed to split controllers list.");
-                                return -ENOMEM;
-                        }
-                        strv_uniq(arg_controllers);
+                        if (!arg_controllers)
+                                return log_oom();
 
+                        cg_shorten_controllers(arg_controllers);
                         break;
 
                 case ARG_PRIVATE_NETWORK:
@@ -224,6 +224,19 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_uuid = optarg;
                         break;
 
+                case 'M':
+                        if (!hostname_is_valid(optarg)) {
+                                log_error("Invalid machine name: %s", optarg);
+                                return -EINVAL;
+                        }
+
+                        free(arg_machine);
+                        arg_machine = strdup(optarg);
+                        if (!arg_machine)
+                                return log_oom();
+
+                        break;
+
                 case ARG_READ_ONLY:
                         arg_read_only = true;
                         break;
@@ -743,25 +756,11 @@ static int setup_kmsg(const char *dest, int kmsg_socket) {
 }
 
 static int setup_hostname(void) {
-        char *hn;
-        int r = 0;
-
-        hn = path_get_file_name(arg_directory);
-        if (hn) {
-                hn = strdup(hn);
-                if (!hn)
-                        return -ENOMEM;
-
-                hostname_cleanup(hn);
 
-                if (!isempty(hn))
-                        if (sethostname(hn, strlen(hn)) < 0)
-                                r = -errno;
-
-                free(hn);
-        }
+        if (sethostname(arg_machine, strlen(arg_machine)) < 0)
+                return -errno;
 
-        return r;
+        return 0;
 }
 
 static int setup_journal(const char *directory) {
@@ -896,6 +895,25 @@ static int setup_journal(const char *directory) {
         return 0;
 }
 
+static int setup_cgroup(const char *path) {
+        char **c;
+        int r;
+
+        r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, path, 1);
+        if (r < 0) {
+                log_error("Failed to create cgroup: %s", strerror(-r));
+                return r;
+        }
+
+        STRV_FOREACH(c, arg_controllers) {
+                r = cg_create_and_attach(*c, path, 1);
+                if (r < 0)
+                        log_warning("Failed to create cgroup in controller %s: %s", *c, strerror(-r));
+        }
+
+        return 0;
+}
+
 static int drop_capabilities(void) {
         return capability_bounding_set_drop(~arg_retain, false);
 }
@@ -1159,9 +1177,9 @@ finish:
 int main(int argc, char *argv[]) {
         pid_t pid = 0;
         int r = EXIT_FAILURE, k;
-        char *oldcg = NULL, *newcg = NULL;
-        char **controller = NULL;
-        int master = -1, n_fd_passed;
+        _cleanup_free_ char *machine_root = NULL, *newcg = NULL;
+        _cleanup_close_ int master = -1;
+        int n_fd_passed;
         const char *console = NULL;
         struct termios saved_attr, raw_attr;
         sigset_t mask;
@@ -1193,6 +1211,20 @@ int main(int argc, char *argv[]) {
 
         path_kill_slashes(arg_directory);
 
+        if (!arg_machine) {
+                arg_machine = strdup(path_get_file_name(arg_directory));
+                if (!arg_machine) {
+                        log_oom();
+                        goto finish;
+                }
+
+                hostname_cleanup(arg_machine);
+                if (isempty(arg_machine)) {
+                        log_error("Failed to determine machine name automatically, please use -M.");
+                        goto finish;
+                }
+        }
+
         if (geteuid() != 0) {
                 log_error("Need to be root.");
                 goto finish;
@@ -1225,27 +1257,26 @@ int main(int argc, char *argv[]) {
         fdset_close_others(fds);
         log_open();
 
-        k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg);
+        k = cg_get_machine_path(&machine_root);
         if (k < 0) {
-                log_error("Failed to determine current cgroup: %s", strerror(-k));
+                log_error("Failed to determine machine cgroup path: %s", strerror(-k));
                 goto finish;
         }
 
-        if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) {
+        newcg = strjoin(machine_root, "/", arg_machine, NULL);
+        if (!newcg) {
                 log_error("Failed to allocate cgroup path.");
                 goto finish;
         }
 
-        k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0);
-        if (k < 0)  {
-                log_error("Failed to create cgroup: %s", strerror(-k));
-                goto finish;
-        }
+        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, newcg, false);
+        if (r <= 0 && r != -ENOENT) {
+                log_error("Container already running.");
 
-        STRV_FOREACH(controller, arg_controllers) {
-                k = cg_create_and_attach(*controller, newcg, 0);
-                if (k < 0)
-                        log_warning("Failed to create cgroup in controller %s: %s", *controller, strerror(-k));
+                free(newcg);
+                newcg = NULL;
+
+                goto finish;
         }
 
         master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
@@ -1279,7 +1310,7 @@ int main(int argc, char *argv[]) {
         }
 
         if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) {
-                log_error("Failed to create kmsg socket pair");
+                log_error("Failed to create kmsg socket pair.");
                 goto finish;
         }
 
@@ -1382,6 +1413,9 @@ int main(int argc, char *argv[]) {
                                 goto child_fail;
                         }
 
+                        if (setup_cgroup(newcg) < 0)
+                                goto child_fail;
+
                         /* Mark everything as slave, so that we still
                          * receive mounts from the real root, but don't
                          * propagate mounts to the real root. */
@@ -1547,7 +1581,7 @@ int main(int argc, char *argv[]) {
                                 }
 
                                 if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) ||
-                                    (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) getpid()) < 0)) {
+                                    (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) 1) < 0)) {
                                         log_oom();
                                         goto child_fail;
                                 }
@@ -1640,21 +1674,14 @@ finish:
         if (saved_attr_valid)
                 tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
 
-        if (master >= 0)
-                close_nointr_nofail(master);
-
         close_pipe(kmsg_socket_pair);
 
-        if (oldcg)
-                cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0);
-
         if (newcg)
                 cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true);
 
         free(arg_directory);
+        free(arg_machine);
         strv_free(arg_controllers);
-        free(oldcg);
-        free(newcg);
 
         fdset_free(fds);
 
index a0b486e51ef8dab8fb83ff09e3eba016a8bc8960..5b5163c250e1b8e60fbba2e9c55715633577a2c7 100644 (file)
@@ -40,9 +40,6 @@ int cg_create(const char *controller, const char *path, const char *suffix) {
         _cleanup_free_ char *fs = NULL;
         int r;
 
-        assert(controller);
-        assert(path);
-
         r = cg_get_path_and_check(controller, path, suffix, &fs);
         if (r < 0)
                 return r;
@@ -65,8 +62,6 @@ int cg_create(const char *controller, const char *path, const char *suffix) {
 int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
         int r, q;
 
-        assert(controller);
-        assert(path);
         assert(pid >= 0);
 
         r = cg_create(controller, path, NULL);
index 966af5e24c5c0ef9b51323273cc0a38c976d5713..9ee532ca22271c3dee9f5d0385668975b7f9d4a5 100644 (file)
@@ -104,20 +104,20 @@ static void show_pid_array(int pids[], unsigned n_pids, const char *prefix, unsi
 
 static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigned n_columns, bool more, bool kernel_threads, OutputFlags flags) {
         char *fn;
-        FILE *f;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t n = 0, n_allocated = 0;
-        pid_t *pids = NULL;
-        char *p;
+        _cleanup_free_ pid_t *pids = NULL;
+        char *p = NULL;
         pid_t pid;
         int r;
 
-        r = cg_fix_path(path, &p);
+        r = cg_mangle_path(path, &p);
         if (r < 0)
                 return r;
 
-        r = asprintf(&fn, "%s/cgroup.procs", p);
+        fn = strappend(p, "/cgroup.procs");
         free(p);
-        if (r < 0)
+        if (!fn)
                 return -ENOMEM;
 
         f = fopen(fn, "re");
@@ -136,10 +136,8 @@ static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigne
                         n_allocated = MAX(16U, n*2U);
 
                         npids = realloc(pids, sizeof(pid_t) * n_allocated);
-                        if (!npids) {
-                                r = -ENOMEM;
-                                goto finish;
-                        }
+                        if (!npids)
+                                return -ENOMEM;
 
                         pids = npids;
                 }
@@ -149,26 +147,18 @@ static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigne
         }
 
         if (r < 0)
-                goto finish;
+                return r;
 
         if (n > 0)
                 show_pid_array(pids, n, prefix, n_columns, false, more, kernel_threads, flags);
 
-        r = 0;
-
-finish:
-        free(pids);
-
-        if (f)
-                fclose(f);
-
-        return r;
+        return 0;
 }
 
 int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, OutputFlags flags) {
-        DIR *d;
-        char *last = NULL;
-        char *p1 = NULL, *p2 = NULL, *fn = NULL, *gn = NULL;
+        _cleanup_free_ char *fn = NULL, *p1 = NULL, *last = NULL, *p2 = NULL;
+        _cleanup_closedir_ DIR *d = NULL;
+        char *gn = NULL;
         bool shown_pids = false;
         int r;
 
@@ -180,30 +170,24 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
         if (!prefix)
                 prefix = "";
 
-        r = cg_fix_path(path, &fn);
+        r = cg_mangle_path(path, &fn);
         if (r < 0)
                 return r;
 
         d = opendir(fn);
-        if (!d) {
-                free(fn);
+        if (!d)
                 return -errno;
-        }
 
         while ((r = cg_read_subgroup(d, &gn)) > 0) {
-                char *k;
+                _cleanup_free_ char *k = NULL;
 
-                r = asprintf(&k, "%s/%s", fn, gn);
+                k = strjoin(fn, "/", gn, NULL);
                 free(gn);
-                if (r < 0) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!k)
+                        return -ENOMEM;
 
-                if (!(flags & OUTPUT_SHOW_ALL) && cg_is_empty_recursive(NULL, k, false) > 0) {
-                        free(k);
+                if (!(flags & OUTPUT_SHOW_ALL) && cg_is_empty_recursive(NULL, k, false) > 0)
                         continue;
-                }
 
                 if (!shown_pids) {
                         show_cgroup_one_by_path(path, prefix, n_columns, true, kernel_threads, flags);
@@ -216,11 +200,8 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
 
                         if (!p1) {
                                 p1 = strappend(prefix, draw_special_char(DRAW_TREE_VERT));
-                                if (!p1) {
-                                        free(k);
-                                        r = -ENOMEM;
-                                        goto finish;
-                                }
+                                if (!p1)
+                                        return -ENOMEM;
                         }
 
                         show_cgroup_by_path(last, p1, n_columns-2, kernel_threads, flags);
@@ -228,10 +209,11 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
                 }
 
                 last = k;
+                k = NULL;
         }
 
         if (r < 0)
-                goto finish;
+                return r;
 
         if (!shown_pids)
                 show_cgroup_one_by_path(path, prefix, n_columns, !!last, kernel_threads, flags);
@@ -242,43 +224,27 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
 
                 if (!p2) {
                         p2 = strappend(prefix, "  ");
-                        if (!p2) {
-                                r = -ENOMEM;
-                                goto finish;
-                        }
+                        if (!p2)
+                                return -ENOMEM;
                 }
 
                 show_cgroup_by_path(last, p2, n_columns-2, kernel_threads, flags);
         }
 
-        r = 0;
-
-finish:
-        free(p1);
-        free(p2);
-        free(last);
-        free(fn);
-
-        closedir(d);
-
-        return r;
+        return 0;
 }
 
 int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, OutputFlags flags) {
-        char *p;
+        _cleanup_free_ char *p = NULL;
         int r;
 
-        assert(controller);
         assert(path);
 
         r = cg_get_path(controller, path, NULL, &p);
         if (r < 0)
                 return r;
 
-        r = show_cgroup_by_path(p, prefix, n_columns, kernel_threads, flags);
-        free(p);
-
-        return r;
+        return show_cgroup_by_path(p, prefix, n_columns, kernel_threads, flags);
 }
 
 static int show_extra_pids(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t pids[], unsigned n_pids, OutputFlags flags) {
@@ -295,8 +261,7 @@ static int show_extra_pids(const char *controller, const char *path, const char
         if (n_columns <= 0)
                 n_columns = columns();
 
-        if (!prefix)
-                prefix = "";
+        prefix = strempty(prefix);
 
         copy = new(pid_t, n_pids);
         if (!copy)
@@ -305,7 +270,7 @@ static int show_extra_pids(const char *controller, const char *path, const char
         for (i = 0, j = 0; i < n_pids; i++) {
                 char _cleanup_free_ *k = NULL;
 
-                r = cg_get_by_pid(controller, pids[i], &k);
+                r = cg_pid_get_path(controller, pids[i], &k);
                 if (r < 0)
                         return r;
 
@@ -323,7 +288,6 @@ static int show_extra_pids(const char *controller, const char *path, const char
 int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags) {
         int r;
 
-        assert(controller);
         assert(path);
 
         r = show_cgroup(controller, path, prefix, n_columns, kernel_threads, flags);
@@ -334,8 +298,8 @@ int show_cgroup_and_extra(const char *controller, const char *path, const char *
 }
 
 int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, bool kernel_threads, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags) {
-        int r;
         _cleanup_free_ char *controller = NULL, *path = NULL;
+        int r;
 
         assert(spec);
 
index 075260783cb001fca0753fc3cdd302d1f6e2f070..0749b6115427f781df37fed6b6c9c88b89c38465 100644 (file)
 #include "fileio.h"
 
 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
-        char *fs;
-        int r;
+        _cleanup_free_ char *fs = NULL;
         FILE *f;
+        int r;
 
-        assert(path);
         assert(_f);
 
         r = cg_get_path(controller, path, "cgroup.procs", &fs);
@@ -52,8 +51,6 @@ int cg_enumerate_processes(const char *controller, const char *path, FILE **_f)
                 return r;
 
         f = fopen(fs, "re");
-        free(fs);
-
         if (!f)
                 return -errno;
 
@@ -62,11 +59,10 @@ int cg_enumerate_processes(const char *controller, const char *path, FILE **_f)
 }
 
 int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) {
-        char *fs;
-        int r;
+        _cleanup_free_ char *fs = NULL;
         FILE *f;
+        int r;
 
-        assert(path);
         assert(_f);
 
         r = cg_get_path(controller, path, "tasks", &fs);
@@ -74,8 +70,6 @@ int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) {
                 return r;
 
         f = fopen(fs, "re");
-        free(fs);
-
         if (!f)
                 return -errno;
 
@@ -89,6 +83,9 @@ int cg_read_pid(FILE *f, pid_t *_pid) {
         /* Note that the cgroup.procs might contain duplicates! See
          * cgroups.txt for details. */
 
+        assert(f);
+        assert(_pid);
+
         errno = 0;
         if (fscanf(f, "%lu", &ul) != 1) {
 
@@ -106,11 +103,10 @@ int cg_read_pid(FILE *f, pid_t *_pid) {
 }
 
 int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
-        char *fs;
+        _cleanup_free_ char *fs = NULL;
         int r;
         DIR *d;
 
-        assert(path);
         assert(_d);
 
         /* This is not recursive! */
@@ -120,8 +116,6 @@ int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
                 return r;
 
         d = opendir(fs);
-        free(fs);
-
         if (!d)
                 return -errno;
 
@@ -133,9 +127,9 @@ int cg_read_subgroup(DIR *d, char **fn) {
         struct dirent *de;
 
         assert(d);
+        assert(fn);
 
-        errno = 0;
-        while ((de = readdir(d))) {
+        FOREACH_DIRENT(de, d, return -errno) {
                 char *b;
 
                 if (de->d_type != DT_DIR)
@@ -145,21 +139,19 @@ int cg_read_subgroup(DIR *d, char **fn) {
                     streq(de->d_name, ".."))
                         continue;
 
-                if (!(b = strdup(de->d_name)))
+                b = strdup(de->d_name);
+                if (!b)
                         return -ENOMEM;
 
                 *fn = b;
                 return 1;
         }
 
-        if (errno)
-                return -errno;
-
         return 0;
 }
 
 int cg_rmdir(const char *controller, const char *path, bool honour_sticky) {
-        char *p;
+        _cleanup_free_ char *p = NULL;
         int r;
 
         r = cg_get_path(controller, path, NULL, &p);
@@ -172,61 +164,59 @@ int cg_rmdir(const char *controller, const char *path, bool honour_sticky) {
                 /* If the sticky bit is set don't remove the directory */
 
                 tasks = strappend(p, "/tasks");
-                if (!tasks) {
-                        free(p);
+                if (!tasks)
                         return -ENOMEM;
-                }
 
                 r = file_is_priv_sticky(tasks);
                 free(tasks);
 
-                if (r > 0) {
-                        free(p);
+                if (r > 0)
                         return 0;
-                }
         }
 
         r = rmdir(p);
-        free(p);
+        if (r < 0 && errno != ENOENT)
+                return -errno;
 
-        return (r < 0 && errno != ENOENT) ? -errno : 0;
+        return 0;
 }
 
 int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
+        _cleanup_set_free_ Set *allocated_set = NULL;
         bool done = false;
         int r, ret = 0;
         pid_t my_pid;
-        FILE *f = NULL;
-        Set *allocated_set = NULL;
 
-        assert(controller);
-        assert(path);
         assert(sig >= 0);
 
         /* This goes through the tasks list and kills them all. This
          * is repeated until no further processes are added to the
          * tasks list, to properly handle forking processes */
 
-        if (!s)
-                if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+        if (!s) {
+                s = allocated_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!s)
                         return -ENOMEM;
+        }
 
         my_pid = getpid();
 
         do {
+                _cleanup_fclose_ FILE *f = NULL;
                 pid_t pid = 0;
                 done = true;
 
-                if ((r = cg_enumerate_processes(controller, path, &f)) < 0) {
+                r = cg_enumerate_processes(controller, path, &f);
+                if (r < 0) {
                         if (ret >= 0 && r != -ENOENT)
-                                ret = r;
+                                return r;
 
-                        goto finish;
+                        return ret;
                 }
 
                 while ((r = cg_read_pid(f, &pid)) > 0) {
 
-                        if (pid == my_pid && ignore_self)
+                        if (ignore_self && pid == my_pid)
                                 continue;
 
                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
@@ -247,100 +237,77 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo
 
                         done = false;
 
-                        if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) {
+                        r = set_put(s, LONG_TO_PTR(pid));
+                        if (r < 0) {
                                 if (ret >= 0)
-                                        ret = r;
+                                        return r;
 
-                                goto finish;
+                                return ret;
                         }
                 }
 
                 if (r < 0) {
                         if (ret >= 0)
-                                ret = r;
+                                return r;
 
-                        goto finish;
+                        return ret;
                 }
 
-                fclose(f);
-                f = NULL;
-
                 /* To avoid racing against processes which fork
                  * quicker than we can kill them we repeat this until
                  * no new pids need to be killed. */
 
         } while (!done);
 
-finish:
-        if (allocated_set)
-                set_free(allocated_set);
-
-        if (f)
-                fclose(f);
-
         return ret;
 }
 
 int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) {
+        _cleanup_set_free_ Set *allocated_set = NULL;
+        _cleanup_closedir_ DIR *d = NULL;
         int r, ret = 0;
-        DIR *d = NULL;
         char *fn;
-        Set *allocated_set = NULL;
 
         assert(path);
-        assert(controller);
         assert(sig >= 0);
 
-        if (!s)
-                if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
+        if (!s) {
+                s = allocated_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!s)
                         return -ENOMEM;
+        }
 
         ret = cg_kill(controller, path, sig, sigcont, ignore_self, s);
 
-        if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) {
+        r = cg_enumerate_subgroups(controller, path, &d);
+        if (r < 0) {
                 if (ret >= 0 && r != -ENOENT)
-                        ret = r;
+                        return r;
 
-                goto finish;
+                return ret;
         }
 
         while ((r = cg_read_subgroup(d, &fn)) > 0) {
-                char *p = NULL;
+                _cleanup_free_ char *p = NULL;
 
-                r = asprintf(&p, "%s/%s", path, fn);
+                p = strjoin(path, "/", fn, NULL);
                 free(fn);
-
-                if (r < 0) {
-                        if (ret >= 0)
-                                ret = -ENOMEM;
-
-                        goto finish;
-                }
+                if (!p)
+                        return -ENOMEM;
 
                 r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s);
-                free(p);
-
-                if (r != 0 && ret >= 0)
+                if (ret >= 0 && r != 0)
                         ret = r;
         }
 
-        if (r < 0 && ret >= 0)
+        if (ret >= 0 && r < 0)
                 ret = r;
 
-        if (rem)
-                if ((r = cg_rmdir(controller, path, true)) < 0) {
-                        if (ret >= 0 &&
-                            r != -ENOENT &&
-                            r != -EBUSY)
-                                ret = r;
-                }
-
-finish:
-        if (d)
-                closedir(d);
-
-        if (allocated_set)
-                set_free(allocated_set);
+        if (rem) {
+                r = cg_rmdir(controller, path, true);
+                if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
+                        return r;
+        }
 
         return ret;
 }
@@ -349,7 +316,6 @@ int cg_kill_recursive_and_wait(const char *controller, const char *path, bool re
         unsigned i;
 
         assert(path);
-        assert(controller);
 
         /* This safely kills all processes; first it sends a SIGTERM,
          * then checks 8 times after 200ms whether the group is now
@@ -367,7 +333,8 @@ int cg_kill_recursive_and_wait(const char *controller, const char *path, bool re
                 else
                         sig = 0;
 
-                if ((r = cg_kill_recursive(controller, path, sig, true, true, rem, NULL)) <= 0)
+                r = cg_kill_recursive(controller, path, sig, true, true, rem, NULL);
+                if (r <= 0)
                         return r;
 
                 usleep(200 * USEC_PER_MSEC);
@@ -381,7 +348,6 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char
         _cleanup_set_free_ Set *s = NULL;
         int r, ret = 0;
         pid_t my_pid;
-        _cleanup_fclose_ FILE *f = NULL;
 
         assert(cfrom);
         assert(pfrom);
@@ -395,13 +361,14 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char
         my_pid = getpid();
 
         do {
+                _cleanup_fclose_ FILE *f = NULL;
                 pid_t pid = 0;
                 done = true;
 
                 r = cg_enumerate_tasks(cfrom, pfrom, &f);
                 if (r < 0) {
                         if (ret >= 0 && r != -ENOENT)
-                                ret = r;
+                                return r;
 
                         return ret;
                 }
@@ -411,7 +378,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char
                         /* This might do weird stuff if we aren't a
                          * single-threaded program. However, we
                          * luckily know we are not */
-                        if (pid == my_pid && ignore_self)
+                        if (ignore_self && pid == my_pid)
                                 continue;
 
                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
@@ -429,7 +396,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char
                         r = set_put(s, LONG_TO_PTR(pid));
                         if (r < 0) {
                                 if (ret >= 0)
-                                        ret = r;
+                                        return r;
 
                                 return ret;
                         }
@@ -437,21 +404,18 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char
 
                 if (r < 0) {
                         if (ret >= 0)
-                                ret = r;
+                                return r;
 
                         return ret;
                 }
-
-                fclose(f);
-                f = NULL;
         } while (!done);
 
         return ret;
 }
 
 int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem) {
-        int r, ret = 0;
         _cleanup_closedir_ DIR *d = NULL;
+        int r, ret = 0;
         char *fn;
 
         assert(cfrom);
@@ -464,7 +428,8 @@ int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto,
         r = cg_enumerate_subgroups(cfrom, pfrom, &d);
         if (r < 0) {
                 if (ret >= 0 && r != -ENOENT)
-                        ret = r;
+                        return r;
+
                 return ret;
         }
 
@@ -475,7 +440,7 @@ int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto,
                 free(fn);
                 if (!p) {
                         if (ret >= 0)
-                                ret = -ENOMEM;
+                                return -ENOMEM;
 
                         return ret;
                 }
@@ -499,6 +464,8 @@ int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto,
 
 static const char *normalize_controller(const char *controller) {
 
+        assert(controller);
+
         if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
                 return "systemd";
         else if (startswith(controller, "name="))
@@ -510,9 +477,6 @@ static const char *normalize_controller(const char *controller) {
 static int join_path(const char *controller, const char *path, const char *suffix, char **fs) {
         char *t = NULL;
 
-        if (!(controller || path))
-                return -EINVAL;
-
         if (controller) {
                 if (path && suffix)
                         t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL);
@@ -521,12 +485,14 @@ static int join_path(const char *controller, const char *path, const char *suffi
                 else if (suffix)
                         t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL);
                 else
-                        t = strjoin("/sys/fs/cgroup/", controller, NULL);
+                        t = strappend("/sys/fs/cgroup/", controller);
         } else {
                 if (path && suffix)
                         t = strjoin(path, "/", suffix, NULL);
                 else if (path)
                         t = strdup(path);
+                else
+                        return -EINVAL;
         }
 
         if (!t)
@@ -556,10 +522,11 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
         }
 
         p = controller ? normalize_controller(controller) : NULL;
+
         return join_path(p, path, suffix, fs);
 }
 
-static int check(const char *p) {
+static int check_hierarchy(const char *p) {
         char *cc;
 
         assert(p);
@@ -577,7 +544,6 @@ int cg_get_path_and_check(const char *controller, const char *path, const char *
         const char *p;
         int r;
 
-        assert(controller);
         assert(fs);
 
         if (isempty(controller))
@@ -587,7 +553,7 @@ int cg_get_path_and_check(const char *controller, const char *path, const char *
         p = normalize_controller(controller);
 
         /* Check if this controller actually really exists */
-        r = check(p);
+        r = check_hierarchy(p);
         if (r < 0)
                 return r;
 
@@ -621,10 +587,9 @@ static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct
 }
 
 int cg_trim(const char *controller, const char *path, bool delete_root) {
-        char *fs;
+        _cleanup_free_ char *fs = NULL;
         int r = 0;
 
-        assert(controller);
         assert(path);
 
         r = cg_get_path(controller, path, NULL, &fs);
@@ -632,7 +597,7 @@ int cg_trim(const char *controller, const char *path, bool delete_root) {
                 return r;
 
         errno = 0;
-        if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
+        if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) != 0)
                 r = errno ? -errno : -EIO;
 
         if (delete_root) {
@@ -640,39 +605,31 @@ int cg_trim(const char *controller, const char *path, bool delete_root) {
                 char *p;
 
                 p = strappend(fs, "/tasks");
-                if (!p) {
-                        free(fs);
+                if (!p)
                         return -ENOMEM;
-                }
 
                 is_sticky = file_is_priv_sticky(p) > 0;
                 free(p);
 
                 if (!is_sticky)
-                        if (rmdir(fs) < 0 && errno != ENOENT) {
-                                if (r == 0)
-                                        r = -errno;
-                        }
+                        if (rmdir(fs) < 0 && errno != ENOENT && r == 0)
+                                return -errno;
         }
 
-        free(fs);
-
         return r;
 }
 
 int cg_delete(const char *controller, const char *path) {
-        char *parent;
+        _cleanup_free_ char *parent = NULL;
         int r;
 
-        assert(controller);
         assert(path);
 
-        if ((r = path_get_parent(path, &parent)) < 0)
+        r = path_get_parent(path, &parent);
+        if (r < 0)
                 return r;
 
         r = cg_migrate_recursive(controller, path, controller, parent, false, true);
-        free(parent);
-
         return r == -ENOENT ? 0 : r;
 }
 
@@ -681,7 +638,6 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
         char c[DECIMAL_STR_MAX(pid_t) + 2];
         int r;
 
-        assert(controller);
         assert(path);
         assert(pid >= 0);
 
@@ -707,7 +663,6 @@ int cg_set_group_access(
         _cleanup_free_ char *fs = NULL;
         int r;
 
-        assert(controller);
         assert(path);
 
         if (mode != (mode_t) -1)
@@ -731,7 +686,6 @@ int cg_set_task_access(
         _cleanup_free_ char *fs = NULL, *procs = NULL;
         int r;
 
-        assert(controller);
         assert(path);
 
         if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1 && sticky < 0)
@@ -778,47 +732,35 @@ int cg_set_task_access(
         return chmod_and_chown(procs, mode, uid, gid);
 }
 
-int cg_get_by_pid(const char *controller, pid_t pid, char **path) {
-        int r;
-        char *p = NULL;
-        FILE *f;
-        char *fs;
+int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
+        char fs[sizeof("/proc/") - 1 + DECIMAL_STR_MAX(pid_t) + sizeof("/cgroup")];
+        _cleanup_fclose_ FILE *f = NULL;
+        char line[LINE_MAX];
         size_t cs;
 
-        assert(controller);
         assert(path);
         assert(pid >= 0);
 
+        if (!controller)
+                controller = SYSTEMD_CGROUP_CONTROLLER;
+
         if (pid == 0)
                 pid = getpid();
 
-        if (asprintf(&fs, "/proc/%lu/cgroup", (unsigned long) pid) < 0)
-                return -ENOMEM;
-
+        sprintf(fs, "/proc/%lu/cgroup", (unsigned long) pid);
         f = fopen(fs, "re");
-        free(fs);
-
         if (!f)
                 return errno == ENOENT ? -ESRCH : -errno;
 
         cs = strlen(controller);
 
-        while (!feof(f)) {
-                char line[LINE_MAX];
-                char *l;
-
-                errno = 0;
-                if (!(fgets(line, sizeof(line), f))) {
-                        if (feof(f))
-                                break;
-
-                        r = errno ? -errno : -EIO;
-                        goto finish;
-                }
+        FOREACH_LINE(line, f, return -errno) {
+                char *l, *p;
 
                 truncate_nl(line);
 
-                if (!(l = strchr(line, ':')))
+                l = strchr(line, ':');
+                if (!l)
                         continue;
 
                 l++;
@@ -828,90 +770,72 @@ int cg_get_by_pid(const char *controller, pid_t pid, char **path) {
                 if (l[cs] != ':')
                         continue;
 
-                if (!(p = strdup(l + cs + 1))) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                p = strdup(l + cs + 1);
+                if (!p)
+                        return -ENOMEM;
 
                 *path = p;
-                r = 0;
-                goto finish;
+                return 0;
         }
 
-        r = -ENOENT;
-
-finish:
-        fclose(f);
-
-        return r;
+        return -ENOENT;
 }
 
 int cg_install_release_agent(const char *controller, const char *agent) {
-        char *fs = NULL, *contents = NULL, *line = NULL, *sc;
+        _cleanup_free_ char *fs = NULL, *contents = NULL;
+        char *sc;
         int r;
 
-        assert(controller);
         assert(agent);
 
-        if ((r = cg_get_path(controller, NULL, "release_agent", &fs)) < 0)
+        r = cg_get_path(controller, NULL, "release_agent", &fs);
+        if (r < 0)
                 return r;
 
-        if ((r = read_one_line_file(fs, &contents)) < 0)
-                goto finish;
+        r = read_one_line_file(fs, &contents);
+        if (r < 0)
+                return r;
 
         sc = strstrip(contents);
         if (sc[0] == 0) {
-
-                if (asprintf(&line, "%s\n", agent) < 0) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
-
-                r = write_string_file(fs, line);
+                r = write_string_file(fs, agent);
                 if (r < 0)
-                        goto finish;
-
-        } else if (!streq(sc, agent)) {
-                r = -EEXIST;
-                goto finish;
-        }
+                        return r;
+        } else if (!streq(sc, agent))
+                return -EEXIST;
 
         free(fs);
         fs = NULL;
-        if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0)
-                goto finish;
+        r = cg_get_path(controller, NULL, "notify_on_release", &fs);
+        if (r < 0)
+                return r;
 
         free(contents);
         contents = NULL;
-        if ((r = read_one_line_file(fs, &contents)) < 0)
-                goto finish;
+        r = read_one_line_file(fs, &contents);
+        if (r < 0)
+                return r;
 
         sc = strstrip(contents);
-
         if (streq(sc, "0")) {
-                if ((r = write_string_file(fs, "1\n")) < 0)
-                        goto finish;
+                r = write_string_file(fs, "1");
+                if (r < 0)
+                        return r;
 
-                r = 1;
-        } else if (!streq(sc, "1")) {
-                r = -EIO;
-                goto finish;
-        } else
-                r = 0;
+                return 1;
+        }
 
-finish:
-        free(fs);
-        free(contents);
-        free(line);
+        if (!streq(sc, "1"))
+                return -EIO;
 
-        return r;
+        return 0;
 }
 
 int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
+        _cleanup_fclose_ FILE *f = NULL;
         pid_t pid = 0, self_pid;
-        int r;
-        FILE *f = NULL;
         bool found = false;
+        int r;
 
         assert(path);
 
@@ -930,8 +854,6 @@ int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
                 break;
         }
 
-        fclose(f);
-
         if (r < 0)
                 return r;
 
@@ -939,8 +861,8 @@ int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
 }
 
 int cg_is_empty_by_spec(const char *spec, bool ignore_self) {
-        int r;
         _cleanup_free_ char *controller = NULL, *path = NULL;
+        int r;
 
         assert(spec);
 
@@ -952,9 +874,9 @@ int cg_is_empty_by_spec(const char *spec, bool ignore_self) {
 }
 
 int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) {
-        int r;
-        DIR *d = NULL;
+        _cleanup_closedir_ DIR *d = NULL;
         char *fn;
+        int r;
 
         assert(path);
 
@@ -967,32 +889,22 @@ int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_
                 return r == -ENOENT ? 1 : r;
 
         while ((r = cg_read_subgroup(d, &fn)) > 0) {
-                char *p = NULL;
+                _cleanup_free_ char *p = NULL;
 
-                r = asprintf(&p, "%s/%s", path, fn);
+                p = strjoin(path, "/", fn, NULL);
                 free(fn);
-
-                if (r < 0) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!p)
+                        return -ENOMEM;
 
                 r = cg_is_empty_recursive(controller, p, ignore_self);
-                free(p);
-
                 if (r <= 0)
-                        goto finish;
+                        return r;
         }
 
-        if (r >= 0)
-                r = 1;
-
-finish:
-
-        if (d)
-                closedir(d);
+        if (r < 0)
+                return r;
 
-        return r;
+        return 1;
 }
 
 int cg_split_spec(const char *spec, char **controller, char **path) {
@@ -1071,22 +983,31 @@ int cg_split_spec(const char *spec, char **controller, char **path) {
 }
 
 int cg_join_spec(const char *controller, const char *path, char **spec) {
-        assert(controller);
+        char *s;
+
         assert(path);
 
-        if (!path_is_absolute(path) ||
-            controller[0] == 0 ||
-            strchr(controller, ':') ||
-            strchr(controller, '/'))
+        if (!controller)
+                controller = "systemd";
+        else if (controller[0] == 0 ||
+                 strchr(controller, ':') ||
+                 strchr(controller, '/'))
                 return -EINVAL;
 
-        if (asprintf(spec, "%s:%s", controller, path) < 0)
+        if (!path_is_absolute(path))
+                return -EINVAL;
+
+        controller = normalize_controller(controller);
+
+        s = strjoin(controller, ":", path, NULL);
+        if (!s)
                 return -ENOMEM;
 
+        *spec = s;
         return 0;
 }
 
-int cg_fix_path(const char *path, char **result) {
+int cg_mangle_path(const char *path, char **result) {
         char *t, *c, *p;
         int r;
 
@@ -1094,8 +1015,7 @@ int cg_fix_path(const char *path, char **result) {
         assert(result);
 
         /* First check if it already is a filesystem path */
-        if (path_startswith(path, "/sys/fs/cgroup") &&
-            access(path, F_OK) >= 0) {
+        if (path_startswith(path, "/sys/fs/cgroup")) {
 
                 t = strdup(path);
                 if (!t)
@@ -1117,8 +1037,58 @@ int cg_fix_path(const char *path, char **result) {
         return r;
 }
 
+int cg_get_system_path(char **path) {
+        char *p;
+        int r;
+
+        assert(path);
+
+        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p);
+        if (r < 0) {
+                p = strdup("/system");
+                if (!p)
+                        return -ENOMEM;
+        }
+
+        if (endswith(p, "/system"))
+                *path = p;
+        else {
+                char *q;
+
+                q = strappend(p, "/system");
+                free(p);
+                if (!q)
+                        return -ENOMEM;
+
+                *path = q;
+        }
+
+        return 0;
+}
+
+int cg_get_root_path(char **path) {
+        char *root, *e;
+        int r;
+
+        assert(path);
+
+        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &root);
+        if (r < 0)
+                return r;
+
+        e = endswith(root, "/system");
+        if (e == root)
+                e[1] = 0;
+        else if (e)
+                *e = 0;
+
+        *path = root;
+        return 0;
+}
+
 int cg_get_user_path(char **path) {
-        char *root, *p;
+        _cleanup_free_ char *root = NULL;
+        char *p;
 
         assert(path);
 
@@ -1126,17 +1096,28 @@ int cg_get_user_path(char **path) {
          * same as PID 1 has but with the "/system" suffix replaced by
          * "/user" */
 
-        if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root) < 0)
+        if (cg_get_root_path(&root) < 0 || streq(root, "/"))
                 p = strdup("/user");
-        else {
-                if (endswith(root, "/system"))
-                        root[strlen(root) - 7] = 0;
-                else if (streq(root, "/"))
-                        root[0] = 0;
-
+        else
                 p = strappend(root, "/user");
-                free(root);
-        }
+
+        if (!p)
+                return -ENOMEM;
+
+        *path = p;
+        return 0;
+}
+
+int cg_get_machine_path(char **path) {
+        _cleanup_free_ char *root = NULL;
+        char *p;
+
+        assert(path);
+
+        if (cg_get_root_path(&root) < 0 || streq(root, "/"))
+                p = strdup("/machine");
+        else
+                p = strappend(root, "/machine");
 
         if (!p)
                 return -ENOMEM;
@@ -1152,17 +1133,17 @@ char **cg_shorten_controllers(char **controllers) {
                 return controllers;
 
         for (f = controllers, t = controllers; *f; f++) {
-                int r;
                 const char *p;
+                int r;
+
+                p = normalize_controller(*f);
 
-                if (streq(*f, "systemd") || streq(*f, SYSTEMD_CGROUP_CONTROLLER)) {
+                if (streq(*f, "systemd")) {
                         free(*f);
                         continue;
                 }
 
-                p = normalize_controller(*f);
-
-                r = check(p);
+                r = check_hierarchy(p);
                 if (r < 0) {
                         log_debug("Controller %s is not available, removing from controllers list.", *f);
                         free(*f);
@@ -1176,33 +1157,24 @@ char **cg_shorten_controllers(char **controllers) {
         return strv_uniq(controllers);
 }
 
-int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
-        char *cg_process, *cg_init, *p, *q;
+int cg_pid_get_path_shifted(pid_t pid, char **root, char **cgroup) {
+        _cleanup_free_ char *cg_root = NULL;
+        char *cg_process, *p;
         int r;
 
-        assert(pid >= 0);
-
-        if (pid == 0)
-                pid = getpid();
-
-        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process);
+        r = cg_get_root_path(&cg_root);
         if (r < 0)
                 return r;
 
-        r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &cg_init);
-        if (r < 0) {
-                free(cg_process);
+        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process);
+        if (r < 0)
                 return r;
-        }
-
-        if (endswith(cg_init, "/system"))
-                cg_init[strlen(cg_init)-7] = 0;
-        else if (streq(cg_init, "/"))
-                cg_init[0] = 0;
 
-        q = startswith(cg_process, cg_init);
-        p = q ? q : cg_process;
-        free(cg_init);
+        p = path_startswith(cg_process, cg_root);
+        if (p)
+                p--;
+        else
+                p = cg_process;
 
         if (cgroup) {
                 char* c;
@@ -1226,7 +1198,7 @@ int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
 }
 
 /* non-static only for testing purposes */
-int cg_cgroup_to_unit(const char *cgroup, char **unit){
+int cg_path_decode_unit(const char *cgroup, char **unit){
         char *p, *e, *c, *s, *k;
 
         assert(cgroup);
@@ -1274,7 +1246,7 @@ int cg_path_get_unit(const char *path, char **unit) {
         if (!e)
                 return -ENOENT;
 
-        return cg_cgroup_to_unit(e, unit);
+        return cg_path_decode_unit(e, unit);
 }
 
 int cg_pid_get_unit(pid_t pid, char **unit) {
@@ -1283,7 +1255,7 @@ int cg_pid_get_unit(pid_t pid, char **unit) {
 
         assert(unit);
 
-        r = cg_pid_get_cgroup(pid, NULL, &cgroup);
+        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
         if (r < 0)
                 return r;
 
@@ -1293,7 +1265,6 @@ int cg_pid_get_unit(pid_t pid, char **unit) {
 static const char *skip_label(const char *e) {
         assert(e);
 
-        e += strspn(e, "/");
         e = strchr(e, '/');
         if (!e)
                 return NULL;
@@ -1331,7 +1302,7 @@ int cg_path_get_user_unit(const char *path, char **unit) {
         if (!e)
                 return -ENOENT;
 
-        return cg_cgroup_to_unit(e, unit);
+        return cg_path_decode_unit(e, unit);
 }
 
 int cg_pid_get_user_unit(pid_t pid, char **unit) {
@@ -1340,13 +1311,93 @@ int cg_pid_get_user_unit(pid_t pid, char **unit) {
 
         assert(unit);
 
-        r = cg_pid_get_cgroup(pid, NULL, &cgroup);
+        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
         if (r < 0)
                 return r;
 
         return cg_path_get_user_unit(cgroup, unit);
 }
 
+int cg_path_get_machine_name(const char *path, char **machine) {
+        const char *e, *n;
+        char *s;
+
+        assert(path);
+        assert(machine);
+
+        e = path_startswith(path, "/machine/");
+        if (!e)
+                return -ENOENT;
+
+        n = strchrnul(e, '/');
+        if (e == n)
+                return -ENOENT;
+
+        s = strndup(e, n - e);
+        if (!s)
+                return -ENOMEM;
+
+        *machine = s;
+        return 0;
+}
+
+int cg_pid_get_machine_name(pid_t pid, char **machine) {
+        char _cleanup_free_ *cgroup = NULL;
+        int r;
+
+        assert(machine);
+
+        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
+        if (r < 0)
+                return r;
+
+        return cg_path_get_machine_name(cgroup, machine);
+}
+
+int cg_path_get_session(const char *path, char **session) {
+        const char *e, *n;
+        char *s;
+
+        assert(path);
+        assert(session);
+
+        e = path_startswith(path, "/user/");
+        if (!e)
+                return -ENOENT;
+
+        /* Skip the user name */
+        e = skip_label(e);
+        if (!e)
+                return -ENOENT;
+
+        n = strchrnul(e, '/');
+        if (e == n)
+                return -ENOENT;
+
+        if (n - e == 6 && memcmp(e, "shared", 6) == 0)
+                return -ENOENT;
+
+        s = strndup(e, n - e);
+        if (!s)
+                return -ENOMEM;
+
+        *session = s;
+        return 0;
+}
+
+int cg_pid_get_session(pid_t pid, char **session) {
+        char _cleanup_free_ *cgroup = NULL;
+        int r;
+
+        assert(session);
+
+        r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
+        if (r < 0)
+                return r;
+
+        return cg_path_get_session(cgroup, session);
+}
+
 int cg_controller_from_attr(const char *attr, char **controller) {
         const char *dot;
         char *c;
index 274380aa2df54c284ea4a75653f9662a0eab8fbc..5457d1bcaa151161dee4eb4c907245fb1dfe780d 100644 (file)
@@ -44,11 +44,12 @@ int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto,
 
 int cg_split_spec(const char *spec, char **controller, char **path);
 int cg_join_spec(const char *controller, const char *path, char **spec);
-int cg_fix_path(const char *path, char **result);
+int cg_mangle_path(const char *path, char **result);
 
 int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs);
 int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs);
-int cg_get_by_pid(const char *controller, pid_t pid, char **path);
+
+int cg_pid_get_path(const char *controller, pid_t pid, char **path);
 
 int cg_trim(const char *controller, const char *path, bool delete_root);
 
@@ -68,16 +69,24 @@ int cg_is_empty(const char *controller, const char *path, bool ignore_self);
 int cg_is_empty_by_spec(const char *spec, bool ignore_self);
 int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self);
 
+int cg_get_root_path(char **path);
+int cg_get_system_path(char **path);
 int cg_get_user_path(char **path);
+int cg_get_machine_path(char **path);
 
+int cg_path_get_session(const char *path, char **session);
 int cg_path_get_unit(const char *path, char **unit);
 int cg_path_get_user_unit(const char *path, char **unit);
+int cg_path_get_machine_name(const char *path, char **machine);
+
+int cg_pid_get_path_shifted(pid_t pid, char **root, char **cgroup);
 
-int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup);
+int cg_pid_get_session(pid_t pid, char **session);
 int cg_pid_get_unit(pid_t pid, char **unit);
 int cg_pid_get_user_unit(pid_t pid, char **unit);
+int cg_pid_get_machine_name(pid_t pid, char **machine);
 
-int cg_cgroup_to_unit(const char *cgroup, char **unit);
+int cg_path_decode_unit(const char *cgroup, char **unit);
 
 char **cg_shorten_controllers(char **controllers);
 
index 11282b76118be3c9a8ed148d88eea244c30fdc90..1083742beb007ff594b6653230bc8af883aafb2f 100644 (file)
@@ -64,12 +64,16 @@ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid);
 
 /* Get systemd unit (i.e. service) name from PID, for system
  * services. This will return an error for non-service processes. */
-int sd_pid_get_unit(pid_t, char **unit);
+int sd_pid_get_unit(pid_t pid, char **unit);
 
 /* Get systemd unit (i.e. service) name from PID, for user
  * services. This will return an error for non-user-service
  * processes. */
-int sd_pid_get_user_unit(pid_t, char **unit);
+int sd_pid_get_user_unit(pid_t pid, char **unit);
+
+/* Get machine name from PID, for processes assigned to VM or
+ * container. This will return an error for non-service processes. */
+int sd_pid_get_machine_name(pid_t pid, char **name);
 
 /* Get state from uid. Possible states: offline, lingering, online, active, closing */
 int sd_uid_get_state(uid_t uid, char**state);
index 8e24d1ceca6586b60492e34003376edeb9ce8284..5eaa129418d3142998da70104476d571eb9c8031 100644 (file)
 #include "util.h"
 #include "cgroup-util.h"
 
-static void check_c_t_u(const char *path, int code, const char *result) {
+static void check_p_d_u(const char *path, int code, const char *result) {
         _cleanup_free_ char *unit = NULL;
 
-        assert_se(cg_cgroup_to_unit(path, &unit) == code);
+        assert_se(cg_path_decode_unit(path, &unit) == code);
         assert_se(streq_ptr(unit, result));
 }
 
-static void test_cgroup_to_unit(void) {
-        check_c_t_u("getty@.service/tty2", 0, "getty@tty2.service");
-        check_c_t_u("getty@.service/tty2/xxx", 0, "getty@tty2.service");
-        check_c_t_u("getty@.service/", -EINVAL, NULL);
-        check_c_t_u("getty@.service", -EINVAL, NULL);
-        check_c_t_u("getty.service", 0, "getty.service");
-        check_c_t_u("getty", -EINVAL, NULL);
+static void test_path_decode_unit(void) {
+        check_p_d_u("getty@.service/tty2", 0, "getty@tty2.service");
+        check_p_d_u("getty@.service/tty2/xxx", 0, "getty@tty2.service");
+        check_p_d_u("getty@.service/", -EINVAL, NULL);
+        check_p_d_u("getty@.service", -EINVAL, NULL);
+        check_p_d_u("getty.service", 0, "getty.service");
+        check_p_d_u("getty", -EINVAL, NULL);
 }
 
 static void check_p_g_u(const char *path, int code, const char *result) {
@@ -62,7 +62,9 @@ static void test_path_get_unit(void) {
         check_p_g_u("/system/getty@tty6.service/tty5", 0, "getty@tty6.service");
         check_p_g_u("sadfdsafsda", -ENOENT, NULL);
         check_p_g_u("/system/getty####@tty6.service/tty5", -EINVAL, NULL);
+}
 
+static void test_path_get_user_unit(void) {
         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service", 0, "foobar.service");
         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service/waldo", 0, "foobar.service");
         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service/waldo/uuuux", 0, "foobar.service");
@@ -71,9 +73,27 @@ static void test_path_get_unit(void) {
         check_p_g_u_u("/user/lennart/2/systemd-21548/foobar@.service/pie/pa/po", 0, "foobar@pie.service");
 }
 
+static void test_get_paths(void) {
+        _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL;
+
+        assert_se(cg_get_root_path(&a) >= 0);
+        log_info("Root = %s", a);
+
+        assert_se(cg_get_system_path(&b) >= 0);
+        log_info("System = %s", b);
+
+        assert_se(cg_get_user_path(&c) >= 0);
+        log_info("User = %s", c);
+
+        assert_se(cg_get_machine_path(&d) >= 0);
+        log_info("Machine = %s", d);
+}
+
 int main(void) {
-        test_cgroup_to_unit();
+        test_path_decode_unit();
         test_path_get_unit();
+        test_path_get_user_unit();
+        test_get_paths();
 
         return 0;
 }
index 2f7cc9be0a5d5744272c16c4b3c7245e6030a2e7..3a3489d6a25badf9710ebc1aeacc290ebd38e3ea 100644 (file)
@@ -37,19 +37,19 @@ int main(int argc, char*argv[]) {
         assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c", NULL) == 0);
         assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0) == 0);
 
-        assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+        assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
         assert_se(streq(path, "/test-b"));
         free(path);
 
         assert_se(cg_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0) == 0);
 
-        assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+        assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
         assert_se(path_equal(path, "/test-a"));
         free(path);
 
         assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", 0) == 0);
 
-        assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
+        assert_se(cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0);
         assert_se(path_equal(path, "/test-b/test-d"));
         free(path);
 
index 2d9093d741c4780d4f5e17eadfb609ea4bdcb4b3..7d13b4f5323efc649c7fd5667806d92c1927472a 100644 (file)
@@ -1104,7 +1104,7 @@ int main(int argc, char *argv[])
                 }
 
                 /* get our own cgroup, we regularly kill everything udev has left behind */
-                if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &udev_cgroup) < 0)
+                if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &udev_cgroup) < 0)
                         udev_cgroup = NULL;
         } else {
                 /* open control and netlink socket */