summaryrefslogtreecommitdiffstats
path: root/src/providers/data_provider_be.c
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2010-04-27 14:57:37 -0400
committerStephen Gallagher <sgallagh@redhat.com>2010-05-07 17:14:32 -0400
commitdd025b4cbd501e2f34461f9d8359a829b81f5c2f (patch)
treeb04795563e7072d0b66ad28383d00624656363fa /src/providers/data_provider_be.c
parent96a6aa73a6ea0982b349ac10b82aaf86d03ec5f5 (diff)
downloadsssd-dd025b4cbd501e2f34461f9d8359a829b81f5c2f.tar.gz
sssd-dd025b4cbd501e2f34461f9d8359a829b81f5c2f.tar.xz
sssd-dd025b4cbd501e2f34461f9d8359a829b81f5c2f.zip
Add callback when the ID provider switches from offline to online
Allow backends to set a callback in the be_ctx that should be invoked when the ID provider goes online. This can be used to perform regular maintenance tasks that are valid only when going online.
Diffstat (limited to 'src/providers/data_provider_be.c')
-rw-r--r--src/providers/data_provider_be.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index e5a5ff7b0..27a4571a7 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -166,8 +166,146 @@ void be_mark_offline(struct be_ctx *ctx)
ctx->offstat.went_offline = time(NULL);
ctx->offstat.offline = true;
+ ctx->run_online_cb = true;
}
+
+struct be_conn_online_cb {
+ struct be_conn_online_cb *prev;
+ struct be_conn_online_cb *next;
+
+ be_conn_online_callback_t cb;
+ void *pvt;
+
+ struct be_ctx *be;
+};
+
+static int online_cb_destructor(TALLOC_CTX *ptr);
+int be_add_online_cb(TALLOC_CTX *mem_ctx,
+ struct be_ctx *ctx,
+ be_conn_online_callback_t cb,
+ void *pvt,
+ struct be_conn_online_cb **online_cb)
+{
+ struct be_conn_online_cb *on_cb;
+
+ if (!ctx || !cb) {
+ return EINVAL;
+ }
+
+ on_cb = talloc(mem_ctx, struct be_conn_online_cb);
+ if (!on_cb) {
+ return ENOMEM;
+ }
+
+ on_cb->cb = cb;
+ on_cb->pvt = pvt;
+ on_cb->be = ctx;
+
+ DLIST_ADD(ctx->online_cb_list, on_cb);
+
+ talloc_set_destructor((TALLOC_CTX *)on_cb, online_cb_destructor);
+
+ /* Make sure we run the callback for the first
+ * connection after startup.
+ */
+ ctx->run_online_cb = true;
+
+ if (online_cb) {
+ *online_cb = on_cb;
+ }
+
+ return EOK;
+}
+
+static int online_cb_destructor(TALLOC_CTX *ptr)
+{
+ struct be_conn_online_cb *cb =
+ talloc_get_type(ptr, struct be_conn_online_cb);
+ DLIST_REMOVE(cb->be->online_cb_list, cb);
+ return 0;
+}
+
+
+struct be_online_cb_ctx {
+ struct be_ctx *be;
+ struct be_conn_online_cb *callback;
+};
+
+static void be_run_online_cb_step(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *pvt);
+void be_run_online_cb(struct be_ctx *be) {
+ struct timeval soon;
+ struct tevent_timer *te;
+ struct be_online_cb_ctx *cb_ctx;
+
+ if (be->run_online_cb && be->online_cb_list) {
+ /* Reset the flag. We only want to run these
+ * callbacks when transitioning to online
+ */
+ be->run_online_cb = false;
+
+ DEBUG(3, ("Going online. Running callbacks.\n"));
+
+ cb_ctx = talloc(be, struct be_online_cb_ctx);
+ if (!cb_ctx) {
+ DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
+ return;
+ }
+ cb_ctx->be = be;
+ cb_ctx->callback = be->online_cb_list;
+
+ /* Delay 30ms so we don't block any other events */
+ soon = tevent_timeval_current_ofs(0, 30000);
+ te = tevent_add_timer(be->ev, cb_ctx, soon,
+ be_run_online_cb_step,
+ cb_ctx);
+ if (!te) {
+ DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
+ talloc_free(cb_ctx);
+ }
+ }
+}
+
+static void be_run_online_cb_step(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *pvt)
+{
+ struct be_online_cb_ctx *cb_ctx =
+ talloc_get_type(pvt, struct be_online_cb_ctx);
+ struct tevent_timer *tev;
+ struct timeval soon;
+
+ /* Call the callback */
+ cb_ctx->callback->cb(cb_ctx->callback->pvt);
+
+ if (cb_ctx->callback->next) {
+ cb_ctx->callback = cb_ctx->callback->next;
+
+ /* Delay 30ms so we don't block any other events */
+ soon = tevent_timeval_current_ofs(0, 30000);
+ tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon,
+ be_run_online_cb_step,
+ cb_ctx);
+ if (!te) {
+ DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
+ goto final;
+ }
+ return;
+ }
+
+final:
+ /* Steal the timer event onto the be_ctx so it doesn't
+ * get freed with the cb_ctx
+ */
+ talloc_steal(cb_ctx->be, te);
+ talloc_free(cb_ctx);
+}
+
+
static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
{
struct be_client *becli;