struct g_lock_dump_state {
TALLOC_CTX *mem_ctx;
TDB_DATA key;
- void (*fn)(const struct g_lock_rec *locks,
- size_t num_locks,
+ void (*fn)(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data);
void *private_data)
{
struct g_lock_dump_state *state = private_data;
- struct g_lock_rec *recs;
+ struct g_lock_rec *recs = NULL;
struct g_lock lck;
+ struct server_id exclusive = { .pid = 0 };
+ struct server_id *shared = NULL;
size_t i;
bool ok;
if (recs == NULL) {
DBG_DEBUG("talloc failed\n");
state->status = NT_STATUS_NO_MEMORY;
- return;
+ goto fail;
}
for (i=0; i<lck.num_recs; i++) {
g_lock_get_rec(&lck, i, &recs[i]);
}
- state->fn(recs, lck.num_recs, lck.data, lck.datalen,
- state->private_data);
+ if ((lck.num_recs == 1) && (recs[0].lock_type == G_LOCK_WRITE)) {
+ exclusive = recs[0].pid;
+ lck.num_recs = 0;
+ } else {
+ shared = talloc_array(recs, struct server_id, lck.num_recs);
+ if (shared == NULL) {
+ DBG_DEBUG("talloc_array failed\n");
+ state->status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+ for (i=0; i<lck.num_recs; i++) {
+ if (recs[i].lock_type != G_LOCK_READ) {
+ DBG_WARNING("locks[%zu] has wrong type %d\n",
+ i,
+ (int)recs[i].lock_type);
+ state->status =
+ NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto fail;
+ }
+ shared[i] = recs[i].pid;
+ }
+ }
- TALLOC_FREE(recs);
+ state->fn(exclusive,
+ lck.num_recs,
+ shared,
+ lck.data,
+ lck.datalen,
+ state->private_data);
state->status = NT_STATUS_OK;
+fail:
+ TALLOC_FREE(recs);
}
NTSTATUS g_lock_dump(struct g_lock_ctx *ctx, TDB_DATA key,
- void (*fn)(const struct g_lock_rec *locks,
- size_t num_locks,
+ void (*fn)(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data),
bool ok;
};
-static void lock2_parser(const struct g_lock_rec *locks,
- size_t num_locks,
+static void lock2_parser(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data)
bool ok;
};
-static void lock3_parser(const struct g_lock_rec *locks,
- size_t num_locks,
+static void lock3_parser(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data)
{
struct lock3_parser_state *state = private_data;
+ size_t num_locks = num_shared + ((exclusive.pid != 0) ? 1 : 0);
+ struct server_id *pid;
if (datalen != 0) {
fprintf(stderr, "datalen=%zu\n", datalen);
fprintf(stderr, "num_locks=%zu\n", num_locks);
return;
}
- if (locks[0].lock_type != state->lock_type) {
- fprintf(stderr, "found type %d, expected %d\n",
- (int)locks[0].lock_type, (int)state->lock_type);
- return;
+
+ if (state->lock_type == G_LOCK_WRITE) {
+ if (exclusive.pid == 0) {
+ fprintf(stderr, "Found READ, expected WRITE\n");
+ return;
+ }
+ } else {
+ if (exclusive.pid != 0) {
+ fprintf(stderr, "Found WRITE, expected READ\n");
+ return;
+ }
}
- if (!server_id_equal(&locks[0].pid, &state->self)) {
+
+ pid = (exclusive.pid != 0) ? &exclusive : &shared[0];
+
+ if (!server_id_equal(pid, &state->self)) {
struct server_id_buf tmp1, tmp2;
fprintf(stderr, "found pid %s, expected %s\n",
- server_id_str_buf(locks[0].pid, &tmp1),
+ server_id_str_buf(*pid, &tmp1),
server_id_str_buf(state->self, &tmp2));
return;
}
bool ok;
};
-static void lock4_check(const struct g_lock_rec *locks,
- size_t num_locks,
+static void lock4_check(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data)
{
struct lock4_check_state *state = private_data;
+ size_t num_locks = num_shared + ((exclusive.pid != 0) ? 1 : 0);
if (num_locks != 1) {
fprintf(stderr, "num_locks=%zu\n", num_locks);
return;
}
- if (!server_id_equal(&state->me, &locks[0].pid)) {
- struct server_id_buf buf1, buf2;
- fprintf(stderr, "me=%s, locker=%s\n",
- server_id_str_buf(state->me, &buf1),
- server_id_str_buf(locks[0].pid, &buf2));
+ if (exclusive.pid == 0) {
+ fprintf(stderr, "Wrong lock type, not WRITE\n");
return;
}
- if (locks[0].lock_type != G_LOCK_WRITE) {
- fprintf(stderr, "wrong lock type: %d\n",
- (int)locks[0].lock_type);
+ if (!server_id_equal(&state->me, &exclusive)) {
+ struct server_id_buf buf1, buf2;
+ fprintf(stderr, "me=%s, locker=%s\n",
+ server_id_str_buf(state->me, &buf1),
+ server_id_str_buf(exclusive, &buf2));
return;
}
size_t num_locks;
};
-static void lock5_parser(const struct g_lock_rec *locks,
- size_t num_locks,
+static void lock5_parser(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data)
{
struct lock5_parser_state *state = private_data;
- state->num_locks = num_locks;
+ state->num_locks = num_shared + ((exclusive.pid != 0) ? 1 : 0);
}
/*
size_t num_locks;
};
-static void lock6_parser(const struct g_lock_rec *locks,
- size_t num_locks,
+static void lock6_parser(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
const uint8_t *data,
size_t datalen,
void *private_data)
{
struct lock6_parser_state *state = private_data;
- state->num_locks = num_locks;
+ state->num_locks = num_shared + ((exclusive.pid != 0) ? 1 : 0);
}
/*
return result;
}
-static void net_g_lock_dump_fn(const struct g_lock_rec *locks,
- size_t num_locks,
- const uint8_t *data,
- size_t datalen,
- void *private_data)
+static void net_g_lock_dump_fn(struct server_id exclusive,
+ size_t num_shared,
+ struct server_id *shared,
+ const uint8_t *data,
+ size_t datalen,
+ void *private_data)
{
- size_t i;
-
- for (i=0; i<num_locks; i++) {
- const struct g_lock_rec *l = &locks[i];
- struct server_id_buf idbuf;
- d_printf("%s: %s\n", server_id_str_buf(l->pid, &idbuf),
- (l->lock_type & 1) ? "WRITE" : "READ");
+ struct server_id_buf idbuf;
+
+ if (exclusive.pid != 0) {
+ d_printf("%s: WRITE\n",
+ server_id_str_buf(exclusive, &idbuf));
+ } else {
+ size_t i;
+ for (i=0; i<num_shared; i++) {
+ d_printf("%s: READ\n",
+ server_id_str_buf(shared[i], &idbuf));
+ }
}
dump_data_file(data, datalen, true, stdout);
}