[systemd-devel] [PATCH] Add "set-default-target" to systemctl

harald at redhat.com harald at redhat.com
Mon Apr 23 00:23:28 PDT 2012


From: Harald Hoyer <harald at redhat.com>

also adds DBUS method "SetDefaultTarget"

This set the symbolic link "default.target".

Useful as an admin command to switch "runlevels".
---
 src/core/dbus-manager.c   |    8 +++++++
 src/shared/install.c      |   53 +++++++++++++++++++++++++++++++++++++++++++++
 src/shared/install.h      |    1 +
 src/systemctl/systemctl.c |   11 ++++++++--
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index e81e6af..29aaaff 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -180,6 +180,12 @@
         "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
         "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
         "  </method>\n"                                                 \
+        "  <method name=\"SetDefaultTarget\">\n"                           \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
         "  <method name=\"UnmaskUnitFiles\">\n"                         \
         "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
         "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
@@ -1392,6 +1398,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
                         carries_install_info = r;
                 } else if (streq(member, "MaskUnitFiles"))
                         r = unit_file_mask(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else if (streq(member, "SetDefaultTarget"))
+                        r = target_set_default(scope, runtime, NULL, l, force, &changes, &n_changes);
                 else
                         assert_not_reached("Uh? Wrong method");
 
diff --git a/src/shared/install.c b/src/shared/install.c
index 080ae6a..527cc16 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1,3 +1,4 @@
+
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
 /***
@@ -1174,6 +1175,58 @@ static int create_symlink(
         return -errno;
 }
 
+int target_set_default(
+                       UnitFileScope scope,
+                       bool runtime,
+                       const char *root_dir,
+                       char *files[],
+                       bool force,
+                       UnitFileChange **changes,
+                       unsigned *n_changes)
+{
+        char **i, *prefix;
+        int r, q;
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+
+        r = get_config_path(scope, runtime, root_dir, &prefix);
+        if (r < 0)
+                return r;
+
+        STRV_FOREACH(i, files) {
+                char *unitpath;
+                char *path;
+
+                if (!unit_name_is_valid_no_type(*i, true)) {
+                        if (r == 0)
+                                r = -EINVAL;
+                        continue;
+                }
+
+                unitpath = path_make_absolute(*i, prefix);
+                if (!unitpath) {
+                        r = -ENOMEM;
+                        break;
+                }
+
+                if (asprintf(&path, "%s/default.target", prefix) < 0)
+                        return -ENOMEM;
+
+                q = create_symlink(unitpath, path, force, changes, n_changes);
+                free(path);
+                free(unitpath);
+
+                if (r == 0)
+                        r = q;
+                if (r == 0)
+                        break;
+        }
+
+        free(prefix);
+
+        return r;
+}
+
 static int install_info_symlink_alias(
                 InstallInfo *i,
                 const char *config_path,
diff --git a/src/shared/install.h b/src/shared/install.h
index d365c01..304a479 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -68,6 +68,7 @@ int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, c
 int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
+int target_set_default(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes);
 
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 28bdfa9..2a9ac84 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3801,7 +3801,9 @@ static int enable_unit(DBusConnection *bus, char **args) {
                 else if (streq(verb, "preset")) {
                         r = unit_file_preset(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
                         carries_install_info = r;
-                } else if (streq(verb, "mask"))
+		} else if (streq(verb, "set-default-target"))
+                        r = target_set_default(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
+                else if (streq(verb, "mask"))
                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
                 else if (streq(verb, "unmask"))
                         r = unit_file_unmask(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes);
@@ -3842,7 +3844,9 @@ static int enable_unit(DBusConnection *bus, char **args) {
                 else if (streq(verb, "preset")) {
                         method = "PresetUnitFiles";
                         expect_carries_install_info = true;
-                } else if (streq(verb, "mask"))
+                } else if (streq(verb, "set-default-target"))
+                        method = "SetDefaultTarget";
+                else if (streq(verb, "mask"))
                         method = "MaskUnitFiles";
                 else if (streq(verb, "unmask")) {
                         method = "UnmaskUnitFiles";
@@ -4142,6 +4146,7 @@ static int systemctl_help(void) {
                "  link [PATH...]                  Link one or more units files into\n"
                "                                  the search path\n"
                "  is-enabled [NAME...]            Check whether unit files are enabled\n\n"
+               "  set-default-target [NAME]       Set the default target\n\n"
                "Job Commands:\n"
                "  list-jobs                       List jobs\n"
                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
@@ -5110,6 +5115,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
                 { "is-enabled",            MORE,  2, unit_is_enabled   },
                 { "reenable",              MORE,  2, enable_unit       },
                 { "preset",                MORE,  2, enable_unit       },
+                { "set-default-target",    MORE,  2, enable_unit       },
                 { "mask",                  MORE,  2, enable_unit       },
                 { "unmask",                MORE,  2, enable_unit       },
                 { "link",                  MORE,  2, enable_unit       }
@@ -5181,6 +5187,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
             !streq(verbs[i].verb, "list-unit-files") &&
             !streq(verbs[i].verb, "reenable") &&
             !streq(verbs[i].verb, "preset") &&
+            !streq(verbs[i].verb, "set-default-target") &&
             !streq(verbs[i].verb, "mask") &&
             !streq(verbs[i].verb, "unmask") &&
             !streq(verbs[i].verb, "link")) {
-- 
1.7.9.3



More information about the systemd-devel mailing list