src/delta_lease.c | 12 +-
src/direct.c | 70 +++++++++----
src/direct.h | 2
src/direct_lib.c | 20 +++
src/diskio.c | 22 ++--
src/host_id.c | 269 +++++++++++++++++++++++++++++++++------------------
src/host_id.h | 7 -
src/main.c | 92 ++++-------------
src/paxos_lease.c | 9 +
src/sanlock_direct.h | 7 +
tests/devcount.c | 9 +
11 files changed, 321 insertions(+), 198 deletions(-)
New commits:
commit ba49a1acb34ac3f003c8298a4b9e1293fab6759f
Author: David Teigland <teigland(a)redhat.com>
Date: Fri Jun 3 13:18:00 2011 -0500
sanlock: official 1MB/8MB alignment
of lease areas and fix direct dump to work with these
alignments. Also add an api
sanlock_direct_align(disk) that returns 1MB if the
disk has 512 sectors and 8MB if the disk has 4k sectors
diff --git a/src/delta_lease.c b/src/delta_lease.c
index 1e3f239..b4a1df7 100644
--- a/src/delta_lease.c
+++ b/src/delta_lease.c
@@ -24,6 +24,7 @@
#include "sanlock_internal.h"
#include "diskio.h"
+#include "direct.h"
#include "log.h"
#include "paxos_lease.h"
#include "delta_lease.h"
@@ -421,9 +422,15 @@ int delta_lease_init(struct task *task,
struct leader_record *leader;
char *iobuf, **p_iobuf;
int iobuf_len;
+ int align_size;
int i, rv;
- iobuf_len = disk->sector_size * max_hosts;
+ align_size = direct_align(disk);
+
+ if (disk->sector_size * max_hosts > align_size)
+ return -E2BIG;
+
+ iobuf_len = align_size;
p_iobuf = &iobuf;
diff --git a/src/direct.c b/src/direct.c
index 594285f..280c5c7 100644
--- a/src/direct.c
+++ b/src/direct.c
@@ -356,6 +356,16 @@ int direct_live_id(struct task *task,
return 0;
}
+int direct_align(struct sync_disk *disk)
+{
+ if (disk->sector_size == 512)
+ return 1024 * 1024;
+ else if (disk->sector_size == 4096)
+ return 8 * 1024 * 1024;
+ else
+ return -EINVAL;
+}
+
/*
* sanlock direct init -n <num_hosts> [-s LOCKSPACE] [-r RESOURCE]
*
@@ -418,7 +428,8 @@ int direct_dump(struct task *task, char *dump_path)
char sname[NAME_ID_SIZE+1];
char rname[NAME_ID_SIZE+1];
uint64_t sector_nr;
- int rv;
+ int sector_count, datalen, align_size;
+ int i, rv;
memset(&sd, 0, sizeof(struct sync_disk));
@@ -436,14 +447,19 @@ int direct_dump(struct task *task, char *dump_path)
if (rv < 0)
return -ENODEV;
- data = malloc(sd.sector_size);
+ rv = direct_align(&sd);
+ if (rv < 0)
+ goto out_close;
+
+ align_size = rv;
+ datalen = align_size;
+ sector_count = align_size / sd.sector_size;
+
+ data = malloc(datalen);
if (!data) {
rv = -ENOMEM;
goto out_close;
}
- lr = (struct leader_record *)data;
-
- sector_nr = 0;
printf("%8s %36s %36s %10s %4s %4s %s\n",
"offset",
@@ -454,26 +470,39 @@ int direct_dump(struct task *task, char *dump_path)
"gen",
"lver");
+ sector_nr = 0;
+
while (1) {
memset(sname, 0, sizeof(rname));
memset(rname, 0, sizeof(rname));
memset(data, 0, sd.sector_size);
- rv = read_sectors(&sd, sector_nr, 1, data, sd.sector_size,
+ rv = read_sectors(&sd, sector_nr, sector_count, data, datalen,
task, "dump");
- if (lr->magic == DELTA_DISK_MAGIC) {
- strncpy(sname, lr->space_name, NAME_ID_SIZE);
- strncpy(rname, lr->resource_name, NAME_ID_SIZE);
-
- printf("%08llu %36s %36s %010llu %04llu %04llu\n",
- (unsigned long long)(sector_nr * sd.sector_size),
- sname, rname,
- (unsigned long long)lr->timestamp,
- (unsigned long long)lr->owner_id,
- (unsigned long long)lr->owner_generation);
+ lr = (struct leader_record *)data;
- sector_nr += 1;
+ if (lr->magic == DELTA_DISK_MAGIC) {
+ for (i = 0; i < sector_count; i++) {
+ lr = (struct leader_record *)(data + (i * sd.sector_size));
+
+ if (!lr->magic)
+ continue;
+
+ /* has never been acquired, don't print */
+ if (!lr->owner_id && !lr->owner_generation)
+ continue;
+
+ strncpy(sname, lr->space_name, NAME_ID_SIZE);
+ strncpy(rname, lr->resource_name, NAME_ID_SIZE);
+
+ printf("%08llu %36s %36s %010llu %04llu %04llu\n",
+ (unsigned long long)((sector_nr + i) * sd.sector_size),
+ sname, rname,
+ (unsigned long long)lr->timestamp,
+ (unsigned long long)lr->owner_id,
+ (unsigned long long)lr->owner_generation);
+ }
} else if (lr->magic == PAXOS_DISK_MAGIC) {
strncpy(sname, lr->space_name, NAME_ID_SIZE);
strncpy(rname, lr->resource_name, NAME_ID_SIZE);
@@ -485,14 +514,11 @@ int direct_dump(struct task *task, char *dump_path)
(unsigned long long)lr->owner_id,
(unsigned long long)lr->owner_generation,
(unsigned long long)lr->lver);
-
- sector_nr += lr->max_hosts + 2;
} else {
- printf("%08llu %36s\n",
- (unsigned long long)(sector_nr * sd.sector_size),
- "uninitialized");
break;
}
+
+ sector_nr += sector_count;
}
rv = 0;
diff --git a/src/direct.h b/src/direct.h
index 99fb53b..952cc00 100644
--- a/src/direct.h
+++ b/src/direct.h
@@ -37,6 +37,8 @@ int direct_live_id(struct task *task,
uint64_t *owner_generation,
int *live);
+int direct_align(struct sync_disk *disk);
+
int direct_init(struct task *task,
struct sanlk_lockspace *ls,
struct sanlk_resource *res,
diff --git a/src/direct_lib.c b/src/direct_lib.c
index 6ccd339..50c75b2 100644
--- a/src/direct_lib.c
+++ b/src/direct_lib.c
@@ -122,3 +122,23 @@ int sanlock_direct_sector_size(struct sanlk_disk *disk_in)
return disk.sector_size;
}
+int sanlock_direct_align(struct sanlk_disk *disk_in)
+{
+ struct sync_disk disk;
+ int align_size, rv;
+
+ memset(&disk, 0, sizeof(disk));
+
+ memcpy(disk.path, disk_in->path, SANLK_PATH_LEN);
+
+ rv = open_disk(&disk);
+ if (rv < 0)
+ return rv;
+
+ align_size = direct_align(&disk);
+
+ close(disk.fd);
+
+ return align_size;
+}
+
diff --git a/src/diskio.c b/src/diskio.c
index 843559b..f386470 100644
--- a/src/diskio.c
+++ b/src/diskio.c
@@ -28,6 +28,7 @@
#include "sanlock_internal.h"
#include "diskio.h"
+#include "direct.h"
#include "log.h"
static int set_disk_properties(struct sync_disk *disk)
@@ -117,12 +118,14 @@ int open_disks_fd(struct sync_disk *disks, int num_disks)
/*
* set fd and sector_size
+ * verify offset is correctly aligned
* returns 0 for success or -EXXX
*/
int open_disk(struct sync_disk *disk)
{
struct stat st;
+ int align_size;
int fd, rv;
fd = open(disk->path, O_RDWR | O_DIRECT | O_SYNC, 0);
@@ -149,6 +152,17 @@ int open_disk(struct sync_disk *disk)
}
}
+ align_size = direct_align(disk);
+
+ if (disk->offset % align_size) {
+ rv = -EBADSLT;
+ log_error("invalid offset %llu align size %u %s",
+ (unsigned long long)disk->offset,
+ align_size, disk->path);
+ close(fd);
+ goto fail;
+ }
+
disk->fd = fd;
return 0;
@@ -161,7 +175,6 @@ int open_disk(struct sync_disk *disk)
/*
* set fd and sector_size in each disk
* verify all sector_size's match
- * verify sector_size is ok for previously set offset
* returns number of opened disks
*/
@@ -193,13 +206,6 @@ int open_disks(struct sync_disk *disks, int num_disks)
goto fail;
}
- if (disk->offset % disk->sector_size) {
- log_error("invalid offset %llu sector size %u %s",
- (unsigned long long)disk->offset,
- disk->sector_size, disk->path);
- goto fail;
- }
-
num_opens++;
}
return num_opens;
diff --git a/src/main.c b/src/main.c
index 25343b7..1145cf4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1919,7 +1919,6 @@ static void process_cmd_daemon(int ci, struct sm_header *h_recv)
auto_close = 0;
break;
case SM_CMD_RESTRICT:
- strcpy(client[ci].owner_name, "restrict");
cmd_restrict(ci, fd, h_recv);
auto_close = 0;
break;
@@ -2439,6 +2438,9 @@ static void print_usage(void)
printf(" <offset> offset on disk in bytes\n");
printf(" <lver> optional disk leader version of resource for
acquire\n");
printf("\n");
+ printf("<offset> must be 1MB aligned for disks with 512 byte
sectors\n");
+ printf(" and 8MB aligned for disks with 4096 byte sectors\n");
+ printf("\n");
}
static int read_command_line(int argc, char *argv[])
@@ -2842,7 +2844,6 @@ static int do_direct(void)
case ACT_DUMP:
rv = direct_dump(&main_task, com.dump_path);
- log_tool("dump done %d", rv);
break;
case ACT_READ_LEADER:
diff --git a/src/paxos_lease.c b/src/paxos_lease.c
index 25ddf37..141c61d 100644
--- a/src/paxos_lease.c
+++ b/src/paxos_lease.c
@@ -23,6 +23,7 @@
#include "sanlock_internal.h"
#include "diskio.h"
+#include "direct.h"
#include "log.h"
#include "crc32c.h"
#include "host_id.h"
@@ -1466,10 +1467,16 @@ int paxos_lease_init(struct task *task,
char *iobuf, **p_iobuf;
struct leader_record *leader;
int iobuf_len;
+ int align_size;
int aio_timeout = 0;
int rv, d;
- iobuf_len = token->disks[0].sector_size * (2 + max_hosts);
+ align_size = direct_align(&token->disks[0]);
+
+ if (token->disks[0].sector_size * (2 + max_hosts) > align_size)
+ return -E2BIG;
+
+ iobuf_len = align_size;
p_iobuf = &iobuf;
diff --git a/src/sanlock_direct.h b/src/sanlock_direct.h
index 435e1bd..d0976f6 100644
--- a/src/sanlock_direct.h
+++ b/src/sanlock_direct.h
@@ -44,4 +44,11 @@ int sanlock_direct_init(struct sanlk_lockspace *ls,
int sanlock_direct_sector_size(struct sanlk_disk *disk);
+/*
+ * Returns the alignment in bytes required by sanlock_direct_init()
+ * (1MB for disks with 512 sectors, 8MB for disks with 4096 sectors)
+ */
+
+int sanlock_direct_align(struct sanlk_disk *disk);
+
#endif
diff --git a/tests/devcount.c b/tests/devcount.c
index f897f74..172eac3 100644
--- a/tests/devcount.c
+++ b/tests/devcount.c
@@ -1358,7 +1358,7 @@ int do_init(int argc, char *argv[])
struct sanlk_resource *res;
struct sanlk_lockspace ls;
char command[4096];
- int rv, ss;
+ int rv, ss, align_size;
if (argc < 4)
return -1;
@@ -1404,6 +1404,13 @@ int do_init(int argc, char *argv[])
return -1;
}
+ align_size = sanlock_direct_align(&disk);
+ if (align_size != LEASE_SIZE) {
+ printf("sanlock_direct align %s error %d\n",
+ disk.path, align_size);
+ return -1;
+ }
+
if (ss != 512) {
printf("unsupported sector size %d\n", ss);
return -1;
commit b7b5783c3ea858eb01d77a3a3fc1e5546e3ce893
Author: David Teigland <teigland(a)redhat.com>
Date: Thu Jun 2 16:58:36 2011 -0500
sanlock: fix adding lockspace
the same lockspace could be added multiple times
since there was no recording or checking of additions
in progress. Fix this mainly by adding a list of
lockspaces being added.
diff --git a/src/delta_lease.c b/src/delta_lease.c
index ead0101..1e3f239 100644
--- a/src/delta_lease.c
+++ b/src/delta_lease.c
@@ -233,7 +233,8 @@ int delta_lease_acquire(struct task *task,
while (1) {
memcpy(&leader1, &leader, sizeof(struct leader_record));
- log_space(sp, "delta_acquire delta_large_delay %d", delay);
+ log_space(sp, "delta_acquire delta_large_delay %d delay %d",
+ delta_large_delay, delay);
sleep(delay);
error = delta_lease_leader_read(task, disk, space_name, host_id,
diff --git a/src/host_id.c b/src/host_id.c
index 52b0054..0ae3138 100644
--- a/src/host_id.c
+++ b/src/host_id.c
@@ -31,8 +31,11 @@
#include "client_msg.h"
#include "task.h"
+static unsigned int space_id_counter = 1;
+
struct list_head spaces;
-struct list_head spaces_remove;
+struct list_head spaces_add;
+struct list_head spaces_rem;
pthread_mutex_t spaces_mutex = PTHREAD_MUTEX_INITIALIZER;
int print_space_state(struct space *sp, char *str)
@@ -64,19 +67,53 @@ int print_space_state(struct space *sp, char *str)
return strlen(str) + 1;
}
-static struct space *_search_space(char *name, struct sync_disk *disk,
- uint64_t host_id, struct list_head *head)
+static struct space *_search_space(char *name,
+ struct sync_disk *disk,
+ uint64_t host_id,
+ struct list_head *head1,
+ struct list_head *head2,
+ struct list_head *head3)
{
struct space *sp;
- list_for_each_entry(sp, head, list) {
- if (strncmp(sp->space_name, name, NAME_ID_SIZE))
- continue;
- if (disk && strncmp(sp->host_id_disk.path, disk->path, SANLK_PATH_LEN))
- continue;
- if (host_id && sp->host_id != host_id)
- continue;
- return sp;
+ if (head1) {
+ list_for_each_entry(sp, head1, list) {
+ if (name && strncmp(sp->space_name, name, NAME_ID_SIZE))
+ continue;
+ if (disk && strncmp(sp->host_id_disk.path, disk->path, SANLK_PATH_LEN))
+ continue;
+ if (disk && sp->host_id_disk.offset != disk->offset)
+ continue;
+ if (host_id && sp->host_id != host_id)
+ continue;
+ return sp;
+ }
+ }
+ if (head2) {
+ list_for_each_entry(sp, head2, list) {
+ if (name && strncmp(sp->space_name, name, NAME_ID_SIZE))
+ continue;
+ if (disk && strncmp(sp->host_id_disk.path, disk->path, SANLK_PATH_LEN))
+ continue;
+ if (disk && sp->host_id_disk.offset != disk->offset)
+ continue;
+ if (host_id && sp->host_id != host_id)
+ continue;
+ return sp;
+ }
+ }
+ if (head3) {
+ list_for_each_entry(sp, head3, list) {
+ if (name && strncmp(sp->space_name, name, NAME_ID_SIZE))
+ continue;
+ if (disk && strncmp(sp->host_id_disk.path, disk->path, SANLK_PATH_LEN))
+ continue;
+ if (disk && sp->host_id_disk.offset != disk->offset)
+ continue;
+ if (host_id && sp->host_id != host_id)
+ continue;
+ return sp;
+ }
}
return NULL;
}
@@ -154,7 +191,7 @@ int host_id_check(struct task *task, struct space *sp)
return 1;
}
-static void *host_id_thread(void *arg_in)
+static void *lockspace_thread(void *arg_in)
{
struct task task;
struct space *sp;
@@ -216,16 +253,8 @@ static void *host_id_thread(void *arg_in)
sp->lease_status.renewal_last_success = last_success;
pthread_mutex_unlock(&sp->mutex);
- if (result < 0) {
- log_erros(sp, "host_id %llu acquire failed %d",
- (unsigned long long)our_host_id, result);
+ if (result < 0)
goto out;
- }
-
- log_erros(sp, "host_id %llu generation %llu acquire %llu",
- (unsigned long long)our_host_id,
- (unsigned long long)leader.owner_generation,
- (unsigned long long)leader.timestamp);
sp->host_generation = leader.owner_generation;
our_host_id_generation = leader.owner_generation;
@@ -271,13 +300,11 @@ static void *host_id_thread(void *arg_in)
sp->lease_status.renewal_last_success = last_success;
if (delta_length > task.id_renewal_seconds) {
- log_erros(sp, "host_id %llu renewed %llu delta_length %d too long",
- (unsigned long long)our_host_id,
+ log_erros(sp, "renewed %llu delta_length %d too long",
(unsigned long long)last_success,
delta_length);
} else if (com.debug_renew) {
- log_space(sp, "host_id %llu renewed %llu delta_length %d interval %d",
- (unsigned long long)our_host_id,
+ log_space(sp, "renewed %llu delta_length %d interval %d",
(unsigned long long)last_success,
delta_length, gap);
}
@@ -285,8 +312,8 @@ static void *host_id_thread(void *arg_in)
if (!sp->thread_stop)
update_watchdog_file(sp, last_success);
} else {
- log_erros(sp, "host_id %llu renewal error %d delta_length %d last_success
%llu",
- (unsigned long long)our_host_id, result, delta_length,
+ log_erros(sp, "renewal error %d delta_length %d last_success %llu",
+ result, delta_length,
(unsigned long long)sp->lease_status.renewal_last_success);
}
stop = sp->thread_stop;
@@ -313,43 +340,81 @@ static void *host_id_thread(void *arg_in)
* watchdog needs to be active watching our host_id renewals.
*/
-int add_space(struct space *sp)
+int add_lockspace(struct sanlk_lockspace *ls)
{
+ struct space *sp, *sp2;
int rv, result;
- if (!sp->space_name[0]) {
- log_erros(sp, "add_space no name");
- rv = -EINVAL;
- goto fail;
+ if (!ls->name[0] || !ls->host_id || !ls->host_id_disk.path[0]) {
+ log_error("add_lockspace bad args id %llu name %zu path %zu",
+ (unsigned long long)ls->host_id,
+ strlen(ls->name), strlen(ls->host_id_disk.path));
+ return -EINVAL;
}
- if (!sp->host_id) {
- log_erros(sp, "add_space zero host_id");
- rv = -EINVAL;
- goto fail;
- }
+ sp = malloc(sizeof(struct space));
+ if (!sp)
+ return -ENOMEM;
+ memset(sp, 0, sizeof(struct space));
- if (space_exists(sp->space_name, &sp->host_id_disk, sp->host_id)) {
- log_erros(sp, "add_space exists");
+ memcpy(sp->space_name, ls->name, NAME_ID_SIZE);
+ memcpy(&sp->host_id_disk, &ls->host_id_disk, sizeof(struct sanlk_disk));
+ sp->host_id_disk.sector_size = 0;
+ sp->host_id_disk.fd = -1;
+ sp->host_id = ls->host_id;
+ pthread_mutex_init(&sp->mutex, NULL);
+
+ pthread_mutex_lock(&spaces_mutex);
+
+ /* search all lists for an identical lockspace */
+
+ sp2 = _search_space(sp->space_name, &sp->host_id_disk, sp->host_id,
+ &spaces, &spaces_add, NULL);
+ if (sp2) {
+ pthread_mutex_unlock(&spaces_mutex);
rv = -EEXIST;
- goto fail;
+ goto fail_free;
}
- if (space_exists(sp->space_name, NULL, 0)) {
- log_erros(sp, "add_space name exists with other host info");
+ sp2 = _search_space(sp->space_name, &sp->host_id_disk, sp->host_id,
+ &spaces_rem, NULL, NULL);
+ if (sp2) {
+ pthread_mutex_unlock(&spaces_mutex);
+ rv = -EAGAIN;
+ goto fail_free;
+ }
+
+ /* search all lists for a lockspace with the same name */
+
+ sp2 = _search_space(sp->space_name, NULL, 0,
+ &spaces, &spaces_add, &spaces_rem);
+ if (sp2) {
+ pthread_mutex_unlock(&spaces_mutex);
rv = -EINVAL;
- goto fail;
+ goto fail_free;
}
- log_space(sp, "add_space host_id %llu path %s offset %llu",
- (unsigned long long)sp->host_id,
- sp->host_id_disk.path,
- (unsigned long long)sp->host_id_disk.offset);
+ /* search all lists for a lockspace with the same host_id_disk */
- rv = pthread_create(&sp->thread, NULL, host_id_thread, sp);
+ sp2 = _search_space(NULL, &sp->host_id_disk, 0,
+ &spaces, &spaces_add, &spaces_rem);
+ if (sp2) {
+ pthread_mutex_unlock(&spaces_mutex);
+ rv = -EINVAL;
+ goto fail_free;
+ }
+
+ sp->space_id = space_id_counter++;
+ list_add(&sp->list, &spaces_add);
+ pthread_mutex_unlock(&spaces_mutex);
+
+ rv = pthread_create(&sp->thread, NULL, lockspace_thread, sp);
if (rv < 0) {
- log_erros(sp, "add_space create thread failed");
- goto fail;
+ log_erros(sp, "add_lockspace create thread failed");
+ pthread_mutex_lock(&spaces_mutex);
+ list_del(&sp->list);
+ pthread_mutex_unlock(&spaces_mutex);
+ goto fail_free;
}
while (1) {
@@ -365,41 +430,74 @@ int add_space(struct space *sp)
/* the thread exits right away if acquire fails */
pthread_join(sp->thread, NULL);
rv = result;
- goto fail;
+ goto fail_free;
}
+ /* once we move sp to spaces list, tokens can begin using it,
+ and the main loop will begin monitoring its renewals */
+
pthread_mutex_lock(&spaces_mutex);
- /* TODO: repeating check here unnecessary if we serialize adds and removes */
- if (_search_space(sp->space_name, NULL, 0, &spaces) ||
- _search_space(sp->space_name, NULL, 0, &spaces_remove)) {
- pthread_mutex_unlock(&spaces_mutex);
- log_erros(sp, "add_space duplicate name");
- goto fail_stop;
- } else {
- list_add(&sp->list, &spaces);
- }
+ list_move(&sp->list, &spaces);
pthread_mutex_unlock(&spaces_mutex);
return 0;
- fail_stop:
- sp->thread_stop = 1;
- pthread_join(sp->thread, NULL);
- fail:
+ fail_free:
+ free(sp);
return rv;
}
-int rem_space(char *name, struct sync_disk *disk, uint64_t host_id)
+int rem_lockspace(struct sanlk_lockspace *ls)
{
- struct space *sp;
- int rv = -ENOENT;
+ struct space *sp, *sp2;
+ unsigned int id;
+ int rv, done;
pthread_mutex_lock(&spaces_mutex);
- sp = _search_space(name, disk, host_id, &spaces);
+
+ sp = _search_space(ls->name, (struct sync_disk *)&ls->host_id_disk,
ls->host_id,
+ &spaces_rem, NULL, NULL);
if (sp) {
- sp->external_remove = 1;
- rv = 0;
+ pthread_mutex_unlock(&spaces_mutex);
+ rv = -EINPROGRESS;
+ goto out;
}
+
+ sp = _search_space(ls->name, (struct sync_disk *)&ls->host_id_disk,
ls->host_id,
+ &spaces_add, NULL, NULL);
+ if (sp) {
+ pthread_mutex_unlock(&spaces_mutex);
+ rv = -EAGAIN;
+ goto out;
+ }
+
+ sp = _search_space(ls->name, (struct sync_disk *)&ls->host_id_disk,
ls->host_id,
+ &spaces, NULL, NULL);
+ if (!sp) {
+ pthread_mutex_unlock(&spaces_mutex);
+ rv = -ENOENT;
+ goto out;
+ }
+
+ sp->external_remove = 1;
+ id = sp->space_id;
pthread_mutex_unlock(&spaces_mutex);
+
+ while (1) {
+ pthread_mutex_lock(&spaces_mutex);
+ sp2 = _search_space(ls->name, (struct sync_disk *)&ls->host_id_disk,
ls->host_id,
+ &spaces, &spaces_rem, NULL);
+ if (sp2 && sp2->space_id == id)
+ done = 0;
+ else
+ done = 1;
+ pthread_mutex_unlock(&spaces_mutex);
+
+ if (done)
+ break;
+ sleep(1);
+ }
+ rv = 0;
+ out:
return rv;
}
@@ -412,16 +510,18 @@ int rem_space(char *name, struct sync_disk *disk, uint64_t host_id)
* "logical" point commented above in host_id_thread.
*/
-static int finish_space(struct space *sp, int wait)
+static int stop_lockspace_thread(struct space *sp, int wait)
{
int stop, rv;
pthread_mutex_lock(&sp->mutex);
stop = sp->thread_stop;
+ sp->thread_stop = 1;
pthread_mutex_unlock(&sp->mutex);
if (!stop) {
- log_erros(sp, "finish_space zero thread_stop");
+ /* should never happen */
+ log_erros(sp, "stop_lockspace_thread zero thread_stop");
return -EINVAL;
}
@@ -433,16 +533,16 @@ static int finish_space(struct space *sp, int wait)
return rv;
}
-void clear_spaces(int wait)
+void free_lockspaces(int wait)
{
struct space *sp, *safe;
int rv;
pthread_mutex_lock(&spaces_mutex);
- list_for_each_entry_safe(sp, safe, &spaces_remove, list) {
- rv = finish_space(sp, wait);
+ list_for_each_entry_safe(sp, safe, &spaces_rem, list) {
+ rv = stop_lockspace_thread(sp, wait);
if (!rv) {
- log_space(sp, "free sp");
+ log_space(sp, "free lockspace");
list_del(&sp->list);
free(sp);
}
@@ -450,23 +550,10 @@ void clear_spaces(int wait)
pthread_mutex_unlock(&spaces_mutex);
}
-int space_exists(char *name, struct sync_disk *disk, uint64_t host_id)
-{
- struct space *sp;
-
- pthread_mutex_lock(&spaces_mutex);
- sp = _search_space(name, disk, host_id, &spaces);
- if (!sp)
- sp = _search_space(name, disk, host_id, &spaces_remove);
- pthread_mutex_unlock(&spaces_mutex);
- if (sp)
- return 1;
- return 0;
-}
-
void setup_spaces(void)
{
INIT_LIST_HEAD(&spaces);
- INIT_LIST_HEAD(&spaces_remove);
+ INIT_LIST_HEAD(&spaces_add);
+ INIT_LIST_HEAD(&spaces_rem);
}
diff --git a/src/host_id.h b/src/host_id.h
index 56eb783..5cc8b50 100644
--- a/src/host_id.h
+++ b/src/host_id.h
@@ -14,10 +14,9 @@ int _get_space_info(char *space_name, struct space *sp_out);
int get_space_info(char *space_name, struct space *sp_out);
int host_id_disk_info(char *name, struct sync_disk *disk);
int host_id_check(struct task *task, struct space *sp);
-int add_space(struct space *sp);
-int rem_space(char *name, struct sync_disk *disk, uint64_t host_id);
-void clear_spaces(int wait);
-int space_exists(char *name, struct sync_disk *disk, uint64_t host_id);
+int add_lockspace(struct sanlk_lockspace *ls);
+int rem_lockspace(struct sanlk_lockspace *ls);
+void free_lockspaces(int wait);
void setup_spaces(void);
#endif
diff --git a/src/main.c b/src/main.c
index 31df837..25343b7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -80,8 +80,7 @@ static char command[COMMAND_MAX];
static int cmd_argc;
static char **cmd_argv;
static int external_shutdown;
-static int token_id_counter = 1;
-static int space_id_counter = 1;
+static unsigned int token_id_counter = 1;
struct cmd_args {
struct list_head list; /* thread_pool data */
@@ -106,7 +105,7 @@ struct thread_pool {
static struct thread_pool pool;
extern struct list_head spaces;
-extern struct list_head spaces_remove;
+extern struct list_head spaces_rem;
extern pthread_mutex_t spaces_mutex;
/* FIXME: add a mutex for client array so we don't try to expand it
@@ -587,7 +586,7 @@ static int main_loop(void)
sp->thread_stop = 1;
unlink_watchdog_file(sp);
pthread_mutex_unlock(&sp->mutex);
- list_move(&sp->list, &spaces_remove);
+ list_move(&sp->list, &spaces_rem);
} else {
kill_pids(sp);
}
@@ -616,7 +615,7 @@ static int main_loop(void)
if (empty && external_shutdown)
break;
- clear_spaces(0);
+ free_lockspaces(0);
gettimeofday(&now, NULL);
ms = time_diff(&last_check, &now);
@@ -626,7 +625,7 @@ static int main_loop(void)
poll_timeout = 1;
}
- clear_spaces(1);
+ free_lockspaces(1);
return 0;
}
@@ -794,7 +793,7 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca)
goto done;
}
- if (res.num_disks > MAX_DISKS) {
+ if (!res.num_disks || res.num_disks > MAX_DISKS) {
result = -ERANGE;
goto done;
}
@@ -851,8 +850,11 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca)
* of full length space_name+resource_name in each log message
* would make excessively long lines. */
- log_token(token, "lockspace %.48s resource %.48s has token_id %u for pid
%u",
- token->r.lockspace_name, token->r.name, token->token_id, cl_pid);
+ log_token(token, "cmd_acquire %d,%d,%d %.48s:%.48s:%s:%llu",
+ cl_ci, cl_fd, cl_pid,
+ token->r.lockspace_name, token->r.name,
+ token->disks[0].path,
+ (unsigned long long)token->disks[0].offset);
}
rv = recv(fd, &opt, sizeof(struct sanlk_options), MSG_WAITALL);
@@ -1309,20 +1311,11 @@ static void cmd_inquire(struct task *task, struct cmd_args *ca)
static void cmd_add_lockspace(struct cmd_args *ca)
{
struct sm_header h;
- struct space *sp;
struct sanlk_lockspace lockspace;
int fd, rv, result;
fd = client[ca->ci_in].fd;
- log_debug("cmd_add_lockspace %d,%d", ca->ci_in, fd);
-
- sp = malloc(sizeof(struct space));
- if (!sp) {
- result = -ENOMEM;
- goto reply;
- }
-
rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
log_error("cmd_add_lockspace %d,%d recv %d %d",
@@ -1331,32 +1324,13 @@ static void cmd_add_lockspace(struct cmd_args *ca)
goto reply;
}
- memset(sp, 0, sizeof(struct space));
- memcpy(sp->space_name, lockspace.name, NAME_ID_SIZE);
- sp->host_id = lockspace.host_id;
- memcpy(&sp->host_id_disk, &lockspace.host_id_disk,
- sizeof(struct sanlk_disk));
- sp->host_id_disk.fd = -1;
- pthread_mutex_init(&sp->mutex, NULL);
-
- pthread_mutex_lock(&spaces_mutex);
- sp->space_id = space_id_counter++;
- pthread_mutex_unlock(&spaces_mutex);
-
- /* We use the space_id in log messages because the full length
- * space_name in each log message woul dmake excessively long lines. */
-
- log_space(sp, "lockspace %.48s host_id %llu has space_id %u",
- sp->space_name, (unsigned long long)sp->host_id,
- sp->space_id);
-
- /* add_space returns once the host_id has been acquired and
- sp space has been added to the spaces list */
+ log_debug("cmd_add_lockspace %d,%d %.48s:%llu:%s:%llu",
+ ca->ci_in, fd, lockspace.name,
+ (unsigned long long)lockspace.host_id,
+ lockspace.host_id_disk.path,
+ (unsigned long long)lockspace.host_id_disk.offset);
- result = add_space(sp);
-
- if (result)
- free(sp);
+ result = add_lockspace(&lockspace);
reply:
log_debug("cmd_add_lockspace %d,%d done %d", ca->ci_in, fd, result);
@@ -1377,8 +1351,6 @@ static void cmd_rem_lockspace(struct cmd_args *ca)
fd = client[ca->ci_in].fd;
- log_debug("cmd_rem_lockspace %d,%d", ca->ci_in, fd);
-
rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
log_error("cmd_rem_lockspace %d,%d recv %d %d",
@@ -1387,29 +1359,10 @@ static void cmd_rem_lockspace(struct cmd_args *ca)
goto reply;
}
- /* rem_space flags the sp as wanting to be removed, so follow with a
- wait loop until it's actually gone */
-
- /* TODO: we should probably prevent add_lockspace during an
- outstanding rem_lockspace and v.v. This would prevent problems
- with the space_exists name check below when the same lockspace
- name was removed and added at once */
-
- result = rem_space(lockspace.name,
- (struct sync_disk *)&lockspace.host_id_disk,
- lockspace.host_id);
-
- if (result < 0)
- goto reply;
-
- while (1) {
- if (!space_exists(lockspace.name,
- (struct sync_disk *)&lockspace.host_id_disk,
- lockspace.host_id))
- break;
- sleep(1);
- }
+ log_debug("cmd_rem_lockspace %d,%d %.48s",
+ ca->ci_in, fd, lockspace.name);
+ result = rem_lockspace(&lockspace);
reply:
log_debug("cmd_rem_lockspace %d,%d done %d", ca->ci_in, fd, result);