assert(b->path);
- if (!b->controller)
+ if (!b->controller) {
if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER)))
return -ENOMEM;
+ b->ours = true;
+ }
+
/* Ensure this hasn't been added yet */
assert(!b->unit);
int unit_add_cgroup_from_text(Unit *u, const char *name) {
char *controller = NULL, *path = NULL;
CGroupBonding *b = NULL;
+ bool ours = false;
int r;
assert(u);
if ((r = cg_split_spec(name, &controller, &path)) < 0)
return r;
- if (!path)
+ if (!path) {
path = default_cgroup_path(u);
+ ours = true;
+ }
- if (!controller)
+ if (!controller) {
controller = strdup(SYSTEMD_CGROUP_CONTROLLER);
+ ours = true;
+ }
if (!path || !controller) {
free(path);
b->controller = controller;
b->path = path;
- b->ours = false;
+ b->ours = ours;
+ b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
if ((r = unit_add_cgroup(u, b)) < 0)
goto fail;
return unit_name_to_path(u->meta.instance);
}
+static char *specifier_cgroup(char specifier, void *data, void *userdata) {
+ Unit *u = userdata;
+ assert(u);
+
+ return default_cgroup_path(u);
+}
+
+static char *specifier_cgroup_root(char specifier, void *data, void *userdata) {
+ Unit *u = userdata;
+ char *p;
+ assert(u);
+
+ if (specifier == 'r')
+ return strdup(u->meta.manager->cgroup_hierarchy);
+
+ if (parent_of_path(u->meta.manager->cgroup_hierarchy, &p) < 0)
+ return strdup("");
+
+ if (streq(p, "/")) {
+ free(p);
+ return strdup("");
+ }
+
+ return p;
+}
+
+static char *specifier_runtime(char specifier, void *data, void *userdata) {
+ Unit *u = userdata;
+ assert(u);
+
+ if (u->meta.manager->running_as == MANAGER_USER) {
+ const char *e;
+
+ e = getenv("XDG_RUNTIME_DIR");
+ if (e)
+ return strdup(e);
+ }
+
+ return strdup("/run");
+}
+
char *unit_name_printf(Unit *u, const char* format) {
/*
char *unit_full_printf(Unit *u, const char *format) {
/* This is similar to unit_name_printf() but also supports
- * unescaping */
+ * unescaping. Also, adds a couple of additional codes:
+ *
+ * %c cgroup path of unit
+ * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711")
+ * %R parent of root cgroup path (e.g. "/usr/lennart/shared")
+ * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
+ */
const Specifier table[] = {
{ 'n', specifier_string, u->meta.id },
{ 'i', specifier_string, u->meta.instance },
{ 'I', specifier_instance_unescaped, NULL },
{ 'f', specifier_filename, NULL },
+ { 'c', specifier_cgroup, NULL },
+ { 'r', specifier_cgroup_root, NULL },
+ { 'R', specifier_cgroup_root, NULL },
+ { 't', specifier_runtime, NULL },
{ 0, NULL, NULL }
};
return UNIT_VTABLE(u)->kill(u, w, m, signo, error);
}
-
int unit_following_set(Unit *u, Set **s) {
assert(u);
assert(s);