Exemple #1
0
/*
  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;
}
Exemple #2
0
/*
  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;
}
Exemple #3
0
/*
  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;
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
0
/***********************************************************************
 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);
}
Exemple #7
0
/*
  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;
}