URL: https://github.com/SSSD/sssd/pull/30 Author: pbrezina Title: #30: sssctl: use systemd D-Bus API Action: synchronized
To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/30/head:pr30 git checkout pr30
From 1123f7df5fc6da1e0d2f1518e268fc4a2acaf619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com> Date: Wed, 21 Sep 2016 12:25:43 +0200 Subject: [PATCH 1/2] 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 --- Makefile.am | 1 + src/tools/sssctl/sssctl.c | 23 ++++--- src/tools/sssctl/sssctl.h | 4 ++ src/tools/sssctl/sssctl_systemd.c | 136 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 src/tools/sssctl/sssctl_systemd.c diff --git a/Makefile.am b/Makefile.am index 1ea8f50..b5f300a 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 20ea26f..2ccb30e 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 d4e3359..5270a9e 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 0000000..d5ce3b6 --- /dev/null +++ b/src/tools/sssctl/sssctl_systemd.c @@ -0,0 +1,136 @@ +/* + Authors: + Pavel Březina <pbrez...@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"); +} From d894abbd86aa983a0ed7e582dc9514b7e1cb704d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com> Date: Fri, 23 Sep 2016 12:02:11 +0200 Subject: [PATCH 2/2] sssctl: call service with absolute path --- src/tools/sssctl/sssctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c index 2ccb30e..89f5d76 100644 --- a/src/tools/sssctl/sssctl.c +++ b/src/tools/sssctl/sssctl.c @@ -131,11 +131,11 @@ static errno_t sssctl_manage_service(enum sssctl_svc_action action) #elif HAVE_SERVICE switch (action) { case SSSCTL_SVC_START: - return sssctl_run_command("service sssd start"); + return sssctl_run_command("/sbin/service sssd start"); case SSSCTL_SVC_STOP: - return sssctl_run_command("service sssd stop"); + return sssctl_run_command("/sbin/service sssd stop"); case SSSCTL_SVC_RESTART: - return sssctl_run_command("service sssd restart"); + return sssctl_run_command("/sbin/service sssd restart"); } #endif
_______________________________________________ sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org