X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=unit.c;h=d1416e03e988b151a004e5459144014d177a3d9e;hp=6d6f56416d1bfb0c6976230546e3ef6855ba9c2f;hb=e537352b9bfffe6f6286483bff2c7601c78407e3;hpb=108736d0d34d7b74a61a6ac7b99d4d4fec81ce09 diff --git a/unit.c b/unit.c index 6d6f56416..d1416e03e 100644 --- a/unit.c +++ b/unit.c @@ -155,6 +155,11 @@ int unit_add_name(Unit *u, const char *text) { if (u->meta.type != _UNIT_TYPE_INVALID && t != u->meta.type) return -EINVAL; + if (u->meta.type != _UNIT_TYPE_INVALID && + UNIT_VTABLE(u)->no_alias && + !set_isempty(u->meta.names)) + return -EEXIST; + if (!(s = strdup(text))) return -ENOMEM; @@ -173,10 +178,14 @@ int unit_add_name(Unit *u, const char *text) { return r; } - if (u->meta.type == _UNIT_TYPE_INVALID) + if (u->meta.type == _UNIT_TYPE_INVALID) { LIST_PREPEND(Meta, units_per_type, u->meta.manager->units_per_type[t], &u->meta); - u->meta.type = t; + u->meta.type = t; + + if (UNIT_VTABLE(u)->init) + UNIT_VTABLE(u)->init(u); + } if (!u->meta.id) u->meta.id = s; @@ -278,9 +287,6 @@ void unit_free(Unit *u) { bus_unit_send_removed_signal(u); /* Detach from next 'bigger' objects */ - - cgroup_bonding_free_list(u->meta.cgroup_bondings); - SET_FOREACH(t, u->meta.names, i) hashmap_remove_value(u->meta.manager->units, t, u); @@ -296,13 +302,15 @@ void unit_free(Unit *u) { if (u->meta.in_cleanup_queue) LIST_REMOVE(Meta, cleanup_queue, u->meta.manager->cleanup_queue, &u->meta); + /* Free data and next 'smaller' objects */ + if (u->meta.job) + job_free(u->meta.job); + if (u->meta.load_state != UNIT_STUB) if (UNIT_VTABLE(u)->done) UNIT_VTABLE(u)->done(u); - /* Free data and next 'smaller' objects */ - if (u->meta.job) - job_free(u->meta.job); + cgroup_bonding_free_list(u->meta.cgroup_bondings); for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) bidi_set_free(u, u->meta.dependencies[d]); @@ -401,9 +409,6 @@ int unit_merge(Unit *u, Unit *other) { if (other == u) return 0; - /* This merges 'other' into 'unit'. FIXME: This does not - * rollback on failure. */ - if (u->meta.type != u->meta.type) return -EINVAL; @@ -569,18 +574,16 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { } /* Common implementation for multiple backends */ -int unit_load_fragment_and_dropin(Unit *u, UnitLoadState *new_state) { +int unit_load_fragment_and_dropin(Unit *u) { int r; assert(u); - assert(new_state); - assert(*new_state == UNIT_STUB || *new_state == UNIT_LOADED); /* Load a .service file */ - if ((r = unit_load_fragment(u, new_state)) < 0) + if ((r = unit_load_fragment(u)) < 0) return r; - if (*new_state == UNIT_STUB) + if (u->meta.load_state == UNIT_STUB) return -ENOENT; /* Load drop-in directory data */ @@ -591,22 +594,20 @@ int unit_load_fragment_and_dropin(Unit *u, UnitLoadState *new_state) { } /* Common implementation for multiple backends */ -int unit_load_fragment_and_dropin_optional(Unit *u, UnitLoadState *new_state) { +int unit_load_fragment_and_dropin_optional(Unit *u) { int r; assert(u); - assert(new_state); - assert(*new_state == UNIT_STUB || *new_state == UNIT_LOADED); /* Same as unit_load_fragment_and_dropin(), but whether * something can be loaded or not doesn't matter. */ /* Load a .service file */ - if ((r = unit_load_fragment(u, new_state)) < 0) + if ((r = unit_load_fragment(u)) < 0) return r; - if (*new_state == UNIT_STUB) - *new_state = UNIT_LOADED; + if (u->meta.load_state == UNIT_STUB) + u->meta.load_state = UNIT_LOADED; /* Load drop-in directory data */ if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) @@ -617,7 +618,6 @@ int unit_load_fragment_and_dropin_optional(Unit *u, UnitLoadState *new_state) { int unit_load(Unit *u) { int r; - UnitLoadState res; assert(u); @@ -626,21 +626,21 @@ int unit_load(Unit *u) { u->meta.in_load_queue = false; } + if (u->meta.type == _UNIT_TYPE_INVALID) + return -EINVAL; + if (u->meta.load_state != UNIT_STUB) return 0; - if (UNIT_VTABLE(u)->init) { - res = UNIT_STUB; - if ((r = UNIT_VTABLE(u)->init(u, &res)) < 0) + if (UNIT_VTABLE(u)->load) + if ((r = UNIT_VTABLE(u)->load(u)) < 0) goto fail; - } - if (res == UNIT_STUB) { + if (u->meta.load_state == UNIT_STUB) { r = -ENOENT; goto fail; } - u->meta.load_state = res; assert((u->meta.load_state != UNIT_MERGED) == !u->meta.merged_into); unit_add_to_dbus_queue(unit_follow_merge(u)); @@ -711,9 +711,6 @@ int unit_stop(Unit *u) { if (!UNIT_VTABLE(u)->stop) return -EBADR; - if (state == UNIT_DEACTIVATING) - return 0; - unit_add_to_dbus_queue(u); return UNIT_VTABLE(u)->stop(u); } @@ -940,25 +937,38 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { retroactively_stop_dependencies(u); } - if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns)) { - + /* Some names are special */ + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) { - log_info("D-Bus became available, trying to reconnect."); - /* The bus just got started, hence try to connect to it. */ + /* The bus just might have become available, + * hence try to connect to it, if we aren't + * yet connected. */ bus_init_system(u->meta.manager); bus_init_api(u->meta.manager); } - if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE)) { - /* The syslog daemon just got started, hence try to connect to it. */ - log_info("Syslog became available, trying to reconnect."); + if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE)) + /* The syslog daemon just might have become + * available, hence try to connect to it, if + * we aren't yet connected. */ log_open_syslog(); - } - } else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns)) { + if (u->meta.type == UNIT_MOUNT) + /* Another directory became available, let's + * check if that is enough to write our utmp + * entry. */ + manager_write_utmp_reboot(u->meta.manager); + + if (u->meta.type == UNIT_TARGET) + /* A target got activated, maybe this is a runlevel? */ + manager_write_utmp_runlevel(u->meta.manager, u); + + } else if (!UNIT_IS_ACTIVE_OR_RELOADING(ns)) { if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE)) - /* The syslog daemon just got terminated, hence try to disconnect from it. */ + /* The syslog daemon might just have + * terminated, hence try to disconnect from + * it. */ log_close_syslog(); /* We don't care about D-Bus here, since we'll get an