+CGroupMask unit_get_enable_mask(Unit *u) {
+ CGroupMask mask;
+
+ /* This returns the cgroup mask of all controllers to enable
+ * for the children of a specific cgroup. This is primarily
+ * useful for the unified cgroup hierarchy, where each cgroup
+ * controls which controllers are enabled for its children. */
+
+ mask = unit_get_members_mask(u);
+ mask &= u->manager->cgroup_supported;
+
+ return mask;
+}
+
+/* Recurse from a unit up through its containing slices, propagating
+ * mask bits upward. A unit is also member of itself. */
+void unit_update_cgroup_members_masks(Unit *u) {
+ CGroupMask m;
+ bool more;
+
+ assert(u);
+
+ /* Calculate subtree mask */
+ m = unit_get_subtree_mask(u);
+
+ /* See if anything changed from the previous invocation. If
+ * not, we're done. */
+ if (u->cgroup_subtree_mask_valid && m == u->cgroup_subtree_mask)
+ return;
+
+ more =
+ u->cgroup_subtree_mask_valid &&
+ ((m & ~u->cgroup_subtree_mask) != 0) &&
+ ((~m & u->cgroup_subtree_mask) == 0);
+
+ u->cgroup_subtree_mask = m;
+ u->cgroup_subtree_mask_valid = true;
+
+ if (UNIT_ISSET(u->slice)) {
+ Unit *s = UNIT_DEREF(u->slice);
+
+ if (more)
+ /* There's more set now than before. We
+ * propagate the new mask to the parent's mask
+ * (not caring if it actually was valid or
+ * not). */
+
+ s->cgroup_members_mask |= m;
+
+ else
+ /* There's less set now than before (or we
+ * don't know), we need to recalculate
+ * everything, so let's invalidate the
+ * parent's members mask */
+
+ s->cgroup_members_mask_valid = false;
+
+ /* And now make sure that this change also hits our
+ * grandparents */
+ unit_update_cgroup_members_masks(s);
+ }
+}
+
+static const char *migrate_callback(CGroupMask mask, void *userdata) {
+ Unit *u = userdata;
+
+ assert(mask != 0);
+ assert(u);
+
+ while (u) {
+ if (u->cgroup_path &&
+ u->cgroup_realized &&
+ (u->cgroup_realized_mask & mask) == mask)
+ return u->cgroup_path;
+
+ u = UNIT_DEREF(u->slice);
+ }
+
+ return NULL;
+}
+
+char *unit_default_cgroup_path(Unit *u) {
+ _cleanup_free_ char *escaped = NULL, *slice = NULL;
+ int r;
+