summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2008-11-04 17:34:03 -0500
committerSimo Sorce <idra@samba.org>2008-11-04 17:39:27 -0500
commit750d1443a285048251c8843acd2c763b413869da (patch)
treec1126f6a01728575701d7714abefa463df2e493e
parent603f59bcb502c48eb577bc6fd3232a6944756983 (diff)
downloadsssd-750d1443a285048251c8843acd2c763b413869da.tar.gz
sssd-750d1443a285048251c8843acd2c763b413869da.tar.xz
sssd-750d1443a285048251c8843acd2c763b413869da.zip
Add the ping funtion to the nss service Make the monitor task ping connecting services Make it possible to configure timeouts and service ping times.
-rw-r--r--server/monitor.c500
-rw-r--r--server/nss/nsssrv.c17
-rw-r--r--server/nss/nsssrv.h2
-rw-r--r--server/sbus/sssd_dbus.h38
-rw-r--r--server/sbus/sssd_dbus_connection.c7
-rw-r--r--server/sbus/sssd_dbus_server.c91
-rw-r--r--server/sbus_interfaces.h1
7 files changed, 506 insertions, 150 deletions
diff --git a/server/monitor.c b/server/monitor.c
index 5574d70c8..1afebd51c 100644
--- a/server/monitor.c
+++ b/server/monitor.c
@@ -32,23 +32,46 @@
#include "sbus/sssd_dbus.h"
#include "sbus_interfaces.h"
-struct mt_ctx {
- struct event_context *ev;
- struct confdb_ctx *cdb;
- char **services;
+struct mt_conn {
+ struct sbus_conn_ctx *conn_ctx;
+ struct mt_svc *svc_ptr;
};
-struct mt_srv {
- const char *name;
+struct mt_svc {
+ struct mt_svc *prev;
+ struct mt_svc *next;
+
+ struct mt_conn *mt_conn;
struct mt_ctx *mt_ctx;
+
+ const char *name;
pid_t pid;
- time_t last_restart;
+
int restarts;
+ time_t last_restart;
+ time_t last_pong;
+};
+
+struct mt_ctx {
+ struct event_context *ev;
+ struct confdb_ctx *cdb;
+ char **services;
+ struct mt_svc *svc_list;
+
+ int service_id_timeout;
+ int service_ping_time;
};
-static int dbus_service_init(struct sbus_conn_ctx *dct_ctx);
+static int dbus_service_init(struct sbus_conn_ctx *conn_ctx, void *data);
static void identity_check(DBusPendingCall *pending, void *data);
+static int service_send_ping(struct mt_svc *svc);
+static void ping_check(DBusPendingCall *pending, void *data);
+
+static int service_check_alive(struct mt_svc *svc);
+
+static void set_tasks_checker(struct mt_svc *srv);
+
/* dbus_get_monitor_version
* Return the monitor version over D-BUS */
static int dbus_get_monitor_version(DBusMessage *message,
@@ -93,109 +116,170 @@ static int monitor_dbus_init(struct mt_ctx *ctx)
sd_ctx = talloc_zero(ctx, struct sbus_method_ctx);
if (!sd_ctx) {
+ talloc_free(sbus_address);
return ENOMEM;
}
/* Set up globally-available D-BUS methods */
sd_ctx->interface = talloc_strdup(sd_ctx, MONITOR_DBUS_INTERFACE);
if (!sd_ctx->interface) {
+ talloc_free(sbus_address);
talloc_free(sd_ctx);
return ENOMEM;
}
sd_ctx->path = talloc_strdup(sd_ctx, MONITOR_DBUS_PATH);
if (!sd_ctx->path) {
+ talloc_free(sbus_address);
talloc_free(sd_ctx);
return ENOMEM;
}
sd_ctx->methods = monitor_methods;
sd_ctx->message_handler = NULL; /* Use the default message_handler */
- ret = sbus_new_server(ctx->ev, sd_ctx, sbus_address, dbus_service_init);
+ ret = sbus_new_server(ctx->ev, sd_ctx, sbus_address, dbus_service_init, ctx);
return ret;
}
-
-static void set_tasks_checker(struct mt_srv *srv);
-
static void tasks_check_handler(struct event_context *ev,
struct timed_event *te,
struct timeval t, void *ptr)
{
- struct mt_srv *srv = talloc_get_type(ptr, struct mt_srv);
+ struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc);
time_t now = time(NULL);
- int status;
- pid_t pid;
+ bool process_alive = true;
int ret;
- pid = waitpid(srv->pid, &status, WNOHANG);
- if (pid == 0) {
- set_tasks_checker(srv);
- return;
- }
+ ret = service_check_alive(svc);
+ switch (ret) {
+ case EOK:
+ /* all fine */
+ break;
- if (pid != srv->pid) {
- DEBUG(1, ("bad return (%d) from waitpid() waiting for %d\n",
- pid, srv->pid));
- /* TODO: what do we do now ? */
- }
+ case ECHILD:
+ DEBUG(1,("Process is stopped!\n"));
+ process_alive = false;
+ break;
- if (WIFEXITED(status)) { /* children exited on it's own ?? */
- /* TODO: check configuration to see if it was removed
- * from the list of process to run */
- DEBUG(0,("Process [%s] exited on it's own ?!\n", srv->name));
+ default:
+ /* TODO: should we tear down it ? */
+ DEBUG(1,("Checking for service process failed!!\n"));
+ break;
}
- if (srv->last_restart != 0) {
- if ((now - srv->last_restart) > 30) { /* TODO: get val from config */
- /* it was long ago reset restart threshold */
- srv->restarts = 0;
+ if (process_alive) {
+ ret = service_send_ping(svc);
+ switch (ret) {
+ case EOK:
+ /* all fine */
+ break;
+
+ case ENXIO:
+ DEBUG(1,("Connection with child not available! (yet)\n"));
+ break;
+
+ default:
+ /* TODO: should we tear it down ? */
+ DEBUG(1,("Sending a message to the service failed!!\n"));
+ break;
+ }
+
+ if (svc->last_pong != 0) {
+ if ((now - svc->last_pong) > 30) { /* TODO: get val from config */
+ /* too long since we last heard of this process */
+ ret = kill(svc->pid, SIGUSR1);
+ if (ret != EOK) {
+ DEBUG(0,("Sending signal to child failed! Ignore and pretend child is dead.\n"));
+ }
+ process_alive = false;
+ }
}
+
}
- /* restart the process */
- if (srv->restarts < 3) { /* TODO: get val from config */
+ if (!process_alive) {
+ if (svc->last_restart != 0) {
+ if ((now - svc->last_restart) > 30) { /* TODO: get val from config */
+ /* it was long ago reset restart threshold */
+ svc->restarts = 0;
+ }
+ }
- ret = server_service_init(srv->name, srv->mt_ctx->ev, &srv->pid);
- if (ret != EOK) {
- DEBUG(0,("Failed to restart service '%s'\n", srv->name));
- talloc_free(srv);
+ /* restart the process */
+ if (svc->restarts > 3) { /* TODO: get val from config */
+ DEBUG(0, ("Process [%s], definitely stopped!\n", svc->name));
+ talloc_free(svc);
return;
}
- srv->restarts++;
- srv->last_restart = now;
+ ret = server_service_init(svc->name, svc->mt_ctx->ev, &svc->pid);
+ if (ret != EOK) {
+ DEBUG(0,("Failed to restart service '%s'\n", svc->name));
+ talloc_free(svc);
+ return;
+ }
- set_tasks_checker(srv);
- return;
+ svc->restarts++;
+ svc->last_restart = now;
+ svc->last_pong = 0;
}
- DEBUG(0, ("Process [%s], definitely stopped!\n", srv->name));
- talloc_free(srv);
+ /* all fine, set up the task checker again */
+ set_tasks_checker(svc);
}
-static void set_tasks_checker(struct mt_srv *srv)
+static void set_tasks_checker(struct mt_svc *svc)
{
struct timed_event *te = NULL;
struct timeval tv;
gettimeofday(&tv, NULL);
- tv.tv_sec += 2;
+ tv.tv_sec += svc->mt_ctx->service_ping_time;
tv.tv_usec = 0;
- te = event_add_timed(srv->mt_ctx->ev, srv, tv, tasks_check_handler, srv);
+ te = event_add_timed(svc->mt_ctx->ev, svc, tv, tasks_check_handler, svc);
if (te == NULL) {
DEBUG(0, ("failed to add event, monitor offline for [%s]!\n",
- srv->name));
+ svc->name));
/* FIXME: shutdown ? */
}
}
+int get_monitor_config(struct mt_ctx *ctx)
+{
+ int ret;
+
+ ret = confdb_get_int(ctx->cdb, ctx,
+ "config.services.monitor", "sbusTimeout",
+ -1, &ctx->service_id_timeout);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = confdb_get_int(ctx->cdb, ctx,
+ "config.services.monitor", "servicePingTime",
+ -1, &ctx->service_ping_time);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = confdb_get_param(ctx->cdb, ctx,
+ "config.services", "activeServices",
+ &ctx->services);
+
+ if (ctx->services[0] == NULL) {
+ DEBUG(0, ("No services configured!\n"));
+ return EINVAL;
+ }
+
+ return EOK;
+}
+
int start_monitor(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
struct confdb_ctx *cdb)
{
struct mt_ctx *ctx;
- struct mt_srv *srv;
+ struct mt_svc *svc;
int ret, i;
ctx = talloc_zero(mem_ctx, struct mt_ctx);
@@ -204,32 +288,32 @@ int start_monitor(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
ctx->ev = event_ctx;
+ ctx->cdb = cdb;
- ret = confdb_get_param(cdb, mem_ctx, "config.services",
- "activeServices", &ctx->services);
-
- if (ctx->services[0] == NULL) {
- DEBUG(0, ("No services configured!\n"));
- return EINVAL;
- }
+ ret = get_monitor_config(ctx);
+ if (ret != EOK)
+ return ret;
for (i = 0; ctx->services[i]; i++) {
- srv = talloc_zero(ctx, struct mt_srv);
- if (!srv) {
+ svc = talloc_zero(ctx, struct mt_svc);
+ if (!svc) {
talloc_free(ctx);
return ENOMEM;
}
- srv->name = ctx->services[i];
- srv->mt_ctx = ctx;
+ svc->name = ctx->services[i];
+ svc->mt_ctx = ctx;
- ret = server_service_init(srv->name, event_ctx, &srv->pid);
+ ret = server_service_init(svc->name, event_ctx, &svc->pid);
if (ret != EOK) {
- DEBUG(0,("Failed to restart service '%s'\n", srv->name));
- talloc_free(srv);
+ DEBUG(0,("Failed to start service '%s'\n", svc->name));
+ talloc_free(svc);
+ continue;
}
- set_tasks_checker(srv);
+ DLIST_ADD(ctx->svc_list, svc);
+
+ set_tasks_checker(svc);
}
/* Initialize D-BUS Server
@@ -243,6 +327,21 @@ int start_monitor(TALLOC_CTX *mem_ctx,
return EOK;
}
+static int mt_conn_destructor(void *ptr)
+{
+ struct mt_conn *mt_conn;
+ struct mt_svc *svc;
+
+ mt_conn = talloc_get_type(ptr, struct mt_conn);
+ svc = mt_conn->svc_ptr;
+
+ /* now clear up so that the rest of the code will know there
+ * is no connection attached to the service anymore */
+ svc->mt_conn = NULL;
+
+ return 0;
+}
+
/*
* dbus_service_init
* This function should initiate a query to the newly connected
@@ -250,27 +349,64 @@ int start_monitor(TALLOC_CTX *mem_ctx,
* method on the new client). The reply callback for this request
* should set the connection destructor appropriately.
*/
-static int dbus_service_init(struct sbus_conn_ctx *dct_ctx) {
+static int dbus_service_init(struct sbus_conn_ctx *conn_ctx, void *data) {
+ struct mt_ctx *ctx;
+ struct mt_svc *svc;
+ struct mt_conn *mt_conn;
DBusMessage *msg;
DBusPendingCall *pending_reply;
DBusConnection *conn;
DBusError dbus_error;
dbus_bool_t dbret;
-
- DEBUG(0,("Initializing D-BUS Service"));
- conn = sbus_get_connection(dct_ctx);
+
+ DEBUG(3, ("Initializing D-BUS Service\n"));
+
+ ctx = talloc_get_type(data, struct mt_ctx);
+ conn = sbus_get_connection(conn_ctx);
dbus_error_init(&dbus_error);
- /*
- * Set up identity request
+ /* hang off this memory to the connection so that when the connection
+ * is freed we can call a destructor to clear up the structure and
+ * have a way to know we need to restart the service */
+ mt_conn = talloc(conn_ctx, struct mt_conn);
+ if (!mt_conn) {
+ DEBUG(0,("Out of memory?!\n"));
+ talloc_free(conn_ctx);
+ return ENOMEM;
+ }
+ mt_conn->conn_ctx = conn_ctx;
+
+ /* at this stage we still do not know what service is this
+ * we will know only after we get its identity, so we make
+ * up a temporary fake service and complete the operation
+ * when we receive the reply */
+ svc = talloc_zero(mt_conn, struct mt_svc);
+ if (!svc) {
+ talloc_free(conn_ctx);
+ return ENOMEM;
+ }
+ svc->mt_ctx = ctx;
+ svc->mt_conn = mt_conn;
+
+ mt_conn->svc_ptr = svc;
+ talloc_set_destructor((TALLOC_CTX *)mt_conn, mt_conn_destructor);
+
+ /*
+ * Set up identity request
* This should be a well-known path and method
* for all services
*/
msg = dbus_message_new_method_call(NULL,
- SERVICE_PATH,
- SERVICE_INTERFACE,
- SERVICE_METHOD_IDENTITY);
- dbret = dbus_connection_send_with_reply(conn, msg, &pending_reply, -1);
+ SERVICE_PATH,
+ SERVICE_INTERFACE,
+ SERVICE_METHOD_IDENTITY);
+ if (msg == NULL) {
+ DEBUG(0,("Out of memory?!\n"));
+ talloc_free(conn_ctx);
+ return ENOMEM;
+ }
+ dbret = dbus_connection_send_with_reply(conn, msg, &pending_reply,
+ ctx->service_id_timeout);
if (!dbret) {
/*
* Critical Failure
@@ -278,25 +414,33 @@ static int dbus_service_init(struct sbus_conn_ctx *dct_ctx) {
* We'll drop it using the default destructor.
*/
DEBUG(0, ("D-BUS send failed.\n"));
- talloc_free(dct_ctx);
+ talloc_free(conn_ctx);
+ return EIO;
}
-
+
/* Set up the reply handler */
- dbus_pending_call_set_notify(pending_reply, identity_check, dct_ctx, NULL);
+ dbus_pending_call_set_notify(pending_reply, identity_check, svc, NULL);
dbus_message_unref(msg);
return EOK;
}
-static void identity_check(DBusPendingCall *pending, void *data) {
- struct sbus_conn_ctx *dct_ctx;
+static void identity_check(DBusPendingCall *pending, void *data)
+{
+ struct mt_svc *fake_svc;
+ struct mt_svc *svc;
+ struct sbus_conn_ctx *conn_ctx;
DBusMessage *reply;
DBusError dbus_error;
+ dbus_uint16_t svc_ver;
+ char *svc_name;
+ dbus_bool_t ret;
int type;
- dct_ctx = talloc_get_type(data, struct sbus_conn_ctx);
+ fake_svc = talloc_get_type(data, struct mt_svc);
+ conn_ctx = fake_svc->mt_conn->conn_ctx;
dbus_error_init(&dbus_error);
-
+
reply = dbus_pending_call_steal_reply(pending);
if (!reply) {
/* reply should never be null. This function shouldn't be called
@@ -304,31 +448,207 @@ static void identity_check(DBusPendingCall *pending, void *data) {
* here, something is seriously wrong and we should bail out.
*/
DEBUG(0, ("Serious error. A reply callback was called but no reply was received and no timeout occurred\n"));
-
+
/* Destroy this connection */
- sbus_disconnect(dct_ctx);
+ sbus_disconnect(conn_ctx);
return;
}
-
+
type = dbus_message_get_type(reply);
switch (type) {
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
- /* Got the service name and version */
- /* Extract the name and version from the message */
+ ret = dbus_message_get_args(reply, &dbus_error,
+ DBUS_TYPE_STRING, &svc_name,
+ DBUS_TYPE_UINT16, &svc_ver,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1,("Failed, to parse message, killing connection\n"));
+ sbus_disconnect(conn_ctx);
+ return;
+ }
+
+ /* search this service in the list */
+ svc = fake_svc->mt_ctx->svc_list;
+ while (svc) {
+ ret = strcasecmp(svc->name, svc_name);
+ if (ret == 0) {
+ break;
+ }
+ svc = svc->next;
+ }
+ if (!svc) {
+ DEBUG(0,("Unable to find peer in list of services, killing connection!\n"));
+ sbus_disconnect(conn_ctx);
+ return;
+ }
+
+ /* transfer all from the fake service and get rid of it */
+ fake_svc->mt_conn->svc_ptr = svc;
+ svc->mt_conn = fake_svc->mt_conn;
+ talloc_free(fake_svc);
+
/* Set up the destructor for this service */
break;
+
case DBUS_MESSAGE_TYPE_ERROR:
- DEBUG(0,("getIdentity returned an error %s, closing connection.\n", dbus_message_get_error_name(reply)));
+ DEBUG(0,("getIdentity returned an error [%s], closing connection.\n",
+ dbus_message_get_error_name(reply)));
/* Falling through to default intentionally*/
default:
/*
* Timeout or other error occurred or something
* unexpected happened.
- * It doesn't matter which, because either way we
+ * It doesn't matter which, because either way we
* know that this connection isn't trustworthy.
* We'll destroy it now.
*/
- sbus_disconnect(dct_ctx);
+ sbus_disconnect(conn_ctx);
+ return;
+ }
+}
+
+/* service_send_ping
+ * this function send a dbus ping to a service.
+ * It returns EOK if all is fine or ENXIO if the connection is
+ * not available (either not yet set up or teared down).
+ * Returns e generic error in other cases.
+ */
+static int service_send_ping(struct mt_svc *svc)
+{
+ DBusMessage *msg;
+ DBusPendingCall *pending_reply;
+ DBusConnection *conn;
+ DBusError dbus_error;
+ dbus_bool_t dbret;
+
+ if (!svc->mt_conn) {
+ return ENXIO;
+ }
+
+ conn = sbus_get_connection(svc->mt_conn->conn_ctx);
+ dbus_error_init(&dbus_error);
+
+ /*
+ * Set up identity request
+ * This should be a well-known path and method
+ * for all services
+ */
+ msg = dbus_message_new_method_call(NULL,
+ SERVICE_PATH,
+ SERVICE_INTERFACE,
+ SERVICE_METHOD_PING);
+ if (!msg) {
+ DEBUG(0,("Out of memory?!\n"));
+ talloc_free(svc->mt_conn->conn_ctx);
+ return ENOMEM;
+ }
+
+ dbret = dbus_connection_send_with_reply(conn, msg, &pending_reply,
+ svc->mt_ctx->service_id_timeout);
+ if (!dbret) {
+ /*
+ * Critical Failure
+ * We can't communicate on this connection
+ * We'll drop it using the default destructor.
+ */
+ DEBUG(0, ("D-BUS send failed.\n"));
+ talloc_free(svc->mt_conn->conn_ctx);
+ return EIO;
+ }
+
+ /* Set up the reply handler */
+ dbus_pending_call_set_notify(pending_reply, ping_check, svc, NULL);
+ dbus_message_unref(msg);
+
+ return EOK;
+}
+
+static void ping_check(DBusPendingCall *pending, void *data)
+{
+ struct mt_svc *svc;
+ struct sbus_conn_ctx *conn_ctx;
+ DBusMessage *reply;
+ DBusError dbus_error;
+ const char *dbus_error_name;
+ int type;
+
+ svc = talloc_get_type(data, struct mt_svc);
+ conn_ctx = svc->mt_conn->conn_ctx;
+ dbus_error_init(&dbus_error);
+
+ reply = dbus_pending_call_steal_reply(pending);
+ if (!reply) {
+ /* reply should never be null. This function shouldn't be called
+ * until reply is valid or timeout has occurred. If reply is NULL
+ * here, something is seriously wrong and we should bail out.
+ */
+ DEBUG(0, ("A reply callback was called but no reply was received"
+ " and no timeout occurred\n"));
+
+ /* Destroy this connection */
+ sbus_disconnect(conn_ctx);
+ return;
+ }
+
+ type = dbus_message_get_type(reply);
+ switch (type) {
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ /* ok peer replied,
+ * set the reply timestamp into the service structure */
+
+ svc->last_pong = time(NULL);
break;
+
+ case DBUS_MESSAGE_TYPE_ERROR:
+
+ dbus_error_name = dbus_message_get_error_name(reply);
+
+ /* timeouts are handled in the main service check function */
+ if (strcmp(dbus_error_name, DBUS_ERROR_TIMEOUT) == 0)
+ break;
+
+ DEBUG(0,("A service PING returned an error [%s], closing connection.\n",
+ dbus_error_name));
+ /* Falling through to default intentionally*/
+ default:
+ /*
+ * Timeout or other error occurred or something
+ * unexpected happened.
+ * It doesn't matter which, because either way we
+ * know that this connection isn't trustworthy.
+ * We'll destroy it now.
+ */
+ sbus_disconnect(conn_ctx);
+ return;
}
}
+
+/* service_check_alive
+ * This function checks if the service child is still alive
+ */
+static int service_check_alive(struct mt_svc *svc)
+{
+ int status;
+ pid_t pid;
+
+ pid = waitpid(svc->pid, &status, WNOHANG);
+ if (pid == 0) {
+ return EOK;
+ }
+
+ if (pid != svc->pid) {
+ DEBUG(1, ("bad return (%d) from waitpid() waiting for %d\n",
+ pid, svc->pid));
+ /* TODO: what do we do now ? */
+ return EINVAL;
+ }
+
+ if (WIFEXITED(status)) { /* children exited on it's own */
+ /* TODO: check configuration to see if it was removed
+ * from the list of process to run */
+ DEBUG(0,("Process [%s] exited\n", svc->name));
+ }
+
+ return ECHILD;
+}
+
diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c
index 04eead6dd..bd0f761b2 100644
--- a/server/nss/nsssrv.c
+++ b/server/nss/nsssrv.c
@@ -40,9 +40,11 @@
#include "sbus_interfaces.h"
static int provide_identity(DBusMessage *message, void *data, DBusMessage **r);
+static int reply_ping(DBusMessage *message, void *data, DBusMessage **r);
struct sbus_method nss_sbus_methods[] = {
{SERVICE_METHOD_IDENTITY, provide_identity},
+ {SERVICE_METHOD_PING, reply_ping},
{NULL, NULL}
};
@@ -223,6 +225,21 @@ static int provide_identity(DBusMessage *message, void *data, DBusMessage **r)
return EOK;
}
+static int reply_ping(DBusMessage *message, void *data, DBusMessage **r)
+{
+ DBusMessage *reply;
+ dbus_bool_t ret;
+
+ reply = dbus_message_new_method_return(message);
+ ret = dbus_message_append_args(reply, DBUS_TYPE_INVALID);
+ if (!ret) {
+ return EIO;
+ }
+
+ *r = reply;
+ return EOK;
+}
+
static int nss_sbus_init(struct nss_ctx *nctx)
{
struct sbus_method_ctx *cli_sm_ctx;
diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h
index 300b8af31..5e2649370 100644
--- a/server/nss/nsssrv.h
+++ b/server/nss/nsssrv.h
@@ -30,7 +30,7 @@
#include "../nss_client/sss_nss.h"
#define NSS_SBUS_SERVICE_VERSION 0x0001
-#define NSS_SBUS_SERVICE_NAME "NSS"
+#define NSS_SBUS_SERVICE_NAME "nss"
struct nss_ldb_ctx;
struct getent_ctx;
diff --git a/server/sbus/sssd_dbus.h b/server/sbus/sssd_dbus.h
index 1bd062d42..5510b6e4a 100644
--- a/server/sbus/sssd_dbus.h
+++ b/server/sbus/sssd_dbus.h
@@ -21,16 +21,16 @@
#ifndef _SSSD_DBUS_H_
#define _SSSD_DBUS_H_
+
struct sbus_conn_ctx;
-typedef int (*sbus_msg_handler_fn)(DBusMessage *msg, void *data,
- DBusMessage **reply);
+
+typedef int (*sbus_msg_handler_fn)(DBusMessage *, void *, DBusMessage **);
/*
* sbus_conn_destructor_fn
* Function to be called when a connection is finalized
*/
-typedef int (*sbus_conn_destructor_fn)(
- void *ctx);
+typedef int (*sbus_conn_destructor_fn)(void *);
/*
* sbus_server_conn_init_fn
@@ -38,8 +38,7 @@ typedef int (*sbus_conn_destructor_fn)(
* This function should define the sbus_conn_destructor_fn
* for this connection at a minimum
*/
-typedef int (*sbus_server_conn_init_fn)(
- struct sbus_conn_ctx *dct_ctx);
+typedef int (*sbus_server_conn_init_fn)(struct sbus_conn_ctx *, void *);
enum {
SBUS_CONN_TYPE_PRIVATE = 1,
@@ -56,7 +55,7 @@ struct sbus_method_ctx {
/*struct event_context *ev;*/
char *interface;
char *path;
-
+
/* If a non-default message_handler is desired, set it in this
* object before calling sbus_conn_add_method_ctx()
* Otherwise it will default to message_handler() in
@@ -67,20 +66,25 @@ struct sbus_method_ctx {
};
/* Server Functions */
-int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, const char *address, sbus_server_conn_init_fn init_fn);
+int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx,
+ const char *address,
+ sbus_server_conn_init_fn init_fn, void *init_pvt_data);
/* Connection Functions */
-int sbus_new_connection(TALLOC_CTX *ctx, struct event_context *ev, const char *address,
- struct sbus_conn_ctx **dct_ctx,
- sbus_conn_destructor_fn destructor);
+int sbus_new_connection(TALLOC_CTX *ctx, struct event_context *ev,
+ const char *address,
+ struct sbus_conn_ctx **conn_ctx,
+ sbus_conn_destructor_fn destructor);
+
+void sbus_conn_set_destructor(struct sbus_conn_ctx *conn_ctx,
+ sbus_conn_destructor_fn destructor);
-void sbus_conn_set_destructor(struct sbus_conn_ctx *dct_ctx,
- sbus_conn_destructor_fn destructor);
int sbus_default_connection_destructor(void *ctx);
-DBusConnection *sbus_get_connection(struct sbus_conn_ctx *dct_ctx);
-void sbus_disconnect (struct sbus_conn_ctx *dct_ctx);
-void sbus_conn_set_private_data(struct sbus_conn_ctx *dct_ctx, void *private);
-int sbus_conn_add_method_ctx(struct sbus_conn_ctx *dct_ctx, struct sbus_method_ctx *method_ctx);
+DBusConnection *sbus_get_connection(struct sbus_conn_ctx *conn_ctx);
+void sbus_disconnect(struct sbus_conn_ctx *conn_ctx);
+void sbus_conn_set_private_data(struct sbus_conn_ctx *conn_ctx, void *pvt_data);
+int sbus_conn_add_method_ctx(struct sbus_conn_ctx *conn_ctx,
+ struct sbus_method_ctx *method_ctx);
#endif /* _SSSD_DBUS_H_*/
diff --git a/server/sbus/sssd_dbus_connection.c b/server/sbus/sssd_dbus_connection.c
index bd95c0abe..7769188b3 100644
--- a/server/sbus/sssd_dbus_connection.c
+++ b/server/sbus/sssd_dbus_connection.c
@@ -15,7 +15,7 @@ struct sbus_conn_ctx {
int disconnect;
struct sbus_method_ctx *method_ctx_list;
sbus_conn_destructor_fn destructor;
- void *private; /* Private data for this connection */
+ void *pvt_data; /* Private data for this connection */
};
struct sbus_conn_watch_ctx {
@@ -571,6 +571,7 @@ static void sbus_unreg_object_paths(struct sbus_conn_ctx *dct_ctx) {
}
}
-void sbus_conn_set_private_data(struct sbus_conn_ctx *dct_ctx, void *private) {
- dct_ctx->private = private;
+void sbus_conn_set_private_data(struct sbus_conn_ctx *conn_ctx, void *pvt_data)
+{
+ conn_ctx->pvt_data = pvt_data;
}
diff --git a/server/sbus/sssd_dbus_server.c b/server/sbus/sssd_dbus_server.c
index 22dcbf39a..f8396b5c9 100644
--- a/server/sbus/sssd_dbus_server.c
+++ b/server/sbus/sssd_dbus_server.c
@@ -40,6 +40,7 @@ struct sbus_srv_ctx {
struct event_context *ev;
struct sbus_method_ctx *sd_ctx;
sbus_server_conn_init_fn init_fn;
+ void *init_pvt_data;
};
struct sbus_srv_watch_ctx {
@@ -198,40 +199,41 @@ static void sbus_toggle_srv_timeout(DBusTimeout *timeout, void *data)
* new connection or else close the connection with
* dbus_connection_close()
*/
-static void sbus_server_init_new_connection(DBusServer *server, DBusConnection *conn,
- void *data)
+static void sbus_server_init_new_connection(DBusServer *server,
+ DBusConnection *conn,
+ void *data)
{
- struct sbus_srv_ctx *dst_ctx;
- struct sbus_conn_ctx *dct_ctx;
+ struct sbus_srv_ctx *srv_ctx;
+ struct sbus_conn_ctx *conn_ctx;
struct sbus_method_ctx *iter;
-
- /*DBusObjectPathVTable *connection_vtable;*/
int ret;
- DEBUG(0,("Entering.\n"));
- dst_ctx = talloc_get_type(data,struct sbus_srv_ctx);
- if(dst_ctx == NULL) {
+
+ DEBUG(3,("Entering.\n"));
+ srv_ctx = talloc_get_type(data,struct sbus_srv_ctx);
+ if (srv_ctx == NULL) {
return;
}
- DEBUG(0,("Adding connection %lX.\n", conn));
- ret = sbus_add_connection(dst_ctx, dst_ctx->ev, conn, &dct_ctx, SBUS_CONN_TYPE_PRIVATE);
+ DEBUG(3,("Adding connection %lX.\n", conn));
+ ret = sbus_add_connection(srv_ctx, srv_ctx->ev, conn,
+ &conn_ctx, SBUS_CONN_TYPE_PRIVATE);
if (ret != 0) {
dbus_connection_close(conn);
- DEBUG(0,("Closing connection (failed setup)"));
+ DEBUG(3,("Closing connection (failed setup)"));
return;
}
-
+
dbus_connection_ref(conn);
- DEBUG(3,("Got a connection\n"));
+ DEBUG(2,("Got a connection\n"));
/* Set up global methods */
- iter = dst_ctx->sd_ctx;
+ iter = srv_ctx->sd_ctx;
while (iter != NULL) {
- sbus_conn_add_method_ctx(dct_ctx, iter);
+ sbus_conn_add_method_ctx(conn_ctx, iter);
iter = iter->next;
}
-
+
/*
* Initialize connection-specific features
* This may set a more detailed destructor, but
@@ -240,7 +242,10 @@ static void sbus_server_init_new_connection(DBusServer *server, DBusConnection *
* This function (or its callbacks) should also
* set up connection-specific methods.
*/
- dst_ctx->init_fn(dct_ctx);
+ ret = srv_ctx->init_fn(conn_ctx, srv_ctx->init_pvt_data);
+ if (ret != EOK) {
+ DEBUG(1,("Initialization failed!\n"));
+ }
}
/*
@@ -248,9 +253,11 @@ static void sbus_server_init_new_connection(DBusServer *server, DBusConnection *
* Set up a D-BUS server, integrate with the event loop
* for handling file descriptor and timed events
*/
-int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, const char *address, sbus_server_conn_init_fn init_fn)
+int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx,
+ const char *address, sbus_server_conn_init_fn init_fn,
+ void *init_pvt_data)
{
- struct sbus_srv_ctx *dst_ctx;
+ struct sbus_srv_ctx *srv_ctx;
DBusServer *dbus_server;
DBusServer **dbus_server_talloc;
DBusError dbus_error;
@@ -268,49 +275,55 @@ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, const
DEBUG(2, ("D-BUS Server listening on %s\n",
dbus_server_get_address(dbus_server)));
- dst_ctx = talloc_zero(ev, struct sbus_srv_ctx);
- if (!dst_ctx) {
+ srv_ctx = talloc_zero(ev, struct sbus_srv_ctx);
+ if (!srv_ctx) {
return ENOMEM;
}
-
- dbus_server_talloc = talloc_takeover(ctx, dbus_server, sbus_server_destructor);
- dst_ctx->ev = ev;
- dst_ctx->server = dbus_server;
- dst_ctx->sd_ctx = ctx;
- dst_ctx->init_fn = init_fn;
+
+ dbus_server_talloc = sssd_mem_takeover(ctx, dbus_server,
+ sbus_server_destructor);
+ srv_ctx->ev = ev;
+ srv_ctx->server = dbus_server;
+ srv_ctx->sd_ctx = ctx;
+ srv_ctx->init_fn = init_fn;
+ srv_ctx->init_pvt_data = init_pvt_data;
/* Set up D-BUS new connection handler */
- dbus_server_set_new_connection_function(dst_ctx->server,
+ dbus_server_set_new_connection_function(srv_ctx->server,
sbus_server_init_new_connection,
- dst_ctx, NULL);
+ srv_ctx, NULL);
/* Set up DBusWatch functions */
- dbret = dbus_server_set_watch_functions(dst_ctx->server, sbus_add_srv_watch,
- sbus_remove_watch, sbus_toggle_srv_watch,
- dst_ctx, NULL);
+ dbret = dbus_server_set_watch_functions(srv_ctx->server,
+ sbus_add_srv_watch,
+ sbus_remove_watch,
+ sbus_toggle_srv_watch,
+ srv_ctx, NULL);
if (!dbret) {
DEBUG(0, ("Error setting up D-BUS server watch functions"));
- talloc_free(dst_ctx);
+ talloc_free(srv_ctx);
return EIO;
}
/* Set up DBusTimeout functions */
- dbret = dbus_server_set_timeout_functions(dst_ctx->server,
+ dbret = dbus_server_set_timeout_functions(srv_ctx->server,
sbus_add_srv_timeout,
sbus_remove_timeout,
sbus_toggle_srv_timeout,
- dst_ctx, NULL);
+ srv_ctx, NULL);
if (!dbret) {
DEBUG(0,("Error setting up D-BUS server timeout functions"));
- dbus_server_set_watch_functions(dst_ctx->server, NULL, NULL, NULL, NULL, NULL);
- talloc_free(dst_ctx);
+ dbus_server_set_watch_functions(srv_ctx->server,
+ NULL, NULL, NULL, NULL, NULL);
+ talloc_free(srv_ctx);
return EIO;
}
return EOK;
}
-static int sbus_server_destructor(void **server) {
+static int sbus_server_destructor(void **server)
+{
dbus_server_disconnect(*server);
return 0;
}
diff --git a/server/sbus_interfaces.h b/server/sbus_interfaces.h
index 106a54957..2e6372de4 100644
--- a/server/sbus_interfaces.h
+++ b/server/sbus_interfaces.h
@@ -36,6 +36,7 @@
/* Service Methods */
#define SERVICE_METHOD_IDENTITY "getIdentity"
+#define SERVICE_METHOD_PING "ping"
#define DEFAULT_SBUS_ADDRESS "unix:path=/var/lib/sss/pipes/private/dbus"