1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

remaning code to finish lock_fetch/store_unlock clientside helpers

(This used to be ctdb commit edf1e1fea8500461a08cd2795251a5cc0bd10229)
This commit is contained in:
Ronnie sahlberg 2007-04-17 11:48:27 +10:00
commit 45660a3c48
4 changed files with 83 additions and 28 deletions

View File

@ -545,19 +545,33 @@ struct ctdb_record_handle *ctdb_client_fetch_lock(struct ctdb_db_context *ctdb_d
return NULL; return NULL;
} }
ret = ctdb_ltdb_fetch(ctdb_db, key, &header, ctdb_db, &data); ret = ctdb_ltdb_fetch(ctdb_db, key, &header, ctdb_db, data);
if (ret != 0) { if (ret != 0) {
ctdb_ltdb_unlock(ctdb_db, key); ctdb_ltdb_unlock(ctdb_db, key);
return NULL; return NULL;
} }
if (header.dmaster != ctdb->vnn) { if (header.dmaster != ctdb_db->ctdb->vnn) {
state = ctdb_client_fetch_lock_send(ctdb_db, mem_ctx, key); state = ctdb_client_fetch_lock_send(ctdb_db, mem_ctx, key);
rec = ctdb_client_fetch_lock_recv(state, mem_ctx, key, data); rec = ctdb_client_fetch_lock_recv(state, mem_ctx, key, data);
return rec; return rec;
} }
rec = talloc(mem_ctx, struct ctdb_record_handle);
CTDB_NO_MEMORY_NULL(ctdb_db->ctdb, rec);
rec->ctdb_db = state->ctdb_db;
rec->key = key;
rec->key.dptr = talloc_memdup(rec, key.dptr, key.dsize);
rec->data = talloc(rec, TDB_DATA);
rec->data->dsize = state->call.reply_data.dsize;
rec->data->dptr = talloc_memdup(rec, state->call.reply_data.dptr, rec->data->dsize);
if (data) {
*data = *rec->data;
}
return rec;
} }
/* /*

View File

@ -186,6 +186,24 @@ static void daemon_request_fetch_lock(struct ctdb_client *client,
struct client_fetch_lock_data *fl_data; struct client_fetch_lock_data *fl_data;
ctdb_db = find_ctdb_db(client->ctdb, f->db_id); ctdb_db = find_ctdb_db(client->ctdb, f->db_id);
if (ctdb_db == NULL) {
struct ctdb_reply_fetch_lock r;
ZERO_STRUCT(r);
r.hdr.length = sizeof(r);
r.hdr.ctdb_magic = CTDB_MAGIC;
r.hdr.ctdb_version = CTDB_VERSION;
r.hdr.operation = CTDB_REPLY_FETCH_LOCK;
r.hdr.reqid = f->hdr.reqid;
r.state = -1;
/*
* Ignore the result, there's not much we can do anyway.
*/
ctdb_queue_send(client->queue, (uint8_t *)&r.hdr,
r.hdr.length);
return;
}
key.dsize = f->keylen; key.dsize = f->keylen;
key.dptr = &f->key[0]; key.dptr = &f->key[0];

View File

@ -71,48 +71,54 @@ static int lockwait_destructor(struct lockwait_handle *h)
*/ */
struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db, struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db,
TDB_DATA key, TDB_DATA key,
void (*callback)(void *), void *private_data) void (*callback)(void *private_data),
void *private_data)
{ {
struct lockwait_handle *h; struct lockwait_handle *result;
int ret; int ret;
h = talloc_zero(ctdb_db, struct lockwait_handle); if (!(result = talloc_zero(ctdb_db, struct lockwait_handle))) {
if (h == NULL) {
return NULL; return NULL;
} }
ret = pipe(h->fd); ret = pipe(result->fd);
if (ret != 0) { if (ret != 0) {
talloc_free(h); talloc_free(result);
return NULL; return NULL;
} }
h->child = fork(); result->child = fork();
if (h->child == (pid_t)-1) {
close(h->fd[0]); if (result->child == (pid_t)-1) {
close(h->fd[1]); close(result->fd[0]);
talloc_free(h); close(result->fd[1]);
talloc_free(result);
return NULL; return NULL;
} }
h->callback = callback; result->callback = callback;
h->private_data = private_data; result->private_data = private_data;
if (h->child == 0) { if (result->child == 0) {
struct tdb_context *tdb = ctdb_db->ltdb->tdb; close(result->fd[0]);
/* in child */ /*
tdb_chainlock(tdb, key); * Do we need a tdb_reopen here?
_exit(0); */
tdb_chainlock(ctdb_db->ltdb->tdb, key);
exit(0);
} }
close(h->fd[1]); close(result->fd[1]);
talloc_set_destructor(h, lockwait_destructor); talloc_set_destructor(result, lockwait_destructor);
h->fde = event_add_fd(ctdb_db->ctdb->ev, h, h->fd[0], EVENT_FD_READ, lockwait_handler, h); result->fde = event_add_fd(ctdb_db->ctdb->ev, result, result->fd[0],
if (h->fde == NULL) { EVENT_FD_READ, lockwait_handler,
talloc_free(h); (void *)result);
if (result->fde == NULL) {
talloc_free(result);
return NULL; return NULL;
} }
return h; return result;
} }

View File

@ -244,6 +244,12 @@ static void lock_fetch_callback(void *p)
immediately satisfied until it can get the lock. This means that immediately satisfied until it can get the lock. This means that
the main ctdb daemon will not block waiting for a chainlock held by the main ctdb daemon will not block waiting for a chainlock held by
a client a client
There are 3 possible return values:
0: means that it got the lock immediately.
-1: means that it failed to get the lock, and won't retry
-2: means that it failed to get the lock immediately, but will retry
*/ */
int ctdb_ltdb_lock_fetch_requeue(struct ctdb_db_context *ctdb_db, int ctdb_ltdb_lock_fetch_requeue(struct ctdb_db_context *ctdb_db,
TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA key, struct ctdb_ltdb_header *header,
@ -255,6 +261,12 @@ int ctdb_ltdb_lock_fetch_requeue(struct ctdb_db_context *ctdb_db,
ret = tdb_chainlock_nonblock(tdb, key); ret = tdb_chainlock_nonblock(tdb, key);
if (ret != 0 &&
!(errno == EACCES || errno == EAGAIN || errno == EDEADLK)) {
/* a hard failure - don't try again */
return -1;
}
/* first the non-contended path */ /* first the non-contended path */
if (ret == 0) { if (ret == 0) {
ret = ctdb_ltdb_fetch(ctdb_db, key, header, hdr, data); ret = ctdb_ltdb_fetch(ctdb_db, key, header, hdr, data);
@ -273,6 +285,11 @@ int ctdb_ltdb_lock_fetch_requeue(struct ctdb_db_context *ctdb_db,
/* we get an extra reference to the packet here, to /* we get an extra reference to the packet here, to
stop it being freed in the top level packet handler */ stop it being freed in the top level packet handler */
(void)talloc_reference(ctdb_db, hdr); if (talloc_reference(ctdb_db, hdr) == NULL) {
return 0; talloc_free(h);
return -1;
}
/* now tell the caller than we will retry asynchronously */
return -2;
} }