From e084bc7a95e41d6134659b9326045a2d4bc25a1d Mon Sep 17 00:00:00 2001 From: David Teigland Date: Aug 30 2012 16:42:17 +0000 Subject: sanlock: add direct next_free command to find the next unused lease area Signed-off-by: David Teigland --- diff --git a/src/direct.c b/src/direct.c index 6e2bcf6..ab39569 100644 --- a/src/direct.c +++ b/src/direct.c @@ -585,3 +585,69 @@ int direct_dump(struct task *task, char *dump_path, int force_mode) return rv; } +int direct_next_free(struct task *task, char *path) +{ + char *data; + char *colon, *off_str; + struct leader_record *lr; + struct sync_disk sd; + uint64_t sector_nr; + int sector_count, datalen, align_size; + int rv; + + memset(&sd, 0, sizeof(struct sync_disk)); + + colon = strstr(path, ":"); + if (colon) { + off_str = colon + 1; + *colon = '\0'; + sd.offset = atoll(off_str); + } + + strncpy(sd.path, path, SANLK_PATH_LEN); + sd.fd = -1; + + rv = open_disk(&sd); + if (rv < 0) + return -ENODEV; + + rv = direct_align(&sd); + if (rv < 0) + goto out_close; + + align_size = rv; + datalen = sd.sector_size; + sector_count = align_size / sd.sector_size; + + data = malloc(datalen); + if (!data) { + rv = -ENOMEM; + goto out_close; + } + + sector_nr = 0; + rv = -ENOSPC; + + while (1) { + memset(data, 0, sd.sector_size); + + rv = read_sectors(&sd, sector_nr, 1, data, datalen, + task, DEFAULT_IO_TIMEOUT, "next_free"); + + lr = (struct leader_record *)data; + + if (lr->magic != DELTA_DISK_MAGIC && lr->magic != PAXOS_DISK_MAGIC) { + printf("%llu\n", (unsigned long long)(sector_nr * sd.sector_size)); + rv = 0; + goto out_free; + } + + sector_nr += sector_count; + } + out_free: + free(data); + out_close: + close_disks(&sd, 1); + return rv; +} + diff --git a/src/direct.h b/src/direct.h index 0529282..bd71096 100644 --- a/src/direct.h +++ b/src/direct.h @@ -57,4 +57,6 @@ int direct_read_leader(struct task *task, int io_timeout, int direct_dump(struct task *task, char *dump_path, int force_mode); +int direct_next_free(struct task *task, char *path); + #endif diff --git a/src/main.c b/src/main.c index 02e58ff..f9d6546 100644 --- a/src/main.c +++ b/src/main.c @@ -1867,6 +1867,8 @@ static int read_command_line(int argc, char *argv[]) com.action = ACT_DIRECT_INIT; else if (!strcmp(act, "dump")) com.action = ACT_DUMP; + else if (!strcmp(act, "next_free")) + com.action = ACT_NEXT_FREE; else if (!strcmp(act, "read_leader")) com.action = ACT_READ_LEADER; else if (!strcmp(act, "acquire")) @@ -1891,8 +1893,8 @@ static int read_command_line(int argc, char *argv[]) }; - /* the only action that has an option without dash-letter prefix */ - if (com.action == ACT_DUMP) { + /* actions that have an option without dash-letter prefix */ + if (com.action == ACT_DUMP || com.action == ACT_NEXT_FREE) { if (argc < 4) exit(EXIT_FAILURE); optionarg = argv[i++]; @@ -2250,6 +2252,10 @@ static int do_direct(void) rv = direct_dump(&main_task, com.dump_path, com.force_mode); break; + case ACT_NEXT_FREE: + rv = direct_next_free(&main_task, com.dump_path); + break; + case ACT_READ_LEADER: rv = direct_read_leader(&main_task, com.io_timeout_arg, &com.lockspace, com.res_args[0], diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h index 23e08e6..2c67fc8 100644 --- a/src/sanlock_internal.h +++ b/src/sanlock_internal.h @@ -304,6 +304,7 @@ enum { ACT_LIVE_ID, ACT_DIRECT_INIT, ACT_DUMP, + ACT_NEXT_FREE, ACT_READ_LEADER, ACT_CLIENT_INIT, ACT_CLIENT_ALIGN,