From 0b01e3f5d7ce1c954aa9f3707aa645508664f7f1 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mon, 22 Oct 2018 15:45:23 -0500 Subject: [PATCH] lvmlockd: use new sanlock sector/align interface The choice about sector size and lease align size is now made by the sanlock user, in this case lvmlockd. This will allow lvmlockd to use other lease sizes in the future. This also prevents breakage if hosts report different sector sizes, or the sector size reported by a device changes. --- daemons/lvmlockd/lvmlockd-core.c | 21 ++- daemons/lvmlockd/lvmlockd-internal.h | 8 +- daemons/lvmlockd/lvmlockd-sanlock.c | 311 +++++++++++++++++++++++++++++++---- 3 files changed, 301 insertions(+), 39 deletions(-) diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c index 6490b40..5bdbefe 100644 --- a/daemons/lvmlockd/lvmlockd-core.c +++ b/daemons/lvmlockd/lvmlockd-core.c @@ -929,12 +929,12 @@ static void lm_rem_resource(struct lockspace *ls, struct resource *r) lm_rem_resource_sanlock(ls, r); } -static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset) +static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size) { if (ls->lm_type == LD_LM_DLM) return 0; else if (ls->lm_type == LD_LM_SANLOCK) - return lm_find_free_lock_sanlock(ls, free_offset); + return lm_find_free_lock_sanlock(ls, free_offset, sector_size, align_size); return -1; } @@ -2427,11 +2427,16 @@ static void *lockspace_thread_main(void *arg_in) if (act->op == LD_OP_FIND_FREE_LOCK && act->rt == LD_RT_VG) { uint64_t free_offset = 0; + int sector_size = 0; + int align_size = 0; + log_debug("S %s find free lock", ls->name); - rv = lm_find_free_lock(ls, &free_offset); - log_debug("S %s find free lock %d offset %llu", - ls->name, rv, (unsigned long long)free_offset); + rv = lm_find_free_lock(ls, &free_offset, §or_size, &align_size); + log_debug("S %s find free lock %d offset %llu sector_size %d align_size %d", + ls->name, rv, (unsigned long long)free_offset, sector_size, align_size); ls->free_lock_offset = free_offset; + ls->free_lock_sector_size = sector_size; + ls->free_lock_align_size = align_size; list_del(&act->list); act->result = rv; add_client_result(act); @@ -3237,6 +3242,8 @@ static int work_init_lv(struct action *act) char vg_args[MAX_ARGS+1]; char lv_args[MAX_ARGS+1]; uint64_t free_offset = 0; + int sector_size = 0; + int align_size = 0; int lm_type = 0; int rv = 0; @@ -3252,6 +3259,8 @@ static int work_init_lv(struct action *act) lm_type = ls->lm_type; memcpy(vg_args, ls->vg_args, MAX_ARGS); free_offset = ls->free_lock_offset; + sector_size = ls->free_lock_sector_size; + align_size = ls->free_lock_align_size; } pthread_mutex_unlock(&lockspaces_mutex); @@ -3268,7 +3277,7 @@ static int work_init_lv(struct action *act) if (lm_type == LD_LM_SANLOCK) { rv = lm_init_lv_sanlock(ls_name, act->vg_name, act->lv_uuid, - vg_args, lv_args, free_offset); + vg_args, lv_args, sector_size, align_size, free_offset); memcpy(act->lv_args, lv_args, MAX_ARGS); return rv; diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h index a2280b8..ead3098 100644 --- a/daemons/lvmlockd/lvmlockd-internal.h +++ b/daemons/lvmlockd/lvmlockd-internal.h @@ -174,7 +174,9 @@ struct lockspace { int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */ void *lm_data; uint64_t host_id; - uint64_t free_lock_offset; /* start search for free lock here */ + uint64_t free_lock_offset; /* for sanlock, start search for free lock here */ + int free_lock_sector_size; /* for sanlock */ + int free_lock_align_size; /* for sanlock */ uint32_t start_client_id; /* client_id that started the lockspace */ pthread_t thread; /* makes synchronous lock requests */ @@ -468,7 +470,7 @@ static inline int lm_hosts_dlm(struct lockspace *ls, int notify) #ifdef LOCKDSANLOCK_SUPPORT int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args); -int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, uint64_t free_offset); +int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, int sector_size, int align_size, uint64_t free_offset); int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r); int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args); int lm_prepare_lockspace_sanlock(struct lockspace *ls); @@ -488,7 +490,7 @@ int lm_gl_is_enabled(struct lockspace *ls); int lm_get_lockspaces_sanlock(struct list_head *ls_rejoin); int lm_data_size_sanlock(void); int lm_is_running_sanlock(void); -int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset); +int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size); static inline int lm_support_sanlock(void) { diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c index d5d6864..892b446 100644 --- a/daemons/lvmlockd/lvmlockd-sanlock.c +++ b/daemons/lvmlockd/lvmlockd-sanlock.c @@ -24,10 +24,29 @@ #include "sanlock_admin.h" #include "sanlock_resource.h" +/* FIXME: these are copied from sanlock.h only until + an updated version of sanlock is available with them. */ +#define SANLK_RES_ALIGN1M 0x00000010 +#define SANLK_RES_ALIGN2M 0x00000020 +#define SANLK_RES_ALIGN4M 0x00000040 +#define SANLK_RES_ALIGN8M 0x00000080 +#define SANLK_RES_SECTOR512 0x00000100 +#define SANLK_RES_SECTOR4K 0x00000200 +#define SANLK_LSF_ALIGN1M 0x00000010 +#define SANLK_LSF_ALIGN2M 0x00000020 +#define SANLK_LSF_ALIGN4M 0x00000040 +#define SANLK_LSF_ALIGN8M 0x00000080 +#define SANLK_LSF_SECTOR512 0x00000100 +#define SANLK_LSF_SECTOR4K 0x00000200 + #include #include #include #include +#include +#include + +#define ONE_MB 1048576 /* ------------------------------------------------------------------------------- @@ -139,6 +158,7 @@ release all the leases for the VG. struct lm_sanlock { struct sanlk_lockspace ss; + int sector_size; int align_size; int sock; /* sanlock daemon connection */ }; @@ -201,7 +221,6 @@ int lm_data_size_sanlock(void) * ... */ -#define LS_BEGIN 0 #define GL_LOCK_BEGIN UINT64_C(65) #define VG_LOCK_BEGIN UINT64_C(66) #define LV_LOCK_BEGIN UINT64_C(67) @@ -324,6 +343,152 @@ fail: return rv; } +static void _read_sysfs_size(dev_t devno, const char *name, unsigned int *val) +{ + char path[PATH_MAX]; + char buf[32]; + FILE *fp; + size_t len; + + snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/queue/%s", + (int)MAJOR(devno), (int)MINOR(devno), name); + + if (!(fp = fopen(path, "r"))) + return; + + if (!fgets(buf, sizeof(buf), fp)) + goto out; + + if ((len = strlen(buf)) && buf[len - 1] == '\n') + buf[--len] = '\0'; + + if (strlen(buf)) + *val = atoi(buf); +out: + fclose(fp); +} + +/* Select sector/align size for a new VG based on what the device reports for + sector size of the lvmlock LV. */ + +static int get_sizes_device(char *path, int *sector_size, int *align_size) +{ + unsigned int physical_block_size = 0; + unsigned int logical_block_size = 0; + struct stat st; + int rv; + + rv = stat(path, &st); + if (rv < 0) { + log_error("Failed to stat device to get block size %s %d", path, errno); + return -1; + } + + _read_sysfs_size(st.st_rdev, "physical_block_size", &physical_block_size); + _read_sysfs_size(st.st_rdev, "logical_block_size", &logical_block_size); + + if ((physical_block_size == 512) && (logical_block_size == 512)) { + *sector_size = 512; + *align_size = ONE_MB; + return 0; + } + + if ((physical_block_size == 4096) && (logical_block_size == 4096)) { + *sector_size = 4096; + *align_size = 8 * ONE_MB; + return 0; + } + + if (physical_block_size && (physical_block_size != 512) && (physical_block_size != 4096)) { + log_warn("WARNING: invalid block sizes physical %u logical %u for %s", + physical_block_size, logical_block_size, path); + physical_block_size = 0; + } + + if (logical_block_size && (logical_block_size != 512) && (logical_block_size != 4096)) { + log_warn("WARNING: invalid block sizes physical %u logical %u for %s", + physical_block_size, logical_block_size, path); + logical_block_size = 0; + } + + if (!physical_block_size && !logical_block_size) { + log_error("Failed to get a block size for %s", path); + return -1; + } + + if (!physical_block_size || !logical_block_size) { + log_warn("WARNING: incomplete block size information physical %u logical %u for %s", + physical_block_size, logical_block_size, path); + if (!physical_block_size) + physical_block_size = logical_block_size; + if (!logical_block_size) + logical_block_size = physical_block_size; + } + + if ((logical_block_size == 4096) && (physical_block_size == 512)) { + log_warn("WARNING: mixed block sizes physical %u logical %u (using 4096) for %s", + physical_block_size, logical_block_size, path); + *sector_size = 4096; + *align_size = 8 * ONE_MB; + return 0; + } + + if ((physical_block_size == 4096) && (logical_block_size == 512)) { + log_warn("WARNING: mixed block sizes physical %u logical %u (using 4096) for %s", + physical_block_size, logical_block_size, path); + *sector_size = 4096; + *align_size = 8 * ONE_MB; + return 0; + } + + if (physical_block_size == 512) { + *sector_size = 512; + *align_size = ONE_MB; + return 0; + } + + if (physical_block_size == 4096) { + *sector_size = 4096; + *align_size = 8 * ONE_MB; + return 0; + } + + log_error("Failed to get a block size for %s", path); + return -1; +} + + +/* Get the sector/align sizes that were used to create an existing VG. + sanlock encoded this in the lockspace/resource structs on disk. */ + +static int get_sizes_lockspace(char *path, int *sector_size, int *align_size) +{ + struct sanlk_lockspace ss; + uint32_t io_timeout = 0; + int rv; + + memset(&ss, 0, sizeof(ss)); + memcpy(ss.host_id_disk.path, path, SANLK_PATH_LEN); + ss.host_id_disk.offset = 0; + + rv = sanlock_read_lockspace(&ss, 0, &io_timeout); + if (rv < 0) { + log_error("get_sizes_lockspace %s error %d", path, rv); + return rv; + } + + if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN8M)) { + *sector_size = 4096; + *align_size = 8 * ONE_MB; + } else if ((ss.flags & SANLK_LSF_SECTOR512) && (ss.flags & SANLK_LSF_ALIGN1M)) { + *sector_size = 512; + *align_size = ONE_MB; + } + + log_debug("get_sizes_lockspace found %d %d", *sector_size, *align_size); + return 0; +} + /* * vgcreate * @@ -343,7 +508,8 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar uint32_t daemon_version; uint32_t daemon_proto; uint64_t offset; - int align_size; + int sector_size = 0; + int align_size = 0; int i, rv; memset(&ss, 0, sizeof(ss)); @@ -387,23 +553,25 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar log_debug("sanlock daemon version %08x proto %08x", daemon_version, daemon_proto); - rv = sanlock_align(&disk); - if (rv <= 0) { + /* Nothing formatted on disk yet, use what the device reports. */ + rv = get_sizes_device(disk.path, §or_size, &align_size); + if (rv < 0) { if (rv == -EACCES) { log_error("S %s init_vg_san sanlock error -EACCES: no permission to access %s", ls_name, disk.path); return -EDEVOPEN; } else { - log_error("S %s init_vg_san sanlock error %d trying to get align size of %s", + log_error("S %s init_vg_san sanlock error %d trying to get sector/align size of %s", ls_name, rv, disk.path); return -EARGS; } - } else - align_size = rv; + } strncpy(ss.name, ls_name, SANLK_NAME_LEN); memcpy(ss.host_id_disk.path, disk.path, SANLK_PATH_LEN); - ss.host_id_disk.offset = LS_BEGIN * align_size; + ss.host_id_disk.offset = 0; + ss.flags = (sector_size == 4096) ? (SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M) : + (SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M); rv = sanlock_write_lockspace(&ss, 0, 0, sanlock_io_timeout); if (rv < 0) { @@ -436,6 +604,8 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN); rd.rs.disks[0].offset = align_size * GL_LOCK_BEGIN; rd.rs.num_disks = 1; + rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); rv = sanlock_write_resource(&rd.rs, 0, 0, 0); if (rv < 0) { @@ -449,6 +619,8 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN); rd.rs.disks[0].offset = align_size * VG_LOCK_BEGIN; rd.rs.num_disks = 1; + rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); rv = sanlock_write_resource(&rd.rs, 0, 0, 0); if (rv < 0) { @@ -472,6 +644,8 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar memset(&rd, 0, sizeof(rd)); rd.rs.num_disks = 1; + rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN); strncpy(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN); strcpy(rd.rs.name, "#unused"); @@ -510,13 +684,13 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar */ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, - char *vg_args, char *lv_args, uint64_t free_offset) + char *vg_args, char *lv_args, + int sector_size, int align_size, uint64_t free_offset) { struct sanlk_resourced rd; char lock_lv_name[MAX_ARGS+1]; char lock_args_version[MAX_ARGS+1]; uint64_t offset; - int align_size; int rv; memset(&rd, 0, sizeof(rd)); @@ -534,7 +708,7 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, LV_LOCK_ARGS_MAJOR, LV_LOCK_ARGS_MINOR, LV_LOCK_ARGS_PATCH); if (daemon_test) { - align_size = 1048576; + align_size = ONE_MB; snprintf(lv_args, MAX_ARGS, "%s:%llu", lock_args_version, (unsigned long long)((align_size * LV_LOCK_BEGIN) + (align_size * daemon_test_lv_count))); @@ -547,12 +721,35 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, if ((rv = build_dm_path(rd.rs.disks[0].path, SANLK_PATH_LEN, vg_name, lock_lv_name))) return rv; - align_size = sanlock_align(&rd.rs.disks[0]); - if (align_size <= 0) { - log_error("S %s init_lv_san align error %d", ls_name, align_size); - return -EINVAL; + /* + * These should not usually be zero, maybe only the first time this function is called? + * We need to use the same sector/align sizes that are already being used. + */ + if (!sector_size || !align_size) { + rv = get_sizes_lockspace(rd.rs.disks[0].path, §or_size, &align_size); + if (rv < 0) { + log_error("S %s init_lv_san read_lockspace error %d %s", + ls_name, rv, rd.rs.disks[0].path); + return rv; + } + + if (sector_size) + log_debug("S %s init_lv_san found ls sector_size %d align_size %d", ls_name, sector_size, align_size); + else { + /* use the old method */ + align_size = sanlock_align(&rd.rs.disks[0]); + if (align_size <= 0) { + log_error("S %s init_lv_san align error %d", ls_name, align_size); + return -EINVAL; + } + sector_size = (align_size == ONE_MB) ? 512 : 4096; + log_debug("S %s init_lv_san found old sector_size %d align_size %d", ls_name, sector_size, align_size); + } } + rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); + if (free_offset) offset = free_offset; else @@ -595,6 +792,8 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, ls_name, lv_name, (unsigned long long)offset); strncpy(rd.rs.name, lv_name, SANLK_NAME_LEN); + rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); rv = sanlock_write_resource(&rd.rs, 0, 0, 0); if (!rv) { @@ -626,7 +825,8 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ char lock_lv_name[MAX_ARGS+1]; uint64_t offset; uint32_t io_timeout; - int align_size; + int sector_size = 0; + int align_size = 0; int i, rv; memset(&disk, 0, sizeof(disk)); @@ -655,20 +855,13 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ /* FIXME: device is not always ready for us here */ sleep(1); - align_size = sanlock_align(&disk); - if (align_size <= 0) { - log_error("S %s rename_vg_san bad align size %d %s", - ls_name, align_size, disk.path); - return -EINVAL; - } - /* * Lockspace */ memset(&ss, 0, sizeof(ss)); memcpy(ss.host_id_disk.path, disk.path, SANLK_PATH_LEN); - ss.host_id_disk.offset = LS_BEGIN * align_size; + ss.host_id_disk.offset = 0; rv = sanlock_read_lockspace(&ss, 0, &io_timeout); if (rv < 0) { @@ -677,6 +870,26 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ return rv; } + if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN8M)) { + sector_size = 4096; + align_size = 8 * ONE_MB; + } else if ((ss.flags & SANLK_LSF_SECTOR512) && (ss.flags & SANLK_LSF_ALIGN1M)) { + sector_size = 512; + align_size = ONE_MB; + } else { + /* use the old method */ + align_size = sanlock_align(&ss.host_id_disk); + if (align_size <= 0) { + log_error("S %s rename_vg_san unknown sector/align size for %s", + ls_name, ss.host_id_disk.path); + return -1; + } + sector_size = (align_size == ONE_MB) ? 512 : 4096; + } + + if (!sector_size || !align_size) + return -1; + strncpy(ss.name, ls_name, SANLK_NAME_LEN); rv = sanlock_write_lockspace(&ss, 0, 0, sanlock_io_timeout); @@ -830,6 +1043,11 @@ int lm_ex_disable_gl_sanlock(struct lockspace *ls) rd1.rs.num_disks = 1; strncpy(rd1.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1); rd1.rs.disks[0].offset = lms->align_size * GL_LOCK_BEGIN; + + rd1.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); + rd2.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); rv = sanlock_acquire(lms->sock, -1, 0, 1, &rs1, NULL); if (rv < 0) { @@ -891,6 +1109,8 @@ int lm_able_gl_sanlock(struct lockspace *ls, int enable) rd.rs.num_disks = 1; strncpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1); rd.rs.disks[0].offset = lms->align_size * GL_LOCK_BEGIN; + rd.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); rv = sanlock_write_resource(&rd.rs, 0, 0, 0); if (rv < 0) { @@ -936,7 +1156,8 @@ static int gl_is_enabled(struct lockspace *ls, struct lm_sanlock *lms) rv = sanlock_read_resource(&rd.rs, 0); if (rv < 0) { - log_error("gl_is_enabled read_resource error %d", rv); + log_error("gl_is_enabled read_resource align_size %d offset %llu error %d", + lms->align_size, (unsigned long long)offset, rv); return rv; } @@ -973,7 +1194,7 @@ int lm_gl_is_enabled(struct lockspace *ls) * been disabled.) */ -int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset) +int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size) { struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data; struct sanlk_resourced rd; @@ -983,15 +1204,22 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset) int round = 0; if (daemon_test) { - *free_offset = (1048576 * LV_LOCK_BEGIN) + (1048576 * (daemon_test_lv_count + 1)); + *free_offset = (ONE_MB * LV_LOCK_BEGIN) + (ONE_MB * (daemon_test_lv_count + 1)); + *sector_size = 512; + *align_size = ONE_MB; return 0; } + *sector_size = lms->sector_size; + *align_size = lms->align_size; + memset(&rd, 0, sizeof(rd)); strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN); rd.rs.num_disks = 1; strncpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1); + rd.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : + (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); if (ls->free_lock_offset) offset = ls->free_lock_offset; @@ -1091,6 +1319,8 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls) char disk_path[SANLK_PATH_LEN]; char killpath[SANLK_PATH_LEN]; char killargs[SANLK_PATH_LEN]; + int sector_size = 0; + int align_size = 0; int gl_found; int ret, rv; @@ -1207,13 +1437,33 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls) goto fail; } - lms->align_size = sanlock_align(&lms->ss.host_id_disk); - if (lms->align_size <= 0) { - log_error("S %s prepare_lockspace_san align error %d", lsname, lms->align_size); + rv = get_sizes_lockspace(disk_path, §or_size, &align_size); + if (rv < 0) { + log_error("S %s prepare_lockspace_san cannot get sector/align sizes %d", lsname, rv); ret = -EMANAGER; goto fail; } + if (!sector_size) { + log_debug("S %s prepare_lockspace_san using old size method", lsname); + /* use the old method */ + align_size = sanlock_align(&lms->ss.host_id_disk); + if (align_size <= 0) { + log_error("S %s prepare_lockspace_san align error %d", lsname, align_size); + return -EINVAL; + } + sector_size = (align_size == ONE_MB) ? 512 : 4096; + log_debug("S %s prepare_lockspace_san found old sector_size %d align_size %d", lsname, sector_size, align_size); + } + + log_debug("S %s prepare_lockspace_san sizes %d %d", lsname, sector_size, align_size); + + lms->align_size = align_size; + lms->sector_size = sector_size; + + lms->ss.flags = (sector_size == 4096) ? (SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M) : + (SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M); + gl_found = gl_is_enabled(ls, lms); if (gl_found < 0) { log_error("S %s prepare_lockspace_san gl_enabled error %d", lsname, gl_found); @@ -1351,6 +1601,7 @@ static int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r) strncpy(rds->rs.name, r->name, SANLK_NAME_LEN); rds->rs.num_disks = 1; memcpy(rds->rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN); + rds->rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M); if (r->type == LD_RT_GL) rds->rs.disks[0].offset = GL_LOCK_BEGIN * lms->align_size; -- 2.9.3