This is an automated email from the git hooks/post-receive script.
teigland pushed a commit to branch master in repository sanlock.
The following commit(s) were added to refs/heads/master by this push: new d3afbf2 sanlock: add direct init_host to initialize one delta lease d3afbf2 is described below
commit d3afbf2472d0db74db943be3ece7399a389f1646 Author: David Teigland teigland@redhat.com AuthorDate: Tue Mar 18 12:21:55 2025 -0500
sanlock: add direct init_host to initialize one delta lease --- src/delta_lease.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ src/delta_lease.h | 8 ++++ src/direct.c | 29 +++++++++++--- src/direct.h | 3 ++ src/main.c | 54 +++++++++++++++++++------- src/sanlock.8 | 11 ++++++ src/sanlock_internal.h | 2 + 7 files changed, 189 insertions(+), 19 deletions(-)
diff --git a/src/delta_lease.c b/src/delta_lease.c index cb04b6f..c1bb3c8 100644 --- a/src/delta_lease.c +++ b/src/delta_lease.c @@ -905,6 +905,107 @@ int delta_lease_release(struct task *task, return SANLK_OK; }
+int delta_lease_init_host(struct task *task, + struct sanlk_lockspace *ls, + char *our_host_name, + uint64_t generation, + uint64_t timestamp, + int io_timeout, + struct sync_disk *disk) +{ + struct leader_record leader_end; + struct leader_record leader; + char *iobuf, **p_iobuf; + int iobuf_len; + int sector_size = 0; + int align_size = 0; + int max_hosts = 0; + int write_io_timeout; + uint32_t checksum; + uint64_t new_ts; + uint64_t offset; + int rv; + + if (!io_timeout) + io_timeout = com.io_timeout; + + if (timestamp == 0) + new_ts = LEASE_FREE; + else if (timestamp == 1) + new_ts = monotime(); + else + new_ts = timestamp; + + rv = sizes_from_flags(ls->flags, §or_size, &align_size, &max_hosts, "LSF"); + if (rv) + return rv; + + if (!sector_size) { + /* sector/align flags were not set, use historical defaults */ + sector_size = disk->sector_size; + align_size = sector_size_to_align_size_old(sector_size); + max_hosts = DEFAULT_MAX_HOSTS; + } + + iobuf_len = sector_size; + + p_iobuf = &iobuf; + + rv = posix_memalign((void *)p_iobuf, getpagesize(), iobuf_len); + if (rv) + return rv; + + memset(iobuf, 0, iobuf_len); + + memset(&leader, 0, sizeof(struct leader_record)); + leader.magic = DELTA_DISK_MAGIC; + leader.version = DELTA_DISK_VERSION_MAJOR | DELTA_DISK_VERSION_MINOR; + leader.flags = leader_align_flag_from_size(align_size); + leader.sector_size = sector_size; + leader.owner_id = ls->host_id; + leader.owner_generation = generation; + leader.max_hosts = 1; + leader.timestamp = new_ts; + leader.io_timeout = io_timeout; + memcpy(leader.space_name, ls->name, NAME_ID_SIZE); + if (our_host_name) + memcpy(leader.resource_name, our_host_name, NAME_ID_SIZE); + leader.checksum = 0; /* set below */ + + leader_record_out(&leader, &leader_end); + + /* + * N.B. must compute checksum after the data has been byte swapped. + */ + checksum = leader_checksum(&leader_end); + leader.checksum = checksum; + leader_end.checksum = cpu_to_le32(checksum); + + memcpy(iobuf, &leader_end, sizeof(struct leader_record)); + + /* + * The io_timeout arg is a part of the lockspace logic, and + * determines how the lockspace times out. The process of + * initializing the lease on disk can to use a longer timeout + * than the algorithm uses. + */ + if (com.write_init_io_timeout) + write_io_timeout = com.write_init_io_timeout; + else + write_io_timeout = io_timeout; + + offset = disk->offset + (sector_size * (ls->host_id - 1)); + + rv = write_iobuf(disk->fd, offset, iobuf, iobuf_len, task, write_io_timeout, NULL); + if (rv < 0) + goto out; + out: + if (rv != SANLK_AIO_TIMEOUT) + free(iobuf); + + return rv; +} + /* the host_id lease area begins disk->offset bytes from the start of block device disk->path */
diff --git a/src/delta_lease.h b/src/delta_lease.h index 22c6faa..3128a0f 100644 --- a/src/delta_lease.h +++ b/src/delta_lease.h @@ -52,6 +52,14 @@ int delta_lease_init(struct task *task, int io_timeout, struct sync_disk *disk);
+int delta_lease_init_host(struct task *task, + struct sanlk_lockspace *ls, + char *our_host_name, + uint64_t generation, + uint64_t timestamp, + int io_timeout, + struct sync_disk *disk); + int delta_read_lockspace(struct task *task, struct sync_disk *disk, int sector_size_hint, diff --git a/src/direct.c b/src/direct.c index 920fd72..208dd35 100644 --- a/src/direct.c +++ b/src/direct.c @@ -293,6 +293,8 @@ static int do_delta_action(int action, struct task *task, int io_timeout, struct sanlk_lockspace *ls, + uint64_t generation, + uint64_t timestamp, char *our_host_name, struct leader_record *leader_in, struct leader_record *leader_ret) @@ -350,6 +352,11 @@ static int do_delta_action(int action, rv = delta_lease_init(task, ls, io_timeout, &sd); break;
+ case ACT_DIRECT_INIT_HOST: + + rv = delta_lease_init_host(task, ls, our_host_name, generation, timestamp, io_timeout, &sd); + break; + case ACT_ACQUIRE_ID: if (!sector_size || !align_size) { rv = direct_read_leader_sizes(task, &sd, §or_size, &align_size); @@ -460,17 +467,17 @@ static int do_delta_action(int action, int direct_acquire_id(struct task *task, int io_timeout, struct sanlk_lockspace *ls, char *our_host_name) { - return do_delta_action(ACT_ACQUIRE_ID, task, io_timeout, ls, our_host_name, NULL, NULL); + return do_delta_action(ACT_ACQUIRE_ID, task, io_timeout, ls, 0, 0, our_host_name, NULL, NULL); }
int direct_release_id(struct task *task, int io_timeout, struct sanlk_lockspace *ls) { - return do_delta_action(ACT_RELEASE_ID, task, io_timeout, ls, NULL, NULL, NULL); + return do_delta_action(ACT_RELEASE_ID, task, io_timeout, ls, 0, 0, NULL, NULL, NULL); }
int direct_renew_id(struct task *task, int io_timeout, struct sanlk_lockspace *ls) { - return do_delta_action(ACT_RENEW_ID, task, io_timeout, ls, NULL, NULL, NULL); + return do_delta_action(ACT_RENEW_ID, task, io_timeout, ls, 0, 0, NULL, NULL, NULL); }
int direct_align(struct sync_disk *disk) @@ -490,7 +497,17 @@ int direct_write_lockspace(struct task *task, struct sanlk_lockspace *ls, if (!ls) return -1;
- return do_delta_action(ACT_DIRECT_INIT, task, io_timeout, ls, NULL, NULL, NULL); + return do_delta_action(ACT_DIRECT_INIT, task, io_timeout, ls, 0, 0, NULL, NULL, NULL); +} + +int direct_write_lockspace_host(struct task *task, struct sanlk_lockspace *ls, char *our_host_name, + uint64_t generation, uint64_t timestamp, uint32_t io_timeout) +{ + if (!ls) + return -1; + + return do_delta_action(ACT_DIRECT_INIT_HOST, task, io_timeout, ls, + generation, timestamp, our_host_name, NULL, NULL); }
int direct_write_resource(struct task *task, struct sanlk_resource *res, @@ -520,7 +537,7 @@ int direct_read_leader(struct task *task, int rv = -1;
if (ls && ls->host_id_disk.path[0]) - rv = do_delta_action(ACT_READ_LEADER, task, io_timeout, ls, NULL, NULL, leader_ret); + rv = do_delta_action(ACT_READ_LEADER, task, io_timeout, ls, 0, 0, NULL, NULL, leader_ret);
else if (res) rv = do_paxos_action(ACT_READ_LEADER, task, io_timeout, res, @@ -539,7 +556,7 @@ int direct_write_leader(struct task *task, int rv = -1;
if (ls && ls->host_id_disk.path[0]) { - rv = do_delta_action(ACT_WRITE_LEADER, task, io_timeout, ls, NULL, leader, NULL); + rv = do_delta_action(ACT_WRITE_LEADER, task, io_timeout, ls, 0, 0, NULL, leader, NULL);
} else if (res) { rv = do_paxos_action(ACT_WRITE_LEADER, task, io_timeout, res, diff --git a/src/direct.h b/src/direct.h index 0ff509b..36845a3 100644 --- a/src/direct.h +++ b/src/direct.h @@ -37,6 +37,9 @@ int direct_align(struct sync_disk *disk); int direct_write_lockspace(struct task *task, struct sanlk_lockspace *ls, uint32_t io_timeout);
+int direct_write_lockspace_host(struct task *task, struct sanlk_lockspace *ls, char *our_host_name, + uint64_t generation, uint64_t timestamp, uint32_t io_timeout); + int direct_write_resource(struct task *task, struct sanlk_resource *res, int num_hosts, int write_clear);
diff --git a/src/main.c b/src/main.c index b77e51e..3afde14 100644 --- a/src/main.c +++ b/src/main.c @@ -2310,6 +2310,7 @@ static void print_usage(void) printf("sanlock client shutdown [-f 0|1] [-w 0|1]\n"); printf("sanlock client init -s LOCKSPACE | -r RESOURCE [-z 0|1] [-Z 512|4096 -A 1M|2M|4M|8M]\n"); printf("sanlock client read -s LOCKSPACE | -r RESOURCE [-D]\n"); + printf("sanlock client init_host -s LOCKSPACE [-g <generation>] [-t <timestamp>] [-Z 512|4096 -A 1M|2M|4M|8M]\n"); printf("sanlock client add_lockspace -s LOCKSPACE\n"); printf("sanlock client inq_lockspace -s LOCKSPACE\n"); printf("sanlock client rem_lockspace -s LOCKSPACE\n"); @@ -2492,7 +2493,9 @@ static int read_command_line(int argc, char *argv[]) break;
case COM_DIRECT: - if (!strcmp(act, "init")) + if (!strcmp(act, "init_host")) + com.action = ACT_DIRECT_INIT_HOST; + else if (!strcmp(act, "init")) com.action = ACT_DIRECT_INIT; else if (!strcmp(act, "dump")) com.action = ACT_DUMP; @@ -2592,9 +2595,13 @@ static int read_command_line(int argc, char *argv[]) com.aio_arg = 1; break; case 't': - com.max_worker_threads = atoi(optionarg); - if (com.max_worker_threads < DEFAULT_MIN_WORKER_THREADS) - com.max_worker_threads = DEFAULT_MIN_WORKER_THREADS; + if (com.action == ACT_DIRECT_INIT_HOST) + com.timestamp = strtoull(optionarg, NULL, 0); + else { + com.max_worker_threads = atoi(optionarg); + if (com.max_worker_threads < DEFAULT_MIN_WORKER_THREADS) + com.max_worker_threads = DEFAULT_MIN_WORKER_THREADS; + } break; case 'w': com.use_watchdog = atoi(optionarg); @@ -3997,7 +4004,7 @@ out: return rv; }
-static int do_direct_init(void) +static int do_direct_init(int action) { char *res_str = NULL; int rv = -EINVAL; @@ -4008,14 +4015,34 @@ static int do_direct_init(void) if (com.align_size) com.lockspace.flags |= sanlk_lsf_align_size_to_flag(com.align_size);
- syslog(LOG_WARNING, "init lockspace %.48s:%llu:%s:%llu 0x%x", - com.lockspace.name, - (unsigned long long)com.lockspace.host_id, - com.lockspace.host_id_disk.path, - (unsigned long long)com.lockspace.host_id_disk.offset, - com.lockspace.flags); + if (action == ACT_DIRECT_INIT_HOST) { + if (!com.lockspace.host_id || com.lockspace.host_id > DEFAULT_MAX_HOSTS) + goto out; + + setup_host_name(); + + syslog(LOG_WARNING, "init_host lockspace %.48s:%llu:%s:%llu 0x%x gen %llu ts %llu %s", + com.lockspace.name, + (unsigned long long)com.lockspace.host_id, + com.lockspace.host_id_disk.path, + (unsigned long long)com.lockspace.host_id_disk.offset, + com.lockspace.flags, + (unsigned long long)com.host_generation, + (unsigned long long)com.timestamp, + our_host_name_global);
- rv = direct_write_lockspace(&main_task, &com.lockspace, com.io_timeout); + rv = direct_write_lockspace_host(&main_task, &com.lockspace, our_host_name_global, + com.host_generation, com.timestamp, com.io_timeout); + } else { + syslog(LOG_WARNING, "init lockspace %.48s:%llu:%s:%llu 0x%x", + com.lockspace.name, + (unsigned long long)com.lockspace.host_id, + com.lockspace.host_id_disk.path, + (unsigned long long)com.lockspace.host_id_disk.offset, + com.lockspace.flags); + + rv = direct_write_lockspace(&main_task, &com.lockspace, com.io_timeout); + } } else if (com.res_args[0]) { if (com.sector_size) com.res_args[0]->flags |= sanlk_res_sector_size_to_flag(com.sector_size); @@ -4061,7 +4088,8 @@ static int do_direct(void) switch (com.action) {
case ACT_DIRECT_INIT: - rv = do_direct_init(); + case ACT_DIRECT_INIT_HOST: + rv = do_direct_init(com.action); break;
case ACT_DUMP: diff --git a/src/sanlock.8 b/src/sanlock.8 index 8b7b89b..ce31271 100644 --- a/src/sanlock.8 +++ b/src/sanlock.8 @@ -846,6 +846,17 @@ lease in the space. With -s, the -o option specifies the io timeout to be written in the host_id leases. With -r, the -z 1 option invalidates the resource lease on disk so it cannot be used until reinitialized normally.
+.BR "sanlock direct init_host -s" " LOCKSPACE" + +Initialize a single delta lease. The host_id specified in the -s arg +will be used, and written as the lease owner (leader.owner_id). +Optionally specify host name (leader.resource_name) with -e, +generation number (leader.owner_generation) with -g, and timestamp +(leader.timestamp) with -t (timestamp value 1 is special, and causes the +current time to be written in the timestamp field. A timestamp value +of 0 is means the delta lease is free, as usual.) +The -Z and -o options apply as with direct init. + .BR "sanlock direct read_leader -s" " LOCKSPACE" .br .BR "sanlock direct read_leader -r" " RESOURCE" diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h index e57127b..61a6ce8 100644 --- a/src/sanlock_internal.h +++ b/src/sanlock_internal.h @@ -409,6 +409,7 @@ struct command_line { uint64_t host_generation; /* -g */ uint64_t he_event; /* -e */ uint64_t he_data; /* -d */ + uint64_t timestamp; /* -t */ int num_hosts; /* -n */ int max_hosts; /* -m */ int res_count; @@ -479,6 +480,7 @@ enum { ACT_LOOKUP, ACT_UPDATE, ACT_REBUILD, + ACT_DIRECT_INIT_HOST, };
EXTERN int external_shutdown;