/* Open up the notify.tdb database. You should close it down using talloc_free(). We need the messaging_ctx to allow for notifications via internal messages */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx, struct event_context *ev, connection_struct *conn) { struct notify_context *notify; if (!lp_change_notify(conn->params)) { return NULL; } notify = talloc(mem_ctx, struct notify_context); if (notify == NULL) { return NULL; } notify->db_recursive = db_open(notify, lock_path("notify.tdb"), 0, TDB_SEQNUM|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_2); if (notify->db_recursive == NULL) { talloc_free(notify); return NULL; } notify->db_onelevel = db_open(notify, lock_path("notify_onelevel.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDWR|O_CREAT, 0644, DBWRAP_LOCK_ORDER_2); if (notify->db_onelevel == NULL) { talloc_free(notify); return NULL; } notify->server = server; notify->messaging_ctx = messaging_ctx; notify->list = NULL; notify->array = NULL; notify->seqnum = dbwrap_get_seqnum(notify->db_recursive); notify->key = string_term_tdb_data(NOTIFY_KEY); talloc_set_destructor(notify, notify_destructor); /* register with the messaging subsystem for the notify message type */ messaging_register(notify->messaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); notify->sys_notify_ctx = sys_notify_context_create(conn, notify, ev); return notify; }
/* Open up the notify.tdb database. You should close it down using talloc_free(). We need the imessaging_ctx to allow for notifications via internal messages */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, struct imessaging_context *imessaging_ctx, struct loadparm_context *lp_ctx, struct tevent_context *ev, struct share_config *scfg) { struct notify_context *notify; if (share_bool_option(scfg, NOTIFY_ENABLE, NOTIFY_ENABLE_DEFAULT) != true) { return NULL; } if (ev == NULL) { return NULL; } notify = talloc(mem_ctx, struct notify_context); if (notify == NULL) { return NULL; } notify->db = cluster_db_tmp_open(notify, lp_ctx, "notify", TDB_SEQNUM); if (notify->db == NULL) { talloc_free(notify); return NULL; } notify->server = server; notify->imessaging_ctx = imessaging_ctx; notify->list = NULL; notify->array = NULL; notify->seqnum = dbwrap_get_seqnum(notify->db); talloc_set_destructor(notify, notify_destructor); /* register with the messaging subsystem for the notify message type */ imessaging_register(notify->imessaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); notify->sys_notify_ctx = sys_notify_context_create(scfg, notify, ev); return notify; }
/* load the notify array */ static NTSTATUS notify_load(struct notify_context *notify) { TDB_DATA dbuf; DATA_BLOB blob; enum ndr_err_code ndr_err; int seqnum; NTSTATUS status; seqnum = dbwrap_get_seqnum(notify->db); if (seqnum == notify->seqnum && notify->array != NULL) { return NT_STATUS_OK; } notify->seqnum = seqnum; talloc_free(notify->array); notify->array = talloc_zero(notify, struct notify_array); NT_STATUS_HAVE_NO_MEMORY(notify->array); status = dbwrap_fetch_bystring(notify->db, notify, NOTIFY_KEY, &dbuf); if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_OK; } blob.data = dbuf.dptr; blob.length = dbuf.dsize; ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array, (ndr_pull_flags_fn_t)ndr_pull_notify_array); talloc_free(dbuf.dptr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } return NT_STATUS_OK; }
static bool dbwrap_cache_validate(struct db_cache_ctx *ctx) { int backing_seqnum; backing_seqnum = dbwrap_get_seqnum(ctx->backing); if (backing_seqnum == ctx->seqnum) { return true; } TALLOC_FREE(ctx->positive); ctx->positive = db_open_rbt(ctx); if (ctx->positive == NULL) { return false; } TALLOC_FREE(ctx->negative); ctx->negative = db_open_rbt(ctx); if (ctx->negative == NULL) { return false; } ctx->seqnum = backing_seqnum; return true; }
static int dbwrap_cache_get_seqnum(struct db_context *db) { struct db_cache_ctx *ctx = talloc_get_type_abort( db->private_data, struct db_cache_ctx); return dbwrap_get_seqnum(ctx->backing); }
/*********************************************************************** return the tdb sequence number of the registry tdb. this is an indicator for the content of the registry having changed. it will change upon regdb_init, too, though. ***********************************************************************/ int regdb_get_seqnum(void) { return dbwrap_get_seqnum(regdb); }
/* load the notify array */ static NTSTATUS notify_load(struct notify_context *notify, struct db_record *rec) { TDB_DATA dbuf; DATA_BLOB blob; NTSTATUS status; int seqnum; seqnum = dbwrap_get_seqnum(notify->db_recursive); if (seqnum == notify->seqnum && notify->array != NULL) { return NT_STATUS_OK; } notify->seqnum = seqnum; talloc_free(notify->array); notify->array = talloc_zero(notify, struct notify_array); NT_STATUS_HAVE_NO_MEMORY(notify->array); if (!rec) { status = dbwrap_fetch(notify->db_recursive, notify, notify->key, &dbuf); if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } } else { dbuf = dbwrap_record_get_value(rec); } blob.data = (uint8 *)dbuf.dptr; blob.length = dbuf.dsize; status = NT_STATUS_OK; if (blob.length > 0) { enum ndr_err_code ndr_err; ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array, (ndr_pull_flags_fn_t)ndr_pull_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { /* 1. log that we got a corrupt notify_array * 2. clear the variable the garbage was stored into to not trip * over it next time this method is entered with the same seqnum * 3. delete it from the database */ DEBUG(2, ("notify_array is corrupt, discarding it\n")); ZERO_STRUCTP(notify->array); if (rec != NULL) { dbwrap_record_delete(rec); } } else { if (DEBUGLEVEL >= 10) { DEBUG(10, ("notify_load:\n")); NDR_PRINT_DEBUG(notify_array, notify->array); } } } if (!rec) { talloc_free(dbuf.dptr); } return status; }