summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--man/systemctl.xml15
-rw-r--r--src/job.c11
-rw-r--r--src/job.h2
-rw-r--r--src/manager.c31
-rw-r--r--src/systemctl-bash-completion.sh2
-rw-r--r--src/systemctl.c16
7 files changed, 54 insertions, 25 deletions
diff --git a/TODO b/TODO
index aa405e6b5c..6196a520f3 100644
--- a/TODO
+++ b/TODO
@@ -10,8 +10,6 @@ Bugs:
Features:
-* add --ignore-deps to systemctl
-
* increase password timeout
* look up crypto partition mount points via fstab to show to the user when prompting for a password
diff --git a/man/systemctl.xml b/man/systemctl.xml
index c45b11a510..d37a7d95dc 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -159,6 +159,21 @@
</varlistentry>
<varlistentry>
+ <term><option>--ignore-dependencies</option></term>
+
+ <listitem><para>When enqueuing a new
+ job ignore all its dependencies and
+ execute it immediately. If passed no
+ required units of the unit passed will
+ be pulled in, and no ordering
+ dependencies will be honoured. This is
+ mostly a debugging and rescue tool for
+ the administrator and should not be
+ used by
+ applications.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--quiet</option></term>
<term><option>-q</option></term>
diff --git a/src/job.c b/src/job.c
index 18a249592b..4700aab6ac 100644
--- a/src/job.c
+++ b/src/job.c
@@ -309,8 +309,12 @@ bool job_is_runnable(Job *j) {
/* Checks whether there is any job running for the units this
* job needs to be running after (in the case of a 'positive'
- * job type) or before (in the case of a 'negative' job type
- * . */
+ * job type) or before (in the case of a 'negative' job
+ * type. */
+
+ /* First check if there is an override */
+ if (j->ignore_deps)
+ return true;
if (j->type == JOB_START ||
j->type == JOB_VERIFY_ACTIVE ||
@@ -667,7 +671,8 @@ DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
static const char* const job_mode_table[_JOB_MODE_MAX] = {
[JOB_FAIL] = "fail",
[JOB_REPLACE] = "replace",
- [JOB_ISOLATE] = "isolate"
+ [JOB_ISOLATE] = "isolate",
+ [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies"
};
DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
diff --git a/src/job.h b/src/job.h
index e42c9647a8..2499e6492a 100644
--- a/src/job.h
+++ b/src/job.h
@@ -66,6 +66,7 @@ enum JobMode {
JOB_FAIL,
JOB_REPLACE,
JOB_ISOLATE,
+ JOB_IGNORE_DEPENDENCIES,
_JOB_MODE_MAX,
_JOB_MODE_INVALID = -1
};
@@ -116,6 +117,7 @@ struct Job {
bool in_dbus_queue:1;
bool sent_dbus_new_signal:1;
bool failed:1;
+ bool ignore_deps:1;
};
Job* job_new(Manager *m, JobType type, Unit *unit);
diff --git a/src/manager.c b/src/manager.c
index b2aa8ee45e..f266aaa01c 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -1412,6 +1412,7 @@ static int transaction_add_job_and_dependencies(
bool matters,
bool override,
bool conflicts,
+ bool ignore_deps,
DBusError *e,
Job **_ret) {
Job *ret;
@@ -1459,18 +1460,20 @@ static int transaction_add_job_and_dependencies(
if (!(ret = transaction_add_one_job(m, type, unit, override, &is_new)))
return -ENOMEM;
+ ret->ignore_deps = ret->ignore_deps || ignore_deps;
+
/* Then, add a link to the job. */
if (!job_dependency_new(by, ret, matters, conflicts))
return -ENOMEM;
- if (is_new) {
+ if (is_new && !ignore_deps) {
Set *following;
/* If we are following some other unit, make sure we
* add all dependencies of everybody following. */
if (unit_following_set(ret->unit, &following) > 0) {
SET_FOREACH(dep, following, i)
- if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, false, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, false, override, false, false, e, NULL)) < 0) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
if (e)
@@ -1483,7 +1486,7 @@ static int transaction_add_job_and_dependencies(
/* Finally, recursively add in all dependencies. */
if (type == JOB_START || type == JOB_RELOAD_OR_START) {
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, e, NULL)) < 0) {
if (r != -EBADR)
goto fail;
@@ -1492,7 +1495,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BIND_TO], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, e, NULL)) < 0) {
if (r != -EBADR)
goto fail;
@@ -1502,7 +1505,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, false, e, NULL)) < 0) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
if (e)
@@ -1510,7 +1513,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, false, false, e, NULL)) < 0) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
if (e)
@@ -1518,7 +1521,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, e, NULL)) < 0) {
if (r != -EBADR)
goto fail;
@@ -1528,7 +1531,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, e, NULL)) < 0) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
if (e)
@@ -1536,7 +1539,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, true, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, true, false, e, NULL)) < 0) {
if (r != -EBADR)
goto fail;
@@ -1546,7 +1549,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTED_BY], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, false, e, NULL)) < 0) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
if (e)
@@ -1556,7 +1559,7 @@ static int transaction_add_job_and_dependencies(
} else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
- if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, e, NULL)) < 0) {
if (r != -EBADR)
goto fail;
@@ -1566,7 +1569,7 @@ static int transaction_add_job_and_dependencies(
}
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BOUND_BY], i)
- if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, e, NULL)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, e, NULL)) < 0) {
if (r != -EBADR)
goto fail;
@@ -1613,7 +1616,7 @@ static int transaction_add_isolate_jobs(Manager *m) {
if (hashmap_get(m->transaction_jobs, u))
continue;
- if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, false, NULL, NULL)) < 0)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, false, false, NULL, NULL)) < 0)
log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->meta.id, strerror(-r));
}
@@ -1641,7 +1644,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove
log_debug("Trying to enqueue job %s/%s/%s", unit->meta.id, job_type_to_string(type), job_mode_to_string(mode));
- if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false, e, &ret)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false, mode == JOB_IGNORE_DEPENDENCIES, e, &ret)) < 0) {
transaction_abort(m);
return r;
}
diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh
index 834e11dbea..f3420217b5 100644
--- a/src/systemctl-bash-completion.sh
+++ b/src/systemctl-bash-completion.sh
@@ -42,7 +42,7 @@ _systemctl () {
local verb comps
local -A OPTS=(
- [STANDALONE]='--all -a --defaults --fail --failed --force -f --full --global
+ [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
--help -h --no-ask-password --no-block --no-reload --no-wall
--order --require --quiet -q --system --user --version'
[ARG]='--kill-mode --kill-who --property -p --signal -s --type -t'
diff --git a/src/systemctl.c b/src/systemctl.c
index df4fccc140..4a8b9a196f 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -60,7 +60,7 @@
static const char *arg_type = NULL;
static char **arg_property = NULL;
static bool arg_all = false;
-static bool arg_fail = false;
+static const char *arg_job_mode = "replace";
static bool arg_user = false;
static bool arg_global = false;
static bool arg_immediate = false;
@@ -1384,9 +1384,7 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) {
mode =
(streq(args[0], "isolate") ||
streq(args[0], "rescue") ||
- streq(args[0], "emergency")) ? "isolate" :
- arg_fail ? "fail" :
- "replace";
+ streq(args[0], "emergency")) ? "isolate" : arg_job_mode;
one_name = table[verb_to_action(args[0])];
@@ -4198,6 +4196,8 @@ static int systemctl_help(void) {
" --full Don't ellipsize unit names on output\n"
" --fail When queueing a new job, fail if conflicting jobs are\n"
" pending\n"
+ " --ignore-dependencies\n"
+ " When queueing a new job, ignore all its dependencies\n"
" -q --quiet Suppress output\n"
" --no-block Do not wait until operation finished\n"
" --no-pager Do not pipe output into a pager.\n"
@@ -4335,6 +4335,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
enum {
ARG_FAIL = 0x100,
+ ARG_IGNORE_DEPENDENCIES,
ARG_VERSION,
ARG_USER,
ARG_SYSTEM,
@@ -4362,6 +4363,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "failed", no_argument, NULL, ARG_FAILED },
{ "full", no_argument, NULL, ARG_FULL },
{ "fail", no_argument, NULL, ARG_FAIL },
+ { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
{ "user", no_argument, NULL, ARG_USER },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "global", no_argument, NULL, ARG_GLOBAL },
@@ -4428,7 +4430,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_FAIL:
- arg_fail = true;
+ arg_job_mode = "fail";
+ break;
+
+ case ARG_IGNORE_DEPENDENCIES:
+ arg_job_mode = "ignore-dependencies";
break;
case ARG_USER: