[systemd-commits] 7 commits - DISTRO_PORTING man/systemctl.xml man/systemd-install.xml man/systemd.xml src/cgroup-util.c src/dbus-manager.c src/dbus-unit.c src/dbus-unit.h src/install.c src/main.c src/manager.c src/manager.h src/snapshot.c src/systemctl.c src/unit.c src/util.c

Lennart Poettering lennart at kemper.freedesktop.org
Tue Jul 13 11:20:51 PDT 2010


 DISTRO_PORTING          |   13 +++++-----
 man/systemctl.xml       |   34 +++++++++++++++++++++------
 man/systemd-install.xml |   60 +++++++++++++++++++++++++++++++++++++-----------
 man/systemd.xml         |   26 +++++++++++---------
 src/cgroup-util.c       |   29 ++++++++++++-----------
 src/dbus-manager.c      |   26 ++++++++++++++++++++
 src/dbus-unit.c         |   16 ++++++++++++
 src/dbus-unit.h         |   10 +++++++-
 src/install.c           |   42 +++++++++++++++++++++------------
 src/main.c              |   52 ++++++++++++++++++++++++++---------------
 src/manager.c           |   24 ++++++++++++++++---
 src/manager.h           |    2 -
 src/snapshot.c          |    2 -
 src/systemctl.c         |   35 +++++++++++++++++++---------
 src/unit.c              |   12 +++++----
 src/util.c              |   11 ++++----
 16 files changed, 280 insertions(+), 114 deletions(-)

New commits:
commit 6f28c033ec506847b3bfa4efaf52478120c36946
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jul 13 20:20:36 2010 +0200

    systemctl: introduce try-restart and reload-or-restart commands

diff --git a/man/systemctl.xml b/man/systemctl.xml
index 22d3f6e..d73e974 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -194,13 +194,6 @@
                                 line.</para></listitem>
                         </varlistentry>
                         <varlistentry>
-                                <term><command>restart [NAME...]</command></term>
-
-                                <listitem><para>Restart one or more
-                                units specified on the command
-                                line.</para></listitem>
-                        </varlistentry>
-                        <varlistentry>
                                 <term><command>reload [NAME...]</command></term>
 
                                 <listitem><para>Asks all services
@@ -227,6 +220,33 @@
 
                         </varlistentry>
                         <varlistentry>
+                                <term><command>restart [NAME...]</command></term>
+
+                                <listitem><para>Restart one or more
+                                units specified on the command
+                                line. If the units are not running yet
+                                they will be
+                                started.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>try-restart [NAME...]</command></term>
+
+                                <listitem><para>Restart one or more
+                                units specified on the command
+                                line. If the units are not running yet
+                                the operation will
+                                fail.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><command>reload-or-restart [NAME...]</command></term>
+                                <term><command>reload-or-try-restart [NAME...]</command></term>
+
+                                <listitem><para>Reload one or more
+                                units if they support it. If not
+                                restart them
+                                instead.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
                                 <term><command>isolate [NAME]</command></term>
 
                                 <listitem><para>Start the unit
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index f52b06e..c717ccd 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -62,6 +62,16 @@
         "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
         "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
         "  </method>\n"                                                 \
+        "  <method name=\"ReloadOrRestartUnit\">\n"                     \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReloadOrTryRestartUnit\">\n"                  \
+        "   <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
         "  <method name=\"GetJob\">\n"                                  \
         "   <arg name=\"id\" type=\"u\" direction=\"in\"/>\n"           \
         "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
@@ -239,6 +249,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
         DBusMessage *reply = NULL;
         char * path = NULL;
         JobType job_type = _JOB_TYPE_INVALID;
+        bool reload_if_possible = false;
 
         assert(connection);
         assert(message);
@@ -310,7 +321,13 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
                 job_type = JOB_RESTART;
         else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "TryRestartUnit"))
                 job_type = JOB_TRY_RESTART;
-        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) {
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrRestartUnit")) {
+                reload_if_possible = true;
+                job_type = JOB_RESTART;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrTryRestartUnit")) {
+                reload_if_possible = true;
+                job_type = JOB_TRY_RESTART;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) {
                 uint32_t id;
                 Job *j;
 
@@ -739,6 +756,13 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
                 if ((r = manager_load_unit(m, name, NULL, &error, &u)) < 0)
                         return bus_send_error_reply(m, connection, message, &error, r);
 
+                if (reload_if_possible && unit_can_reload(u)) {
+                        if (job_type == JOB_RESTART)
+                                job_type = JOB_RELOAD_OR_START;
+                        else if (job_type == JOB_TRY_RESTART)
+                                job_type = JOB_RELOAD;
+                }
+
                 if (job_type == JOB_START && u->meta.only_by_dependency) {
                         dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Unit may be activated by dependency only.");
                         return bus_send_error_reply(m, connection, message, &error, -EPERM);
diff --git a/src/dbus-unit.c b/src/dbus-unit.c
index 735e5a5..da7d1bd 100644
--- a/src/dbus-unit.c
+++ b/src/dbus-unit.c
@@ -260,6 +260,7 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn
         DBusError error;
         JobType job_type = _JOB_TYPE_INVALID;
         char *path = NULL;
+        bool reload_if_possible = false;
 
         dbus_error_init(&error);
 
@@ -273,7 +274,13 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn
                 job_type = JOB_RESTART;
         else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "TryRestart"))
                 job_type = JOB_TRY_RESTART;
-        else if (UNIT_VTABLE(u)->bus_message_handler)
+        else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrRestart")) {
+                reload_if_possible = true;
+                job_type = JOB_RESTART;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrTryRestart")) {
+                reload_if_possible = true;
+                job_type = JOB_TRY_RESTART;
+        } else if (UNIT_VTABLE(u)->bus_message_handler)
                 return UNIT_VTABLE(u)->bus_message_handler(u, connection, message);
         else
                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -296,6 +303,13 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn
                                     DBUS_TYPE_INVALID))
                         return bus_send_error_reply(m, connection, message, &error, -EINVAL);
 
+                if (reload_if_possible && unit_can_reload(u)) {
+                        if (job_type == JOB_RESTART)
+                                job_type = JOB_RELOAD_OR_START;
+                        else if (job_type == JOB_TRY_RESTART)
+                                job_type = JOB_RELOAD;
+                }
+
                 if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) {
                         dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode);
                         return bus_send_error_reply(m, connection, message, &error, -EINVAL);
diff --git a/src/dbus-unit.h b/src/dbus-unit.h
index 17965b6..1d11af3 100644
--- a/src/dbus-unit.h
+++ b/src/dbus-unit.h
@@ -36,6 +36,10 @@
         "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
         "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
         "  </method>\n"                                                 \
+        "  <method name=\"Reload\">\n"                                  \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
         "  <method name=\"Restart\">\n"                                 \
         "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
         "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
@@ -44,7 +48,11 @@
         "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
         "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
         "  </method>\n"                                                 \
-        "  <method name=\"Reload\">\n"                                  \
+        "  <method name=\"ReloadOrRestart\">\n"                         \
+        "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReloadOrTryRestart\">\n"                      \
         "   <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"         \
         "   <arg name=\"job\" type=\"o\" direction=\"out\"/>\n"         \
         "  </method>\n"                                                 \
diff --git a/src/systemctl.c b/src/systemctl.c
index 4218a22..bdb294e 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -733,10 +733,13 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) {
 
         if (arg_action == ACTION_SYSTEMCTL) {
                 method =
-                        streq(args[0], "stop")    ? "StopUnit" :
-                        streq(args[0], "reload")  ? "ReloadUnit" :
-                        streq(args[0], "restart") ? "RestartUnit" :
-                                                    "StartUnit";
+                        streq(args[0], "stop")                  ? "StopUnit" :
+                        streq(args[0], "reload")                ? "ReloadUnit" :
+                        streq(args[0], "restart")               ? "RestartUnit" :
+                        streq(args[0], "try-restart")           ? "TryRestartUnit" :
+                        streq(args[0], "reload-or-restart")     ? "ReloadOrRestartUnit" :
+                        streq(args[0], "reload-or-try-restart") ? "ReloadOrTryRestartUnit" :
+                                                                  "StartUnit";
 
                 mode =
                         (streq(args[0], "isolate") ||
@@ -2497,7 +2500,8 @@ static int systemctl_help(void) {
                "  -t --type=TYPE     List only units of a particular type\n"
                "  -p --property=NAME Show only properties by this name\n"
                "  -a --all           Show all units/properties, including dead/empty ones\n"
-               "     --fail          When installing a new job, fail if conflicting jobs are pending\n"
+               "     --fail          When installing a new job, fail if conflicting jobs are\n"
+               "                     pending\n"
                "     --system        Connect to system bus\n"
                "     --session       Connect to session bus\n"
                "  -q --quiet         Suppress output\n"
@@ -2507,12 +2511,18 @@ static int systemctl_help(void) {
                "  list-units                      List units\n"
                "  start [NAME...]                 Start one or more units\n"
                "  stop [NAME...]                  Stop one or more units\n"
-               "  restart [NAME...]               Restart one or more units\n"
                "  reload [NAME...]                Reload one or more units\n"
+               "  restart [NAME...]               Start or restart one or more units\n"
+               "  try-restart [NAME...]           Restart one or more units if active\n"
+               "  reload-or-restart [NAME...]     Reload one or more units is possible,\n"
+               "                                  otherwise start or restart\n"
+               "  reload-or-try-restart [NAME...] Reload one or more units is possible,\n"
+               "                                  otherwise restart if active\n"
                "  isolate [NAME]                  Start one unit and stop all others\n"
-               "  check [NAME...]                 Check whether any of the passed units are active\n"
+               "  check [NAME...]                 Check whether units are active\n"
                "  status [NAME...]                Show status of one or more units\n"
-               "  show [NAME...|JOB...]           Show properties of one or more units/jobs/manager\n"
+               "  show [NAME...|JOB...]           Show properties of one or more\n"
+               "                                  units/jobs/manager\n"
                "  load [NAME...]                  Load one or more units\n"
                "  list-jobs                       List jobs\n"
                "  cancel [JOB...]                 Cancel one or more jobs\n"
@@ -2530,9 +2540,9 @@ static int systemctl_help(void) {
                "  halt                            Shut down and halt the system\n"
                "  poweroff                        Shut down and power-off the system\n"
                "  reboot                          Shut down and reboot the system\n"
-               "  default                         Enter default mode\n"
-               "  rescue                          Enter rescue mode\n"
-               "  emergency                       Enter emergency mode\n",
+               "  rescue                          Enter system rescue mode\n"
+               "  emergency                       Enter system emergency mode\n"
+               "  default                         Enter system default mode\n",
                program_invocation_short_name);
 
         return 0;
@@ -3193,6 +3203,9 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[]) {
                 { "stop",              MORE,  2, start_unit      },
                 { "reload",            MORE,  2, start_unit      },
                 { "restart",           MORE,  2, start_unit      },
+                { "try-restart",       MORE,  2, start_unit      },
+                { "reload-or-restart", MORE,  2, start_unit      },
+                { "reload-or-try-restart", MORE, 2, start_unit   },
                 { "isolate",           EQUAL, 2, start_unit      },
                 { "check",             MORE,  2, check_unit      },
                 { "show",              MORE,  1, show            },
commit 3dda9fc3a738241e42df43dbebf9e479e5ad1da8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jul 13 20:07:00 2010 +0200

    manager: always allow stopping of units that failed to load

diff --git a/src/manager.c b/src/manager.c
index cdcd693..5884835 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -1328,7 +1328,8 @@ static int transaction_add_job_and_dependencies(
         assert(type < _JOB_TYPE_MAX);
         assert(unit);
 
-        if (unit->meta.load_state != UNIT_LOADED) {
+        if (type != JOB_STOP &&
+            unit->meta.load_state != UNIT_LOADED) {
                 dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load. See logs for details.", unit->meta.id);
                 return -EINVAL;
         }
commit 1d2e23ab72b15524ffc009e0553c4b8d08f073b8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jul 13 20:06:29 2010 +0200

    main: introduce -D as quick acess to debugging

diff --git a/src/main.c b/src/main.c
index 27ad4c4..5af3587 100644
--- a/src/main.c
+++ b/src/main.c
@@ -582,7 +582,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 1);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "hD", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -715,6 +715,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_action = ACTION_HELP;
                         break;
 
+                case 'D':
+                        log_set_max_level(LOG_DEBUG);
+                        break;
+
                 case '?':
                         return -EINVAL;
 
commit 53b543608ec293cd3138c526fa39b1f888120498
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jul 13 20:05:47 2010 +0200

    install: implement systemd-install realize

diff --git a/man/systemd-install.xml b/man/systemd-install.xml
index 28415d1..1e26310 100644
--- a/man/systemd-install.xml
+++ b/man/systemd-install.xml
@@ -56,6 +56,9 @@
                         <command>systemd-install <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="plain">disable</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
                 </cmdsynopsis>
                 <cmdsynopsis>
+                        <command>systemd-install <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="plain">realize</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
+                </cmdsynopsis>
+                <cmdsynopsis>
                         <command>systemd-install <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="plain">test</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
                 </cmdsynopsis>
         </refsynopsisdiv>
@@ -168,8 +171,10 @@
                                 <option>yes</option> starts the unit
                                 unconditionally after enabling. This
                                 setting defaults to
-                                <option>no</option>. If the mode value
-                                is omitted defaults to
+                                <option>no</option>. If
+                                <option>--realize</option> is
+                                specifieed but the mode value is
+                                omitted defaults to
                                 <option>maybe</option>. This option
                                 has no effect when
                                 <option>--global</option> or
@@ -177,7 +182,9 @@
                                 when systemd is not running or the
                                 command is executed in a
                                 <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-                                environment.</para></listitem>
+                                environment. This option is implied if
+                                the <command>realize</command> command
+                                is used.</para></listitem>
                         </varlistentry>
                 </variablelist>
 
@@ -187,9 +194,9 @@
                         <varlistentry>
                                 <term><command>enable</command></term>
 
-                                <listitem><para>Enable a unit. This
-                                will create a number of symlinks as
-                                encoded in the
+                                <listitem><para>Enable one or more
+                                units. This will create a number of
+                                symlinks as encoded in the
                                 <literal>[Install]</literal> section
                                 of a unit file.</para></listitem>
                         </varlistentry>
@@ -197,24 +204,51 @@
                         <varlistentry>
                                 <term><command>disable</command></term>
 
-                                <listitem><para>Disable a unit. This
-                                will remove a number of symlinks as
-                                encoded in the
+                                <listitem><para>Disable or more
+                                units. This will remove a number of
+                                symlinks as encoded in the
                                 <literal>[Install]</literal> section
                                 of a unit file.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
+                                <term><command>realize</command></term>
+
+                                <listitem><para>Does not enable or
+                                disable any unit. Checks whether any
+                                of the units specified are enabled,
+                                and then starts/stops/restarts the
+                                units accordingly. This will check for
+                                the existence of a number of symlinks
+                                as encoded in the
+                                <literal>[Install]</literal> section
+                                of a unit file, and then executes the
+                                action normally specified by
+                                <option>--realize</option>. If
+                                <option>--realize</option> is not
+                                specified implies
+                                <option>maybe</option> mode. To
+                                override this mode specify
+                                <option>--realize=</option> in
+                                addition to
+                                <command>realize</command>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><command>test</command></term>
 
-                                <listitem><para>Checks whether any of
-                                the units specified are
-                                installed. This will check for the
+                                <listitem><para>Does not enable or
+                                disable any unit. Checks whether any
+                                of the units specified are
+                                enabled. This will check for the
                                 existence of a number of symlinks as
                                 encoded in the
                                 <literal>[Install]</literal> section
-                                of a unit file.</para></listitem>
+                                of a unit file, and return with an
+                                exit code of 0 if a unit is enabled, 1
+                                otherwise.</para></listitem>
                         </varlistentry>
+
                 </variablelist>
 
         </refsect1>
diff --git a/src/install.c b/src/install.c
index 38c0513..6fc2a9f 100644
--- a/src/install.c
+++ b/src/install.c
@@ -46,6 +46,7 @@ static enum {
         ACTION_INVALID,
         ACTION_ENABLE,
         ACTION_DISABLE,
+        ACTION_REALIZE,
         ACTION_TEST
 } arg_action = ACTION_INVALID;
 
@@ -81,6 +82,8 @@ static int help(void) {
                "Commands:\n"
                "  enable [NAME...]    Enable one or more units\n"
                "  disable [NAME...]   Disable one or more units\n"
+               "  realize [NAME...]   Test whether any of the specified units are enabled\n"
+               "                      and the start/stop/restart units accordingly\n"
                "  test [NAME...]      Test whether any of the specified units are enabled\n",
                program_invocation_short_name);
 
@@ -108,6 +111,7 @@ static int parse_argv(int argc, char *argv[]) {
         };
 
         int c;
+        bool realize_switch = false;
 
         assert(argc >= 1);
         assert(argv);
@@ -138,6 +142,8 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case ARG_REALIZE:
 
+                        realize_switch = true;
+
                         if (!optarg)
                                 arg_realize = REALIZE_MAYBE;
                         else if (streq(optarg, "no"))
@@ -177,7 +183,12 @@ static int parse_argv(int argc, char *argv[]) {
                 arg_action = ACTION_DISABLE;
         else if (streq(argv[optind], "test"))
                 arg_action = ACTION_TEST;
-        else {
+        else if (streq(argv[optind], "realize")) {
+                arg_action = ACTION_REALIZE;
+
+                if (!realize_switch)
+                        arg_realize = REALIZE_MAYBE;
+        } else {
                 log_error("Unknown verb %s.", argv[optind]);
                 return -EINVAL;
         }
@@ -297,7 +308,7 @@ finish:
         return r;
 }
 
-static int install_info_run(DBusConnection *bus, InstallInfo *i) {
+static int install_info_run(DBusConnection *bus, InstallInfo *i, bool enabled) {
         DBusMessage *m = NULL, *reply = NULL;
         DBusError error;
         int r;
@@ -308,7 +319,8 @@ static int install_info_run(DBusConnection *bus, InstallInfo *i) {
 
         dbus_error_init(&error);
 
-        if (arg_action == ACTION_ENABLE) {
+        if (arg_action == ACTION_ENABLE ||
+            (arg_action == ACTION_REALIZE && enabled)) {
 
                 if (arg_realize == REALIZE_MAYBE) {
                         char **k;
@@ -436,7 +448,8 @@ static int install_info_run(DBusConnection *bus, InstallInfo *i) {
                 }
 
 
-        } else if (arg_action == ACTION_DISABLE) {
+        } else if (arg_action == ACTION_DISABLE ||
+                   (arg_action == ACTION_REALIZE && !enabled)) {
 
                 if (!(m = dbus_message_new_method_call(
                                       "org.freedesktop.systemd1",
@@ -456,10 +469,11 @@ static int install_info_run(DBusConnection *bus, InstallInfo *i) {
                         r = -ENOMEM;
                         goto finish;
                 }
-        }
+        } else
+                assert_not_reached("install_info_run() called but nothing to do?");
 
         if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
-                log_error("Failed to reload configuration: %s", error.message);
+                log_error("Failed to realize unit: %s", error.message);
                 r = -EIO;
                 goto finish;
         }
@@ -591,7 +605,7 @@ static int create_symlink(const char *old_path, const char *new_path) {
                 log_error("Cannot unlink %s: %m", new_path);
                 return -errno;
 
-        } else if (arg_action == ACTION_TEST) {
+        } else if (arg_action == ACTION_TEST || arg_action == ACTION_REALIZE) {
                 char *dest;
 
                 if ((r = readlink_and_make_absolute(new_path, &dest)) < 0) {
@@ -773,7 +787,7 @@ static char *get_config_path(void) {
         }
 }
 
-static int do_realize(void) {
+static int do_realize(bool enabled) {
         DBusConnection *bus = NULL;
         DBusError error;
         int r, q;
@@ -790,7 +804,7 @@ static int do_realize(void) {
                 return 0;
         }
 
-        if (arg_action != ACTION_ENABLE && arg_action != ACTION_DISABLE) {
+        if (arg_action == ACTION_TEST) {
                 log_warning("Warning: --realize has no effect with test.");
                 return 0;
         }
@@ -812,13 +826,13 @@ static int do_realize(void) {
 
         r = 0;
 
-        if (arg_action == ACTION_ENABLE)
+        if (arg_action == ACTION_ENABLE || arg_action == ACTION_REALIZE)
                 if ((r = daemon_reload(bus)) < 0)
                         goto finish;
 
         if (arg_realize != REALIZE_RELOAD) {
                 HASHMAP_FOREACH(j, have_installed, i)
-                        if ((q = install_info_run(bus, j)) < 0)
+                        if ((q = install_info_run(bus, j, enabled)) < 0)
                                 r = q;
         }
 
@@ -887,15 +901,13 @@ int main(int argc, char *argv[]) {
 
                         /* In test mode and found something */
                         retval = 0;
-                        goto finish;
+                        break;
                 }
         }
 
-        if (do_realize() < 0)
+        if (do_realize(!retval) < 0)
                 goto finish;
 
-        retval = arg_action == ACTION_TEST ? 1 : 0;
-
 finish:
         install_info_hashmap_free(will_install);
         install_info_hashmap_free(have_installed);
commit 9f611ad82e1eb1a9885f07ac95c244b25a7fbac7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jul 13 19:01:20 2010 +0200

    unit: disable retroactive starting/stopping of units when deserializing

diff --git a/src/manager.c b/src/manager.c
index 9667e29..cdcd693 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -544,6 +544,12 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
 
         manager_build_unit_path_cache(m);
 
+        /* If we will deserialize make sure that during enumeration
+         * this is already known, so we increase the counter here
+         * already */
+        if (serialization)
+                m->n_deserializing ++;
+
         /* First, enumerate what we can from all config files */
         r = manager_enumerate(m);
 
@@ -556,6 +562,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
         if ((q = manager_coldplug(m)) < 0)
                 r = q;
 
+        if (serialization) {
+                assert(m->n_deserializing > 0);
+                m->n_deserializing --;
+        }
+
         /* Now that the initial devices are available, let's see if we
          * can write the utmp file */
         manager_write_utmp_reboot(m);
@@ -2334,7 +2345,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
 
         log_debug("Deserializing state...");
 
-        m->deserializing = true;
+        m->n_deserializing ++;
 
         for (;;) {
                 Unit *u;
@@ -2366,7 +2377,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
         r = 0;
 
 finish:
-        m->deserializing = false;
+        assert(m->n_deserializing > 0);
+        m->n_deserializing --;
 
         return r;
 }
@@ -2402,6 +2414,8 @@ int manager_reload(Manager *m) {
         if ((q = lookup_paths_init(&m->lookup_paths, m->running_as)) < 0)
                 r = q;
 
+        m->n_deserializing ++;
+
         /* First, enumerate what we can from all config files */
         if ((q = manager_enumerate(m)) < 0)
                 r = q;
@@ -2417,6 +2431,9 @@ int manager_reload(Manager *m) {
         if ((q = manager_coldplug(m)) < 0)
                 r = q;
 
+        assert(m->n_deserializing > 0);
+        m->n_deserializing ++;
+
 finish:
         if (f)
                 fclose(f);
diff --git a/src/manager.h b/src/manager.h
index 0eceab9..32fbacc 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -192,7 +192,7 @@ struct Manager {
 
         bool utmp_reboot_written:1;
 
-        bool deserializing:1;
+        int n_deserializing;
 
         bool show_status;
         bool confirm_spawn;
diff --git a/src/snapshot.c b/src/snapshot.c
index 11e7c3e..e158338 100644
--- a/src/snapshot.c
+++ b/src/snapshot.c
@@ -56,7 +56,7 @@ static int snapshot_load(Unit *u) {
 
         /* Make sure that only snapshots created via snapshot_create()
          * can be loaded */
-        if (!s->by_snapshot_create && !s->meta.manager->deserializing)
+        if (!s->by_snapshot_create && s->meta.manager->n_deserializing <= 0)
                 return -ENOENT;
 
         u->meta.load_state = UNIT_LOADED;
diff --git a/src/unit.c b/src/unit.c
index 3f42f0f..0c92756 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -1043,14 +1043,16 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
                         assert_not_reached("Job type unknown");
                 }
 
-                /* If this state change happened without being
-                 * requested by a job, then let's retroactively start
-                 * or stop dependencies */
-
         } else
                 unexpected = true;
 
-        if (unexpected) {
+        /* If this state change happened without being requested by a
+         * job, then let's retroactively start or stop
+         * dependencies. We skip that step when deserializing, since
+         * we don't want to create any additional jobs just because
+         * something is already activated. */
+
+        if (unexpected && u->meta.manager->n_deserializing <= 0) {
                 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
                         retroactively_start_dependencies(u);
                 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
commit 4c633005eacdf964d22107f453ba804868f33a25
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jul 13 19:00:01 2010 +0200

    cgroup: treat non-existing cgroups like empty ones, to deal with races

diff --git a/src/cgroup-util.c b/src/cgroup-util.c
index 26e8f69..828b304 100644
--- a/src/cgroup-util.c
+++ b/src/cgroup-util.c
@@ -189,7 +189,7 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self)
                 done = true;
 
                 if ((r = cg_enumerate_processes(controller, path, &f)) < 0) {
-                        if (ret >= 0)
+                        if (ret >= 0 && r != -ENOENT)
                                 ret = r;
 
                         goto finish;
@@ -205,8 +205,8 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self)
 
                         /* If we haven't killed this process yet, kill
                          * it */
-                        if (kill(pid, sig) < 0 && errno != ESRCH) {
-                                if (ret >= 0)
+                        if (kill(pid, sig) < 0) {
+                                if (ret >= 0 && errno != ESRCH)
                                         ret = -errno;
                         } else if (ret == 0)
                                 ret = 1;
@@ -258,7 +258,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool ig
         ret = cg_kill(controller, path, sig, ignore_self);
 
         if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) {
-                if (ret >= 0)
+                if (ret >= 0 && r != -ENOENT)
                         ret = r;
 
                 goto finish;
@@ -289,7 +289,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool ig
 
         if (rem)
                 if ((r = cg_rmdir(controller, path)) < 0) {
-                        if (ret >= 0)
+                        if (ret >= 0 && r != -ENOENT)
                                 ret = r;
                 }
 
@@ -351,7 +351,7 @@ int cg_migrate(const char *controller, const char *from, const char *to, bool ig
                 done = true;
 
                 if ((r = cg_enumerate_tasks(controller, from, &f)) < 0) {
-                        if (ret >= 0)
+                        if (ret >= 0 && r != -ENOENT)
                                 ret = r;
 
                         goto finish;
@@ -369,7 +369,7 @@ int cg_migrate(const char *controller, const char *from, const char *to, bool ig
                                 continue;
 
                         if ((r = cg_attach(controller, to, pid)) < 0) {
-                                if (ret >= 0)
+                                if (ret >= 0 && r != -ESRCH)
                                         ret = r;
                         } else if (ret == 0)
                                 ret = 1;
@@ -417,7 +417,7 @@ int cg_migrate_recursive(const char *controller, const char *from, const char *t
         ret = cg_migrate(controller, from, to, ignore_self);
 
         if ((r = cg_enumerate_subgroups(controller, from, &d)) < 0) {
-                if (ret >= 0)
+                if (ret >= 0 && r != -ENOENT)
                         ret = r;
                 goto finish;
         }
@@ -447,7 +447,7 @@ int cg_migrate_recursive(const char *controller, const char *from, const char *t
 
         if (rem)
                 if ((r = cg_rmdir(controller, from)) < 0) {
-                        if (ret >= 0)
+                        if (ret >= 0 && r != -ENOENT)
                                 ret = r;
                 }
 
@@ -517,7 +517,7 @@ int cg_trim(const char *controller, const char *path, bool delete_root) {
         r = rm_rf(fs, true, delete_root);
         free(fs);
 
-        return r;
+        return r == -ENOENT ? 0 : r;
 }
 
 int cg_delete(const char *controller, const char *path) {
@@ -533,7 +533,7 @@ int cg_delete(const char *controller, const char *path) {
         r = cg_migrate_recursive(controller, path, parent, false, true);
         free(parent);
 
-        return r;
+        return r == -ENOENT ? 0 : r;
 }
 
 int cg_create(const char *controller, const char *path) {
@@ -646,6 +646,9 @@ int cg_get_by_pid(const char *controller, pid_t pid, char **path) {
         f = fopen(fs, "re");
         free(fs);
 
+        if (!f)
+                return errno == ENOENT ? -ESRCH : -errno;
+
         cs = strlen(controller);
 
         while (!feof(f)) {
@@ -763,7 +766,7 @@ int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
         assert(path);
 
         if ((r = cg_enumerate_tasks(controller, path, &f)) < 0)
-                return r;
+                return r == -ENOENT ? 1 : r;
 
         while ((r = cg_read_pid(f, &pid)) > 0) {
 
@@ -794,7 +797,7 @@ int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_
                 return r;
 
         if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0)
-                return r;
+                return r == -ENOENT ? 1 : r;
 
         while ((r = cg_read_subgroup(d, &fn)) > 0) {
                 char *p = NULL;
diff --git a/src/util.c b/src/util.c
index e5d8456..519d229 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2565,7 +2565,8 @@ static int rm_rf_children(int fd, bool only_dirs) {
 
         if (!(d = fdopendir(fd))) {
                 close_nointr_nofail(fd);
-                return -errno;
+
+                return errno == ENOENT ? 0 : -errno;
         }
 
         for (;;) {
@@ -2589,7 +2590,7 @@ static int rm_rf_children(int fd, bool only_dirs) {
                         struct stat st;
 
                         if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
-                                if (ret == 0)
+                                if (ret == 0 && errno != ENOENT)
                                         ret = -errno;
                                 continue;
                         }
@@ -2602,7 +2603,7 @@ static int rm_rf_children(int fd, bool only_dirs) {
                         int subdir_fd;
 
                         if ((subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)) < 0) {
-                                if (ret == 0)
+                                if (ret == 0 && errno != ENOENT)
                                         ret = -errno;
                                 continue;
                         }
@@ -2613,13 +2614,13 @@ static int rm_rf_children(int fd, bool only_dirs) {
                         }
 
                         if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
-                                if (ret == 0)
+                                if (ret == 0 && errno != ENOENT)
                                         ret = -errno;
                         }
                 } else  if (!only_dirs) {
 
                         if (unlinkat(fd, de->d_name, 0) < 0) {
-                                if (ret == 0)
+                                if (ret == 0 && errno != ENOENT)
                                         ret = -errno;
                         }
                 }
commit edb9aaa8b27adf89cc712000318b1e9cf40ea296
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jul 13 18:57:58 2010 +0200

    main: replace --running-as= by --session and --system do mimic related tools and D-Bus

diff --git a/DISTRO_PORTING b/DISTRO_PORTING
index fedbc0e..2b08bf8 100644
--- a/DISTRO_PORTING
+++ b/DISTRO_PORTING
@@ -10,7 +10,8 @@ HOWTO:
         you need to add/change things.
 
         1) Patch src/hostname-setup.c so that systemd knows where to
-        read your host name from.
+        read your host name from. You might also want to update
+        status_welcome() in util.c.
 
         2) Check the unit files in units/ if they match your
         distribution. Most likely you will have to make additions to
@@ -23,11 +24,11 @@ HOWTO:
         and you should be able to find the places where you need to
         add/change things.
 
-        4) Try it out. Play around with 'systemd --test
-        --running-as=init' for a test run of systemd without
-        booting. This will read the unit files and print the initial
-        transaction it would execute during boot-up. This will also
-        inform you about ordering loops and suchlike.
+        4) Try it out. Play around with 'systemd --test --system' for
+        a test run of systemd without booting. This will read the unit
+        files and print the initial transaction it would execute
+        during boot-up. This will also inform you about ordering loops
+        and suchlike.
 
 CONTRIBUTING UPSTREAM:
         We are interested in merging your changes upstream, if they
diff --git a/man/systemd.xml b/man/systemd.xml
index 0798f23..d19094c 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -135,17 +135,19 @@
                                 <filename>default.target</filename>.</para></listitem>
                         </varlistentry>
                         <varlistentry>
-                                <term><option>--running-as=</option></term>
-
-                                <listitem><para>Tell systemd to run in
-                                a particular mode. Argument is one of
-                                <option>system</option>,
-                                <option>session</option>. Normally it
-                                should not be necessary to pass this
-                                option, as systemd automatically
-                                detects the mode it is started
-                                in. This call is hence of little use
-                                except for
+                                <term><option>--system</option></term>
+                                <term><option>--session</option></term>
+
+                                <listitem><para>Tell systemd to run a
+                                system instance (resp. session
+                                instance), even if the process ID is
+                                not 1 (resp. is 1), i.e. system is not
+                                (resp. is) run as init process.
+                                Normally it should not be necessary to
+                                pass these options, as systemd
+                                automatically detects the mode it is
+                                started in. These options are hence of
+                                little use except for
                                 debugging.</para></listitem>
                         </varlistentry>
                         <varlistentry>
@@ -466,7 +468,7 @@
                                 when figuring out whether a service
                                 shall be enabled. Note that a service
                                 unit with a native unit configuration
-                                file can be started by activating it
+                                file cannot be started by activating it
                                 in the SysV runlevel link
                                 farm.</para></listitem>
                         </varlistentry>
diff --git a/src/main.c b/src/main.c
index 9f2a569..27ad4c4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -545,7 +545,8 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_LOG_COLOR,
                 ARG_LOG_LOCATION,
                 ARG_UNIT,
-                ARG_RUNNING_AS,
+                ARG_SYSTEM,
+                ARG_SESSION,
                 ARG_TEST,
                 ARG_DUMP_CONFIGURATION_ITEMS,
                 ARG_DUMP_CORE,
@@ -562,7 +563,8 @@ static int parse_argv(int argc, char *argv[]) {
                 { "log-color",                optional_argument, NULL, ARG_LOG_COLOR                },
                 { "log-location",             optional_argument, NULL, ARG_LOG_LOCATION             },
                 { "unit",                     required_argument, NULL, ARG_UNIT                     },
-                { "running-as",               required_argument, NULL, ARG_RUNNING_AS               },
+                { "system",                   no_argument,       NULL, ARG_SYSTEM                   },
+                { "session",                  no_argument,       NULL, ARG_SESSION                  },
                 { "test",                     no_argument,       NULL, ARG_TEST                     },
                 { "help",                     no_argument,       NULL, 'h'                          },
                 { "dump-configuration-items", no_argument,       NULL, ARG_DUMP_CONFIGURATION_ITEMS },
@@ -634,17 +636,13 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
-                case ARG_RUNNING_AS: {
-                        ManagerRunningAs as;
-
-                        if ((as = manager_running_as_from_string(optarg)) < 0) {
-                                log_error("Failed to parse running as value %s", optarg);
-                                return -EINVAL;
-                        }
+                case ARG_SYSTEM:
+                        arg_running_as = MANAGER_SYSTEM;
+                        break;
 
-                        arg_running_as = as;
+                case ARG_SESSION:
+                        arg_running_as = MANAGER_SESSION;
                         break;
-                }
 
                 case ARG_TEST:
                         arg_action = ACTION_TEST;
@@ -746,7 +744,8 @@ static int help(void) {
                "     --dump-configuration-items  Dump understood unit configuration items\n"
                "     --introspect[=INTERFACE]    Extract D-Bus interface data\n"
                "     --unit=UNIT                 Set default unit\n"
-               "     --running-as=AS             Set running as (system, session)\n"
+               "     --system                    Run a system instance, even if PID != 1\n"
+               "     --session                   Run a session instance\n"
                "     --dump-core                 Dump core on crash\n"
                "     --crash-shell               Run shell on crash\n"
                "     --confirm-spawn             Ask for confirmation when spawning processes\n"
@@ -1042,7 +1041,7 @@ finish:
         dbus_shutdown();
 
         if (reexecute) {
-                const char *args[11];
+                const char *args[14];
                 unsigned i = 0;
                 char sfd[16];
 
@@ -1057,8 +1056,22 @@ finish:
                 args[i++] = "--log-target";
                 args[i++] = log_target_to_string(log_get_target());
 
-                args[i++] = "--running-as";
-                args[i++] = manager_running_as_to_string(arg_running_as);
+                if (arg_running_as == MANAGER_SYSTEM)
+                        args[i++] = "--system";
+                else
+                        args[i++] = "--session";
+
+                if (arg_dump_core)
+                        args[i++] = "--dump-core";
+
+                if (arg_crash_shell)
+                        args[i++] = "--crash-shell";
+
+                if (arg_confirm_spawn)
+                        args[i++] = "--confirm-spawn";
+
+                if (arg_show_status)
+                        args[i++] = "--show-status";
 
                 snprintf(sfd, sizeof(sfd), "%i", fileno(serialization));
                 char_array_0(sfd);
@@ -1066,9 +1079,6 @@ finish:
                 args[i++] = "--deserialize";
                 args[i++] = sfd;
 
-                if (arg_confirm_spawn)
-                        args[i++] = "--confirm-spawn";
-
                 args[i++] = NULL;
 
                 assert(i <= ELEMENTSOF(args));


More information about the systemd-commits mailing list