[SSSD] [PATCH] Add callback when the ID provider switches from offline to online
Sumit Bose
sbose at redhat.com
Tue May 4 17:27:40 UTC 2010
On Mon, May 03, 2010 at 03:41:18PM -0400, Stephen Gallagher wrote:
> On 04/29/2010 07:41 AM, Stephen Gallagher wrote:
> >On 04/29/2010 05:52 AM, Sumit Bose wrote:
> >>>+
> >>>+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 (!online_cb) {
> >>if (!on_cb) ??
> >>
> >>bye,
> >>Sumit
> >Thanks for catching that. When I added the **online_cb return, I changed
> >the name of the internal struct to be on_cb, but I missed that use of
> >it. That would have been a bug, since it would have returned on error if
> >called without expecting a returned struct.
> >
> >New patch attached.
> >
>
> Rebased to current sssd-1-2.
ACK
bye,
Sumit
>
> --
> Stephen Gallagher
> RHCE 804006346421761
>
> Delivering value year after year.
> Red Hat ranks #1 in value among software vendors.
> http://www.redhat.com/promo/vendor/
> From 5aaf82cdf4838105dab6e7601ead134a5309f89f Mon Sep 17 00:00:00 2001
> From: Stephen Gallagher <sgallagh at redhat.com>
> Date: Tue, 27 Apr 2010 14:57:37 -0400
> Subject: [PATCH 1/3] 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.
> ---
> src/providers/data_provider_be.c | 138 ++++++++++++++++++++++++++++
> src/providers/dp_backend.h | 17 ++++
> src/providers/ldap/sdap_async_connection.c | 9 ++
> src/providers/proxy.c | 10 ++
> 4 files changed, 174 insertions(+), 0 deletions(-)
>
> diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
> index 22f18024858a73da8788ad93dcc863a1c3222069..320821ae41daf1f7a64ba69aac0e8f0d91c3e5f1 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;
> diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
> index f1069d0db313ca278e6125908668e2aad2c25b76..330f0f03b7b107cfbe272c92afed83e687f32d70 100644
> --- a/src/providers/dp_backend.h
> +++ b/src/providers/dp_backend.h
> @@ -35,6 +35,8 @@ typedef void (*be_shutdown_fn)(void *);
> typedef void (*be_req_fn_t)(struct be_req *);
> typedef void (*be_async_callback_t)(struct be_req *, int, int, const char *);
>
> +typedef void (*be_conn_online_callback_t)(void *);
> +
> enum bet_type {
> BET_NULL = 0,
> BET_ID,
> @@ -76,6 +78,8 @@ struct be_client {
>
> struct be_failover_ctx;
>
> +struct be_conn_online_cb;
> +
> struct be_ctx {
> struct tevent_context *ev;
> struct confdb_ctx *cdb;
> @@ -85,6 +89,12 @@ struct be_ctx {
> const char *conf_path;
> struct be_failover_ctx *be_fo;
>
> + /* Functions to be invoked when the
> + * backend goes online
> + */
> + struct be_conn_online_cb *online_cb_list;
> + bool run_online_cb;
> +
> struct be_offline_status offstat;
>
> struct sbus_connection *mon_conn;
> @@ -122,6 +132,13 @@ struct be_acct_req {
> bool be_is_offline(struct be_ctx *ctx);
> void be_mark_offline(struct be_ctx *ctx);
>
> +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);
> +void be_run_online_cb(struct be_ctx *be);
> +
> /* from data_provider_fo.c */
> typedef void (be_svc_callback_fn_t)(void *, struct fo_server *);
>
> diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
> index 9871dc2109d2c0eac00f95401ba5dae2d16486ce..214c58efb63d71580f64dce95c8a9a1bec302581 100644
> --- a/src/providers/ldap/sdap_async_connection.c
> +++ b/src/providers/ldap/sdap_async_connection.c
> @@ -813,6 +813,7 @@ struct sdap_cli_connect_state {
> struct tevent_context *ev;
> struct sdap_options *opts;
> struct sdap_service *service;
> + struct be_ctx *be;
>
> bool use_rootdse;
> struct sysdb_attrs *rootdse;
> @@ -848,6 +849,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
> state->opts = opts;
> state->service = service;
> state->srv = NULL;
> + state->be = be;
>
> if (rootdse) {
> state->use_rootdse = true;
> @@ -1077,6 +1079,8 @@ static void sdap_cli_auth_done(struct tevent_req *subreq)
> {
> struct tevent_req *req = tevent_req_callback_data(subreq,
> struct tevent_req);
> + struct sdap_cli_connect_state *state = tevent_req_data(req,
> + struct sdap_cli_connect_state);
> enum sdap_result result;
> int ret;
>
> @@ -1091,6 +1095,11 @@ static void sdap_cli_auth_done(struct tevent_req *subreq)
> return;
> }
>
> + /* Reconnection succeeded
> + * Run any post-connection routines
> + */
> + be_run_online_cb(state->be);
> +
> tevent_req_done(req);
> }
>
> diff --git a/src/providers/proxy.c b/src/providers/proxy.c
> index 09a2555c5c509ee837019c69ad2c2ddd9f9d01d5..d3ec7ef35361300fb6e7d708e1f91d9b230eeb4a 100644
> --- a/src/providers/proxy.c
> +++ b/src/providers/proxy.c
> @@ -296,6 +296,16 @@ static void proxy_pam_handler_cache_done(struct tevent_req *subreq)
> static void proxy_reply(struct be_req *req, int dp_err,
> int error, const char *errstr)
> {
> + if (!req->be_ctx->offstat.offline) {
> + /* This action took place online.
> + * Fire any online callbacks if necessary.
> + * Note: we're checking the offline value directly,
> + * because if the activity took a long time to
> + * complete, calling be_is_offline() might report false
> + * incorrectly.
> + */
> + be_run_online_cb(req->be_ctx);
> + }
> return req->fn(req, dp_err, error, errstr);
> }
>
> --
> 1.7.0.1
>
> _______________________________________________
> sssd-devel mailing list
> sssd-devel at lists.fedorahosted.org
> https://fedorahosted.org/mailman/listinfo/sssd-devel
More information about the sssd-devel
mailing list