diff options
author | Pavel Březina <pbrezina@redhat.com> | 2016-09-21 12:25:43 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-10-11 14:31:35 +0200 |
commit | f4f2edba5c555773d7c9adfa95562b96b0c0cdb2 (patch) | |
tree | 406c739cdbc315531d454870dba5acbc4c8e6350 | |
parent | 03713a6444fdecd01465b9d5fbfead9601adce6e (diff) | |
download | sssd-f4f2edba5c555773d7c9adfa95562b96b0c0cdb2.tar.gz sssd-f4f2edba5c555773d7c9adfa95562b96b0c0cdb2.tar.xz sssd-f4f2edba5c555773d7c9adfa95562b96b0c0cdb2.zip |
sssctl: use systemd D-Bus API
If systemd is used we leverage it's D-Bus API instead of running systemctl.
Resolves:
https://fedorahosted.org/sssd/ticket/3056
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/tools/sssctl/sssctl.c | 23 | ||||
-rw-r--r-- | src/tools/sssctl/sssctl.h | 4 | ||||
-rw-r--r-- | src/tools/sssctl/sssctl_systemd.c | 136 |
4 files changed, 154 insertions, 10 deletions
diff --git a/Makefile.am b/Makefile.am index 1ea8f5066..b5f300a37 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1573,6 +1573,7 @@ sss_override_CFLAGS = \ sssctl_SOURCES = \ src/tools/sssctl/sssctl.c \ + src/tools/sssctl/sssctl_systemd.c \ src/tools/sssctl/sssctl_cache.c \ src/tools/sssctl/sssctl_data.c \ src/tools/sssctl/sssctl_logs.c \ diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c index 20ea26f8f..2ccb30eb1 100644 --- a/src/tools/sssctl/sssctl.c +++ b/src/tools/sssctl/sssctl.c @@ -26,12 +26,6 @@ #include "tools/common/sss_tools.h" #include "tools/common/sss_process.h" -#ifdef HAVE_SYSTEMD - #define SSSD_SVC_CMD(cmd) "systemctl " cmd " sssd.service" -#else - #define SSSD_SVC_CMD(cmd) "service sssd " cmd -#endif - static const char * sssctl_prompt_str(enum sssctl_prompt_result result) { @@ -125,14 +119,23 @@ errno_t sssctl_run_command(const char *command) static errno_t sssctl_manage_service(enum sssctl_svc_action action) { -#if defined(HAVE_SYSTEMD) || defined(HAVE_SERVICE) +#ifdef HAVE_SYSTEMD + switch (action) { + case SSSCTL_SVC_START: + return sssctl_systemd_start(); + case SSSCTL_SVC_STOP: + return sssctl_systemd_stop(); + case SSSCTL_SVC_RESTART: + return sssctl_systemd_restart(); + } +#elif HAVE_SERVICE switch (action) { case SSSCTL_SVC_START: - return sssctl_run_command(SSSD_SVC_CMD("start")); + return sssctl_run_command("service sssd start"); case SSSCTL_SVC_STOP: - return sssctl_run_command(SSSD_SVC_CMD("stop")); + return sssctl_run_command("service sssd stop"); case SSSCTL_SVC_RESTART: - return sssctl_run_command(SSSD_SVC_CMD("restart")); + return sssctl_run_command("service sssd restart"); } #endif diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h index d4e3359b0..5270a9ec6 100644 --- a/src/tools/sssctl/sssctl.h +++ b/src/tools/sssctl/sssctl.h @@ -70,6 +70,10 @@ sss_sifp_error _sssctl_sifp_send(TALLOC_CTX *mem_ctx, _sssctl_sifp_send(mem_ctx, sifp, reply, path, iface, method, \ ##__VA_ARGS__, DBUS_TYPE_INVALID); +errno_t sssctl_systemd_start(void); +errno_t sssctl_systemd_stop(void); +errno_t sssctl_systemd_restart(void); + errno_t sssctl_domain_list(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt); diff --git a/src/tools/sssctl/sssctl_systemd.c b/src/tools/sssctl/sssctl_systemd.c new file mode 100644 index 000000000..d5ce3b6f5 --- /dev/null +++ b/src/tools/sssctl/sssctl_systemd.c @@ -0,0 +1,136 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2016 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <talloc.h> +#include <dbus/dbus.h> +#include <errno.h> + +#include "util/util.h" +#include "tools/sssctl/sssctl.h" + +#define SSS_SYSTEMD_BUS "org.freedesktop.systemd1" +#define SSS_SYSTEMD_PATH "/org/freedesktop/systemd1" +#define SSS_SYSTEMD_IFACE "org.freedesktop.systemd1.Manager" +#define SSS_SYSTEMD_UNIT "sssd.service" +#define SSS_SYSTEMD_MODE "replace" /* replace queued job if present */ + +static DBusConnection * +sssctl_systemd_connect(void) +{ + DBusConnection *conn; + DBusError error; + + dbus_error_init(&error); + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (dbus_error_is_set(&error)) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to connect to systemd D-Bus " + "[%s]: %s\n", error.name, error.message); + conn = NULL; + goto done; + } + +done: + dbus_error_free(&error); + return conn; +} + +static errno_t sssctl_systemd_call(const char *method) +{ + DBusConnection *conn = NULL; + DBusMessage *reply = NULL; + DBusMessage *msg = NULL; + DBusError error; + const char *unit = SSS_SYSTEMD_UNIT; + const char *mode = SSS_SYSTEMD_MODE; + const char *job; + errno_t ret; + + dbus_error_init(&error); + + conn = sssctl_systemd_connect(); + if (conn == NULL) { + ret = EIO; + goto done; + } + + msg = sbus_create_message(NULL, SSS_SYSTEMD_BUS, SSS_SYSTEMD_PATH, + SSS_SYSTEMD_IFACE, method, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_STRING, &mode); + if (msg == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create D-Bus Message!\n"); + ret = ENOMEM; + goto done; + } + + reply = dbus_connection_send_with_reply_and_block(conn, msg, 5000, &error); + if (dbus_error_is_set(&error)) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send D-Bus message " + "[%s]: %s\n", error.name, error.message); + ret = EIO; + goto done; + } + + ret = sbus_parse_message(reply, DBUS_TYPE_OBJECT_PATH, &job); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get D-Bus reply [%d]: %s!\n", + ret, sss_strerror(ret)); + goto done; + } + + DEBUG(SSSDBG_TRACE_FUNC, "New systemd job created: %s\n", job); + +done: + if (msg != NULL) { + dbus_message_unref(msg); + } + + if (reply != NULL) { + dbus_message_unref(reply); + } + + if (conn != NULL) { + dbus_connection_unref(conn); + } + + return ret; +} + +errno_t sssctl_systemd_start(void) +{ + DEBUG(SSSDBG_TRACE_FUNC, "Starting SSSD via systemd...\n"); + + return sssctl_systemd_call("StartUnit"); +} + +errno_t sssctl_systemd_stop(void) +{ + DEBUG(SSSDBG_TRACE_FUNC, "Stopping SSSD via systemd...\n"); + + return sssctl_systemd_call("StopUnit"); +} + +errno_t sssctl_systemd_restart(void) +{ + DEBUG(SSSDBG_TRACE_FUNC, "Restarting SSSD via systemd...\n"); + + return sssctl_systemd_call("RestartUnit"); +} |