[systemd-commits] 4 commits - man/systemctl.xml src/core src/login src/systemctl

Michal Schmidt michich at kemper.freedesktop.org
Fri Feb 22 07:06:37 PST 2013


 man/systemctl.xml         |   27 ++++++++---
 src/core/job.c            |   15 +++++-
 src/core/job.h            |    2 
 src/core/manager.c        |    2 
 src/core/transaction.c    |   20 ++++----
 src/core/transaction.h    |    3 -
 src/login/logind-dbus.c   |    2 
 src/systemctl/systemctl.c |  107 ++++++++++++++++++----------------------------
 8 files changed, 93 insertions(+), 85 deletions(-)

New commits:
commit 47a0eaa60cb5434d13f0acbe048aa4681bc8b8a8
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Fri Feb 22 13:37:57 2013 +0100

    systemctl: generalize action table to be usable in more action<->verb mappings
    
    Should be no functional change.

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 3d59a8b..8174376 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1518,53 +1518,39 @@ static int start_unit_one(
         return 0;
 }
 
+static const struct {
+        const char *target;
+        const char *verb;
+        const char *mode;
+} action_table[_ACTION_MAX] = {
+        [ACTION_HALT]         = { SPECIAL_HALT_TARGET,         "halt",         "replace-irreversibly" },
+        [ACTION_POWEROFF]     = { SPECIAL_POWEROFF_TARGET,     "poweroff",     "replace-irreversibly" },
+        [ACTION_REBOOT]       = { SPECIAL_REBOOT_TARGET,       "reboot",       "replace-irreversibly" },
+        [ACTION_KEXEC]        = { SPECIAL_KEXEC_TARGET,        "kexec",        "replace-irreversibly" },
+        [ACTION_RUNLEVEL2]    = { SPECIAL_RUNLEVEL2_TARGET,    NULL,           "isolate" },
+        [ACTION_RUNLEVEL3]    = { SPECIAL_RUNLEVEL3_TARGET,    NULL,           "isolate" },
+        [ACTION_RUNLEVEL4]    = { SPECIAL_RUNLEVEL4_TARGET,    NULL,           "isolate" },
+        [ACTION_RUNLEVEL5]    = { SPECIAL_RUNLEVEL5_TARGET,    NULL,           "isolate" },
+        [ACTION_RESCUE]       = { SPECIAL_RESCUE_TARGET,       "rescue",       "isolate" },
+        [ACTION_EMERGENCY]    = { SPECIAL_EMERGENCY_TARGET,    "emergency",    "isolate" },
+        [ACTION_DEFAULT]      = { SPECIAL_DEFAULT_TARGET,      "default",      "isolate" },
+        [ACTION_EXIT]         = { SPECIAL_EXIT_TARGET,         "exit",         "replace-irreversibly" },
+        [ACTION_SUSPEND]      = { SPECIAL_SUSPEND_TARGET,      "suspend",      "replace-irreversibly" },
+        [ACTION_HIBERNATE]    = { SPECIAL_HIBERNATE_TARGET,    "hibernate",    "replace-irreversibly" },
+        [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
+};
+
 static enum action verb_to_action(const char *verb) {
-        if (streq(verb, "halt"))
-                return ACTION_HALT;
-        else if (streq(verb, "poweroff"))
-                return ACTION_POWEROFF;
-        else if (streq(verb, "reboot"))
-                return ACTION_REBOOT;
-        else if (streq(verb, "kexec"))
-                return ACTION_KEXEC;
-        else if (streq(verb, "rescue"))
-                return ACTION_RESCUE;
-        else if (streq(verb, "emergency"))
-                return ACTION_EMERGENCY;
-        else if (streq(verb, "default"))
-                return ACTION_DEFAULT;
-        else if (streq(verb, "exit"))
-                return ACTION_EXIT;
-        else if (streq(verb, "suspend"))
-                return ACTION_SUSPEND;
-        else if (streq(verb, "hibernate"))
-                return ACTION_HIBERNATE;
-        else if (streq(verb, "hybrid-sleep"))
-                return ACTION_HYBRID_SLEEP;
-        else
-                return ACTION_INVALID;
+        enum action i;
+
+        for (i = ACTION_INVALID; i < _ACTION_MAX; i++)
+                if (action_table[i].verb && streq(verb, action_table[i].verb))
+                        return i;
+        return ACTION_INVALID;
 }
 
 static int start_unit(DBusConnection *bus, char **args) {
 
-        static const char * const table[_ACTION_MAX] = {
-                [ACTION_HALT] = SPECIAL_HALT_TARGET,
-                [ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET,
-                [ACTION_REBOOT] = SPECIAL_REBOOT_TARGET,
-                [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET,
-                [ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET,
-                [ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET,
-                [ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET,
-                [ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET,
-                [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET,
-                [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET,
-                [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET,
-                [ACTION_EXIT] = SPECIAL_EXIT_TARGET,
-                [ACTION_SUSPEND] = SPECIAL_SUSPEND_TARGET,
-                [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET,
-                [ACTION_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET
-        };
-
         int r, ret = 0;
         const char *method, *mode, *one_name;
         Set _cleanup_set_free_free_ *s = NULL;
@@ -1578,6 +1564,7 @@ static int start_unit(DBusConnection *bus, char **args) {
         ask_password_agent_open_if_enabled();
 
         if (arg_action == ACTION_SYSTEMCTL) {
+                enum action action;
                 method =
                         streq(args[0], "stop") ||
                         streq(args[0], "condstop")              ? "StopUnit" :
@@ -1594,40 +1581,21 @@ static int start_unit(DBusConnection *bus, char **args) {
 
                         streq(args[0], "force-reload")          ? "ReloadOrTryRestartUnit" :
                                                                   "StartUnit";
+                action = verb_to_action(args[0]);
 
-                if (streq(args[0], "isolate") ||
-                    streq(args[0], "rescue")  ||
-                    streq(args[0], "emergency") ||
-                    streq(args[0], "default"))
-                        mode = "isolate";
-                else if (streq(args[0], "halt") ||
-                         streq(args[0], "poweroff") ||
-                         streq(args[0], "reboot") ||
-                         streq(args[0], "kexec") ||
-                         streq(args[0], "exit") ||
-                         streq(args[0], "suspend") ||
-                         streq(args[0], "hibernate") ||
-                         streq(args[0], "hybrid-sleep"))
-                        mode = "replace-irreversibly";
-                else
-                        mode = arg_job_mode;
+                mode = streq(args[0], "isolate") ? "isolate" :
+                       action_table[action].mode ?: arg_job_mode;
 
-                one_name = table[verb_to_action(args[0])];
+                one_name = action_table[action].target;
 
         } else {
-                assert(arg_action < ELEMENTSOF(table));
-                assert(table[arg_action]);
+                assert(arg_action < ELEMENTSOF(action_table));
+                assert(action_table[arg_action].target);
 
                 method = "StartUnit";
 
-                mode = (arg_action == ACTION_EMERGENCY ||
-                        arg_action == ACTION_RESCUE ||
-                        arg_action == ACTION_RUNLEVEL2 ||
-                        arg_action == ACTION_RUNLEVEL3 ||
-                        arg_action == ACTION_RUNLEVEL4 ||
-                        arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace-irreversibly";
-
-                one_name = table[arg_action];
+                mode = action_table[arg_action].mode;
+                one_name = action_table[arg_action].target;
         }
 
         if (!arg_no_block) {
@@ -1850,12 +1818,7 @@ static int check_inhibitors(DBusConnection *bus, enum action a) {
                 return 0;
 
         log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
-                  a == ACTION_HALT ? "halt" :
-                  a == ACTION_POWEROFF ? "poweroff" :
-                  a == ACTION_REBOOT ? "reboot" :
-                  a == ACTION_KEXEC ? "kexec" :
-                  a == ACTION_SUSPEND ? "suspend" :
-                  a == ACTION_HIBERNATE ? "hibernate" : "hybrid-sleep");
+                  action_table[a].verb);
 
         return -EPERM;
 #else

commit b85bdddafb321fa870b9250a2ff17040d6996061
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Fri Feb 22 11:21:47 2013 +0100

    systemctl: make shutdown operations use irreversible jobs
    
    Occasionally people report problem with reboot/poweroff operations hanging in
    the middle. One known cause is when a new transaction to start a unit is
    enqueued while the shutdown is going on. The start of the unit conflicts with
    the shutdown jobs, so they get cancelled. The failure case can be quite unpleasant,
    becase getty and sshd may already be stopped.
    
    Fix it by using irreversible jobs for shutdown (reboot/poweroff/...) actions.
    This applies to commands like "reboot", "telinit 6", "systemctl reboot". Should
    someone desire to use reversible jobs, they can say "systemctl start reboot.target".`

diff --git a/man/systemctl.xml b/man/systemctl.xml
index 0ceb26d..39229a0 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -1006,8 +1006,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
         <term><command>halt</command></term>
 
         <listitem>
-          <para>Shut down and halt the system. This is mostly
-          equivalent to <command>start halt.target</command> but also
+          <para>Shut down and halt the system. This is mostly equivalent to
+          <command>start halt.target --irreversible</command> but also
           prints a wall message to all users.  If combined with
           <option>--force</option> shutdown of all running services is
           skipped, however all processes are killed and all file
@@ -1023,8 +1023,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
         <listitem>
           <para>Shut down and power-off the system. This is mostly
-          equivalent to <command>start poweroff.target</command> but
-          also prints a wall message to all users. If combined with
+          equivalent to <command>start poweroff.target --irreversible</command>
+          but also prints a wall message to all users. If combined with
           <option>--force</option> shutdown of all running services is
           skipped, however all processes are killed and all file
           systems are unmounted or mounted read-only, immediately
@@ -1039,8 +1039,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
         <listitem>
           <para>Shut down and reboot the system. This is mostly
-          equivalent to <command>start reboot.target</command> but
-          also prints a wall message to all users. If combined with
+          equivalent to <command>start reboot.target --irreversible</command>
+          but also prints a wall message to all users. If combined with
           <option>--force</option> shutdown of all running services is
           skipped, however all processes are killed and all file
           systems are unmounted or mounted read-only, immediately
@@ -1055,7 +1055,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
         <listitem>
           <para>Shut down and reboot the system via kexec. This is
-          mostly equivalent to <command>start kexec.target</command>
+          mostly equivalent to <command>start kexec.target --irreversible</command>
           but also prints a wall message to all users. If combined
           with <option>--force</option> shutdown of all running
           services is skipped, however all processes are killed and
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index d235474..818f2fa 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1051,7 +1051,7 @@ static int execute_shutdown_or_sleep(
                 DBusError *error) {
 
         _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
-        const char *mode = "replace", *p;
+        const char *mode = "replace-irreversibly", *p;
         int r;
         char *c;
 
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 723be76..3d59a8b 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1595,11 +1595,22 @@ static int start_unit(DBusConnection *bus, char **args) {
                         streq(args[0], "force-reload")          ? "ReloadOrTryRestartUnit" :
                                                                   "StartUnit";
 
-                mode =
-                        (streq(args[0], "isolate") ||
-                         streq(args[0], "rescue")  ||
-                         streq(args[0], "emergency") ||
-                         streq(args[0], "default")) ? "isolate" : arg_job_mode;
+                if (streq(args[0], "isolate") ||
+                    streq(args[0], "rescue")  ||
+                    streq(args[0], "emergency") ||
+                    streq(args[0], "default"))
+                        mode = "isolate";
+                else if (streq(args[0], "halt") ||
+                         streq(args[0], "poweroff") ||
+                         streq(args[0], "reboot") ||
+                         streq(args[0], "kexec") ||
+                         streq(args[0], "exit") ||
+                         streq(args[0], "suspend") ||
+                         streq(args[0], "hibernate") ||
+                         streq(args[0], "hybrid-sleep"))
+                        mode = "replace-irreversibly";
+                else
+                        mode = arg_job_mode;
 
                 one_name = table[verb_to_action(args[0])];
 
@@ -1614,7 +1625,7 @@ static int start_unit(DBusConnection *bus, char **args) {
                         arg_action == ACTION_RUNLEVEL2 ||
                         arg_action == ACTION_RUNLEVEL3 ||
                         arg_action == ACTION_RUNLEVEL4 ||
-                        arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace";
+                        arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace-irreversibly";
 
                 one_name = table[arg_action];
         }

commit 23ade460e5a118daa575a961b405d089f95e0617
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Fri Feb 22 11:21:37 2013 +0100

    core, systemctl: add support for irreversible jobs
    
    Add a new job mode: replace-irreversibly. Jobs enqueued using this mode
    cannot be implicitly canceled by later enqueued conflicting jobs.
    They can however still be canceled with an explicit "systemctl cancel"
    call.

diff --git a/man/systemctl.xml b/man/systemctl.xml
index c233543..0ceb26d 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -171,6 +171,17 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       </varlistentry>
 
       <varlistentry>
+        <term><option>--irreversible</option></term>
+
+        <listitem>
+          <para>Mark this transaction's jobs as irreversible. This prevents
+          future conflicting transactions from replacing these jobs.
+          The jobs can still be cancelled using the <command>cancel</command>
+          command.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--ignore-dependencies</option></term>
 
         <listitem>
diff --git a/src/core/job.c b/src/core/job.c
index 2bafbc1..990607f 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -169,6 +169,7 @@ static void job_merge_into_installed(Job *j, Job *other) {
                 assert(other->type == JOB_NOP);
 
         j->override = j->override || other->override;
+        j->irreversible = j->irreversible || other->irreversible;
         j->ignore_order = j->ignore_order || other->ignore_order;
 }
 
@@ -294,11 +295,13 @@ void job_dump(Job *j, FILE*f, const char *prefix) {
                 "%s-> Job %u:\n"
                 "%s\tAction: %s -> %s\n"
                 "%s\tState: %s\n"
-                "%s\tForced: %s\n",
+                "%s\tForced: %s\n"
+                "%s\tIrreversible: %s\n",
                 prefix, j->id,
                 prefix, j->unit->id, job_type_to_string(j->type),
                 prefix, job_state_to_string(j->state),
-                prefix, yes_no(j->override));
+                prefix, yes_no(j->override),
+                prefix, yes_no(j->irreversible));
 }
 
 /*
@@ -947,6 +950,7 @@ int job_serialize(Job *j, FILE *f, FDSet *fds) {
         fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
         fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
         fprintf(f, "job-override=%s\n", yes_no(j->override));
+        fprintf(f, "job-irreversible=%s\n", yes_no(j->irreversible));
         fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
         fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
         /* Cannot save bus clients. Just note the fact that we're losing
@@ -1014,6 +1018,12 @@ int job_deserialize(Job *j, FILE *f, FDSet *fds) {
                                 log_debug("Failed to parse job override flag %s", v);
                         else
                                 j->override = j->override || b;
+                } else if (streq(l, "job-irreversible")) {
+                        int b = parse_boolean(v);
+                        if (b < 0)
+                                log_debug("Failed to parse job irreversible flag %s", v);
+                        else
+                                j->irreversible = j->irreversible || b;
                 } else if (streq(l, "job-sent-dbus-new-signal")) {
                         int b = parse_boolean(v);
                         if (b < 0)
@@ -1110,6 +1120,7 @@ DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
 static const char* const job_mode_table[_JOB_MODE_MAX] = {
         [JOB_FAIL] = "fail",
         [JOB_REPLACE] = "replace",
+        [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
         [JOB_ISOLATE] = "isolate",
         [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
         [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
diff --git a/src/core/job.h b/src/core/job.h
index d10e6b6..45d0487 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -83,6 +83,7 @@ enum JobState {
 enum JobMode {
         JOB_FAIL,                /* Fail if a conflicting job is already queued */
         JOB_REPLACE,             /* Replace an existing conflicting job */
+        JOB_REPLACE_IRREVERSIBLY, /* Like JOB_REPLACE + produce irreversible jobs */
         JOB_ISOLATE,             /* Start a unit, and stop all others */
         JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */
         JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */
@@ -161,6 +162,7 @@ struct Job {
         bool sent_dbus_new_signal:1;
         bool ignore_order:1;
         bool forgot_bus_clients:1;
+        bool irreversible:1;
 };
 
 JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name);
diff --git a/src/core/manager.c b/src/core/manager.c
index 28f169d..a578813 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -766,7 +766,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove
 
         job_type_collapse(&type, unit);
 
-        tr = transaction_new();
+        tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
         if (!tr)
                 return -ENOMEM;
 
diff --git a/src/core/transaction.c b/src/core/transaction.c
index dbc30af..0329366 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -97,6 +97,7 @@ static void transaction_merge_and_delete_job(Transaction *tr, Job *j, Job *other
         j->type = t;
         j->state = JOB_WAITING;
         j->override = j->override || other->override;
+        j->irreversible = j->irreversible || other->irreversible;
 
         j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor;
 
@@ -488,7 +489,7 @@ rescan:
         }
 }
 
-static int transaction_is_destructive(Transaction *tr, DBusError *e) {
+static int transaction_is_destructive(Transaction *tr, JobMode mode, DBusError *e) {
         Iterator i;
         Job *j;
 
@@ -503,7 +504,7 @@ static int transaction_is_destructive(Transaction *tr, DBusError *e) {
                 assert(!j->transaction_prev);
                 assert(!j->transaction_next);
 
-                if (j->unit->job &&
+                if (j->unit->job && (mode == JOB_FAIL || j->unit->job->irreversible) &&
                     !job_type_is_superset(j->type, j->unit->job->type)) {
 
                         dbus_set_error(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive.");
@@ -709,12 +710,10 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e
         transaction_drop_redundant(tr);
 
         /* Ninth step: check whether we can actually apply this */
-        if (mode == JOB_FAIL) {
-                r = transaction_is_destructive(tr, e);
-                if (r < 0) {
-                        log_notice("Requested transaction contradicts existing jobs: %s", bus_error(e, r));
-                        return r;
-                }
+        r = transaction_is_destructive(tr, mode, e);
+        if (r < 0) {
+                log_notice("Requested transaction contradicts existing jobs: %s", bus_error(e, r));
+                return r;
         }
 
         /* Tenth step: apply changes */
@@ -770,6 +769,7 @@ static Job* transaction_add_one_job(Transaction *tr, JobType type, Unit *unit, b
         j->marker = NULL;
         j->matters_to_anchor = false;
         j->override = override;
+        j->irreversible = tr->irreversible;
 
         LIST_PREPEND(Job, transaction, f, j);
 
@@ -1106,7 +1106,7 @@ int transaction_add_isolate_jobs(Transaction *tr, Manager *m) {
         return 0;
 }
 
-Transaction *transaction_new(void) {
+Transaction *transaction_new(bool irreversible) {
         Transaction *tr;
 
         tr = new0(Transaction, 1);
@@ -1119,6 +1119,8 @@ Transaction *transaction_new(void) {
                 return NULL;
         }
 
+        tr->irreversible = irreversible;
+
         return tr;
 }
 
diff --git a/src/core/transaction.h b/src/core/transaction.h
index 67ace4d..12f9194 100644
--- a/src/core/transaction.h
+++ b/src/core/transaction.h
@@ -33,9 +33,10 @@ struct Transaction {
         /* Jobs to be added */
         Hashmap *jobs;      /* Unit object => Job object list 1:1 */
         Job *anchor_job;      /* the job the user asked for */
+        bool irreversible;
 };
 
-Transaction *transaction_new(void);
+Transaction *transaction_new(bool irreversible);
 void transaction_free(Transaction *tr);
 
 int transaction_add_job_and_dependencies(
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 0f19c25..723be76 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -4306,6 +4306,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_FAIL = 0x100,
+                ARG_IRREVERSIBLE,
                 ARG_IGNORE_DEPENDENCIES,
                 ARG_VERSION,
                 ARG_USER,
@@ -4334,6 +4335,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      },
+                { "irreversible", no_argument,    NULL, ARG_IRREVERSIBLE },
                 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
                 { "ignore-inhibitors", no_argument, NULL, 'i'         },
                 { "user",      no_argument,       NULL, ARG_USER      },
@@ -4433,6 +4435,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         arg_job_mode = "fail";
                         break;
 
+                case ARG_IRREVERSIBLE:
+                        arg_job_mode = "replace-irreversibly";
+                        break;
+
                 case ARG_IGNORE_DEPENDENCIES:
                         arg_job_mode = "ignore-dependencies";
                         break;

commit b7cf6049a36dfd8e5f3c6420243eb49d348dbd2f
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Fri Feb 22 09:56:16 2013 +0100

    systemctl: make "systemctl default" use "isolate" job mode
    
    "systemctl default" should behave identically to "telinit N" (where N is the
    corresponding runlevel target number), therefore it should use isolate job mode
    too.

diff --git a/man/systemctl.xml b/man/systemctl.xml
index 683f2e7..c233543 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -970,7 +970,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
         <listitem>
           <para>Enter default mode. This is mostly equivalent to
-          <command>start default.target</command>.</para>
+          <command>isolate default.target</command>.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 509651c..0f19c25 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1598,7 +1598,8 @@ static int start_unit(DBusConnection *bus, char **args) {
                 mode =
                         (streq(args[0], "isolate") ||
                          streq(args[0], "rescue")  ||
-                         streq(args[0], "emergency")) ? "isolate" : arg_job_mode;
+                         streq(args[0], "emergency") ||
+                         streq(args[0], "default")) ? "isolate" : arg_job_mode;
 
                 one_name = table[verb_to_action(args[0])];
 



More information about the systemd-commits mailing list