From 59d8d870b339ef9655169e74a03f7741d4efbb9f Mon Sep 17 00:00:00 2001 From: David Teigland Date: May 10 2024 16:48:59 +0000 Subject: sanlock: improve handling our_host_name --- diff --git a/src/main.c b/src/main.c index 403e358..eb906c9 100644 --- a/src/main.c +++ b/src/main.c @@ -1488,28 +1488,64 @@ int get_rand(int a, int b) static void read_product_uuid(char *buf, size_t buf_size) { + char full[256] = { 0 }; + int len; FILE *fp; - size_t len; if (!(fp = fopen("/sys/devices/virtual/dmi/id/product_uuid", "r"))) return; - if (!fgets(buf, buf_size, fp)) + if (!fgets(full, sizeof(full), fp)) { + buf[0] = '\0'; + fclose(fp); return; + } + fclose(fp); - if ((len = strlen(buf)) && buf[len - 1] == '\n') - buf[--len] = '\0'; + full[sizeof(full)-1] = '\0'; - fclose(fp); + len = strlen(full); + + if (len && full[len - 1] == '\n') + full[--len] = '\0'; + + /* + * Randomly pick 16 as a minimum legitimate size for a product_uuid + * (expected to be 36 for a proper uuid including dashes) + */ + if (len < 16) { + log_debug("Ignore product_uuid that is too short %d (%s)", len, full); + buf[0] = '\0'; + return; + } + + /* + * We can't trust that only a portion of the product_uuid + * would be unique. + */ + if (len > SANLK_NAME_LEN) { + log_debug("Ignore product_uuid that is too long %d (%s)", len, full); + buf[0] = '\0'; + return; + } + + /* + * buf_size is NAME_LEN+1 for easy printing (+1 is \0), + * the actual size used in leader_record is NAME_LEN + * with no required termination. + */ + memcpy(buf, full, SANLK_NAME_LEN); } static void setup_host_name(void) { + char our_host_name_long[1024] = { 0 }; /* temp buf for snprintf, then memcpy to _global */ char product_uuid[SANLK_NAME_LEN+1] = { 0 }; - char uuid[37]; - struct utsname name; + char rand_uuid[37] = { 0 }; + struct utsname name = { 0 }; uuid_t uu; - int ret; + + memset(&our_host_name_global, 0, sizeof(our_host_name_global)); /* * Get host name value from: @@ -1519,31 +1555,32 @@ static void setup_host_name(void) * 4. generate random uuid that won't collide with another host */ - if (com.our_host_name[0]) { - memcpy(our_host_name_global, com.our_host_name, SANLK_NAME_LEN); + if (com.our_host_name_opt[0]) { + memcpy(our_host_name_global, com.our_host_name_opt, SANLK_NAME_LEN); + if (strlen(com.our_host_name_opt) > SANLK_NAME_LEN) + log_warn("our_host_name shortened from config %s to: %s", + com.our_host_name_opt, our_host_name_global); + else + log_debug("our_host_name set from config: %s", our_host_name_global); return; } - memset(&our_host_name_global, 0, sizeof(our_host_name_global)); - memset(product_uuid, 0, sizeof(product_uuid)); - memset(&name, 0, sizeof(name)); - memset(&uuid, 0, sizeof(uuid)); - read_product_uuid(product_uuid, sizeof(product_uuid)); uname(&name); if (product_uuid[0]) { - ret = snprintf(our_host_name_global, SANLK_NAME_LEN, "%s.", product_uuid); + snprintf(our_host_name_long, sizeof(our_host_name_long), "%s.%s", product_uuid, name.nodename); + memcpy(our_host_name_global, our_host_name_long, SANLK_NAME_LEN); + log_debug("our_host_name set from product_uuid: %s", our_host_name_global); } else { memset(rand_state, 0, sizeof(rand_state)); initstate(time(NULL), rand_state, sizeof(rand_state)); uuid_generate(uu); - uuid_unparse_lower(uu, uuid); - ret = snprintf(our_host_name_global, SANLK_NAME_LEN, "%s.", uuid); + uuid_unparse_lower(uu, rand_uuid); + snprintf(our_host_name_long, sizeof(our_host_name_long), "%s.%s", rand_uuid, name.nodename); + memcpy(our_host_name_global, our_host_name_long, SANLK_NAME_LEN); + log_debug("our_host_name set from uuid_generate: %s", our_host_name_global); } - - if (ret < SANLK_NAME_LEN) - memcpy(our_host_name_global+ret, name.nodename, SANLK_NAME_LEN-ret); } static void setup_limits(void) @@ -2170,8 +2207,8 @@ static void print_usage(void) printf(" -l use mlockall (0 none, 1 current, 2 current and future) (%d)\n", DEFAULT_MLOCK_LEVEL); printf(" -b seconds a host id bit will remain set in delta lease bitmap\n"); printf(" (default: 6 * io_timeout)\n"); - printf(" -e local host name used in delta leases\n"); - printf(" (default: generate new uuid)\n"); + printf(" -e local host name used in delta leases, max len 48\n"); + printf(" (default: product_uuid or randomly generated uuid)\n"); printf("\n"); printf("sanlock client [options]\n"); printf("sanlock client status [-D] [-o p|s]\n"); @@ -2514,7 +2551,7 @@ static int read_command_line(int argc, char *argv[]) if (com.rindex_op) { parse_arg_rentry(optionarg); } else { - strncpy(com.our_host_name, optionarg, NAME_ID_SIZE); + strncpy(com.our_host_name_opt, optionarg, sizeof(com.our_host_name_opt)-1); com.he_event = strtoull(optionarg, NULL, 0); } break; @@ -2910,7 +2947,7 @@ static void read_config_file(void) } else if (!strcmp(str, "our_host_name")) { memset(str, 0, sizeof(str)); get_val_str(line, str); - memcpy(com.our_host_name, str, NAME_ID_SIZE); + strncpy(com.our_host_name_opt, str, sizeof(com.our_host_name_opt)-1); } else if (!strcmp(str, "renewal_read_extend_sec")) { /* zero is a valid setting so we need the _set field to say it's set */ diff --git a/src/sanlock.8 b/src/sanlock.8 index 6466689..cddf23f 100644 --- a/src/sanlock.8 +++ b/src/sanlock.8 @@ -612,7 +612,7 @@ use mlockall (0 none, 1 current, 2 current and future) seconds a host id bit will remain set in delta lease bitmap .BI -e " str" -local host name used in delta leases +unique local host name used in delta leases as host_id owner .\" non-aio is untested and may not work .\" .BR \-a " 0|1" @@ -1343,7 +1343,13 @@ See -G .IP \[bu] 2 our_host_name = .br -See -e +A unique name that a host uses to ensure exclusive ownership of a +lockspace host_id (delta lease owner.) The maximum length is 48 +characters. If no value is provided in sanlock.conf or on the +command line (-e), sanlock attempts to set our_host_name from +/sys/devices/virtual/dmi/id/product_uuid. If that is not available, +sanlock generates a random uuid to use as our_host_name. Using a +fixed our_host_name value will reduce delays when using a lockspace. .IP \[bu] 2 renewal_read_extend_sec = diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h index a8ffdf5..5de92b5 100644 --- a/src/sanlock_internal.h +++ b/src/sanlock_internal.h @@ -393,7 +393,7 @@ struct command_line { int renewal_history_size; int renewal_read_extend_sec_set; /* 1 if renewal_read_extend_sec is configured */ uint32_t renewal_read_extend_sec; - char our_host_name[SANLK_NAME_LEN+1]; + char our_host_name_opt[256]; /* max SANLK_NAME_LEN will be used */ char *file_path; char *dump_path; int rindex_op;