X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Funit.c;h=0c92756cb7f7deb93aa2ace3f1a3bd60c10d53cc;hb=d04247cf25057cb5b3359244cd145e4027bd8536;hp=66372f2a92a8e4b98f5302aa1ec5bb2a6f371882;hpb=3b6fdb5b5afebc49a7e987e3e3bf7aa2615d1671;p=elogind.git diff --git a/src/unit.c b/src/unit.c index 66372f2a9..0c92756cb 100644 --- a/src/unit.c +++ b/src/unit.c @@ -949,6 +949,7 @@ static void retroactively_stop_dependencies(Unit *u) { void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { dual_timestamp ts; + bool unexpected; assert(u); assert(os < _UNIT_ACTIVE_STATE_MAX); @@ -983,7 +984,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { path_unit_notify(u, ns); if (u->meta.job) { - bool unexpected = false; + unexpected = false; if (u->meta.job->state == JOB_WAITING) @@ -1042,16 +1043,20 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { assert_not_reached("Job type unknown"); } - /* If this state change happened without being - * requested by a job, then let's retroactively start - * or stop dependencies */ - - if (unexpected) { - if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) - retroactively_start_dependencies(u); - else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) - retroactively_stop_dependencies(u); - } + } else + unexpected = true; + + /* If this state change happened without being requested by a + * job, then let's retroactively start or stop + * dependencies. We skip that step when deserializing, since + * we don't want to create any additional jobs just because + * something is already activated. */ + + if (unexpected && u->meta.manager->n_deserializing <= 0) { + if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) + retroactively_start_dependencies(u); + else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + retroactively_stop_dependencies(u); } /* Some names are special */ @@ -1511,12 +1516,9 @@ char *unit_dbus_path(Unit *u) { if (!(e = bus_path_escape(u->meta.id))) return NULL; - if (asprintf(&p, "/org/freedesktop/systemd1/unit/%s", e) < 0) { - free(e); - return NULL; - } - + p = strappend("/org/freedesktop/systemd1/unit/", e); free(e); + return p; } @@ -1526,8 +1528,13 @@ int unit_add_cgroup(Unit *u, CGroupBonding *b) { assert(u); assert(b); + assert(b->path); + if (!b->controller) + if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER))) + return -ENOMEM; + /* Ensure this hasn't been added yet */ assert(!b->unit); @@ -1566,7 +1573,6 @@ static char *default_cgroup_path(Unit *u) { } int unit_add_cgroup_from_text(Unit *u, const char *name) { - size_t n; char *controller = NULL, *path = NULL; CGroupBonding *b = NULL; int r; @@ -1574,38 +1580,20 @@ int unit_add_cgroup_from_text(Unit *u, const char *name) { assert(u); assert(name); - /* Detect controller name */ - n = strcspn(name, ":"); - - if (name[n] == 0 || - (name[n] == ':' && name[n+1] == 0)) { - - /* Only controller name, no path? */ - - if (!(path = default_cgroup_path(u))) - return -ENOMEM; - - } else { - const char *p; - - /* Controller name, and path. */ - p = name+n+1; - - if (!path_is_absolute(p)) - return -EINVAL; + if ((r = cg_split_spec(name, &controller, &path)) < 0) + return r; - if (!(path = strdup(p))) - return -ENOMEM; - } + if (!path) + path = default_cgroup_path(u); - if (n > 0) - controller = strndup(name, n); - else + if (!controller) controller = strdup(SYSTEMD_CGROUP_CONTROLLER); - if (!controller) { - r = -ENOMEM; - goto fail; + if (!path || !controller) { + free(path); + free(controller); + + return -ENOMEM; } if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller)) { @@ -1650,9 +1638,6 @@ int unit_add_default_cgroup(Unit *u) { if (!(b = new0(CGroupBonding, 1))) return -ENOMEM; - if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER))) - goto fail; - if (!(b->path = default_cgroup_path(u))) goto fail;