unit: introduce 'banned' load state for units symlinked to /dev/null

This commit is contained in:
Lennart Poettering 2010-10-08 02:31:36 +02:00
parent c2b3f093d9
commit 00dc5d769a
11 changed files with 57 additions and 16 deletions

4
TODO
View File

@ -1,5 +1,3 @@
* do not throw error when .service file is linked to /dev/null
* oneshot services which do not remain: 'exited' instead of 'dead'?
it should be visible in 'systemctl' that they have been run
@ -9,8 +7,6 @@
* implicitly import "defaults" settings file into all types
* "disabled" load state?
* ability to kill services? i.e. in contrast to stopping them, go directly
into killing mode?

View File

@ -37,6 +37,7 @@
#define BUS_ERROR_ONLY_BY_DEPENDENCY "org.freedesktop.systemd1.OnlyByDependency"
#define BUS_ERROR_NO_ISOLATION "org.freedesktop.systemd1.NoIsolation"
#define BUS_ERROR_LOAD_FAILED "org.freedesktop.systemd1.LoadFailed"
#define BUS_ERROR_BANNED "org.freedesktop.systemd1.Banned"
#define BUS_ERROR_JOB_TYPE_NOT_APPLICABLE "org.freedesktop.systemd1.JobTypeNotApplicable"
#define BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE "org.freedesktop.systemd1.TransactionIsDestructive"
#define BUS_ERROR_TRANSACTION_JOBS_CONFLICTING "org.freedesktop.systemd1.TransactionJobsConflicting"

View File

@ -1883,9 +1883,15 @@ static int load_from_path(Unit *u, const char *path) {
goto finish;
}
/* Now, parse the file contents */
if ((r = config_parse(filename, f, sections, items, false, u)) < 0)
goto finish;
if (null_or_empty(&st))
u->meta.load_state = UNIT_BANNED;
else {
/* Now, parse the file contents */
if ((r = config_parse(filename, f, sections, items, false, u)) < 0)
goto finish;
u->meta.load_state = UNIT_LOADED;
}
free(u->meta.fragment_path);
u->meta.fragment_path = filename;
@ -1893,7 +1899,6 @@ static int load_from_path(Unit *u, const char *path) {
u->meta.fragment_mtime = timespec_load(&st.st_mtim);
u->meta.load_state = UNIT_LOADED;
r = 0;
finish:

View File

@ -1060,8 +1060,10 @@ int main(int argc, char *argv[]) {
if ((r = manager_load_unit(m, arg_default_unit, NULL, &error, &target)) < 0) {
log_error("Failed to load default target: %s", bus_error(&error, r));
dbus_error_free(&error);
} else if (target->meta.load_state != UNIT_LOADED)
} else if (target->meta.load_state == UNIT_ERROR)
log_error("Failed to load default target: %s", strerror(-target->meta.load_error));
else if (target->meta.load_state == UNIT_BANNED)
log_error("Default target banned.");
if (!target || target->meta.load_state != UNIT_LOADED) {
log_info("Trying to load rescue target...");
@ -1070,12 +1072,17 @@ int main(int argc, char *argv[]) {
log_error("Failed to load rescue target: %s", bus_error(&error, r));
dbus_error_free(&error);
goto finish;
} else if (target->meta.load_state != UNIT_LOADED) {
} else if (target->meta.load_state == UNIT_ERROR) {
log_error("Failed to load rescue target: %s", strerror(-target->meta.load_error));
goto finish;
} else if (target->meta.load_state == UNIT_BANNED) {
log_error("Rescue target banned.");
goto finish;
}
}
assert(target->meta.load_state == UNIT_LOADED);
if (arg_action == ACTION_TEST) {
printf("-> By units:\n");
manager_dump_units(m, stdout, "\t");

View File

@ -1398,18 +1398,27 @@ static int transaction_add_job_and_dependencies(
assert(type < _JOB_TYPE_MAX);
assert(unit);
if (unit->meta.load_state != UNIT_LOADED && unit->meta.load_state != UNIT_ERROR) {
if (unit->meta.load_state != UNIT_LOADED &&
unit->meta.load_state != UNIT_ERROR &&
unit->meta.load_state != UNIT_BANNED) {
dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->meta.id);
return -EINVAL;
}
if (type != JOB_STOP && unit->meta.load_state == UNIT_ERROR) {
dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load: %s. You might find more information in the system logs.",
dbus_set_error(e, BUS_ERROR_LOAD_FAILED,
"Unit %s failed to load: %s. "
"You might find more information in the system logs.",
unit->meta.id,
strerror(-unit->meta.load_error));
return -EINVAL;
}
if (type != JOB_STOP && unit->meta.load_state == UNIT_BANNED) {
dbus_set_error(e, BUS_ERROR_BANNED, "Unit %s is banned.", unit->meta.id);
return -EINVAL;
}
if (!unit_job_is_applicable(unit, type)) {
dbus_set_error(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->meta.id);
return -EBADR;

View File

@ -389,7 +389,8 @@ static int path_start(Unit *u) {
return -ENOENT;
p->failure = false;
path_enter_waiting(p, true);
path_enter_waiting(p, true);
return 0;
}

View File

@ -297,7 +297,8 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
if (!output_show_job(u))
continue;
if (!streq(u->load_state, "loaded")) {
if (!streq(u->load_state, "loaded") &&
!streq(u->load_state, "banned")) {
on_loaded = ansi_highlight(true);
off_loaded = ansi_highlight(false);
} else
@ -1628,7 +1629,8 @@ static void print_status_info(UnitStatusInfo *i) {
printf("\n");
if (streq_ptr(i->load_state, "failed")) {
if (streq_ptr(i->load_state, "failed") ||
streq_ptr(i->load_state, "banned")) {
on = ansi_highlight(true);
off = ansi_highlight(false);
} else

View File

@ -2236,7 +2236,8 @@ static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
[UNIT_STUB] = "stub",
[UNIT_LOADED] = "loaded",
[UNIT_ERROR] = "error",
[UNIT_MERGED] = "merged"
[UNIT_MERGED] = "merged",
[UNIT_BANNED] = "banned"
};
DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);

View File

@ -62,6 +62,7 @@ enum UnitLoadState {
UNIT_LOADED,
UNIT_ERROR,
UNIT_MERGED,
UNIT_BANNED,
_UNIT_LOAD_STATE_MAX,
_UNIT_LOAD_STATE_INVALID = -1
};

View File

@ -3313,6 +3313,21 @@ void freeze(void) {
pause();
}
bool null_or_empty(struct stat *st) {
assert(st);
if (S_ISREG(st->st_mode) && st->st_size <= 0)
return true;
/* /dev/null has major/minor of 1:3 */
if (S_ISCHR(st->st_mode) &&
major(st->st_rdev) == 1 &&
minor(st->st_rdev) == 3)
return true;
return false;
}
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",

View File

@ -31,6 +31,7 @@
#include <signal.h>
#include <sched.h>
#include <limits.h>
#include <sys/stat.h>
#include "macro.h"
@ -358,6 +359,8 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid);
_noreturn_ void freeze(void);
bool null_or_empty(struct stat *st);
#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)