Exemplo n.º 1
0
/*
  this is called when the ctdb daemon received a ctdb request message
  from a local client over the unix domain socket
 */
static void daemon_request_message_from_client(struct ctdb_client *client, 
					       struct ctdb_req_message *c)
{
	TDB_DATA data;
	int res;

	if (c->hdr.destnode == CTDB_CURRENT_NODE) {
		c->hdr.destnode = ctdb_get_pnn(client->ctdb);
	}

	/* maybe the message is for another client on this node */
	if (ctdb_get_pnn(client->ctdb)==c->hdr.destnode) {
		ctdb_request_message(client->ctdb, (struct ctdb_req_header *)c);
		return;
	}

	/* its for a remote node */
	data.dptr = &c->data[0];
	data.dsize = c->datalen;
	res = ctdb_daemon_send_message(client->ctdb, c->hdr.destnode,
				       c->srvid, data);
	if (res != 0) {
		DEBUG(DEBUG_ERR,(__location__ " Failed to send message to remote node %u\n",
			 c->hdr.destnode));
	}
}
Exemplo n.º 2
0
/*
	Just try locking/unlocking a single record once
*/
static void fetch_lock_once(struct ctdb_context *ctdb, struct event_context *ev, uint32_t generation)
{
	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
	TDB_DATA key, data;
	struct ctdb_record_handle *h;
	struct ctdb_ltdb_header *header;
	int ret;

	key.dptr = discard_const(TESTKEY);
	key.dsize = strlen(TESTKEY);

	printf("Trying to fetch lock the record ...\n");

	h = ctdb_fetch_readonly_lock(ctdb_db, tmp_ctx, key, &data, false);
	if (h == NULL) {
		printf("Failed to fetch record '%s' on node %d\n", 
	       		(const char *)key.dptr, ctdb_get_pnn(ctdb));
		talloc_free(tmp_ctx);
		exit(10);
	}

	printf("Record fetchlocked.\n");
	header = talloc_memdup(tmp_ctx, ctdb_header_from_record_handle(h), sizeof(*header));
       	printf("RSN:%d\n", (int)header->rsn);
	talloc_free(h);
	printf("Record released.\n");

	printf("Write new record with RSN+10\n");
	header->rsn += 10;
	data.dptr = (void *)talloc_asprintf(tmp_ctx, "%d", (int)header->rsn);
	data.dsize = strlen((char *)data.dptr);

	ret = ctdb_ctrl_updaterecord(ctdb, ctdb, timeval_zero(), CTDB_CURRENT_NODE, ctdb_db, key, header, data);
	if (ret != 0) {
		printf("Failed to writerecord,  ret==%d\n", ret);	
		exit(1);
	}

	printf("re-fetch the record\n");
	h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
	if (h == NULL) {
		printf("Failed to fetch record '%s' on node %d\n", 
	       		(const char *)key.dptr, ctdb_get_pnn(ctdb));
		talloc_free(tmp_ctx);
		exit(10);
	}

	printf("Record fetchlocked.\n");
	header = talloc_memdup(tmp_ctx, ctdb_header_from_record_handle(h), sizeof(*header));
       	printf("RSN:%d\n", (int)header->rsn);
	talloc_free(h);
	printf("Record released.\n");

	talloc_free(tmp_ctx);
}
Exemplo n.º 3
0
/*
	Just try locking/unlocking a single record once
*/
static void fetch_lock_once(struct ctdb_context *ctdb, struct event_context *ev)
{
	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
	TDB_DATA key, data;
	struct ctdb_record_handle *h;
	static time_t t = 0, t2;

	key.dptr = discard_const(TESTKEY);
	key.dsize = strlen(TESTKEY);

//	printf("Trying to fetch lock the record ...\n");

	h = ctdb_fetch_readonly_lock(ctdb_db, tmp_ctx, key, &data, true);
	if (h == NULL) {
		printf("Failed to fetch record '%s' on node %d\n", 
	       		(const char *)key.dptr, ctdb_get_pnn(ctdb));
		talloc_free(tmp_ctx);
		exit(10);
	}

	count++;
	t2 = time(NULL);
	if (t != 0 && t != t2) {
		static int last_count = 0;

		printf("count : %d\n", count - last_count);
		last_count = count;
	}
	t = t2;

	talloc_free(tmp_ctx);
}
Exemplo n.º 4
0
static void store_records(struct ctdb_context *ctdb, struct event_context *ev)
{
    TDB_DATA key, data;
    struct ctdb_db_context *ctdb_db;
    TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
    int ret;
    struct ctdb_record_handle *h;
    uint32_t i=0;

    ctdb_db = ctdb_db_handle(ctdb, "test.tdb");

    srandom(time(NULL) ^ getpid());

    start_timer();

    printf("working with %d records\n", num_records);
    while (1) {
        unsigned r = random() % num_records;
        key.dptr = (uint8_t *)&r;
        key.dsize = sizeof(r);

        h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
        if (h == NULL) {
            printf("Failed to fetch record '%s' on node %d\n",
                   (const char *)key.dptr, ctdb_get_pnn(ctdb));
            talloc_free(tmp_ctx);
            return;
        }

        if (random() % 100 < delete_pct) {
            data.dptr = NULL;
            data.dsize = 0;
        } else {
            data.dptr = talloc_zero_size(h, data.dsize + sizeof(r));
            data.dsize += sizeof(r);
        }

        ret = ctdb_record_store(h, data);
        if (ret != 0) {
            printf("Failed to store record\n");
        }

        if (data.dptr == NULL && data.dsize == 0) {
            struct ctdb_control_schedule_for_deletion *dd;
            TDB_DATA indata;
            int32_t status;

            indata.dsize = offsetof(struct ctdb_control_schedule_for_deletion, key) + key.dsize;
            indata.dptr = talloc_zero_array(ctdb, uint8_t, indata.dsize);
            if (indata.dptr == NULL) {
                printf("out of memory\n");
                exit(1);
            }
            dd = (struct ctdb_control_schedule_for_deletion *)(void *)indata.dptr;
            dd->db_id = ctdb_db->db_id;
            dd->hdr = *ctdb_header_from_record_handle(h);
            dd->keylen = key.dsize;
            memcpy(dd->key, key.dptr, key.dsize);

            ret = ctdb_control(ctdb,
                               CTDB_CURRENT_NODE,
                               ctdb_db->db_id,
                               CTDB_CONTROL_SCHEDULE_FOR_DELETION,
                               0, /* flags */
                               indata,
                               NULL, /* mem_ctx */
                               NULL, /* outdata */
                               &status,
                               NULL, /* timeout : NULL == wait forever */
                               NULL); /* error message */

            talloc_free(indata.dptr);

            if (ret != 0 || status != 0) {
                DEBUG(DEBUG_ERR, (__location__ " Error sending "
                                  "SCHEDULE_FOR_DELETION "
                                  "control.\n"));
            }
        }

        talloc_free(h);

        if (i % 1000 == 0) {
            printf("%7.0f recs/second   %u total\r", 1000.0 / end_timer(), i);
            fflush(stdout);
            start_timer();
        }
        i++;
    }

    talloc_free(tmp_ctx);
}
Exemplo n.º 5
0
static void store_records(struct ctdb_context *ctdb, struct event_context *ev)
{
	TDB_DATA key, data;
	struct ctdb_db_context *ctdb_db;
	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
	int ret;
	struct ctdb_record_handle *h;
	uint32_t i;
	
	ctdb_db = ctdb_db_handle(ctdb, "test.tdb");

	printf("creating %d records\n", num_records);
	for (i=0;i<num_records;i++) {
		int r = base_rec + i;
		key.dptr = (uint8_t *)&r;
		key.dsize = sizeof(uint32_t); 

		h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
		if (h == NULL) {
			printf("Failed to fetch record '%s' on node %d\n", 
			       (const char *)key.dptr, ctdb_get_pnn(ctdb));
			talloc_free(tmp_ctx);
			return;
		}

		data.dptr = (uint8_t *)&i;
		data.dsize = sizeof(uint32_t);

		ret = ctdb_record_store(h, data);
		talloc_free(h);
		if (ret != 0) {
			printf("Failed to store record\n");
		}
		if (i % 1000 == 0) {
			printf("%u\r", i);
			fflush(stdout);
		}
	}

	printf("fetching all %d records\n", num_records);
	while (1) {
		for (i=0;i<num_records;i++) {
			int r = base_rec + i;
			key.dptr = (uint8_t *)&r;
			key.dsize = sizeof(uint32_t); 

			h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
			if (h == NULL) {
				printf("Failed to fetch record '%s' on node %d\n", 
				       (const char *)key.dptr, ctdb_get_pnn(ctdb));
				talloc_free(tmp_ctx);
				return;
			}
			talloc_free(h);
		}
		sleep(1);
		printf(".");
		fflush(stdout);
	}

	talloc_free(tmp_ctx);
}
Exemplo n.º 6
0
/*
  main program
*/
int main(int argc, const char *argv[])
{
	struct ctdb_context *ctdb;
	struct ctdb_db_context *ctdb_db;
	int unsafe_writes = 0;
	struct poptOption popt_options[] = {
		POPT_AUTOHELP
		POPT_CTDB_CMDLINE
		{ "timelimit", 't', POPT_ARG_INT, &timelimit, 0, "timelimit", "integer" },
		{ "delay", 'D', POPT_ARG_INT, &delay, 0, "delay (in seconds) between operations", "integer" },
		{ "verbose", 'v', POPT_ARG_NONE,  &verbose, 0, "switch on verbose mode", NULL },
		{ "unsafe-writes", 'u', POPT_ARG_NONE, &unsafe_writes, 0, "do not use tdb transactions when writing", NULL },
		POPT_TABLEEND
	};
	int opt;
	const char **extra_argv;
	int extra_argc = 0;
	poptContext pc;
	struct event_context *ev;

	printf("SUCCESS (transaction test disabled while transactions are being rewritten)\n");
	exit(0);

	if (verbose) {
		setbuf(stdout, (char *)NULL); /* don't buffer */
	} else {
		setlinebuf(stdout);
	}

	pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		default:
			fprintf(stderr, "Invalid option %s: %s\n", 
				poptBadOption(pc, 0), poptStrerror(opt));
			exit(1);
		}
	}

	/* setup the remaining options for the main program to use */
	extra_argv = poptGetArgs(pc);
	if (extra_argv) {
		extra_argv++;
		while (extra_argv[extra_argc]) extra_argc++;
	}

	ev = event_context_init(NULL);

	ctdb = ctdb_cmdline_client(ev);
	if (ctdb == NULL) {
		DEBUG(DEBUG_ERR, ("Could not attach to daemon\n"));
		return 1;
	}

	/* attach to a specific database */
	if (unsafe_writes == 1) {
		ctdb_db = ctdb_attach(ctdb, "transaction.tdb", true, TDB_NOSYNC);
	} else {
		ctdb_db = ctdb_attach(ctdb, "transaction.tdb", true, 0);
	}

	if (!ctdb_db) {
		DEBUG(DEBUG_ERR, ("ctdb_attach failed - %s\n", ctdb_errstr(ctdb)));
		exit(1);
	}

	DEBUG(DEBUG_ERR, ("Waiting for cluster\n"));
	while (1) {
		uint32_t recmode=1;
		ctdb_ctrl_getrecmode(ctdb, ctdb, timeval_zero(), CTDB_CURRENT_NODE, &recmode);
		if (recmode == 0) break;
		event_loop_once(ev);
	}

	pnn = ctdb_get_pnn(ctdb);
	printf("Starting test on node %u. running for %u seconds. sleep delay: %u seconds.\n", pnn, timelimit, delay);

	if (!verbose && (pnn == 0)) {
		event_add_timed(ev, ctdb, timeval_current_ofs(1, 0), each_second, ctdb);
	}

	test_store_records(ctdb, ev);

	if (verbose || (pnn == 0)) {
		if (success != true) {
			printf("The test FAILED\n");
			return 1;
		} else {
			printf("SUCCESS!\n");
		}
	}
	return 0;
}
Exemplo n.º 7
0
static void test_store_records(struct ctdb_context *ctdb, struct event_context *ev)
{
	TDB_DATA key;
	struct ctdb_db_context *ctdb_db;
	int ret;
	uint32_t *counters;
	ctdb_db = ctdb_db_handle(ctdb, "transaction.tdb");

	key.dptr = discard_const("testkey");
	key.dsize = strlen((const char *)key.dptr)+1;

	start_timer();
	while ((timelimit == 0) || (end_timer() < timelimit)) {
		TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
		TDB_DATA data;
		struct ctdb_transaction_handle *h;

		if (verbose) DEBUG(DEBUG_ERR, ("starting transaction\n"));
		h = ctdb_transaction_start(ctdb_db, tmp_ctx);
		if (h == NULL) {
			DEBUG(DEBUG_ERR, ("Failed to start transaction on node %d\n",
			       ctdb_get_pnn(ctdb)));
			talloc_free(tmp_ctx);
			return;
		}
		if (verbose) DEBUG(DEBUG_ERR, ("transaction started\n"));
		do_sleep(delay);

		if (verbose) DEBUG(DEBUG_ERR, ("calling transaction_fetch\n"));
		ret = ctdb_transaction_fetch(h, tmp_ctx, key, &data);
		if (ret != 0) {
			DEBUG(DEBUG_ERR,("Failed to fetch record\n"));
			exit(1);
		}
		if (verbose) DEBUG(DEBUG_ERR, ("fetched data ok\n"));
		do_sleep(delay);

		if (data.dsize < sizeof(uint32_t) * (pnn+1)) {
			unsigned char *ptr = data.dptr;

			data.dptr = talloc_zero_size(tmp_ctx, sizeof(uint32_t) * (pnn+1));
			memcpy(data.dptr, ptr, data.dsize);
			talloc_free(ptr);

			data.dsize = sizeof(uint32_t) * (pnn+1);
		}

		if (data.dptr == NULL) {
			DEBUG(DEBUG_ERR, ("Failed to realloc array\n"));
			talloc_free(tmp_ctx);
			return;
		}

		counters = (uint32_t *)data.dptr;

		/* bump our counter */
		counters[pnn]++;

		if (verbose) DEBUG(DEBUG_ERR, ("calling transaction_store\n"));
		ret = ctdb_transaction_store(h, key, data);
		if (ret != 0) {
			DEBUG(DEBUG_ERR,("Failed to store record\n"));
			exit(1);
		}
		if (verbose) DEBUG(DEBUG_ERR, ("stored data ok\n"));
		do_sleep(delay);

		if (verbose) DEBUG(DEBUG_ERR, ("calling transaction_commit\n"));
		ret = ctdb_transaction_commit(h);
		if (ret != 0) {
			DEBUG(DEBUG_ERR,("Failed to commit transaction\n"));
			check_counters(ctdb, data);
			exit(1);
		}
		if (verbose) DEBUG(DEBUG_ERR, ("transaction committed\n"));

		/* store the counters and verify that they are sane */
		if (verbose || (pnn == 0)) {
			check_counters(ctdb, data);
		}

		do_sleep(delay);

		talloc_free(tmp_ctx);
	}

}