#include "dbus.h"
#include "execute.h"
#include "virt.h"
+#include "dropin.h"
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = &service_vtable,
cc->cpu_accounting = u->manager->default_cpu_accounting;
cc->blockio_accounting = u->manager->default_blockio_accounting;
cc->memory_accounting = u->manager->default_memory_accounting;
- cc->cpu_quota_period_usec = u->manager->default_cpu_quota_period_usec;
}
ec = unit_get_exec_context(u);
}
set_remove(u->manager->failed_units, u);
+ set_remove(u->manager->startup_units, u);
free(u->description);
strv_free(u->documentation);
return 0;
}
+static int unit_add_startup_units(Unit *u) {
+ CGroupContext *c;
+ int r = 0;
+
+ c = unit_get_cgroup_context(u);
+ if (!c)
+ return 0;
+
+ if (c->startup_cpu_shares == (unsigned long) -1 &&
+ c->startup_blockio_weight == (unsigned long) -1)
+ return 0;
+
+ r = set_put(u->manager->startup_units, u);
+ if (r == -EEXIST)
+ return 0;
+
+ return r;
+}
+
int unit_load(Unit *u) {
int r;
if (r < 0)
goto fail;
+ r = unit_add_startup_units(u);
+ if (r < 0)
+ goto fail;
+
if (u->on_failure_job_mode == JOB_ISOLATE && set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
log_error_unit(u->id, "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
r = -EINVAL;
/* Note that this is called for all low-level state changes,
* even if they might map to the same high-level
- * UnitActiveState! That means that ns == os is OK an expected
+ * UnitActiveState! That means that ns == os is an expected
* behavior here. For example: if a mount point is remounted
* this function will be called too! */
u->active_exit_timestamp = ts;
}
- /* Keep track of failed of units */
+ /* Keep track of failed units */
if (ns == UNIT_FAILED && os != UNIT_FAILED)
set_put(u->manager->failed_units, u);
else if (os == UNIT_FAILED && ns != UNIT_FAILED)
if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
- /* The bus just might have become available,
+ /* The bus might have just become available,
* hence try to connect to it, if we aren't
* yet connected. */
bus_init(m, true);
return *(ExecRuntime**) ((uint8_t*) u + offset);
}
-static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
- _cleanup_free_ char *b = NULL;
- char *p, *q;
- int r;
-
- assert(u);
- assert(name);
- assert(_p);
- assert(_q);
-
- b = xescape(name, "/.");
- if (!b)
- return -ENOMEM;
-
- if (!filename_is_safe(b))
- return -EINVAL;
-
+static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) {
if (u->manager->running_as == SYSTEMD_USER) {
- _cleanup_free_ char *c = NULL;
+ int r;
- r = user_config_home(&c);
- if (r < 0)
- return r;
+ r = user_config_home(dir);
if (r == 0)
return -ENOENT;
+ return r;
+ }
- p = strjoin(c, "/", u->id, ".d", NULL);
- } else if (mode == UNIT_PERSISTENT && !u->transient)
- p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
+ if (mode == UNIT_PERSISTENT && !transient)
+ *dir = strdup("/etc/systemd/system");
else
- p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
- if (!p)
- return -ENOMEM;
-
- q = strjoin(p, "/90-", b, ".conf", NULL);
- if (!q) {
- free(p);
+ *dir = strdup("/run/systemd/system");
+ if (!*dir)
return -ENOMEM;
- }
- *_p = p;
- *_q = q;
return 0;
}
+static int unit_drop_in_file(Unit *u,
+ UnitSetPropertiesMode mode, const char *name, char **p, char **q) {
+ _cleanup_free_ char *dir = NULL;
+ int r;
+
+ assert(u);
+
+ r = unit_drop_in_dir(u, mode, u->transient, &dir);
+ if (r < 0)
+ return r;
+
+ return drop_in_file(dir, u->id, 50, name, p, q);
+}
+
int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
- _cleanup_free_ char *p = NULL, *q = NULL;
+
+ _cleanup_free_ char *dir = NULL;
int r;
assert(u);
- assert(name);
- assert(data);
if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
return 0;
- r = drop_in_file(u, mode, name, &p, &q);
+ r = unit_drop_in_dir(u, mode, u->transient, &dir);
if (r < 0)
return r;
- mkdir_p(p, 0755);
- return write_string_file_atomic_label(q, data);
+ return write_drop_in(dir, u->id, 50, name, data);
}
int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
return 0;
- r = drop_in_file(u, mode, name, &p, &q);
+ r = unit_drop_in_file(u, mode, name, &p, &q);
if (r < 0)
return r;