-static int parse_mode(DBusMessageIter *iter, bool *runtime, bool next) {
- const char *mode;
- int r;
-
- assert(iter);
- assert(runtime);
-
- r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &mode, next);
- if (r < 0)
- return r;
-
- if (streq(mode, "runtime"))
- *runtime = true;
- else if (streq(mode, "persistent"))
- *runtime = false;
- else
- return -EINVAL;
-
- return 0;
-}
-
-int bus_unit_cgroup_set(Unit *u, DBusMessageIter *iter) {
- _cleanup_free_ char *controller = NULL, *old_path = NULL, *new_path = NULL, *contents = NULL;
- const char *name;
- CGroupBonding *b;
- bool runtime;
- int r;
-
- assert(u);
- assert(iter);
-
- if (!unit_get_exec_context(u))
- return -EINVAL;
-
- r = bus_iter_get_basic_and_next(iter, DBUS_TYPE_STRING, &name, true);
- if (r < 0)
- return r;
-
- r = parse_mode(iter, &runtime, false);
- if (r < 0)
- return r;
-
- r = cg_split_spec(name, &controller, &new_path);
- if (r < 0)
- return r;
-
- if (!new_path) {
- new_path = unit_default_cgroup_path(u);
- if (!new_path)
- return -ENOMEM;
- }
-
- if (!controller || streq(controller, SYSTEMD_CGROUP_CONTROLLER))
- return -EINVAL;
-
- b = cgroup_bonding_find_list(u->cgroup_bondings, controller);
- if (b) {
- if (streq(b->path, new_path))
- return 0;
-
- if (b->essential)
- return -EINVAL;
-
- old_path = strdup(b->path);
- if (!old_path)
- return -ENOMEM;
- }
-
- r = unit_add_cgroup_from_text(u, name, true, &b);
- if (r < 0)
- return r;
- if (r > 0) {
- CGroupAttribute *a;
-
- /* Try to move things to the new place, and clean up the old place */
- cgroup_bonding_realize(b);
- cgroup_bonding_migrate(b, u->cgroup_bondings);
-
- if (old_path)
- cg_trim(controller, old_path, true);
-
- /* Apply the attributes to the new group */
- LIST_FOREACH(by_unit, a, u->cgroup_attributes)
- if (streq(a->controller, controller))
- cgroup_attribute_apply(a, b);
- }
-
- contents = strjoin("[", UNIT_VTABLE(u)->exec_section, "]\n"
- "ControlGroup=", name, "\n", NULL);
- if (!contents)
- return -ENOMEM;
-
- return unit_write_drop_in(u, runtime, controller, contents);
-}