summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-08-11 06:36:36 -0400
committerStephen Gallagher <sgallagh@redhat.com>2009-08-11 12:29:36 -0400
commitab9cfe72d18531ca0fc93c772582329a3b0c5dc9 (patch)
tree81d7a680a3441b71b2ba64333fdb1100967dff20
parent06a3b13134e29b75971970aa45ba14576a4f6ced (diff)
downloadsssd-ab9cfe72d18531ca0fc93c772582329a3b0c5dc9.tar.gz
sssd-ab9cfe72d18531ca0fc93c772582329a3b0c5dc9.tar.bz2
sssd-ab9cfe72d18531ca0fc93c772582329a3b0c5dc9.zip
Prevent races between dp startup and others
Simply delay anything other service by 1 second only at startup.
-rw-r--r--server/monitor/monitor.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index f9dc9b0c..ba92a906 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -118,7 +118,7 @@ struct mt_ctx {
int service_id_timeout;
};
-static int start_service(struct mt_svc *mt_svc);
+static int start_service(struct mt_svc *mt_svc, bool startup);
static int monitor_service_init(struct sbus_connection *conn, void *data);
@@ -135,8 +135,8 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
struct mt_svc **svc_cfg);
static int get_provider_config(struct mt_ctx *ctx, const char *name,
struct mt_svc **svc_cfg);
-static int add_new_service(struct mt_ctx *ctx, const char *name);
-static int add_new_provider(struct mt_ctx *ctx, const char *name);
+static int add_new_service(struct mt_ctx *ctx, const char *name, bool startup);
+static int add_new_provider(struct mt_ctx *ctx, const char *name, bool startup);
static int monitor_signal_reconf(struct config_file_ctx *file_ctx,
const char *filename);
@@ -378,7 +378,7 @@ static void svc_try_restart(struct mt_svc *svc, time_t now)
*/
talloc_free(svc->ping_ev);
- ret = start_service(svc);
+ ret = start_service(svc, false);
if (ret != EOK) {
DEBUG(0,("Failed to restart service '%s'\n", svc->name));
talloc_free(svc);
@@ -923,14 +923,14 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
return EOK;
}
-static int add_new_service(struct mt_ctx *ctx, const char *name)
+static int add_new_service(struct mt_ctx *ctx, const char *name, bool startup)
{
int ret;
struct mt_svc *svc;
ret = get_service_config(ctx, name, &svc);
- ret = start_service(svc);
+ ret = start_service(svc, startup);
if (ret != EOK) {
DEBUG(0,("Failed to start service '%s'\n", svc->name));
talloc_free(svc);
@@ -1023,7 +1023,7 @@ static int get_provider_config(struct mt_ctx *ctx, const char *name,
return EOK;
}
-static int add_new_provider(struct mt_ctx *ctx, const char *name)
+static int add_new_provider(struct mt_ctx *ctx, const char *name, bool startup)
{
int ret;
struct mt_svc *svc;
@@ -1035,7 +1035,7 @@ static int add_new_provider(struct mt_ctx *ctx, const char *name)
return ret;
}
- ret = start_service(svc);
+ ret = start_service(svc, startup);
if (ret != EOK) {
DEBUG(0,("Failed to start service '%s'\n", svc->name));
talloc_free(svc);
@@ -1115,7 +1115,7 @@ static int update_monitor_config(struct mt_ctx *ctx)
if (ctx->services[j] == NULL) {
/* New service added */
- add_new_service(ctx, new_config->services[i]);
+ add_new_service(ctx, new_config->services[i], false);
}
else {
/* Service already enabled, check for changes */
@@ -1200,7 +1200,7 @@ static int update_monitor_config(struct mt_ctx *ctx)
if (dom == NULL) {
/* New provider added */
- add_new_provider(ctx, new_dom->name);
+ add_new_provider(ctx, new_dom->name, false);
}
else {
/* Provider is already in the list.
@@ -1852,14 +1852,14 @@ int monitor_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- /* start all services */
+ /* then start all services */
for (i = 0; ctx->services[i]; i++) {
- add_new_service(ctx, ctx->services[i]);
+ add_new_service(ctx, ctx->services[i], true);
}
/* now start the data providers */
for (dom = ctx->domains; dom; dom = dom->next) {
- add_new_provider(ctx, dom->name);
+ add_new_provider(ctx, dom->name, true);
}
/* now start checking for global events */
@@ -2201,22 +2201,32 @@ static void service_startup_handler(struct tevent_context *ev,
struct tevent_timer *te,
struct timeval t, void *ptr);
-static int start_service(struct mt_svc *svc)
+static int start_service(struct mt_svc *svc, bool startup)
{
struct tevent_timer *te;
struct timeval tv;
DEBUG(4,("Queueing service %s for startup\n", svc->name));
+ /* at startup we need to start the data provider service before all others
+ * to avoid races where a service that need dp starts before it is ready
+ * to accept connections on its dbus. So if startup is true delay by 1
+ * second any process that is not the data provider */
+
+ if (startup && strcasecmp(svc->name, "dp")) {
+ tv = tevent_timeval_current_ofs(1, 0);
+ } else {
+ tv = tevent_timeval_current();
+ }
+
/* Add a timed event to start up the service.
* We have to do this in order to avoid a race
* condition where the service being started forks
* and attempts to connect to the SBUS before
* the monitor is serving it.
*/
- gettimeofday(&tv, NULL);
te = tevent_add_timer(svc->mt_ctx->ev, svc, tv,
- service_startup_handler, svc);
+ service_startup_handler, svc);
if (te == NULL) {
DEBUG(0, ("Unable to queue service %s for startup\n", svc->name));
return ENOMEM;