1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-23 17:44:22 +03:00

Compare commits

..

2 Commits

Author SHA1 Message Date
David Teigland
60270a4288 lvmlockd: use persistent reservations for lock recovery in sanlock 2025-09-15 15:58:26 -05:00
David Teigland
813d333e0c vgcreate: support --setpersist
Previously, setpersist was only supported from vgchange
on an existing VG.  The PR is acquired exclusively before
the devices are modified, and in the case of a shared
VG the PR is subsequently changed to a shared mode.
2025-09-10 13:36:40 -05:00
64 changed files with 3042 additions and 1603 deletions

View File

@@ -1,6 +1,5 @@
Version 2.03.36 -
==================
Detect and use existing XFS quota mount options for lvresize --fs resize.
Version 2.03.35 - 09th September 2025
=====================================

View File

@@ -39,7 +39,7 @@ local {
# system_id = ""
# Configuration option local/pr_key.
# The local persistent reservation key in hexadecimal.
# The local persistent reservation key in hexidecimal.
# The value must be unique among all hosts using the same VG.
# The max length is 16 hex characters (8 bytes), plus an optional
# 0x prefix. If pr_key is not set, host_id will be used to create a key.

View File

@@ -934,7 +934,7 @@ AC_MSG_RESULT([$BUILD_LOCKDSANLOCK])
dnl -- Look for sanlock libraries
AS_IF([test "$BUILD_LOCKDSANLOCK" = "yes"], [
LOCKDSANLOCK_SUPPORT=370
LOCKDSANLOCK_SUPPORT=410
PKG_CHECK_EXISTS(libsanlock_client >= 4.0.0, [LOCKDSANLOCK_SUPPORT=400])
PKG_CHECK_EXISTS(libsanlock_client >= 4.1.0, [LOCKDSANLOCK_SUPPORT=410])
PKG_CHECK_MODULES(LIBSANLOCKCLIENT, libsanlock_client >= 3.7.0, [BUILD_LVMLOCKD="yes"])

View File

@@ -15,7 +15,6 @@
#include "lib/misc/lib.h"
#include "dmeventd_lvm.h"
#include "daemons/dmeventd/libdevmapper-event.h"
#include "lib/metadata/metadata-exported.h" /* MIRROR_SYNC_LAYER */
#include "tools/lvm2cmd.h"
#include <pthread.h>
@@ -144,7 +143,7 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
}
/* strip off the mirror component designations */
if ((layer = strstr(lv, MIRROR_SYNC_LAYER)) ||
if ((layer = strstr(lv, "_mimagetmp")) ||
(layer = strstr(lv, "_mlog")))
*layer = '\0';

View File

@@ -15,7 +15,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = lvmlockd-core.c
SOURCES = lvmlockd-core.c lvmlockd-helper.c
SOURCES2 = lvmlockctl.c
TARGETS = lvmlockd lvmlockctl

View File

@@ -60,4 +60,11 @@ static inline void lvmlockd_close(daemon_handle h)
#define EIOTIMEOUT 225
#define ELOCKREPAIR 226
#define LOCKARGS_VERSION 0x00000001 /* meta only */
#define LOCKARGS_LVMLOCK 0x00000002 /* meta only */
#define LOCKARGS_TIMEOUT 0x00000004 /* user only */
#define LOCKARGS_NOTIMEOUT 0x00000008 /* meta or user */
#define LOCKARGS_PERSIST 0x00000010 /* meta or user */
#define LOCKARGS_NOPERSIST 0x00000020 /* user only */
#endif /* _LVM_LVMLOCKD_CLIENT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -76,7 +76,7 @@ static int check_args_version(char *vg_args)
unsigned int major = 0;
int rv;
rv = version_from_args(vg_args, &major, NULL, NULL);
rv = lockd_lockargs_get_version(vg_args, &major, NULL, NULL);
if (rv < 0) {
log_error("check_args_version %s error %d", vg_args, rv);
return rv;

View File

@@ -0,0 +1,264 @@
/*
* Copyright 2025 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v2 or (at your option) any later version.
*/
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <poll.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <time.h>
#include <stdarg.h>
#include <signal.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <grp.h>
#include <syslog.h>
#include "lvmlockd-internal.h"
struct list_head commands; /* helper_msg_list entries */
static int _log_stderr;
#define log_helper(fmt, args...) \
do { \
if (_log_stderr) \
fprintf(stderr, fmt "\n", ##args); \
} while (0)
static void _save_command(struct helper_msg *msg)
{
struct helper_msg_list *ml;
ml = malloc(sizeof(struct helper_msg_list));
if (!ml)
return;
memcpy(&ml->msg, msg, sizeof(struct helper_msg));
list_add_tail(&ml->list, &commands);
}
static struct helper_msg_list *_get_command(int pid)
{
struct helper_msg_list *ml;
list_for_each_entry(ml, &commands, list) {
if (ml->msg.pid == pid)
return ml;
}
return NULL;
}
static int read_msg(int fd, struct helper_msg *msg)
{
int rv;
retry:
rv = read(fd, msg, sizeof(struct helper_msg));
if (rv == -1 && errno == EINTR)
goto retry;
if (rv != sizeof(struct helper_msg))
return -1;
return 0;
}
static void exec_command(char *cmd_str)
{
char arg[ONE_ARG_LEN];
char *av[MAX_AV_COUNT + 1]; /* +1 for NULL */
int av_count = 0;
int i, arg_len, cmd_len;
for (i = 0; i < MAX_AV_COUNT + 1; i++)
av[i] = NULL;
if (!cmd_str[0])
return;
/* this should already be done, but make sure */
cmd_str[RUN_COMMAND_LEN - 1] = '\0';
memset(&arg, 0, sizeof(arg));
arg_len = 0;
cmd_len = strlen(cmd_str);
for (i = 0; i < cmd_len; i++) {
if (!cmd_str[i])
break;
if (av_count == MAX_AV_COUNT)
break;
if (cmd_str[i] == '\\') {
if (i == (cmd_len - 1))
break;
i++;
if (cmd_str[i] == '\\') {
arg[arg_len++] = cmd_str[i];
continue;
}
if (isspace(cmd_str[i])) {
arg[arg_len++] = cmd_str[i];
continue;
} else {
break;
}
}
if (isalnum(cmd_str[i]) || ispunct(cmd_str[i])) {
arg[arg_len++] = cmd_str[i];
} else if (isspace(cmd_str[i])) {
if (arg_len)
av[av_count++] = strdup(arg);
memset(arg, 0, sizeof(arg));
arg_len = 0;
} else {
break;
}
}
if ((av_count < MAX_AV_COUNT) && arg_len) {
av[av_count++] = strdup(arg);
}
execvp(av[0], av);
}
static int send_result(struct helper_msg *msg, int fd)
{
int rv;
rv = write(fd, msg, sizeof(struct helper_msg));
if (rv == sizeof(struct helper_msg))
return 0;
return -1;
}
#define IDLE_TIMEOUT_MS (30 * 1000)
#define ACTIVE_TIMEOUT_MS 500
__attribute__((noreturn)) void helper_main(int in_fd, int out_fd, int log_stderr)
{
struct pollfd pollfd;
struct helper_msg msg;
struct helper_msg_list *ml;
siginfo_t info;
unsigned int fork_count = 0;
unsigned int done_count = 0;
int timeout = IDLE_TIMEOUT_MS;
int rv, pid;
INIT_LIST_HEAD(&commands);
_log_stderr = log_stderr;
rv = setgroups(0, NULL);
if (rv < 0)
log_helper("error clearing helper groups errno %i", errno);
memset(&pollfd, 0, sizeof(pollfd));
pollfd.fd = in_fd;
pollfd.events = POLLIN;
openlog("lvmlockd-helper", LOG_CONS | LOG_PID, LOG_LOCAL4);
while (1) {
rv = poll(&pollfd, 1, timeout);
if (rv == -1 && errno == EINTR)
continue;
if (rv < 0)
exit(0);
if (pollfd.revents & POLLIN) {
memset(&msg, 0, sizeof(msg));
rv = read_msg(in_fd, &msg);
if (rv)
continue;
if (msg.type == HELPER_COMMAND) {
pid = fork();
if (!pid) {
exec_command(msg.command);
exit(1);
}
msg.pid = pid;
_save_command(&msg);
fork_count++;
}
}
if (pollfd.revents & (POLLERR | POLLHUP | POLLNVAL))
exit(0);
/* collect child exits until no more children exist (ECHILD)
or none are ready (WNOHANG) */
while (1) {
memset(&info, 0, sizeof(info));
rv = waitid(P_ALL, 0, &info, WEXITED | WNOHANG);
if ((rv < 0) && (errno == ECHILD)) {
/*
log_helper("helper no children exist fork_count %d done_count %d", fork_count, done_count);
*/
timeout = IDLE_TIMEOUT_MS;
}
else if (!rv && !info.si_pid) {
log_helper("helper no children ready fork_count %d done_count %d", fork_count, done_count);
timeout = ACTIVE_TIMEOUT_MS;
}
else if (!rv && info.si_pid) {
done_count++;
if (!(ml = _get_command(info.si_pid))) {
log_helper("command for pid %d result %d not found",
info.si_pid, info.si_status);
continue;
}
log_helper("command for pid %d result %d done", info.si_pid, info.si_status);
ml->msg.type = HELPER_COMMAND_RESULT;
ml->msg.result = info.si_status;
send_result(&ml->msg, out_fd);
list_del(&ml->list);
free(ml);
continue;
}
else {
log_helper("helper waitid rv %d errno %d fork_count %d done_count %d",
rv, errno, fork_count, done_count);
}
break;
}
}
}

View File

@@ -63,6 +63,10 @@ enum {
LD_OP_QUERY_LOCK,
LD_OP_REFRESH_LV,
LD_OP_VG_STATUS,
LD_OP_FENCE,
LD_OP_FENCE_RESULT,
LD_OP_SETLOCKARGS_BEFORE,
LD_OP_SETLOCKARGS_FINAL,
};
/* resource types */
@@ -119,6 +123,7 @@ struct client {
#define LD_AF_ADOPT_ONLY 0x00200000 /* adopt orphan or fail */
#define LD_AF_NODELAY 0x00400000
#define LD_AF_REPAIR 0x00800000
#define LD_AF_NO_TIMEOUT 0x01000000
/*
* Number of times to repeat a lock request after
@@ -132,6 +137,32 @@ struct pvs {
int num;
};
#define RUN_COMMAND_LEN 1024
#define MAX_AV_COUNT 32
#define ONE_ARG_LEN 256
/* helper_msg types */
#define HELPER_COMMAND 0x1
#define HELPER_COMMAND_RESULT 0x2
struct helper_msg {
uint8_t type;
uint8_t act;
uint16_t unused1;
uint32_t msg_id;
int pid;
int result;
char ls_name[MAX_NAME+1];
uint8_t unused2;
uint16_t unused3;
char command[RUN_COMMAND_LEN];
};
struct helper_msg_list {
struct helper_msg msg;
struct list_head list;
};
#define OWNER_NAME_SIZE 64
#define OWNER_STATE_SIZE 32
@@ -147,8 +178,11 @@ struct action {
struct list_head list;
uint32_t client_id;
uint32_t flags; /* LD_AF_ */
uint32_t msg_id;
uint32_t version;
uint32_t host_id;
uint64_t ourkey;
uint64_t remkey;
uint64_t lv_size_bytes;
int8_t op; /* operation type LD_OP_ */
int8_t rt; /* resource type LD_RT_ */
@@ -166,7 +200,7 @@ struct action {
char lv_uuid[MAX_NAME+1];
char vg_args[MAX_ARGS+1];
char lv_args[MAX_ARGS+1];
char prev_lv_args[MAX_ARGS+1];
char other_args[MAX_ARGS+1];
struct owner owner;
struct pvs pvs; /* PV list for idm */
};
@@ -187,6 +221,7 @@ struct resource {
unsigned int use_vb : 1;
struct list_head locks;
struct list_head actions;
struct list_head fence_wait_actions;
char lv_args[MAX_ARGS+1];
char lm_data[]; /* lock manager specific data */
};
@@ -209,8 +244,10 @@ struct lockspace {
char vg_args[MAX_ARGS+1]; /* lock manager specific args */
int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
void *lm_data;
uint32_t lock_args_flags;
uint32_t host_id;
uint64_t generation;
uint64_t ourkey;
uint64_t free_lock_offset; /* for sanlock, start search for free lock here */
struct pvs pvs; /* for idm: PV list */
@@ -225,13 +262,14 @@ struct lockspace {
unsigned int thread_done : 1;
unsigned int sanlock_gl_enabled: 1;
unsigned int sanlock_gl_dup: 1;
unsigned int free_vg: 1;
unsigned int kill_vg: 1;
unsigned int drop_vg: 1;
unsigned int fence_pr: 1;
unsigned int no_timeout: 1;
struct list_head actions; /* new client actions */
struct list_head resources; /* resource/lock state for gl/vg/lv */
struct list_head dispose; /* resources to free */
struct list_head fence_history; /* internally created actions for fencing */
};
/* val_blk version */
@@ -390,7 +428,9 @@ void log_level(int level, const char *fmt, ...) __attribute__((format(printf, 2
struct lockspace *alloc_lockspace(void);
int lockspaces_empty(void);
int last_string_from_args(char *args_in, char *last);
int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsigned int *patch);
void helper_main(int in_fd, int out_fd, int log_stderr);
int lockd_lockargs_get_user_flags(const char *str, uint32_t *flags);
int lockd_lockargs_get_version(char *str, unsigned int *major, unsigned int *minor, unsigned int *patch);
static inline const char *mode_str(int x)
{
@@ -559,7 +599,7 @@ static inline int lm_refresh_lv_check_dlm(struct action *act)
#ifdef LOCKDSANLOCK_SUPPORT
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb);
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb, char *other_args);
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args);
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);
@@ -584,6 +624,9 @@ int lm_data_size_sanlock(void);
int lm_is_running_sanlock(void);
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes);
int lm_vg_status_sanlock(struct lockspace *ls, struct action *act);
void lm_set_host_dead_sanlock(struct lockspace *ls, struct owner *owner);
int lm_setlockargs_supported_sanlock(struct lockspace *ls, struct action *act);
int lm_setlockargs_vg_sanlock(char *ls_name, char *vg_name, struct action *act);
static inline int lm_support_sanlock(void)
{
@@ -592,7 +635,7 @@ static inline int lm_support_sanlock(void)
#else
static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb)
static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb, char *other_args)
{
return -1;
}
@@ -706,6 +749,20 @@ static inline int lm_support_sanlock(void)
return 0;
}
void lm_set_host_dead_sanlock(struct lockspace *ls, struct owner *owner)
{
}
int lm_setlockargs_supported_sanlock(struct lockspace *ls, struct action *act)
{
return 0;
}
int lm_setlockargs_vg_sanlock(char *ls_name, char *vg_name, struct action *act)
{
return 0;
}
#endif /* sanlock support */
#ifdef LOCKDIDM_SUPPORT

View File

@@ -175,30 +175,32 @@ int lm_data_size_sanlock(void)
}
/*
* lock_args format
* If a new variant of the lock_args string cannot be
* handled by the previous version of lvmlockd, then the
* new variant should contain a larger major number.
*
* vg_lock_args format for sanlock is
* vg_version_string:undefined:lock_lv_name
* VG_LOCK_ARGS_V1 format:
* 1.0.0:lvname
*
* lv_lock_args format for sanlock is
* lv_version_string:undefined:offset
*
* version_string is MAJOR.MINOR.PATCH
* undefined may contain ":"
*
* If a new version of the lock_args string cannot be
* handled by an old version of lvmlockd, then the
* new lock_args string should contain a larger major number.
* VG_LOCK_ARGS_V2 format:
* 2.0.0:lvname:notimeout:persist
* 2.0.0:lvname:notimeout
* 2.0.0:lvname:persist
*/
#define VG_LOCK_ARGS_MAJOR 1
#define VG_LOCK_ARGS_MAJOR 2
#define VG_LOCK_ARGS_MINOR 0
#define VG_LOCK_ARGS_PATCH 0
#define VG_LOCK_ARGS_V1 "1.0.0"
#define VG_LOCK_ARGS_V2 "2.0.0"
#define LV_LOCK_ARGS_MAJOR 1
#define LV_LOCK_ARGS_MINOR 0
#define LV_LOCK_ARGS_PATCH 0
#define LV_LOCK_ARGS_V1 "1.0.0"
/*
* offset 0 is lockspace
* offset align_size * 1 is unused
@@ -241,9 +243,31 @@ static void strcpy_name_len(char *buf, const char *str, size_t len)
memccpy(buf, str, 0, len);
}
static int lock_lv_name_from_args(char *vg_args, char *lock_lv_name)
/*
* copy out lvname from lock_args string:
* 1.0.0:lvname
* 2.0.0:lvname
* 2.0.0:lvname:other
*/
static int lockd_lockargs_get_locklv(char *vg_args, char *lock_lv_name)
{
return last_string_from_args(vg_args, lock_lv_name);
char args[MAX_ARGS+1] = {0};
char *p, *name;
strncpy(args, vg_args, MAX_ARGS);
if (!(p = strchr(args, ':')))
return -1;
name = p+1;
if (!*name)
return -1;
if ((p = strchr(name, ':')))
*p = '\0';
strncpy(lock_lv_name, name, MAX_ARGS);
return 0;
}
static int lock_lv_offset_from_args(char *lv_args, uint64_t *lock_lv_offset)
@@ -269,7 +293,7 @@ static int check_args_version(char *args, unsigned int our_major)
unsigned int major = 0;
int rv;
rv = version_from_args(args, &major, NULL, NULL);
rv = lockd_lockargs_get_version(args, &major, NULL, NULL);
if (rv < 0) {
log_error("check_args_version %s error %d", args, rv);
return rv;
@@ -333,13 +357,13 @@ out:
}
#if LOCKDSANLOCK_SUPPORT >= 410
static int read_info_file(struct lockspace *ls, uint32_t *host_id, uint64_t *generation, int *sector_size, int *align_size)
static int read_info_file(char *vg_name, uint32_t *host_id, uint64_t *generation, int *sector_size, int *align_size, int *no_timeout)
{
char line[MAX_LINE];
char path[PATH_MAX] = { 0 };
FILE *fp;
if (dm_snprintf(path, sizeof(path), "/var/lib/lvm/lvmlockd_info_%s", ls->vg_name) < 0)
if (dm_snprintf(path, sizeof(path), "/var/lib/lvm/lvmlockd_info_%s", vg_name) < 0)
return -1;
if (!(fp = fopen(path, "r"))) {
@@ -362,11 +386,14 @@ static int read_info_file(struct lockspace *ls, uint32_t *host_id, uint64_t *gen
} else if (!strncmp(line, "align_size ", 11)) {
if (sscanf(line, "align_size %d", align_size) != 1)
goto fail;
} else if (!strncmp(line, "no_timeout ", 11)) {
if (sscanf(line, "no_timeout %d", no_timeout) != 1)
goto fail;
}
}
_fclose(fp, path);
log_debug("info file: read %u %llu %d %d", *host_id, (unsigned long long)*generation, *sector_size, *align_size);
log_debug("info file: read %u %llu %d %d %d", *host_id, (unsigned long long)*generation, *sector_size, *align_size, *no_timeout);
return 0;
fail:
@@ -376,14 +403,13 @@ fail:
}
#endif
static int write_info_file(struct lockspace *ls)
static int write_info_file(char *vg_name, uint32_t host_id, uint64_t generation, int sector_size, int align_size, int no_timeout)
{
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
char path[PATH_MAX] = { 0 };
FILE *fp;
time_t t = time(NULL);
if (dm_snprintf(path, sizeof(path), "/var/lib/lvm/lvmlockd_info_%s", ls->vg_name) < 0)
if (dm_snprintf(path, sizeof(path), "/var/lib/lvm/lvmlockd_info_%s", vg_name) < 0)
return -1;
if (!(fp = fopen(path, "w"))) {
@@ -391,17 +417,38 @@ static int write_info_file(struct lockspace *ls)
return -1;
}
fprintf(fp, "# vg %s %s created %s", ls->vg_name, ls->vg_uuid, ctime(&t));
fprintf(fp, "host_id %u\n", ls->host_id);
fprintf(fp, "generation %llu\n", (unsigned long long)ls->generation);
fprintf(fp, "sector_size %d\n", lms->sector_size);
fprintf(fp, "align_size %d\n", lms->align_size);
fprintf(fp, "# vg %s created %s", vg_name, ctime(&t));
fprintf(fp, "host_id %u\n", host_id);
fprintf(fp, "generation %llu\n", (unsigned long long)generation);
fprintf(fp, "sector_size %d\n", sector_size);
fprintf(fp, "align_size %d\n", align_size);
fprintf(fp, "no_timeout %d\n", no_timeout);
if (fflush(fp))
log_warn("Failed to write/flush %s", path);
_fclose(fp, path);
log_debug("info file: wrote %u %llu %d %d", ls->host_id, (unsigned long long)ls->generation, lms->sector_size, lms->align_size);
log_debug("info file: wrote %u %llu %d %d %d", host_id, (unsigned long long)generation, sector_size, align_size, no_timeout);
return 0;
}
static int update_info_file(char *vg_name, int no_timeout_new)
{
uint32_t host_id;
uint64_t generation;
int sector_size;
int align_size;
int no_timeout;
int rv;
rv = read_info_file(vg_name, &host_id, &generation, &sector_size, &align_size, &no_timeout);
if (rv < 0)
return rv;
rv = write_info_file(vg_name, host_id, generation, sector_size, align_size, no_timeout_new);
if (rv < 0)
return rv;
return 0;
}
@@ -591,7 +638,7 @@ static int _lease_corrupt_error(int rv)
sanlock encoded this in the lockspace/resource structs on disk. */
static int read_lockspace_info(char *path, uint32_t host_id, int *sector_size, int *align_size, int *align_mb,
uint32_t *ss_flags, uint32_t *rs_flags, struct sanlk_host *hs)
uint32_t *ss_size_flags, uint32_t *rs_size_flags, int *no_timeout, struct sanlk_host *hs)
{
struct sanlk_lockspace ss;
uint32_t io_timeout = 0;
@@ -623,40 +670,43 @@ static int read_lockspace_info(char *path, uint32_t host_id, int *sector_size, i
*sector_size = 4096;
*align_mb = 8;
*align_size = 8 * ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M;
*ss_size_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M;
*rs_size_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M;
} else if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN4M)) {
*sector_size = 4096;
*align_mb = 4;
*align_size = 4 * ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN4M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN4M;
*ss_size_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN4M;
*rs_size_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN4M;
} else if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN2M)) {
*sector_size = 4096;
*align_mb = 2;
*align_size = 2 * ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN2M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN2M;
*ss_size_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN2M;
*rs_size_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN2M;
} else if ((ss.flags & SANLK_LSF_SECTOR4K) && (ss.flags & SANLK_LSF_ALIGN1M)) {
*sector_size = 4096;
*align_mb = 1;
*align_size = ONE_MB;
*ss_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN1M;
*rs_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN1M;
*ss_size_flags = SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN1M;
*rs_size_flags = SANLK_RES_SECTOR4K | SANLK_RES_ALIGN1M;
} else if ((ss.flags & SANLK_LSF_SECTOR512) && (ss.flags & SANLK_LSF_ALIGN1M)) {
*sector_size = 512;
*align_mb = 1;
*align_size = ONE_MB;
*ss_flags = SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M;
*rs_flags = SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M;
*ss_size_flags = SANLK_LSF_SECTOR512 | SANLK_LSF_ALIGN1M;
*rs_size_flags = SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M;
}
log_debug("read_lockspace_info %s %u found sector_size %d align_size %d",
path, host_id, *sector_size, *align_size);
if (ss.flags & SANLK_LSF_NO_TIMEOUT)
*no_timeout = 1;
log_debug("read_lockspace_info %s %u found sector_size %d align_size %d no_timeout %d",
path, host_id, *sector_size, *align_size, *no_timeout);
return 0;
}
@@ -670,43 +720,45 @@ static int read_lockspace_info(char *path, uint32_t host_id, int *sector_size, i
#define MAX_VERSION 16
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb)
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb, char *other_args)
{
struct sanlk_lockspace ss;
struct sanlk_resourced rd;
struct sanlk_disk disk;
char lock_lv_name[MAX_ARGS+1];
char lock_args_version[MAX_VERSION+1];
const char *gl_name = NULL;
uint32_t lock_args_flags = 0;
uint32_t rs_flags;
uint32_t daemon_version;
uint32_t daemon_proto;
uint64_t offset;
uint64_t dev_size;
int no_timeout;
int persist;
int sector_size = 0;
int align_size = 0;
int align_mb = 0;
int i, rv;
if (other_args && !lockd_lockargs_get_user_flags(other_args, &lock_args_flags)) {
log_error("S %s init_vg_san unknown other args %s", ls_name, other_args);
return -EARGS;
}
no_timeout = (lock_args_flags & LOCKARGS_NOTIMEOUT) ? 1 :0;
persist = (lock_args_flags & LOCKARGS_PERSIST) ? 1 : 0;
memset(&ss, 0, sizeof(ss));
memset(&rd, 0, sizeof(rd));
memset(&disk, 0, sizeof(disk));
memset(lock_args_version, 0, sizeof(lock_args_version));
if (!vg_args || !vg_args[0] || !strcmp(vg_args, "none")) {
log_error("S %s init_vg_san vg_args missing", ls_name);
return -EARGS;
}
snprintf(lock_args_version, MAX_VERSION, "%u.%u.%u",
VG_LOCK_ARGS_MAJOR, VG_LOCK_ARGS_MINOR, VG_LOCK_ARGS_PATCH);
/* see comment above about input vg_args being only lock_lv_name */
dm_strncpy(lock_lv_name, vg_args, sizeof(lock_lv_name));
if (strlen(lock_lv_name) + strlen(lock_args_version) + 2 > MAX_ARGS)
return -EARGS;
if ((rv = build_dm_path(disk.path, SANLK_PATH_LEN, vg_name, lock_lv_name)))
return rv;
@@ -715,7 +767,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
if (daemon_test) {
if (!gl_lsname_sanlock[0])
strncpy(gl_lsname_sanlock, ls_name, MAX_NAME);
rv = snprintf(vg_args, MAX_ARGS, "%s:%s", lock_args_version, lock_lv_name);
rv = snprintf(vg_args, MAX_ARGS, "%s:%s", VG_LOCK_ARGS_V1, lock_lv_name);
if (rv >= MAX_ARGS)
log_debug("init_vg_san vg_args may be too long %d %s", rv, vg_args);
return 0;
@@ -787,6 +839,9 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
return -EARGS;
}
if (no_timeout)
ss.flags |= SANLK_LSF_NO_TIMEOUT;
rv = sanlock_write_lockspace(&ss, 0, 0, sanlock_io_timeout);
if (rv < 0) {
log_error("S %s init_vg_san write_lockspace error %d %s",
@@ -841,15 +896,6 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
return rv;
}
if (!strcmp(gl_name, R_NAME_GL))
dm_strncpy(gl_lsname_sanlock, ls_name, sizeof(gl_lsname_sanlock));
rv = snprintf(vg_args, MAX_ARGS, "%s:%s", lock_args_version, lock_lv_name);
if (rv >= MAX_ARGS)
log_debug("init_vg_san vg_args may be too long %d %s", rv, vg_args);
log_debug("S %s init_vg_san done vg_args %s", ls_name, vg_args);
/*
* Go through all lv resource slots and initialize them with the
* correct lockspace name but a special resource name that indicates
@@ -888,6 +934,25 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
offset += align_size;
}
if (no_timeout && persist)
rv = snprintf(vg_args, MAX_ARGS, "%s:%s:notimeout:persist", VG_LOCK_ARGS_V2, lock_lv_name);
else if (no_timeout)
rv = snprintf(vg_args, MAX_ARGS, "%s:%s:notimeout", VG_LOCK_ARGS_V2, lock_lv_name);
else if (persist)
rv = snprintf(vg_args, MAX_ARGS, "%s:%s:persist", VG_LOCK_ARGS_V2, lock_lv_name);
else
rv = snprintf(vg_args, MAX_ARGS, "%s:%s", VG_LOCK_ARGS_V1, lock_lv_name);
if (rv >= MAX_ARGS) {
log_error("S %s init_vg_san vg_args string too long %d %s", ls_name, rv, vg_args);
return -EINVAL;
}
if (!strcmp(gl_name, R_NAME_GL))
dm_strncpy(gl_lsname_sanlock, ls_name, sizeof(gl_lsname_sanlock));
log_debug("S %s init_vg_san done vg_args %s", ls_name, vg_args);
return 0;
}
@@ -905,12 +970,12 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
struct lm_sanlock *lms;
struct sanlk_resourced rd;
char lock_lv_name[MAX_ARGS+1];
char lock_args_version[MAX_VERSION+1];
uint64_t offset;
uint64_t prev_offset = 0;
int sector_size = 0;
int align_size = 0;
int align_mb;
int no_timeout = 0;
uint32_t ss_flags;
uint32_t rs_flags = 0;
uint32_t tries = 1;
@@ -918,24 +983,20 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
memset(&rd, 0, sizeof(rd));
memset(lock_lv_name, 0, sizeof(lock_lv_name));
memset(lock_args_version, 0, sizeof(lock_args_version));
memset(disk_path, 0, sizeof(disk_path));
snprintf(lock_args_version, MAX_VERSION, "%u.%u.%u",
LV_LOCK_ARGS_MAJOR, LV_LOCK_ARGS_MINOR, LV_LOCK_ARGS_PATCH);
if (daemon_test) {
align_size = 1024 * 1024;
snprintf(lv_args, MAX_ARGS, "%s:%llu",
lock_args_version,
LV_LOCK_ARGS_V1,
(unsigned long long)((align_size * LV_LOCK_BEGIN) + (align_size * daemon_test_lv_count)));
daemon_test_lv_count++;
return 0;
}
rv = lock_lv_name_from_args(vg_args, lock_lv_name);
rv = lockd_lockargs_get_locklv(vg_args, lock_lv_name);
if (rv < 0) {
log_error("S %s init_lv_san lock_lv_name_from_args error %d %s",
log_error("S %s init_lv_san lockd_lockargs_get_locklv error %d %s",
ls_name, rv, vg_args);
return rv;
}
@@ -957,7 +1018,7 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
/* using host_id 1 to get sizes since we don't need host-specific info */
rv = read_lockspace_info(disk_path, 1, &sector_size, &align_size, &align_mb, &ss_flags, &rs_flags, NULL);
rv = read_lockspace_info(disk_path, 1, &sector_size, &align_size, &align_mb, &ss_flags, &rs_flags, &no_timeout, NULL);
if (rv < 0) {
log_error("S %s init_lv_san read_lockspace_info error %d %s",
ls_name, rv, disk_path);
@@ -1025,7 +1086,7 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
if (!rv) {
snprintf(lv_args, MAX_ARGS, "%s:%llu",
lock_args_version, (unsigned long long)offset);
LV_LOCK_ARGS_V1, (unsigned long long)offset);
} else {
log_error("S %s init_lv_san write error %d offset %llu",
ls_name, rv, (unsigned long long)rv);
@@ -1065,9 +1126,9 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_
return -EINVAL;
}
rv = lock_lv_name_from_args(vg_args, lock_lv_name);
rv = lockd_lockargs_get_locklv(vg_args, lock_lv_name);
if (rv < 0) {
log_error("S %s init_lv_san lock_lv_name_from_args error %d %s",
log_error("S %s init_lv_san lockd_lockargs_get_locklv error %d %s",
ls_name, rv, vg_args);
return rv;
}
@@ -1587,6 +1648,7 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation
int sector_size = 0;
int align_size = 0;
int align_mb = 0;
int no_timeout = 0;
int retries = 0;
int gl_found;
int ret, rv;
@@ -1612,9 +1674,9 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation
goto fail;
}
rv = lock_lv_name_from_args(ls->vg_args, lock_lv_name);
rv = lockd_lockargs_get_locklv(ls->vg_args, lock_lv_name);
if (rv < 0) {
log_error("S %s prepare_lockspace_san lock_lv_name_from_args error %d %s",
log_error("S %s prepare_lockspace_san lockd_lockargs_get_locklv error %d %s",
ls->name, rv, ls->vg_args);
ret = -EARGS;
goto fail;
@@ -1711,15 +1773,16 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation
#endif
sector_size = 0;
align_size = 0;
no_timeout = 0;
rv = read_lockspace_info(disk_path, lms->ss.host_id, &sector_size, &align_size, &align_mb, &ss_flags, &rs_flags, &hs);
rv = read_lockspace_info(disk_path, lms->ss.host_id, &sector_size, &align_size, &align_mb, &ss_flags, &rs_flags, &no_timeout, &hs);
#if LOCKDSANLOCK_SUPPORT >= 410
if ((rv == -ELOCKREPAIR) && repair && !retries) {
uint64_t generation = 0;
uint32_t host_id = 0;
rv = read_info_file(ls, &host_id, &generation, &sector_size, &align_size);
rv = read_info_file(ls->vg_name, &host_id, &generation, &sector_size, &align_size, &no_timeout);
if (rv < 0) {
log_error("S %s prepare_lockspace_san cannot repair lockspace no info file", lsname);
ret = -EINVAL;
@@ -1750,6 +1813,9 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation
ret = -EINVAL;
}
if (no_timeout)
lms->ss.flags |= SANLK_LSF_NO_TIMEOUT;
log_debug("S %s prepare_lockspace_san repair host %u lease", lsname, host_id);
rv = sanlock_init_lockspace_host(&lms->ss, NULL, generation, 0, 0, 0);
@@ -1899,7 +1965,7 @@ int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok,
free(hs);
write_info_file(ls);
write_info_file(ls->vg_name, ls->host_id, ls->generation, lms->sector_size, lms->align_size, ls->no_timeout);
/*
* Don't let the lockspace be cleanly released if orphan locks
@@ -2203,6 +2269,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
rv == SANLK_ACQUIRE_OWNED ||
rv == SANLK_ACQUIRE_OTHER ||
rv == SANLK_ACQUIRE_OWNED_RETRY ||
rv == SANLK_ACQUIRE_OWNED_NO_TIMEOUT ||
rv == -EAGAIN) {
/*
@@ -2231,6 +2298,9 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
if (rv == SANLK_ACQUIRE_OWNED_RETRY)
*retry = 0;
if (rv == SANLK_ACQUIRE_OWNED_NO_TIMEOUT)
*retry = 0;
if (owner && owner_host.host_id) {
const char *host_state;
@@ -2421,6 +2491,7 @@ int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
case SANLK_ACQUIRE_IDLIVE:
case SANLK_ACQUIRE_OWNED:
case SANLK_ACQUIRE_OWNED_RETRY:
case SANLK_ACQUIRE_OWNED_NO_TIMEOUT:
case SANLK_ACQUIRE_OTHER:
case SANLK_AIO_TIMEOUT:
/* expected errors from known/normal cases like lock contention or io timeouts */
@@ -2729,3 +2800,137 @@ int lm_is_running_sanlock(void)
return 1;
}
void lm_set_host_dead_sanlock(struct lockspace *ls, struct owner *owner)
{
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
struct sanlk_host host = { 0 };
int rv;
log_debug("S %s set_host_dead_sanlock host_id %u gen %u", ls->name, owner->host_id, owner->generation);
host.host_id = owner->host_id;
host.generation = owner->generation;
rv = sanlock_set_host(&lms->ss, SANLK_SET_HOST_DEAD_EXT, 0, 0, &host);
if (rv < 0)
log_error("S %s set_host_dead_sanlock host_id %u gen %u error %d", ls->name, owner->host_id, owner->generation, rv);
}
int lm_setlockargs_supported_sanlock(struct lockspace *ls, struct action *act)
{
uint32_t daemon_version;
uint32_t daemon_proto;
uint32_t lock_args_flags = 0;
uint32_t ver_major, ver_minor;
int rv;
if (!lockd_lockargs_get_user_flags(act->other_args, &lock_args_flags)) {
log_error("S %s setlockargs_supported invalid user lock args %s", ls->name, act->other_args);
return 0;
}
if (!(lock_args_flags & LOCKARGS_NOTIMEOUT) && !(lock_args_flags & LOCKARGS_PERSIST))
return 1;
rv = sanlock_version(0, &daemon_version, &daemon_proto);
if (rv < 0) {
log_error("S %s setlockargs failed to connect to sanlock daemon", ls->name);
return 0;
}
log_debug("S %s setlockargs sanlock version 0x%x lock_args_flags 0x%x", ls->name, daemon_version, lock_args_flags);
ver_major = (daemon_version & 0xFF000000) >> 24;
ver_minor = (daemon_version & 0x00FF0000) >> 16;
/* sanlock 4.1.0 added support for LOCKARGS_NOTIMEOUT or LOCKARGS_PERSIST. */
if (ver_major < 4)
return 0;
if ((ver_major == 4) && (ver_minor < 1))
return 0;
return 1;
}
int lm_setlockargs_vg_sanlock(char *ls_name, char *vg_name, struct action *act)
{
struct sanlk_lockspace ss = {0};
char lock_lv_name[MAX_ARGS+1] = {0};
char disk_path[SANLK_PATH_LEN] = {0};
uint32_t ss_size_flags = 0;
uint32_t rs_size_flags = 0;
uint32_t lock_args_flags = 0;
int sector_size = 0;
int align_size = 0;
int align_mb = 0;
int no_timeout;
int persist;
int rv;
if (!lockd_lockargs_get_user_flags(act->other_args, &lock_args_flags)) {
log_error("S %s setlockargs invalid user lock args %s", ls_name, act->other_args);
return 0;
}
rv = lockd_lockargs_get_locklv(act->vg_args, lock_lv_name);
if (rv < 0) {
log_error("S %s setlockargs lockd_lockargs_get_locklv error %d %s",
ls_name, rv, act->vg_args);
return rv;
}
if ((rv = build_dm_path(disk_path, SANLK_PATH_LEN, vg_name, lock_lv_name)))
return rv;
/* get the sector and align flags from host_id 1 in the current lockspace */
rv = read_lockspace_info(disk_path, 1, &sector_size, &align_size, &align_mb, &ss_size_flags, &rs_size_flags, &no_timeout, NULL);
if (rv < 0) {
log_error("S %s setlockargs read_lockspace_info error %d %s", ls_name, rv, disk_path);
return rv;
}
/* initialize lockspace */
no_timeout = (lock_args_flags & LOCKARGS_NOTIMEOUT) ? 1 :0;
persist = (lock_args_flags & LOCKARGS_PERSIST) ? 1 : 0;
strcpy_name_len(ss.name, ls_name, SANLK_NAME_LEN);
memcpy(ss.host_id_disk.path, disk_path, SANLK_PATH_LEN);
ss.host_id_disk.offset = 0;
ss.flags = ss_size_flags;
if (no_timeout)
ss.flags |= SANLK_LSF_NO_TIMEOUT;
log_debug("S %s setlockargs write_lockspace no_timeout %d flags 0x%x", ls_name, no_timeout, ss.flags);
rv = sanlock_write_lockspace(&ss, 0, 0, sanlock_io_timeout);
if (rv < 0) {
log_error("S %s setlockargs write_lockspace error %d %s", ls_name, rv, ss.host_id_disk.path);
return rv;
}
update_info_file(vg_name, no_timeout);
if (no_timeout && persist)
rv = snprintf(act->vg_args, MAX_ARGS, "%s:%s:notimeout:persist", VG_LOCK_ARGS_V2, lock_lv_name);
else if (no_timeout)
rv = snprintf(act->vg_args, MAX_ARGS, "%s:%s:notimeout", VG_LOCK_ARGS_V2, lock_lv_name);
else if (persist)
rv = snprintf(act->vg_args, MAX_ARGS, "%s:%s:persist", VG_LOCK_ARGS_V2, lock_lv_name);
else
rv = snprintf(act->vg_args, MAX_ARGS, "%s:%s", VG_LOCK_ARGS_V1, lock_lv_name);
log_debug("S %s setlockargs new args %s", ls_name, act->vg_args);
if (rv >= MAX_ARGS) {
log_error("S %s setlockargs vg_args string too long %d %s", ls_name, rv, act->vg_args);
return -EINVAL;
}
return 0;
}

View File

@@ -72,7 +72,6 @@ incorrectly!
Make one by running `pvcreate /dev/sdX`.
See [pvcreate(8)](https://man7.org/linux/man-pages/man8/pvcreate.8.html). This step is optional.
* Volume Group (VG) consisting of one or more PVs is used as a pool from which LVs are allocated.
List VGs using [vgs(8)](https://man7.org/linux/man-pages/man8/vgs.8.html) or
[vgdisplay(8)](https://man7.org/linux/man-pages/man8/vgdisplay.8.html).
@@ -81,34 +80,27 @@ incorrectly!
To use LVM at least one Volume Group must be present on the system.
See [vgcreate(8)](https://man7.org/linux/man-pages/man8/vgcreate.8.html), and
[vgextend(8)](https://man7.org/linux/man-pages/man8/vgextend.8.html).
* Logical Volume (LV) is the block device usually visible to user to be used for file system.
List LVs using [lvs(8)](https://man7.org/linux/man-pages/man8/lvs.8.html) or
List PVs using [lvs(8)](https://man7.org/linux/man-pages/man8/lvs.8.html) or
[lvdisplay(8)](https://man7.org/linux/man-pages/man8/lvdisplay.8.html).
Make one by running `lvcreate [-n LVNAME] -L SIZE VGNAME`, and you are done!
See [lvcreate(8)](https://man7.org/linux/man-pages/man8/lvcreate.8.html).
To change size of LV it is recommended to use [lvresize(8)](https://man7.org/linux/man-pages/man8/lvresize.8.html) with `--resizefs` option.
To change properties of LV (e.g. to acivate/deactivate a volume, or change it to read only) use [lvchange(8)](https://man7.org/linux/man-pages/man8/lvchange.8.html).
To change the type of LV (e.g. change a linear volume to a RAID) use [lvconvert(8)](https://man7.org/linux/man-pages/man8/lvconvert.8.html).
See [vgcreate(8)](https://man7.org/linux/man-pages/man8/vgcreate.8.html).
## Avoiding Problems
Good start is to **avoid using `{--force|-f}` and `{--yes|-y}` options** which are
Good start is to avoid using `{--force|-f}` and `{--yes|-y}` options which are
often seen on internet discussions.
there is a possibility of data loss, LVM tools usually ask, so read the prompts
carefully! Using `--yes` removes these safety.
Also in some cases where it is too dangerous to proceed, e.g. device is used,
LVM refuses to do so, which can be overridden by `--force`.
Second, when **resizing** and especially when shrinking LVs it is always a good
idea to **use `--resizefs` option** which ensures the devices are resized in
Second, when resizing and especially when shrinking LVs it is always a good
idea to use `--resizefs` option which ensures the devices are resized in
correct order.
Third, if you still make a mess, **never ever run fsck on damaged LV/FS**, this is
Third, if you still make a mess, never ever run fsck on damaged LV/FS, this is
usually the final blow to your data. It is always better to ask first!

View File

@@ -2280,7 +2280,7 @@ cfg(local_system_id_CFG, "system_id", local_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_D
"#\n")
cfg(local_pr_key_CFG, "pr_key", local_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, 0, vsn(2, 3, 32), NULL, 0, NULL,
"The local persistent reservation key in hexadecimal.\n"
"The local persistent reservation key in hexidecimal.\n"
"The value must be unique among all hosts using the same VG.\n"
"The max length is 16 hex characters (8 bytes), plus an optional\n"
"0x prefix. If pr_key is not set, host_id will be used to create a key.\n")

View File

@@ -813,7 +813,7 @@ int vg_is_registered(struct cmd_context *cmd, struct volume_group *vg, uint64_t
}
}
int persist_is_started(struct cmd_context *cmd, struct volume_group *vg, int may_fail)
int persist_is_started(struct cmd_context *cmd, struct volume_group *vg, int may_fail, uint64_t *our_key_ret)
{
struct pv_list *pvl;
struct device *dev;
@@ -826,6 +826,9 @@ int persist_is_started(struct cmd_context *cmd, struct volume_group *vg, int may
if (!vg_is_registered(cmd, vg, &our_key_val, &partial))
goto out;
if (our_key_ret)
*our_key_ret = our_key_val;
if (partial) {
log_debug("PR is started: partial");
goto out;
@@ -1053,7 +1056,7 @@ static int get_our_key_sanlock_start(struct cmd_context *cmd, struct volume_grou
/*
* Called after sanlock lockstart to check if a registered PR key contains the
* latest generation number (from sanlock) for the host, and if not to update
* the PR key. The sanlock lockstart actually returns the previous generation
* the PR key. The sanlock lockstart atually returns the previous generation
* number that was used for this host_id in the lockspace, and we expect that
* the next generation number just will be +1.
*
@@ -1166,6 +1169,8 @@ int persist_key_update(struct cmd_context *cmd, struct volume_group *vg, uint32_
return 0;
}
/* TODO: send new key to lvmlockd, e.g. call lockd_vg_is_started() and have that include our key */
log_debug("persist_key_update: updated 0x%llx to %s", (unsigned long long)our_key_val, new_key_buf);
return 1;
}
@@ -1567,78 +1572,23 @@ static int _run_stop(struct cmd_context *cmd, struct volume_group *vg, struct dm
}
/*
* For vgremove, separate persist_stop into before and after parts:
* - before cannot happen after normal vgremove, because the list
* Separate persist_stop_prepare() and persist_stop_run() is needed
* for vgremove, where prepare is needed before the normal vgremove,
* and run should happen after the normal vgremove.
* - prepare cannot happen after normal vgremove, because the list
* of PVs is no longer available.
* - after cannot happen before normal vgremove, because removing the
* - run cannot happen before normal vgremove, because removing the
* reservation will prevent writing metadata for normal vgremove if
* another host has a PR key registered (which may not happen in the
* normal usage pattern, but is still possible.)
*/
int persist_vgremove_before(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char **key)
int persist_stop_prepare(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char **key)
{
char *local_key = (char *)find_config_tree_str(cmd, local_pr_key_CFG, NULL);
int local_host_id = find_config_tree_int(cmd, local_host_id_CFG, NULL);
char our_key_buf[PR_KEY_BUF_SIZE] = { 0 };
uint64_t our_key_val = 0;
if (!local_key && !local_host_id)
return 1;
if (!get_our_key(cmd, vg, local_key, local_host_id, our_key_buf, &our_key_val))
return_0;
/*
* When removing a shared VG, verify that other hosts
* have stopped PR to avoid leaving dangling reservations.
*/
if (vg_is_shared(vg)) {
struct pv_list *pvl;
struct device *dev;
int found_key_count;
dm_list_iterate_items(pvl, &vg->pvs) {
if (!(dev = pvl->pv->dev))
continue;
found_key_count = 0;
if (!dev_find_key(cmd, dev, 0, 0, NULL, 0, NULL, 1, &found_key_count, NULL)) {
/* shouldn't happen */
log_error("Failed to get PR keys from %s", dev_name(dev));
return 0;
}
if (found_key_count > 1) {
log_error("Found %d PR keys on %s", found_key_count, dev_name(dev));
log_error("Stop PR for VG %s on other hosts (vgchange --persist stop)", vg->name);
return 0;
}
}
}
if (!pv_list_to_dev_list(cmd->mem, &vg->pvs, devs))
return_0;
if (!(*key = dm_pool_strdup(cmd->mem, our_key_buf)))
return_0;
return 1;
}
void persist_vgremove_after(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char *key)
{
_run_stop(cmd, vg, devs, key, 0);
persist_key_file_remove(cmd, vg);
}
int persist_stop(struct cmd_context *cmd, struct volume_group *vg)
{
DM_LIST_INIT(devs);
char *local_key = (char *)find_config_tree_str(cmd, local_pr_key_CFG, NULL);
int local_host_id = find_config_tree_int(cmd, local_host_id_CFG, NULL);
char our_key_buf[PR_KEY_BUF_SIZE] = { 0 };
uint64_t our_key_val = 0;
uint32_t cur_gen = 0;
if (!local_key && !local_host_id)
@@ -1652,15 +1602,34 @@ int persist_stop(struct cmd_context *cmd, struct volume_group *vg)
if (!get_our_key(cmd, vg, local_key, local_host_id, our_key_buf, &our_key_val))
return_0;
if (!pv_list_to_dev_list(cmd->mem, &vg->pvs, &devs))
if (!pv_list_to_dev_list(cmd->mem, &vg->pvs, devs))
return_0;
if (!_run_stop(cmd, vg, &devs, our_key_buf, 0))
if (!(*key = dm_pool_strdup(cmd->mem, our_key_buf)))
return_0;
return 1;
}
int persist_stop_run(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char *key)
{
if (!_run_stop(cmd, vg, devs, key, 0))
return_0;
return 1;
}
int persist_stop(struct cmd_context *cmd, struct volume_group *vg)
{
DM_LIST_INIT(devs);
char *key = NULL;
if (!persist_stop_prepare(cmd, vg, &devs, &key))
return_0;
if (!persist_stop_run(cmd, vg, &devs, key))
return_0;
return 1;
}
static int _persist_extend_shared(struct cmd_context *cmd, struct volume_group *vg,
uint64_t our_key_val, struct device *check_dev)
{
@@ -1794,6 +1763,117 @@ static int _persist_extend_shared(struct cmd_context *cmd, struct volume_group *
return error ? 0 : 1;
}
int persist_upgrade_stop(struct cmd_context *cmd, struct volume_group *vg, uint64_t our_key_val)
{
DM_LIST_INIT(devs);
char our_key_buf[PR_KEY_BUF_SIZE] = { 0 };
if (!pv_list_to_dev_list(cmd->mem, &vg->pvs, &devs))
return_0;
if (dm_snprintf(our_key_buf, PR_KEY_BUF_SIZE-1, "0x%llx", (unsigned long long)our_key_val) < 0)
return_0;
if (!_run_stop(cmd, vg, &devs, our_key_buf, 0))
return_0;
return 1;
}
/*
* Host currently holds a normal sh access PR on shared VG,
* and wants to switch to an ex access PR on that VG
* (to prevent other hosts from using it while it's making
* changes.)
*/
int persist_upgrade_ex(struct cmd_context *cmd, struct volume_group *vg, uint64_t *our_key_held)
{
DM_LIST_INIT(devs);
struct device_list *devl;
char *local_key = (char *)find_config_tree_str(cmd, local_pr_key_CFG, NULL);
int local_host_id = find_config_tree_int(cmd, local_host_id_CFG, NULL);
char our_key_buf[PR_KEY_BUF_SIZE] = { 0 };
char new_key_buf[PR_KEY_BUF_SIZE] = { 0 };
uint64_t our_key_val = 0;
uint64_t new_key_val = 0;
const char *devname;
const char **argv;
int pv_count;
int args;
int status;
if (!local_key && !local_host_id)
return 1;
if (!get_our_key(cmd, vg, local_key, local_host_id, our_key_buf, &our_key_val))
return_0;
if (!pv_list_to_dev_list(cmd->mem, &vg->pvs, &devs))
return_0;
log_debug("persist_upgrade_ex stop PR %s", our_key_buf);
if (!_run_stop(cmd, vg, &devs, our_key_buf, 0))
return_0;
if (local_key) {
new_key_val = our_key_val;
memcpy(new_key_buf, our_key_buf, PR_KEY_BUF_SIZE);
} else if (local_host_id) {
if (dm_snprintf(new_key_buf, PR_KEY_BUF_SIZE-1, "0x100000000000%04x", local_host_id) != 18) {
log_error("Failed to format key string for host_id %d", local_host_id);
return 0;
}
if (!parse_prkey(new_key_buf, &new_key_val)) {
log_error("Failed to parse generated key %s", new_key_buf);
return 0;
}
}
pv_count = dm_list_size(&devs);
log_debug("persist_upgrade_ex start PR on %d devs with local key %llx", pv_count, (unsigned long long)new_key_val);
args = 9 + pv_count*2;
if (vg->pr & VG_PR_PTPL)
args += 1;
if (!(argv = dm_pool_alloc(cmd->mem, args * sizeof(char *))))
return_0;
args = 0;
argv[0] = LVMPERSIST_PATH;
argv[++args] = "start";
argv[++args] = "--ourkey";
argv[++args] = new_key_buf;
argv[++args] = "--access";
argv[++args] = "ex";
argv[++args] = "--vg";
argv[++args] = vg->name;
if (vg->pr & VG_PR_PTPL)
argv[++args] = "--ptpl";
dm_list_iterate_items(devl, &devs) {
if (!(devname = dm_pool_strdup(cmd->mem, dev_name(devl->dev))))
return_0;
argv[++args] = "--device";
argv[++args] = devname;
}
argv[++args] = NULL;
if (!exec_cmd(cmd, argv, &status, 1)) {
log_error("persistent reservation exclusive start failed: lvmpersist command error.");
log_error("(Use vgchange --persist stop to stop PR on other hosts.");
return 0;
}
*our_key_held = new_key_val;
return 1;
}
/*
* Start PR on devices that are being used for vgcreate.
* This is somewhat awkward because it happens early in
@@ -1817,6 +1897,8 @@ int persist_vgcreate_begin(struct cmd_context *cmd, char *vg_name, char *local_k
int args;
int status;
persist_key_file_remove_name(cmd, vg_name);
if (local_key) {
if (!parse_prkey(local_key, &our_key_val)) {
log_error("Failed to parse local key %s", local_key);
@@ -1950,7 +2032,7 @@ int persist_vgcreate_update(struct cmd_context *cmd, struct volume_group *vg, ui
log_debug("stop PR on %d devs with local key %s", pv_count, our_key_buf_stop);
if (!_run_stop(cmd, vg, &devs, our_key_buf_stop, 0))
log_warn("WARNING: failed to stop PR with key %s", our_key_buf_stop);
log_warn("WARNING: failed to stop PR");
log_debug("start PR on %d devs with local key %llx", pv_count, (unsigned long long)our_key_val);
@@ -1987,6 +2069,7 @@ int persist_vgcreate_update(struct cmd_context *cmd, struct volume_group *vg, ui
return 0;
}
/* key file is an optimization, not an error condition */
if (!write_key_file(cmd, vg, our_key_val))
stack;

View File

@@ -48,9 +48,8 @@ int persist_start(struct cmd_context *cmd, struct volume_group *vg,
char *local_key, int local_host_id, const char *remkey);
int persist_stop(struct cmd_context *cmd, struct volume_group *vg);
int persist_vgremove_before(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char **key);
void persist_vgremove_after(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char *key);
int persist_stop_prepare(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char **key);
int persist_stop_run(struct cmd_context *cmd, struct volume_group *vg, struct dm_list *devs, char *key);
int persist_remove(struct cmd_context *cmd, struct volume_group *vg,
char *local_key, int local_host_id, const char *remkey);
@@ -64,7 +63,10 @@ int persist_vgcreate_begin(struct cmd_context *cmd, char *vg_name, char *local_k
uint32_t set_flags, struct dm_list *devs);
int persist_vgcreate_update(struct cmd_context *cmd, struct volume_group *vg, uint32_t set_flags);
int persist_is_started(struct cmd_context *cmd, struct volume_group *vg, int may_fail);
int persist_upgrade_ex(struct cmd_context *cmd, struct volume_group *vg, uint64_t *our_key_held);
int persist_upgrade_stop(struct cmd_context *cmd, struct volume_group *vg, uint64_t our_key_val);
int persist_is_started(struct cmd_context *cmd, struct volume_group *vg, int may_fail, uint64_t *our_key);
int persist_key_update(struct cmd_context *cmd, struct volume_group *vg, uint32_t prev_gen);

View File

@@ -117,6 +117,41 @@ void lvmlockd_disconnect(void)
_lvmlockd_connected = 0;
}
#define MAX_LOCKARGS 8
/* parse lock_args string for values that may appear in command line --setlockargs */
int lockd_lockargs_get_user_flags(const char *str, uint32_t *flags)
{
char buf[PATH_MAX];
char *argv[MAX_LOCKARGS];
int argc;
int i;
if (!str)
return 0;
dm_strncpy(buf, str, sizeof(buf));
split_line(buf, &argc, argv, MAX_LOCKARGS, ',');
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "persist"))
*flags |= LOCKARGS_PERSIST;
else if (!strcmp(argv[i], "nopersist"))
*flags |= LOCKARGS_NOPERSIST;
else if (!strcmp(argv[i], "timeout"))
*flags |= LOCKARGS_TIMEOUT;
else if (!strcmp(argv[i], "notimeout"))
*flags |= LOCKARGS_NOTIMEOUT;
else {
log_error("Unknown lockargs option value: %s", argv[i]);
return 0;
}
}
return 1;
}
/* Translate the result strings from lvmlockd to bit flags. */
static void _flags_str_to_lockd_flags(const char *flags_str, uint32_t *lockd_flags)
{
@@ -892,7 +927,7 @@ static int _init_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
return _init_vg(cmd, vg, "idm");
}
static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, int lv_lock_count)
static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, int lv_lock_count, const char *set_args)
{
daemon_reply reply;
const char *reply_str;
@@ -908,9 +943,9 @@ static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, in
int ret;
if (!_use_lvmlockd)
return 0;
return_0;
if (!_lvmlockd_connected)
return 0;
return_0;
/*
* We need the sector size to know what size to create the LV,
@@ -1014,6 +1049,7 @@ static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, in
"vg_name = %s", vg->name,
"vg_lock_type = %s", "sanlock",
"vg_lock_args = %s", vg->sanlock_lv->name,
"set_lock_args = %s", set_args ?: "none",
"align_mb = " FMTd64, (int64_t) align_size,
"opts = %s", opts ?: "none",
NULL);
@@ -1301,7 +1337,7 @@ static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
/* vgcreate */
int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
const char *lock_type, int lv_lock_count)
const char *lock_type, int lv_lock_count, const char *set_args)
{
switch (get_lock_type_from_string(lock_type)) {
case LOCK_TYPE_NONE:
@@ -1311,7 +1347,7 @@ int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
case LOCK_TYPE_DLM:
return _init_vg_dlm(cmd, vg);
case LOCK_TYPE_SANLOCK:
return _init_vg_sanlock(cmd, vg, lv_lock_count);
return _init_vg_sanlock(cmd, vg, lv_lock_count, set_args);
case LOCK_TYPE_IDM:
return _init_vg_idm(cmd, vg);
default:
@@ -1410,7 +1446,7 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
case LOCK_TYPE_CLVM:
break;
case LOCK_TYPE_SANLOCK:
persist_key_file_remove(cmd, vg);
persist_key_file_remove(cmd, vg->name);
break;
case LOCK_TYPE_DLM:
_free_vg_dlm(cmd, vg);
@@ -1437,7 +1473,7 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
* lock the vg, read/use/write the vg, unlock the vg.
*/
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists)
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, uint64_t our_key, int *exists)
{
char uuid[64] __attribute__((aligned(8)));
const char *opts = NULL;
@@ -1515,6 +1551,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists
"vg_uuid = %s", uuid[0] ? uuid : "none",
"version = " FMTd64, (int64_t) vg->seqno,
"host_id = " FMTd64, (int64_t) host_id,
"our_key = " FMTd64, (int64_t) our_key,
"opts = %s", opts ?: "none",
NULL);
_lockd_free_pv_list(&lock_pvs);
@@ -1528,6 +1565,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists
"vg_uuid = %s", uuid[0] ? uuid : "none",
"version = " FMTd64, (int64_t) vg->seqno,
"host_id = " FMTd64, (int64_t) host_id,
"our_key = " FMTd64, (int64_t) our_key,
"opts = %s", opts ?: "none",
NULL);
}
@@ -4231,7 +4269,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
* Depending on the problem that caused the rename to
* fail, it may make sense to not restart the VG here.
*/
if (!lockd_start_vg(cmd, vg, NULL))
if (!lockd_start_vg(cmd, vg, 0, NULL))
log_error("Failed to restart VG %s lockspace.", vg->name);
return 1;
}
@@ -4271,7 +4309,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
}
}
if (!lockd_start_vg(cmd, vg, NULL))
if (!lockd_start_vg(cmd, vg, 0, NULL))
log_error("Failed to start VG %s lockspace.", vg->name);
return 1;
@@ -4487,3 +4525,171 @@ void lockd_lockopt_get_flags(const char *str, uint32_t *flags)
log_warn("Ignoring unknown lockopt value: %s", argv[i]);
}
}
int lockd_setlockargs(struct cmd_context *cmd, struct volume_group *vg, const char *set_args, uint64_t *our_key_held)
{
daemon_reply reply;
const char *reply_str;
const char *vg_lock_args = NULL;
uint32_t lockd_flags = 0;
uint32_t lock_args_flags = 0;
int result;
int ret;
if (!_use_lvmlockd) {
log_error("lvmlockd is not in use.");
return 0;
}
if (!_lvmlockd_connected) {
log_error("lvmlockd is not connected.");
return 0;
}
if (!vg->lock_type || strcmp(vg->lock_type, "sanlock")) {
log_error("setlockargs is only supported for lock type sanlock.");
return 0;
}
if (!set_args)
return_0;
if (!lockd_lockargs_get_user_flags(set_args, &lock_args_flags))
return_0;
if ((lock_args_flags & LOCKARGS_PERSIST) && !(vg->pr & VG_PR_REQUIRE)) {
log_error("lockargs \"persist\" requires persistent reservation setting \"require\".");
return 0;
}
/*
* Check if other PR keys are registered, which would
* cause the persist_upgrade_ex below to fail.
*/
if (vg->pr & (VG_PR_REQUIRE | VG_PR_AUTOSTART)) {
struct pv_list *pvl;
struct device *dev;
int key_count;
dm_list_iterate_items(pvl, &vg->pvs) {
if (!(dev = pvl->pv->dev))
continue;
if (dm_list_empty(&dev->aliases))
continue;
if (!dev_find_key(cmd, dev, 0, 0, NULL, 0, NULL, 1, &key_count, NULL)) {
/* Shouldn't happen if persist_is_started already passed. */
log_error("No PR key found on %s.", dev_name(dev));
return 0;
}
if (key_count != 1) {
log_error("Found %d PR keys on %s, stop PR and lockspace on other hosts.", key_count, dev_name(dev));
log_error("(See vgchange --lockstop --persist stop.)");
return 0;
}
}
}
/*
* setlockargs_before checks that sanlock version supports
* the new set_lock_args, checks that no LV locks are held,
* checks we are the only host in the lockspace, and stops
* the lockspace.
*/
log_debug("lockd setlockargs_vg_before %s", vg->name);
reply = _lockd_send("setlockargs_vg_before",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", vg->name,
"vg_lock_type = %s", vg->lock_type,
"vg_lock_args = %s", vg->lock_args,
"set_lock_args = %s", set_args,
NULL);
if (!_lockd_result(cmd, "setlockargs_vg_before", reply, &result, &lockd_flags, NULL)) {
ret = 0;
goto out;
}
if (result == -EBUSY) {
log_error("Lockspace for \"%s\" not stopped on other hosts", vg->name);
ret = 0;
goto out;
} else if (result < 0) {
log_error("Lockspace setlockargs error %d for \"%s\"", result, vg->name);
ret = 0;
goto out;
}
daemon_reply_destroy(reply);
/*
* When the VG has the ability to use PR, change the
* current PR to an exclusive mode (WE), using a key
* with our host_id and gen 0. The exclusive PR protects
* the VG from other hosts while the locking parameters
* are being changed (since locking can't be used while
* the locking is being changed.) The lockspace is stopped
* while it's being changed. At the end of the vgchange
* setlockargs command, persist_ugprade_stop() releases
* the exclusive PR. After this, any host can do a normal
* start of PR/locking using the new lockargs.
*/
if (vg->pr & (VG_PR_REQUIRE | VG_PR_AUTOSTART)) {
if (!persist_upgrade_ex(cmd, vg, our_key_held)) {
log_error("Failed to upgrade to exclusive PR.");
log_error("Restart PR and locking to retry setlockargs.");
return 0;
}
}
/*
* setlockargs_final reformats sanlock leases on the lvmlock LV.
* The host generation numbers will all be reset back to 0, and
* the PR keys containing the gen will start over from gen 1.
* lvmlockd returns a new lock_args string that this command
* writes in VG metadata.
*/
retry_final:
log_debug("lockd setlockargs_vg_final %s", vg->name);
reply = _lockd_send("setlockargs_vg_final",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", vg->name,
"vg_lock_type = %s", vg->lock_type,
"vg_lock_args = %s", vg->lock_args,
"set_lock_args = %s", set_args,
NULL);
if (!_lockd_result(cmd, "setlockargs_vg_final", reply, &result, &lockd_flags, NULL)) {
ret = 0;
goto out;
}
if (result == -EAGAIN) {
daemon_reply_destroy(reply);
sleep(1);
goto retry_final;
}
if (!(reply_str = daemon_reply_str(reply, "vg_lock_args", NULL))) {
log_error("VG %s setlockargs failed: result %d new lock_args not returned", vg->name, result);
ret = 0;
goto out;
}
if (!(vg_lock_args = dm_pool_strdup(cmd->mem, reply_str))) {
ret = 0;
goto out;
}
log_debug("lockd setlockargs_vg %s result %d new lock_args %s", vg->name, result, vg_lock_args);
vg->lock_args = vg_lock_args;
ret = 1;
out:
daemon_reply_destroy(reply);
return ret;
}

View File

@@ -14,6 +14,7 @@
#include "libdaemon/client/config-util.h"
#include "libdaemon/client/daemon-client.h"
#include "lib/metadata/metadata-exported.h" /* is_lockd_type() */
#include "daemons/lvmlockd/lvmlockd-client.h"
#define LOCKD_SANLOCK_LV_NAME "lvmlock"
@@ -66,6 +67,7 @@
#ifdef LVMLOCKD_SUPPORT
void lockd_lockopt_get_flags(const char *str, uint32_t *flags);
int lockd_lockargs_get_user_flags(const char *str, uint32_t *flags);
struct lvresize_params;
struct lvcreate_params;
@@ -82,7 +84,8 @@ void lvmlockd_disconnect(void);
/* vgcreate/vgremove use init/free */
int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count);
int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
const char *lock_type, int lv_lock_count, const char *set_args);
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg, int changing, int yes);
void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
@@ -93,7 +96,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
/* start and stop the lockspace for a vg */
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists);
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, uint64_t our_key, int *exists);
int lockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
int lockd_start_wait(struct cmd_context *cmd);
int lockd_vg_is_started(struct cmd_context *cmd, struct volume_group *vg, uint32_t *cur_gen);
@@ -142,12 +145,19 @@ void lockd_lvcreate_done(struct cmd_context *cmd, struct volume_group *vg, struc
int lockd_lvremove_lock(struct cmd_context *cmd, struct logical_volume *lv, struct logical_volume **lv_other, int *other_unlock);
void lockd_lvremove_done(struct cmd_context *cmd, struct logical_volume *lv, struct logical_volume *lv_other, int other_unlock);
int lockd_setlockargs(struct cmd_context *cmd, struct volume_group *vg, const char *set_args, uint64_t *our_key_held);
#else /* LVMLOCKD_SUPPORT */
static inline void lockd_lockopt_get_flags(const char *str, uint32_t *flags)
{
}
static inline int lockd_lockargs_get_user_flags(const char *str, uint32_t *flags)
{
return 0;
}
static inline void lvmlockd_set_socket(const char *sock)
{
}
@@ -173,7 +183,8 @@ static inline int lvmlockd_use(void)
return 0;
}
static inline int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count)
static inline int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
const char *lock_type, int lv_lock_count, const char *set_args)
{
return 1;
}
@@ -345,6 +356,11 @@ static inline int lockd_vg_is_busy(struct cmd_context *cmd, struct volume_group
return 0;
}
static inline int lockd_setlockargs(struct cmd_context *cmd, struct volume_group *vg, const char *set_args, uint64_t *our_key_held)
{
return 0;
}
#endif /* LVMLOCKD_SUPPORT */
#endif /* _LVMLOCKD_H */

View File

@@ -2230,16 +2230,6 @@ static int _validate_lock_args_chars(const char *lock_args)
return r;
}
static int _validate_vg_lock_args(struct volume_group *vg)
{
if (!vg->lock_args || !_validate_lock_args_chars(vg->lock_args)) {
log_error(INTERNAL_ERROR "VG %s has invalid lock_args chars", vg->name);
return 0;
}
return 1;
}
/*
* For lock_type sanlock, LV lock_args are <version>:<info>
* For lock_type dlm, LV lock_args are not used, and lock_args is
@@ -2606,8 +2596,6 @@ int vg_validate(struct volume_group *vg)
r = 0;
}
if (!_validate_vg_lock_args(vg))
r = 0;
} else {
if (vg->lock_args) {
log_error(INTERNAL_ERROR "VG %s has lock_args %s without lock_type",
@@ -5150,7 +5138,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const
}
if ((vg->pr & VG_PR_REQUIRE) && (writing || activating) && !cmd->disable_pr_required) {
if (!persist_is_started(cmd, vg, 0)) {
if (!persist_is_started(cmd, vg, 0, NULL)) {
failure |= FAILED_PR_REQUIRED;
goto_bad;
}

View File

@@ -341,3 +341,4 @@ void split_line(char *buf, int *argc, char **argv, int max_args, char sep)
}
*argc = i;
}

View File

@@ -452,50 +452,50 @@ required, after which the others are optional.
(
.O_contiguous
.in +2n
.O_setactivationskip
.br
.O_persistent
.br
.O_permission
.br
.O_readahead
.br
.O_setactivationskip
.br
.O_zero
.br
.O_persistent
.br
.O_addtag
.br
.O_deltag
.br
.O_alloc
.br
.O_compression
.br
.O_deduplication
.br
.O_detachprofile
.br
.O_metadataprofile
.br
.O_setautoactivation
.br
.O_errorwhenfull
.br
.O_discards
.br
.O_cachemode
.br
.O_cachepolicy
.br
.O_cachesettings
.br
.O_compression
.br
.O_deduplication
.br
.O_deltag
.br
.O_detachprofile
.br
.O_discards
.br
.O_errorwhenfull
.br
.O_integritysettings
.O_minrecoveryrate
.br
.O_maxrecoveryrate
.br
.O_metadataprofile
.br
.O_minrecoveryrate
.br
.O_setautoactivation
.br
.O_vdosettings
.br
.O_integritysettings
.br
.O_writebehind
.br
.O_writemostly
@@ -508,11 +508,11 @@ required, after which the others are optional.
]
.br
[
.O_monitor
.O_poll
]
.br
[
.O_poll
.O_monitor
]
.br
[ COMMON_OPTIONS ]
@@ -583,11 +583,11 @@ Activate or deactivate an LV.
\fIVG\fP|\fILV\fP|\fITag\fP|\fISelect\fP\ .\|.\|.\&
.RS
[
.O_ignoreactivationskip
.O_partial
]
.br
[
.O_partial
.O_ignoreactivationskip
]
.br
[
@@ -595,7 +595,7 @@ Activate or deactivate an LV.
]
.br
[
.O_ignorelockingfailure
.O_poll
]
.br
[
@@ -603,17 +603,17 @@ Activate or deactivate an LV.
]
.br
[
.O_poll
]
.br
[
.O_readonly
.O_ignorelockingfailure
]
.br
[
.O_sysinit
]
.br
[
.O_readonly
]
.br
[ COMMON_OPTIONS ]
.RE
.
@@ -636,11 +636,11 @@ Reactivate an LV using the latest metadata.
]
.br
[
.O_monitor
.O_poll
]
.br
[
.O_poll
.O_monitor
]
.br
[ COMMON_OPTIONS ]
@@ -683,26 +683,26 @@ Start or stop processing an LV conversion.
Make the minor device number persistent for an LV.
.P
.B lvchange
.O_minor
.O_persistent
.O_minor
\fILV\fP
.RS
[
.O_activate
]
.br
[
.O_major
]
.br
[
.O_monitor
.O_activate
]
.br
[
.O_poll
]
.br
[
.O_monitor
]
.br
[ COMMON_OPTIONS ]
.RE
.P

View File

@@ -620,10 +620,6 @@ Convert LV to striped.
\fILV\fP
.RS
[
.O_interval
]
.br
[
.O_stripesize
]
.br
@@ -632,6 +628,10 @@ Convert LV to striped.
]
.br
[
.O_interval
]
.br
[
.O_stripes
]
.br
@@ -651,7 +651,7 @@ Convert LV to type mirror (also see type raid1),
\fILV\fP
.RS
[
.O_interval
.O_mirrors
]
.br
[
@@ -659,21 +659,21 @@ Convert LV to type mirror (also see type raid1),
]
.br
[
.O_mirrors
]
.br
[
.O_regionsize
]
.br
[
.O_mirrorlog
.O_interval
]
.br
[
.O_stripes
]
.br
[
.O_mirrorlog
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -691,7 +691,7 @@ Convert LV to raid or change raid layout
\fILV\fP
.RS
[
.O_interval
.O_mirrors
]
.br
[
@@ -699,11 +699,11 @@ Convert LV to raid or change raid layout
]
.br
[
.O_mirrors
.O_regionsize
]
.br
[
.O_regionsize
.O_interval
]
.br
[
@@ -726,11 +726,11 @@ Convert LV to raid1 or mirror, or change number of mirror images.
\fILV\fP
.RS
[
.O_interval
.O_regionsize
]
.br
[
.O_regionsize
.O_interval
]
.br
[
@@ -757,11 +757,11 @@ Convert raid LV to change number of stripe images.
]
.br
[
.O_stripesize
.O_regionsize
]
.br
[
.O_regionsize
.O_stripesize
]
.br
[ COMMON_OPTIONS ]
@@ -861,11 +861,15 @@ raid
Convert LV to a thin LV, using the original LV as an external origin.
.P
.B lvconvert
\fB--thinpool\fP \fILV\fP
\fB--type\fP \fBthin\fP
\fB--thinpool\fP \fILV\fP
\fILV1\fP
.RS
[
.O_thin
]
.br
[
.O_chunksize
]
.br
@@ -874,10 +878,6 @@ Convert LV to a thin LV, using the original LV as an external origin.
]
.br
[
.O_thin
]
.br
[
.O_wipesignatures
]
.br
@@ -886,10 +886,6 @@ Convert LV to a thin LV, using the original LV as an external origin.
]
.br
[
.O_metadataprofile
]
.br
[
.O_originname
]
.br
@@ -905,6 +901,10 @@ Convert LV to a thin LV, using the original LV as an external origin.
.O_poolmetadataspare
]
.br
[
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -930,6 +930,10 @@ Convert LV to a thin LV, using LV as thin-pool data volume.
\fILV1\fP
.RS
[
.O_thin
]
.br
[
.O_chunksize
]
.br
@@ -938,10 +942,6 @@ Convert LV to a thin LV, using LV as thin-pool data volume.
]
.br
[
.O_thin
]
.br
[
.O_wipesignatures
]
.br
@@ -950,10 +950,6 @@ Convert LV to a thin LV, using LV as thin-pool data volume.
]
.br
[
.O_metadataprofile
]
.br
[
.O_poolmetadata
]
.br
@@ -965,6 +961,10 @@ Convert LV to a thin LV, using LV as thin-pool data volume.
.O_poolmetadataspare
]
.br
[
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -987,16 +987,20 @@ error
Attach a cache pool to an LV, converts the LV to type cache.
.P
.B lvconvert
\fB--cachepool\fP \fILV\fP
\fB--type\fP \fBcache\fP
\fB--cachepool\fP \fILV\fP
\fILV1\fP
.RS
[
.O_chunksize
.O_cache
]
.br
[
.O_cache
.O_zero
]
.br
[
.O_chunksize
]
.br
[
@@ -1008,10 +1012,6 @@ Attach a cache pool to an LV, converts the LV to type cache.
]
.br
[
.O_zero
]
.br
[
.O_cachemetadataformat
]
.br
@@ -1028,10 +1028,6 @@ Attach a cache pool to an LV, converts the LV to type cache.
]
.br
[
.O_metadataprofile
]
.br
[
.O_poolmetadata
]
.br
@@ -1043,6 +1039,10 @@ Attach a cache pool to an LV, converts the LV to type cache.
.O_poolmetadataspare
]
.br
[
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -1068,8 +1068,8 @@ error
Attach a writecache to an LV, converts the LV to type writecache.
.P
.B lvconvert
.O_cachevol
\fB--type\fP \fBwritecache\fP
.O_cachevol
\fILV1\fP
.RS
[
@@ -1092,15 +1092,11 @@ thinpool
Attach a cache to an LV, converts the LV to type cache.
.P
.B lvconvert
.O_cachevol
\fB--type\fP \fBcache\fP
.O_cachevol
\fILV1\fP
.RS
[
.O_chunksize
]
.br
[
.O_cache
]
.br
@@ -1109,6 +1105,10 @@ Attach a cache to an LV, converts the LV to type cache.
]
.br
[
.O_chunksize
]
.br
[
.O_cachemetadataformat
]
.br
@@ -1144,16 +1144,16 @@ thinpool
Add a writecache to an LV, using a specified cache device.
.P
.B lvconvert
.O_cachedevice
\fB--type\fP \fBwritecache\fP
.O_cachedevice
\fILV1\fP
.RS
[
.O_cachesettings
.O_cachesize
]
.br
[
.O_cachesize
.O_cachesettings
]
.br
[ COMMON_OPTIONS ]
@@ -1172,8 +1172,8 @@ thinpool
Add a cache to an LV, using a specified cache device.
.P
.B lvconvert
.O_cachedevice
\fB--type\fP \fBcache\fP
.O_cachedevice
\fILV1\fP
.RS
[
@@ -1181,11 +1181,11 @@ Add a cache to an LV, using a specified cache device.
]
.br
[
.O_cachesettings
.O_cachesize
]
.br
[
.O_cachesize
.O_cachesettings
]
.br
[ COMMON_OPTIONS ]
@@ -1208,11 +1208,11 @@ Convert LV to type thin-pool (existing data on LV will be erased).
\fILV1\fP
.RS
[
.O_chunksize
.O_stripesize
]
.br
[
.O_stripesize
.O_chunksize
]
.br
[
@@ -1228,11 +1228,7 @@ Convert LV to type thin-pool (existing data on LV will be erased).
]
.br
[
.O_compression
]
.br
[
.O_deduplication
.O_stripes
]
.br
[
@@ -1244,11 +1240,19 @@ Convert LV to type thin-pool (existing data on LV will be erased).
]
.br
[
.O_metadataprofile
.O_pooldatavdo
]
.br
[
.O_pooldatavdo
.O_compression
]
.br
[
.O_deduplication
]
.br
[
.O_vdosettings
]
.br
[
@@ -1264,11 +1268,7 @@ Convert LV to type thin-pool (existing data on LV will be erased).
]
.br
[
.O_stripes
]
.br
[
.O_vdosettings
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
@@ -1297,6 +1297,10 @@ Convert LV to type cache-pool (existing data on LV will be erased).
\fILV1\fP
.RS
[
.O_zero
]
.br
[
.O_chunksize
]
.br
@@ -1309,10 +1313,6 @@ Convert LV to type cache-pool (existing data on LV will be erased).
]
.br
[
.O_zero
]
.br
[
.O_cachemetadataformat
]
.br
@@ -1329,10 +1329,6 @@ Convert LV to type cache-pool (existing data on LV will be erased).
]
.br
[
.O_metadataprofile
]
.br
[
.O_poolmetadata
]
.br
@@ -1344,6 +1340,10 @@ Convert LV to type cache-pool (existing data on LV will be erased).
.O_poolmetadataspare
]
.br
[
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -1371,11 +1371,11 @@ Convert LV to type vdopool (existing data on LV will be erased).
]
.br
[
.O_readahead
.O_virtualsize
]
.br
[
.O_virtualsize
.O_readahead
]
.br
[
@@ -1395,11 +1395,11 @@ Convert LV to type vdopool (existing data on LV will be erased).
]
.br
[
.O_metadataprofile
.O_vdosettings
]
.br
[
.O_vdosettings
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
@@ -1483,11 +1483,11 @@ origin LV (first arg) to reverse a splitsnapshot command.
\fILV\fP \fILV1\fP
.RS
[
.O_chunksize
.O_snapshot
]
.br
[
.O_snapshot
.O_chunksize
]
.br
[
@@ -1522,11 +1522,11 @@ Repair a cache pool.
]
.br
[
.O_poolmetadataspare
.O_usepolicies
]
.br
[
.O_usepolicies
.O_poolmetadataspare
]
.br
[ COMMON_OPTIONS ]
@@ -1587,7 +1587,7 @@ Add or remove data integrity checksums to raid images.
\fILV1\fP
.RS
[
.O_integritysettings
.O_raidintegritymode
]
.br
[
@@ -1595,7 +1595,7 @@ Add or remove data integrity checksums to raid images.
]
.br
[
.O_raidintegritymode
.O_integritysettings
]
.br
[ COMMON_OPTIONS ]
@@ -2374,8 +2374,8 @@ mirror
Convert LV to a thin LV, using the original LV as an external origin.
.P
.B lvconvert
\fB--thinpool\fP \fILV\fP
.O_thin
\fB--thinpool\fP \fILV\fP
\fILV1\fP
.RS
[ \fB--type thin\fP ] (implied)
@@ -2397,10 +2397,6 @@ Convert LV to a thin LV, using the original LV as an external origin.
]
.br
[
.O_metadataprofile
]
.br
[
.O_originname
]
.br
@@ -2416,6 +2412,10 @@ Convert LV to a thin LV, using the original LV as an external origin.
.O_poolmetadataspare
]
.br
[
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -2459,10 +2459,6 @@ Convert LV to a thin LV, using LV as thin-pool data volume.
]
.br
[
.O_metadataprofile
]
.br
[
.O_poolmetadata
]
.br
@@ -2474,6 +2470,10 @@ Convert LV to a thin LV, using LV as thin-pool data volume.
.O_poolmetadataspare
]
.br
[
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -2496,13 +2496,17 @@ error
Attach a cache pool to an LV.
.P
.B lvconvert
\fB--cachepool\fP \fILV\fP
.O_cache
\fB--cachepool\fP \fILV\fP
\fILV1\fP
.RS
[ \fB--type cache\fP ] (implied)
.br
[
.O_zero
]
.br
[
.O_chunksize
]
.br
@@ -2515,10 +2519,6 @@ Attach a cache pool to an LV.
]
.br
[
.O_zero
]
.br
[
.O_cachemetadataformat
]
.br
@@ -2535,10 +2535,6 @@ Attach a cache pool to an LV.
]
.br
[
.O_metadataprofile
]
.br
[
.O_poolmetadata
]
.br
@@ -2550,6 +2546,10 @@ Attach a cache pool to an LV.
.O_poolmetadataspare
]
.br
[
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -2574,16 +2574,16 @@ error
Attach a cache to an LV, converts the LV to type cache.
.P
.B lvconvert
.O_cachevol
.O_cache
.O_cachevol
\fILV1\fP
.RS
[
.O_chunksize
.O_zero
]
.br
[
.O_zero
.O_chunksize
]
.br
[
@@ -2632,11 +2632,11 @@ existing data on LV will be erased).
]
.br
[
.O_readahead
.O_virtualsize
]
.br
[
.O_virtualsize
.O_readahead
]
.br
[
@@ -2656,11 +2656,11 @@ existing data on LV will be erased).
]
.br
[
.O_metadataprofile
.O_vdosettings
]
.br
[
.O_vdosettings
.O_metadataprofile
]
.br
[ COMMON_OPTIONS ]
@@ -2702,8 +2702,8 @@ writecache
Swap metadata LV in a thin pool or cache pool (for repair only).
.P
.B lvconvert
.O_poolmetadata
.O_swapmetadata
.O_poolmetadata
\fILV1\fP
.RS
[

File diff suppressed because it is too large Load Diff

View File

@@ -366,11 +366,11 @@ Display output in columns like lvs.
]
.br
[
.O_sort
.O_select
]
.br
[
.O_select
.O_sort
]
.br
[
@@ -386,11 +386,11 @@ Display output in columns like lvs.
]
.br
[
.O_headings
.O_logonly
]
.br
[
.O_logonly
.O_headings
]
.br
[

View File

@@ -306,6 +306,10 @@ Extend an LV by a specified size.
]
.br
[
.O_resizefs
]
.br
[
.O_stripes
]
.br
@@ -314,7 +318,7 @@ Extend an LV by a specified size.
]
.br
[
.O_resizefs
.O_poolmetadatasize
]
.br
[
@@ -325,10 +329,6 @@ Extend an LV by a specified size.
.O_fsmode
]
.br
[
.O_poolmetadatasize
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]
@@ -344,6 +344,10 @@ Extend an LV by specified PV extents.
\fILV\fP \fIPV\fP\ .\|.\|.\&
.RS
[
.O_resizefs
]
.br
[
.O_stripes
]
.br
@@ -352,10 +356,6 @@ Extend an LV by specified PV extents.
]
.br
[
.O_resizefs
]
.br
[
.O_fs
]
.br

View File

@@ -239,11 +239,35 @@ if information changes between commands.
]
.br
[
.O_select
]
.br
[
.O_sort
]
.br
[
.O_select
.O_foreign
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_shared
]
.br
[
.O_units
]
.br
[
@@ -259,7 +283,7 @@ if information changes between commands.
]
.br
[
.O_foreign
.O_logonly
]
.br
[
@@ -267,14 +291,6 @@ if information changes between commands.
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_logonly
]
.br
[
.O_nameprefixes
]
.br
@@ -287,14 +303,6 @@ if information changes between commands.
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_rows
]
.br
@@ -303,18 +311,10 @@ if information changes between commands.
]
.br
[
.O_shared
]
.br
[
.O_unbuffered
]
.br
[
.O_units
]
.br
[
.O_unquoted
]
.br

View File

@@ -175,7 +175,9 @@ is reserved for udev output.)
.
Autoactivation commands use a number of temp files in
.I #DEFAULT_RUN_DIR#
(with the expectation that it is cleared between boots).
(with the expectation that
.I #DEFAULT_PID_DIR#
is cleared between boots).
.
.TP
.B pvs_online

View File

@@ -214,15 +214,19 @@ line settings from --config.
]
.br
[
.O_typeconfig
]
.br
[
.O_ignoreadvanced
]
.br
[
.O_ignorelocal
.O_ignoreunsupported
]
.br
[
.O_ignoreunsupported
.O_ignorelocal
]
.br
[
@@ -234,6 +238,10 @@ line settings from --config.
]
.br
[
.O_sinceversion
]
.br
[
.O_showdeprecated
]
.br
@@ -242,18 +250,6 @@ line settings from --config.
]
.br
[
.O_sinceversion
]
.br
[
.O_typeconfig
]
.br
[
.O_unconfigured
]
.br
[
.O_validate
]
.br
@@ -262,6 +258,10 @@ line settings from --config.
]
.br
[
.O_withsummary
]
.br
[
.O_withcomments
]
.br
@@ -278,7 +278,7 @@ line settings from --config.
]
.br
[
.O_withsummary
.O_unconfigured
]
.br
[

View File

@@ -258,7 +258,7 @@ Display the settings.
.P
.SS VG PR commands
.P
vgchange --persist is used to perform PR operations on the VG's devices.
vgchange --persist is used to perfom PR operations on the VG's devices.
.P
.B vgchange --persist start
.I VG

View File

@@ -198,14 +198,6 @@ the options section.
]
.br
[
.O_fs
]
.br
[
.O_fsmode
]
.br
[
.O_noudevsync
]
.br
@@ -213,6 +205,14 @@ the options section.
.O_reportformat
]
.br
[
.O_fs
]
.br
[
.O_fsmode
]
.br
[ COMMON_OPTIONS ]
.RE
.P

View File

@@ -293,6 +293,10 @@ Resize an LV by a specified size.
]
.br
[
.O_poolmetadatasize
]
.br
[
.O_fs
]
.br
@@ -300,10 +304,6 @@ Resize an LV by a specified size.
.O_fsmode
]
.br
[
.O_poolmetadatasize
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIPV\fP\ .\|.\|.\& ]

View File

@@ -233,11 +233,11 @@ lvs produces formatted output about LVs.
.B lvs
.RS
[
.O_all
.O_history
]
.br
[
.O_history
.O_all
]
.br
[
@@ -245,11 +245,39 @@ lvs produces formatted output about LVs.
]
.br
[
.O_select
]
.br
[
.O_sort
]
.br
[
.O_select
.O_segments
]
.br
[
.O_foreign
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_shared
]
.br
[
.O_units
]
.br
[
@@ -265,7 +293,7 @@ lvs produces formatted output about LVs.
]
.br
[
.O_foreign
.O_logonly
]
.br
[
@@ -273,14 +301,6 @@ lvs produces formatted output about LVs.
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_logonly
]
.br
[
.O_nameprefixes
]
.br
@@ -293,38 +313,18 @@ lvs produces formatted output about LVs.
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_rows
]
.br
[
.O_segments
]
.br
[
.O_separator
]
.br
[
.O_shared
]
.br
[
.O_unbuffered
]
.br
[
.O_units
]
.br
[
.O_unquoted
]
.br

View File

@@ -166,9 +166,9 @@ Change properties of all PVs.
.O_all
.RS
(
.O_uuid
.in +2n
.O_allocatable
.in +2n
.O_uuid
.br
.O_addtag
.br
@@ -189,9 +189,9 @@ Change properties of specified PVs.
.B pvchange
.RS
(
.O_uuid
.in +2n
.O_allocatable
.in +2n
.O_uuid
.br
.O_addtag
.br

View File

@@ -366,11 +366,11 @@ Check and print LVM headers and metadata on a device
]
.br
[
.O_pvmetadatacopies
.O_settings
]
.br
[
.O_settings
.O_pvmetadatacopies
]
.br
[ COMMON_OPTIONS ]

View File

@@ -276,10 +276,6 @@ pe_start value.
]
.br
[
.O_bootloaderareasize
]
.br
[
.O_dataalignment
]
.br
@@ -288,11 +284,15 @@ pe_start value.
]
.br
[
.O_bootloaderareasize
]
.br
[
.O_labelsector
]
.br
[
.O_metadataignore
.O_pvmetadatacopies
]
.br
[
@@ -300,11 +300,15 @@ pe_start value.
]
.br
[
.O_metadataignore
]
.br
[
.O_norestorefile
]
.br
[
.O_pvmetadatacopies
.O_setphysicalvolumesize
]
.br
[
@@ -315,10 +319,6 @@ pe_start value.
.O_restorefile
]
.br
[
.O_setphysicalvolumesize
]
.br
[ COMMON_OPTIONS ]
.RE
.P

View File

@@ -374,11 +374,11 @@ Display output in columns like pvs.
]
.br
[
.O_sort
.O_select
]
.br
[
.O_select
.O_sort
]
.br
[
@@ -394,11 +394,11 @@ Display output in columns like pvs.
]
.br
[
.O_headings
.O_logonly
]
.br
[
.O_logonly
.O_headings
]
.br
[

View File

@@ -140,11 +140,11 @@ LVs allocated on it.
]
.br
[
.O_reportformat
.O_setphysicalvolumesize
]
.br
[
.O_setphysicalvolumesize
.O_reportformat
]
.br
[ COMMON_OPTIONS ]

View File

@@ -233,11 +233,11 @@ pvs produces formatted output about PVs.
.B pvs
.RS
[
.O_all
.O_allpvs
]
.br
[
.O_allpvs
.O_all
]
.br
[
@@ -245,11 +245,39 @@ pvs produces formatted output about PVs.
]
.br
[
.O_select
]
.br
[
.O_sort
]
.br
[
.O_select
.O_segments
]
.br
[
.O_foreign
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_shared
]
.br
[
.O_units
]
.br
[
@@ -265,7 +293,7 @@ pvs produces formatted output about PVs.
]
.br
[
.O_foreign
.O_logonly
]
.br
[
@@ -273,14 +301,6 @@ pvs produces formatted output about PVs.
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_logonly
]
.br
[
.O_nameprefixes
]
.br
@@ -293,38 +313,18 @@ pvs produces formatted output about PVs.
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_rows
]
.br
[
.O_segments
]
.br
[
.O_separator
]
.br
[
.O_shared
]
.br
[
.O_unbuffered
]
.br
[
.O_units
]
.br
[
.O_unquoted
]
.br

View File

@@ -315,10 +315,6 @@ Display PV information.
.B pvscan
.RS
[
.O_allpvs
]
.br
[
.O_exported
]
.br
@@ -335,6 +331,10 @@ Display PV information.
]
.br
[
.O_allpvs
]
.br
[
.O_ignorelockingfailure
]
.br
@@ -363,6 +363,10 @@ Record that a PV is online or offline.
]
.br
[
.O_reportformat
]
.br
[
.O_minor
]
.br
@@ -370,10 +374,6 @@ Record that a PV is online or offline.
.O_noudevsync
]
.br
[
.O_reportformat
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIString\fP|\fIPV\fP\ .\|.\|.\& ]
@@ -394,11 +394,11 @@ Record that a PV is online and autoactivate the VG if complete.
]
.br
[
.O_autoactivation
.O_ignorelockingfailure
]
.br
[
.O_ignorelockingfailure
.O_reportformat
]
.br
[
@@ -410,7 +410,7 @@ Record that a PV is online and autoactivate the VG if complete.
]
.br
[
.O_reportformat
.O_autoactivation
]
.br
[ COMMON_OPTIONS ]
@@ -430,7 +430,7 @@ Record that a PV is online and list the VG using the PV.
\fIPV\fP
.RS
[
.O_autoactivation
.O_ignorelockingfailure
]
.br
[
@@ -438,7 +438,7 @@ Record that a PV is online and list the VG using the PV.
]
.br
[
.O_ignorelockingfailure
.O_vgonline
]
.br
[
@@ -446,7 +446,7 @@ Record that a PV is online and list the VG using the PV.
]
.br
[
.O_vgonline
.O_autoactivation
]
.br
[ COMMON_OPTIONS ]
@@ -464,11 +464,11 @@ Record that a PV is online and list LVs using the PV.
\fIPV\fP
.RS
[
.O_checkcomplete
.O_ignorelockingfailure
]
.br
[
.O_ignorelockingfailure
.O_checkcomplete
]
.br
[

View File

@@ -238,8 +238,8 @@ List all VG metadata backups.
List one VG metadata backup file.
.P
.B vgcfgrestore
.O_file
.O_list
.O_file
.RS
[ COMMON_OPTIONS ]
.br

View File

@@ -403,27 +403,27 @@ required, after which the others are optional.
.in +2n
.O_maxphysicalvolumes
.br
.O_physicalextentsize
.br
.O_uuid
.br
.O_physicalextentsize
.br
.O_resizeable
.br
.O_addtag
.br
.O_deltag
.br
.O_alloc
.br
.O_deltag
.O_pvmetadatacopies
.br
.O_vgmetadatacopies
.br
.O_detachprofile
.br
.O_metadataprofile
.br
.O_pvmetadatacopies
.br
.O_setautoactivation
.br
.O_vgmetadatacopies
)
.in
[
@@ -431,11 +431,15 @@ required, after which the others are optional.
]
.br
[
.O_select
]
.br
[
.O_force
]
.br
[
.O_select
.O_poll
]
.br
[
@@ -447,10 +451,6 @@ required, after which the others are optional.
]
.br
[
.O_poll
]
.br
[
.O_reportformat
]
.br
@@ -473,18 +473,26 @@ Start or stop monitoring LVs from dmeventd.
]
.br
[
.O_force
]
.br
[
.O_select
]
.br
[
.O_force
]
.br
[
.O_sysinit
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_poll
]
.br
[
.O_ignoremonitoring
]
.br
@@ -493,17 +501,9 @@ Start or stop monitoring LVs from dmeventd.
]
.br
[
.O_poll
]
.br
[
.O_reportformat
]
.br
[
.O_sysinit
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIVG\fP|\fITag\fP|\fISelect\fP\ .\|.\|.\& ]
@@ -523,11 +523,11 @@ Start or stop processing LV conversions.
]
.br
[
.O_force
.O_select
]
.br
[
.O_select
.O_force
]
.br
[
@@ -561,14 +561,6 @@ Activate or deactivate LVs.
.O_activate
.RS
[
.O_autobackup
]
.br
[
.O_force
]
.br
[
.O_ignoreactivationskip
]
.br
@@ -577,39 +569,23 @@ Activate or deactivate LVs.
]
.br
[
.O_autobackup
]
.br
[
.O_select
]
.br
[
.O_force
]
.br
[
.O_activationmode
]
.br
[
.O_autoactivation
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_ignoremonitoring
]
.br
[
.O_monitor
]
.br
[
.O_noudevsync
]
.br
[
\fB--persist\fP \fIString\fP
]
.br
[
.O_poll
.O_sysinit
]
.br
[
@@ -617,11 +593,35 @@ Activate or deactivate LVs.
]
.br
[
.O_reportformat
.O_ignorelockingfailure
]
.br
[
.O_sysinit
.O_monitor
]
.br
[
.O_poll
]
.br
[
.O_autoactivation
]
.br
[
.O_persist
]
.br
[
.O_ignoremonitoring
]
.br
[
.O_noudevsync
]
.br
[
.O_reportformat
]
.br
[ COMMON_OPTIONS ]
@@ -643,18 +643,26 @@ Reactivate LVs using the latest metadata.
]
.br
[
.O_force
]
.br
[
.O_select
]
.br
[
.O_force
]
.br
[
.O_sysinit
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_poll
]
.br
[
.O_ignoremonitoring
]
.br
@@ -663,17 +671,9 @@ Reactivate LVs using the latest metadata.
]
.br
[
.O_poll
]
.br
[
.O_reportformat
]
.br
[
.O_sysinit
]
.br
[ COMMON_OPTIONS ]
.br
[ \fIVG\fP|\fITag\fP|\fISelect\fP\ .\|.\|.\& ]
@@ -698,7 +698,7 @@ Change the system ID of a VG.
]
.br
[
\fB--persist\fP \fIString\fP
.O_persist
]
.br
[
@@ -723,7 +723,7 @@ Set or clear flags to control persistent reservation behavior.
]
.br
[
\fB--persist\fP \fBstart\fP
.O_persist
]
.br
[ COMMON_OPTIONS ]
@@ -740,21 +740,21 @@ Perform persistent reservation commands on devices.
\fIVG\fP|\fITag\fP|\fISelect\fP
.RS
[
.O_force
]
.br
[
.O_select
]
.br
[
.O_majoritypvs
.O_force
]
.br
[
.O_removekey
]
.br
[
.O_majoritypvs
]
.br
[ COMMON_OPTIONS ]
.RE
.
@@ -772,7 +772,7 @@ Start the lockspace of a shared VG in lvmlockd.
]
.br
[
\fB--persist\fP \fBstart\fP
.O_persist
]
.br
[ COMMON_OPTIONS ]
@@ -794,7 +794,7 @@ Stop the lockspace of a shared VG in lvmlockd.
]
.br
[
\fB--persist\fP \fBstop\fP
.O_persist
]
.br
[ COMMON_OPTIONS ]
@@ -1254,14 +1254,12 @@ for individual LVs.
.TP
.O_setpersist
Set or clear flags to control persistent reservation behavior.
y: set require and autostart flags.
n: clear require and autostart flags.
require: set flag, PR will be required to write or activate VG.
norequire: clear require flag.
autostart: set flag, PR will be automatically started.
noautostart: clear autostart flag.
ptpl: set flag, use persist through power loss on devices.
noptpl: clear ptpl flag.
require: set flag, PR will be required to write or activate VG.
norequire: clear require flag.
y: set autostart and require flags.
n: clear autostart and require flags.
When autostart is enabled, autoactivation and auto-lockstart
commands will first start PR.
lvmlocal.conf pr_key or host_id must be configured to use PR.

View File

@@ -161,15 +161,11 @@ convert VGs from the LVM1 format to LVM2.
]
.br
[
.O_bootloaderareasize
]
.br
[
.O_labelsector
]
.br
[
.O_metadatasize
.O_bootloaderareasize
]
.br
[
@@ -177,6 +173,10 @@ convert VGs from the LVM1 format to LVM2.
]
.br
[
.O_metadatasize
]
.br
[
.O_reportformat
]
.br

View File

@@ -134,10 +134,6 @@
.de O_nolocking
.OPS nolocking
..
.de O_persist
.OPA persist
\fIString\fP
..
.de O_physicalextentsize
.OPA s physicalextentsize
\fISize\fP[m|\:UNIT]
@@ -164,10 +160,6 @@
.OPA setautoactivation
\fBy\fP|\fBn\fP
..
.de O_setpersist
.OPA setpersist
\fIString\fP
..
.de O_shared
.OPS shared
..
@@ -243,26 +235,26 @@ device.
]
.br
[
.O_force
]
.br
[
.O_maxlogicalvolumes
]
.br
[
.O_metadatatype
]
.br
[
.O_maxphysicalvolumes
]
.br
[
.O_metadatatype
]
.br
[
.O_physicalextentsize
]
.br
[
.O_force
]
.br
[
.O_zero
]
.br
@@ -275,11 +267,7 @@ device.
]
.br
[
.O_dataalignment
]
.br
[
.O_dataalignmentoffset
.O_metadataprofile
]
.br
[
@@ -287,35 +275,27 @@ device.
]
.br
[
.O_locktype
]
.br
[
.O_metadataprofile
]
.br
[
.O_metadatasize
]
.br
[
\fB--persist\fP \fBstart\fP
]
.br
[
.O_pvmetadatacopies
]
.br
[
.O_vgmetadatacopies
]
.br
[
.O_reportformat
]
.br
[
.O_setautoactivation
.O_dataalignment
]
.br
[
.O_setpersist
.O_dataalignmentoffset
]
.br
[
@@ -327,7 +307,11 @@ device.
]
.br
[
.O_vgmetadatacopies
.O_locktype
]
.br
[
.O_setautoactivation
]
.br
[ COMMON_OPTIONS ]
@@ -576,20 +560,6 @@ Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.TP
.O_persist
Persistent Reservation operation.
start: register local key and acquire reservation.
stop: unregister local key, releasing reservation.
remove: preempt and abort another key.
clear: remove reservation and keys.
check: check if started.
autostart: start if the VG autostart flag is set.
lvmlocal.conf pr_key or host_id must be configured to use PR.
For local VGs, Write Exclusive (WE) is used, and for shared VGs
Write Exclusive, all registrants (WEAR) is used.
Use --setpersist to automate and/or require PR.
.
.TP
.O_physicalextentsize
Sets the physical extent size of PVs in the VG.
The value must be either a power of 2 of at least 1 sector
@@ -642,18 +612,6 @@ If autoactivation is enabled on a VG, autoactivation can be disabled
for individual LVs.
.
.TP
.O_setpersist
Set flags to control persistent reservation behavior.
y: set require and autostart flags.
require: PR will be required to write or activate VG.
autostart: PR will be automatically started.
ptpl: use persist through power loss on devices.
When autostart is enabled, autoactivation and auto-lockstart
commands will first start PR.
lvmlocal.conf pr_key or host_id must be configured to use PR.
For local VGs, enabling system_id is also recommended.
.
.TP
.O_shared
Create a shared VG using lvmlockd if LVM is compiled with lockd support.
lvmlockd will select lock type sanlock or dlm depending on which lock

View File

@@ -338,11 +338,11 @@ and more, using a more compact and configurable output format.
.B vgdisplay
.RS
[
.O_activevolumegroups
.O_short
]
.br
[
.O_short
.O_activevolumegroups
]
.br
[ COMMON_OPTIONS ]
@@ -368,11 +368,11 @@ Display output in columns like vgs.
]
.br
[
.O_sort
.O_select
]
.br
[
.O_select
.O_sort
]
.br
[
@@ -388,11 +388,11 @@ Display output in columns like vgs.
]
.br
[
.O_headings
.O_logonly
]
.br
[
.O_logonly
.O_headings
]
.br
[

View File

@@ -162,7 +162,7 @@ Export specified VGs.
]
.br
[
\fB--persist\fP \fBstop\fP
.O_persist
]
.br
[ COMMON_OPTIONS ]

View File

@@ -188,19 +188,11 @@ will initialize them. In this case pvcreate options can be used, e.g.
]
.br
[
.O_metadatatype
]
.br
[
.O_zero
]
.br
[
.O_dataalignment
]
.br
[
.O_dataalignmentoffset
.O_metadatatype
]
.br
[
@@ -208,10 +200,6 @@ will initialize them. In this case pvcreate options can be used, e.g.
]
.br
[
.O_metadataignore
]
.br
[
.O_metadatasize
]
.br
@@ -220,6 +208,18 @@ will initialize them. In this case pvcreate options can be used, e.g.
]
.br
[
.O_metadataignore
]
.br
[
.O_dataalignment
]
.br
[
.O_dataalignmentoffset
]
.br
[
.O_reportformat
]
.br

View File

@@ -152,7 +152,7 @@ Import specified VGs.
]
.br
[
\fB--persist\fP \fBstart\fP
.O_persist
]
.br
[ COMMON_OPTIONS ]

View File

@@ -136,11 +136,11 @@ changes the associated VG and PV UUIDs.
\fIPV\fP\ .\|.\|.\&
.RS
[
.O_import
.O_basevgname
]
.br
[
.O_basevgname
.O_import
]
.br
[

View File

@@ -235,11 +235,35 @@ vgs produces formatted output about VGs.
]
.br
[
.O_select
]
.br
[
.O_sort
]
.br
[
.O_select
.O_foreign
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_shared
]
.br
[
.O_units
]
.br
[
@@ -255,7 +279,7 @@ vgs produces formatted output about VGs.
]
.br
[
.O_foreign
.O_logonly
]
.br
[
@@ -263,14 +287,6 @@ vgs produces formatted output about VGs.
]
.br
[
.O_ignorelockingfailure
]
.br
[
.O_logonly
]
.br
[
.O_nameprefixes
]
.br
@@ -283,14 +299,6 @@ vgs produces formatted output about VGs.
]
.br
[
.O_readonly
]
.br
[
.O_reportformat
]
.br
[
.O_rows
]
.br
@@ -299,18 +307,10 @@ vgs produces formatted output about VGs.
]
.br
[
.O_shared
]
.br
[
.O_unbuffered
]
.br
[
.O_units
]
.br
[
.O_unquoted
]
.br

View File

@@ -514,7 +514,7 @@ device_supports_type_str() {
fi
}
check_devices() {
check_device_types() {
err=0
FOUND_MPATH=0
FOUND_SCSI=0
@@ -559,31 +559,11 @@ check_devices() {
if [[ $FOUND_SCSI -eq 1 ]]; then
which sg_persist > /dev/null || errorexit "sg_persist command not found."
which sg_turs > /dev/null || errorexit "sg_turs command not found."
fi
if [[ $FOUND_NVME -eq 1 ]]; then
which nvme > /dev/null || errorexit "nvme command not found."
fi
# Sometimes a device will return a Unit Attention error
# for an sg_persist/mpathpersist command, e.g. after the
# host's key was cleared. A single tur command clears
# the error. Alternatively, each command in the script
# could be retried if it fails due to a UA error.
for dev in "${DEVICES[@]}"; do
case "$dev" in
/dev/sd*)
;&
/dev/dm-*)
;&
/dev/mapper*)
sg_turs "$dev" >/dev/null 2>&1
ec=$?
test $ec -eq 0 || logmsg "test unit ready error $ec from $dev"
esac
done
}
undo_register() {
@@ -886,7 +866,6 @@ do_remove() {
for dev in "${DEVICES[@]}"; do
if ! key_is_on_device "$dev" "$OURKEY" ; then
logmsg "cannot remove $REMKEY from $dev without ourkey $OURKEY being registered"
err=1
continue
fi
@@ -1222,7 +1201,7 @@ fi
# subsequent string matching of keys fails.
DECDIGITS='^[0-9]+$'
HEXDIGITS='^[0-9a-fA-F]+$'
HEXDIGITS='^[0-9a-zA-Z]+$'
if [[ -n "$OURKEY" && "$OURKEY" == "0x0"* ]]; then
echo "Leading 0s are not permitted in keys."
@@ -1251,7 +1230,7 @@ if [[ -n "$OURKEY" && "$OURKEY" != "0x"* ]]; then
fi
if [[ -n "$OURKEY" && "$OURKEY" == "0x"* ]]; then
if [[ ! "${OURKEY:2}" =~ $HEXDIGITS ]]; then
if [[ ! "$OURKEY" =~ $HEXDIGITS ]]; then
echo "Invalid hex digits in key: $OURKEY"
exit 1
fi
@@ -1270,7 +1249,7 @@ if [[ -n "$REMKEY" && "$REMKEY" != "0x"* ]]; then
fi
if [[ -n "$REMKEY" && "$REMKEY" == "0x"* ]]; then
if [[ ! "${REMKEY:2}" =~ $HEXDIGITS ]]; then
if [[ ! "$REMKEY" =~ $HEXDIGITS ]]; then
echo "Invalid hex digits in key: $REMKEY"
exit 1
fi
@@ -1402,31 +1381,38 @@ else
fi
fi
#
# Main program function
#
check_devices
if [[ "$DO_START" -eq 1 && -n "$REMKEY" ]]; then
check_device_types
do_takeover
elif [[ "$DO_START" -eq 1 ]]; then
check_device_types
do_start
elif [[ "$DO_STOP" -eq 1 ]]; then
do_stop
elif [[ "$DO_REMOVE" -eq 1 ]]; then
do_remove
elif [[ "$DO_CLEAR" -eq 1 ]]; then
check_device_types
do_clear
elif [[ "$DO_DEVTEST" -eq 1 ]]; then
check_device_types
do_devtest
elif [[ "$DO_CHECKKEY" -eq 1 ]]; then
check_device_types
do_checkkey
elif [[ "$DO_READKEYS" -eq 1 ]]; then
check_device_types
do_readkeys
elif [[ "$DO_READRESERVATION" -eq 1 ]]; then
check_device_types
do_readreservation
elif [[ "$DO_READ" -eq 1 ]]; then
check_device_types
do_readkeys
do_readreservation
fi

View File

@@ -19,11 +19,6 @@ errorexit() {
exit 1
}
logerror() {
echo "$1" >&2
logger "${SCRIPTNAME}: $1"
}
logmsg() {
echo "$1"
logger "${SCRIPTNAME}: $1"
@@ -73,72 +68,6 @@ TMP_MOUNT_DONE=0
# Set to 1 if the fs resize command fails
RESIZEFS_FAILED=0
# Function to detect XFS mount options
detect_xfs_mount_options() {
local device=$1
local qflags_output qflags_hex
MOUNT_OPTIONS=""
# Get quota flags using xfs_db.
if ! qflags_output=$(xfs_db -r "$device" -c 'sb 0' -c 'p qflags'); then
logerror "xfs_db failed"
return 1
fi
# Extract the hex value from output that is in format "qflags = 0x<hex_number>".
qflags_hex="${qflags_output#qflags = }"
# No flags set, no extra mount options needed.
if [[ "$qflags_hex" == "0" ]]; then
return 0
fi
if [[ ! "$qflags_hex" =~ ^0x[0-9a-fA-F]+$ ]]; then
logerror "xfs_db unexpected output"
return 1
fi
# Check XFS quota flags and set MOUNT_OPTIONS appropriately
# The quota flags as defined in Linux kernel source: fs/xfs/libxfs/xfs_log_format.h:
# XFS_UQUOTA_ACCT = 0x0001
# XFS_UQUOTA_ENFD = 0x0002
# XFS_GQUOTA_ACCT = 0x0040
# XFS_GQUOTA_ENFD = 0x0080
# XFS_PQUOTA_ACCT = 0x0008
# XFS_PQUOTA_ENFD = 0x0200
if [ $(($qflags_hex & 0x0001)) -ne 0 ]; then
if [ $(($qflags_hex & 0x0002)) -ne 0 ]; then
MOUNT_OPTIONS="${MOUNT_OPTIONS}uquota,"
else
MOUNT_OPTIONS="${MOUNT_OPTIONS}uqnoenforce,"
fi
fi
if [ $(($qflags_hex & 0x0040)) -ne 0 ]; then
if [ $(($qflags_hex & 0x0080)) -ne 0 ]; then
MOUNT_OPTIONS="${MOUNT_OPTIONS}gquota,"
else
MOUNT_OPTIONS="${MOUNT_OPTIONS}gqnoenforce,"
fi
fi
if [ $(($qflags_hex & 0x0008)) -ne 0 ]; then
if [ $(($qflags_hex & 0x0200)) -ne 0 ]; then
MOUNT_OPTIONS="${MOUNT_OPTIONS}pquota,"
else
MOUNT_OPTIONS="${MOUNT_OPTIONS}pqnoenforce,"
fi
fi
# Trim trailing comma
MOUNT_OPTIONS="${MOUNT_OPTIONS%,}"
if [[ -n "$MOUNT_OPTIONS" ]]; then
logmsg "mount options for xfs: ${MOUNT_OPTIONS}"
fi
}
fsextend() {
if [ "$DO_UNMOUNT" -eq 1 ]; then
logmsg "unmount ${MOUNTDIR}"
@@ -169,7 +98,7 @@ fsextend() {
fi
fi
fi
if [ "$DO_CRYPTRESIZE" -eq 1 ]; then
logmsg "cryptsetup resize ${DEVPATH}"
if cryptsetup resize "$DEVPATH"; then
@@ -181,12 +110,8 @@ fsextend() {
fi
if [ "$DO_MOUNT" -eq 1 ]; then
if [[ "$FSTYPE" == "xfs" ]]; then
detect_xfs_mount_options "$DEVPATH" || logmsg "not using XFS mount options"
fi
logmsg "mount ${DEVPATH} ${TMPDIR}"
if mount -t "$FSTYPE" ${MOUNT_OPTIONS:+-o "$MOUNT_OPTIONS"} "$DEVPATH" "$TMPDIR"; then
if mount -t "$FSTYPE" "$DEVPATH" "$TMPDIR"; then
logmsg "mount done"
TMP_MOUNT_DONE=1
else
@@ -245,12 +170,8 @@ fsextend() {
# If the fs was temporarily unmounted, now remount it.
# Not considered a command failure if this fails.
if [[ $DO_UNMOUNT -eq 1 && $REMOUNT -eq 1 ]]; then
if [[ "$FSTYPE" == "xfs" ]]; then
detect_xfs_mount_options "$DEVPATH" || logmsg "not using XFS mount options"
fi
logmsg "remount ${DEVPATH} ${MOUNTDIR}"
if mount -t "$FSTYPE" ${MOUNT_OPTIONS:+-o "$MOUNT_OPTIONS"} "$DEVPATH" "$MOUNTDIR"; then
if mount -t "$FSTYPE" "$DEVPATH" "$MOUNTDIR"; then
logmsg "remount done"
else
logmsg "remount failed"
@@ -463,9 +384,6 @@ DO_FSCK=0
# mounted and the script unmounted it.
REMOUNT=0
# Initialize MOUNT_OPTIONS to ensure clean state
MOUNT_OPTIONS=""
if [ "$UID" != 0 ] && [ "$EUID" != 0 ]; then
errorexit "${SCRIPTNAME} must be run as root."
fi

View File

@@ -2003,8 +2003,8 @@ have_raid_resizable() {
# array resync, so it's better to skip the test for affected kernels.
case "$(uname -r)" in
6.1[34]*) return 1 ;;
5.14.0-61[123].el9.*) return 1 ;; # Kernel is missing fixing commit!
6.12.0-12[456].el10.*) return 1 ;; # -- '' --
5.14.0-611.el9.*) return 1 ;; # Kernel is missing fixing commit!
6.12.0-124.el10.*) return 1 ;; # -- '' --
esac
}

View File

@@ -89,24 +89,12 @@ check lv_field $vg/$lv lv_size "380.00m"
df --output=size "$mount_dir" |tee df2
not diff df1 df2
# lvextend, xfs, active, not mounted, quotas defined, --fs resize
umount "$mount_dir"
mount -o uquota,gquota,pquota "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
umount "$mount_dir"
lvextend -y --fs resize -L+10M $vg/$lv | tee out
grep "mount options for xfs: uquota,gquota,pquota" out # must preserve the mount options!
# lvextend, xfs, active, not mounted, quotas not defined, --fs resize
mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
umount "$mount_dir"
lvextend -y --fs resize -L+10M $vg/$lv | tee out
not grep "mount options for xfs" out # mount options not needed
lvchange -an $vg/$lv
# lvextend, xfs, inactive, --fs ignore
lvextend --fs ignore -L+20M $vg/$lv
check lv_field $vg/$lv lv_size "420.00m"
check lv_field $vg/$lv lv_size "400.00m"
lvremove -f $vg/$lv

View File

@@ -40,16 +40,26 @@ arg(activationmode_ARG, '\0', "activationmode", activationmode_VAL, 0, 0,
"For default, see \\fBlvm.conf\\fP(5) activation_mode.\n"
"See \\fBlvmraid\\fP(7) for more information.\n")
arg(adddev_ARG, '\0', "adddev", pv_VAL, 0, 0,
"Add a device to the devices file.\n")
arg(addpvid_ARG, '\0', "addpvid", string_VAL, 0, 0,
"Find a device with the PVID and add the device to the devices file.\n")
arg(addtag_ARG, '\0', "addtag", tag_VAL, ARG_GROUPABLE, 0,
"Adds a tag to a PV, VG or LV. This option can be repeated to add\n"
"multiple tags at once. See \\fBlvm\\fP(8) for information about tags.\n")
arg(adddev_ARG, '\0', "adddev", pv_VAL, 0, 0,
"Add a device to the devices file.\n")
arg(deldev_ARG, '\0', "deldev", string_VAL, 0, 0,
"Remove a device from the devices file.\n"
"When used alone, --deldev specifies a device name.\n"
"When used with --deviceidtype, --deldev specifies a device id.\n")
arg(delnotfound_ARG, '\0', "delnotfound", 0, 0, 0,
"Remove devices file entries with no matching device.\n")
arg(addpvid_ARG, '\0', "addpvid", string_VAL, 0, 0,
"Find a device with the PVID and add the device to the devices file.\n")
arg(delpvid_ARG, '\0', "delpvid", string_VAL, 0, 0,
"Remove a device with the PVID from the devices file.\n")
arg(aligned_ARG, '\0', "aligned", 0, 0, 0,
"Use with --separator to align the output columns.\n")
@@ -98,6 +108,17 @@ arg(autoactivation_ARG, '\0', "autoactivation", string_VAL, 0, 0,
"to event activation, such as device scanning optimizations\n"
"using pvs_online files created by event-based pvscans.\n")
arg(setautoactivation_ARG, '\0', "setautoactivation", bool_VAL, 0, 0,
"Set the autoactivation property on a VG or LV.\n"
"Display the property with vgs or lvs \"-o autoactivation\".\n"
"When the autoactivation property is disabled, the VG or LV\n"
"will not be activated by a command doing autoactivation\n"
"(vgchange, lvchange, or pvscan using -aay.)\n"
"If autoactivation is disabled on a VG, no LVs will be autoactivated\n"
"in that VG, and the LV autoactivation property has no effect.\n"
"If autoactivation is enabled on a VG, autoactivation can be disabled\n"
"for individual LVs.\n")
arg(binary_ARG, '\0', "binary", 0, 0, 0,
"Use binary values \"0\" or \"1\" instead of descriptive literal values\n"
"for columns that have exactly two valid values to report (not counting\n"
@@ -124,9 +145,6 @@ arg(cache_long_ARG, '\0', "cache", 0, ARG_LONG_OPT, 0,
"#lvscan\n"
"This option is no longer used.\n")
arg(cachedevice_ARG, '\0', "cachedevice", pv_VAL, ARG_GROUPABLE, 0,
"The name of a device to use for a cache.\n")
arg(cachemetadataformat_ARG, '\0', "cachemetadataformat", cachemetadataformat_VAL, 0, 0,
"Specifies the cache metadata format used by cache target.\n")
@@ -143,40 +161,22 @@ arg(cachemode_ARG, '\0', "cachemode", cachemode_VAL, 0, 0,
"forwarded to the origin LV; additionally, write hits cause cache\n"
"block invalidates. See \\fBlvmcache\\fP(7) for more information.\n")
arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0,
"Specifies the cache policy for a cache LV.\n"
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(cachepool_ARG, '\0', "cachepool", lv_VAL, 0, 0,
"The name of a cache pool.\n")
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0,
"Specifies tunable kernel options for dm-cache or dm-writecache LVs.\n"
"Use the form 'option=value' or 'option1=value option2=value', or\n"
"repeat --cachesettings for each option being set.\n"
"These settings override the default kernel behaviors which are\n"
"usually adequate. To remove cachesettings and revert to the default\n"
"kernel behaviors, use --cachesettings 'default' for dm-cache or\n"
"an empty string --cachesettings '' for dm-writecache.\n"
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(cachesize_ARG, '\0', "cachesize", sizemb_VAL, 0, 0,
"The size of cache to use.\n")
arg(cachevol_ARG, '\0', "cachevol", lv_VAL, 0, 0,
"The name of a cache volume.\n")
arg(cachedevice_ARG, '\0', "cachedevice", pv_VAL, ARG_GROUPABLE, 0,
"The name of a device to use for a cache.\n")
arg(cachesize_ARG, '\0', "cachesize", sizemb_VAL, 0, 0,
"The size of cache to use.\n")
arg(check_ARG, '\0', "check", 0, 0, 0,
"Checks the content of the devices file.\n"
"Reports incorrect device names or PVIDs for entries.\n")
arg(checkcomplete_ARG, '\0', "checkcomplete", 0, 0, 0,
"Check if all the devices used by a VG or LV are present,\n"
"and print \"complete\" or \"incomplete\" for each listed\n"
"VG or LV. This option is used as a part of event-based\n"
"autoactivation, so pvscan will do nothing if this option\n"
"is set and event_activation=0 in the config settings.\n")
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0,
"The command profile to use for command configuration.\n"
"See \\fBlvm.conf\\fP(5) for more information about profiles.\n")
@@ -194,6 +194,40 @@ arg(config_ARG, '\0', "config", string_VAL, 0, 0,
arg(configreport_ARG, '\0', "configreport", configreport_VAL, ARG_GROUPABLE, 1,
"See \\fBlvmreport\\fP(7).\n")
arg(configtype_ARG, '\0', "typeconfig", configtype_VAL, 0, 0,
"\\fBcurrent\\fP prints the config settings that would be applied\n"
"to an lvm command (assuming the command does not override them\n"
"on the command line.) This includes:\n"
"settings that have been modified in lvm config files,\n"
"settings that get their default values from config files,\n"
"and default settings that have been uncommented in config files.\n"
"\\fBdefault\\fP prints all settings with their default values.\n"
"Changes made in lvm config files are not reflected in the output.\n"
"Some settings get their default values internally,\n"
"and these settings are printed as comments.\n"
"Other settings get their default values from config files,\n"
"and these settings are not printed as comments.\n"
"\\fBdiff\\fP prints only config settings that have been modified\n"
"from their default values in config files (the difference between\n"
"current and default.)\n"
"\\fBfull\\fP prints every setting uncommented and set to the\n"
"current value, i.e. how it would be used by an lvm command.\n"
"This includes settings modified in config files, settings that usually\n"
"get defaults internally, and settings that get defaults from config files.\n"
"\\fBlist\\fP prints all config names without values.\n"
"\\fBmissing\\fP prints settings that are missing from the\n"
"lvm config files. A missing setting that usually gets its default\n"
"from config files is printed uncommented and set to the internal default.\n"
"Settings that get their default internally and are not set in config files\n"
"are printed commented with the internal default.\n"
"\\fBnew\\fP prints config settings that have been added since\n"
"the lvm version specified by --sinceversion. They are printed\n"
"with their default values.\n"
"\\fBprofilable\\fP prints settings with their default values that can be set from a profile.\n"
"\\fBprofilable-command\\fP prints settings with their default values that can be set from a command profile.\n"
"\\fBprofilable-metadata\\fP prints settings with their default values that can be set from a metadata profile.\n"
"Also see \\fBlvm.conf\\fP(5).\n")
arg(dataalignment_ARG, '\0', "dataalignment", sizekb_VAL, 0, 0,
"Align the start of a PV data area with a multiple of this number.\n"
"To see the location of the first Physical Extent (PE) of an existing PV,\n"
@@ -208,17 +242,6 @@ arg(deduplication_ARG, '\0', "deduplication", bool_VAL, 0, 0,
"Controls whether deduplication is enabled or disabled for VDO volume.\n"
"See \\fBlvmvdo\\fP(7) for more information about VDO usage.\n")
arg(deldev_ARG, '\0', "deldev", string_VAL, 0, 0,
"Remove a device from the devices file.\n"
"When used alone, --deldev specifies a device name.\n"
"When used with --deviceidtype, --deldev specifies a device id.\n")
arg(delnotfound_ARG, '\0', "delnotfound", 0, 0, 0,
"Remove devices file entries with no matching device.\n")
arg(delpvid_ARG, '\0', "delpvid", string_VAL, 0, 0,
"Remove a device with the PVID from the devices file.\n")
arg(deltag_ARG, '\0', "deltag", tag_VAL, ARG_GROUPABLE, 0,
"Deletes a tag from a PV, VG or LV. This option can be repeated to delete\n"
"multiple tags at once. See \\fBlvm\\fP(8) for information about tags.\n")
@@ -363,10 +386,6 @@ arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", 0, 0, 0,
arg(importdevices_ARG, '\0', "importdevices", 0, 0, 0,
"Add devices to the devices file.\n")
arg(integritysettings_ARG, '\0', "integritysettings", string_VAL, ARG_GROUPABLE, 0,
"Specifies tunable kernel options for dm-integrity.\n"
"See \\fBlvmraid\\fP(7) for more information.\n")
arg(journal_ARG, '\0', "journal", string_VAL, 0, 0,
"Record information in the systemd journal.\n"
"This information is in addition to information\n"
@@ -387,6 +406,13 @@ arg(listlvs_ARG, '\0', "listlvs", 0, 0, 0,
arg(listvg_ARG, '\0', "listvg", 0, 0, 0,
"Print the VG that uses the device.\n")
arg(checkcomplete_ARG, '\0', "checkcomplete", 0, 0, 0,
"Check if all the devices used by a VG or LV are present,\n"
"and print \"complete\" or \"incomplete\" for each listed\n"
"VG or LV. This option is used as a part of event-based\n"
"autoactivation, so pvscan will do nothing if this option\n"
"is set and event_activation=0 in the config settings.\n")
arg(lockopt_ARG, '\0', "lockopt", string_VAL, 0, 0,
"Used to pass options for special cases to lvmlockd.\n"
"See \\fBlvmlockd\\fP(8) for more information.\n")
@@ -429,15 +455,6 @@ arg(merge_ARG, '\0', "merge", 0, 0, 0,
"An alias for --mergethin, --mergemirrors, or --mergesnapshot,\n"
"depending on the type of LV.\n")
arg(mergedconfig_ARG, '\0', "mergedconfig", 0, 0, 0,
"When the command is run with --config\n"
"and/or --commandprofile (or using LVM_COMMAND_PROFILE\n"
"environment variable), --profile, or --metadataprofile,\n"
"merge all the contents of the \"config cascade\" before displaying it.\n"
"Without merging, only the configuration at the front of the\n"
"cascade is displayed.\n"
"See \\fBlvm.conf\\fP(5) for more information about config.\n")
arg(mergemirrors_ARG, '\0', "mergemirrors", 0, 0, 0,
"Merge LV images that were split from a raid1 LV.\n"
"See --splitmirrors with --trackchanges.\n")
@@ -462,6 +479,15 @@ arg(mergethin_ARG, '\0', "mergethin", 0, 0, 0,
"and the thin snapshot LV is removed.\n"
"See \\fBlvmthin\\fP(7) for more information.\n")
arg(mergedconfig_ARG, '\0', "mergedconfig", 0, 0, 0,
"When the command is run with --config\n"
"and/or --commandprofile (or using LVM_COMMAND_PROFILE\n"
"environment variable), --profile, or --metadataprofile,\n"
"merge all the contents of the \"config cascade\" before displaying it.\n"
"Without merging, only the configuration at the front of the\n"
"cascade is displayed.\n"
"See \\fBlvm.conf\\fP(5) for more information about config.\n")
arg(metadataignore_ARG, '\0', "metadataignore", bool_VAL, 0, 0,
"Specifies the metadataignore property of a PV.\n"
"If yes, metadata areas on the PV are ignored, and lvm will\n"
@@ -575,6 +601,15 @@ arg(originname_ARG, '\0', "originname", lv_VAL, 0, 0,
"to a thin LV. The LV being converted becomes a read-only external origin\n"
"with this name.\n")
arg(setphysicalvolumesize_ARG, '\0', "setphysicalvolumesize", sizemb_VAL, 0, 0,
"Overrides the automatically detected size of the PV.\n"
"Use with care, or prior to reducing the physical size of the device.\n")
arg(settings_ARG, '\0', "settings", string_VAL, ARG_GROUPABLE, 0,
"Specifies command specific settings in \"Key = Value\" form.\n"
"Combine multiple settings in quotes, or repeat the settings\n"
"option for each.\n")
arg(persist_ARG, '\0', "persist", string_VAL, 0, 0,
"Persistent Reservation operation.\n"
"start: register local key and acquire reservation.\n"
@@ -588,6 +623,49 @@ arg(persist_ARG, '\0', "persist", string_VAL, 0, 0,
"Write Exclusive, all registrants (WEAR) is used.\n"
"Use --setpersist to automate and/or require PR.\n")
arg(setpersist_ARG, '\0', "setpersist", string_VAL, 0, 0,
"#vgcreate\n"
"Set flags to control persistent reservation behavior.\n"
"y: set require and autostart flags.\n"
"require: PR will be required to write or activate VG.\n"
"autostart: PR will be automatically started.\n"
"ptpl: use persist through power loss on devices.\n"
"When autostart is enabled, autoactivation and auto-lockstart\n"
"commands will first start PR.\n"
"lvmlocal.conf pr_key or host_id must be configured to use PR.\n"
"For local VGs, enabling system_id is also recommended.\n"
"#vgchange\n"
"Set or clear flags to control persistent reservation behavior.\n"
"y: set require and autostart flags.\n"
"n: clear require and autostart flags.\n"
"require: set flag, PR will be required to write or activate VG.\n"
"norequire: clear require flag.\n"
"autostart: set flag, PR will be automatically started.\n"
"noautostart: clear autostart flag.\n"
"ptpl: set flag, use persist through power loss on devices.\n"
"noptpl: clear ptpl flag.\n"
"When autostart is enabled, autoactivation and auto-lockstart\n"
"commands will first start PR.\n"
"lvmlocal.conf pr_key or host_id must be configured to use PR.\n"
"For local VGs, enabling system_id is also recommended.\n")
arg(setlockargs_ARG, '\0', "setlockargs", string_VAL, 0, 0,
"Add or remove lock_args settings for a shared VG.\n"
"The lock_args determine lock manager behavior for the VG.\n"
"These settings are only allowed for lock_type sanlock.\n"
"persist: use persistent reservations for lock recovery.\n"
"lvmlockd will preempt-abort the persistent reservation of a failed\n"
"lock owner so that the lock can be acquired.\n"
"notimeout: use locks that do not time out when the owner fails.\n"
"In this case, a lock owned by a failed host can only be acquired\n"
"using the persist feature.\n"
"nopersist: do not use the persist feature.\n"
"timeout: do not use the notimeout feature.\n"
"The default behavior with no settings configured is: nopersist and timeout.\n")
arg(removekey_ARG, '\0', "removekey", string_VAL, 0, 0,
"A persistent reservation key to remove.\n")
arg(poll_ARG, '\0', "poll", bool_VAL, 0, 0,
"When yes, start the background transformation of an LV.\n"
"An incomplete transformation, e.g. pvmove or lvconvert interrupted\n"
@@ -662,14 +740,6 @@ arg(readonly_ARG, '\0', "readonly", 0, 0, 0,
"Prevent the command from making changes, including activation and\n"
"metadata updates. (See --permission r for read only LVs.)\n")
arg(rebuild_ARG, '\0', "rebuild", pv_VAL, ARG_GROUPABLE, 0,
"Selects a PV to rebuild in a raid LV. Multiple PVs can be rebuilt by\n"
"repeating this option.\n"
"Use this option in place of --resync or --syncaction repair when the\n"
"PVs with corrupted data are known, and their data should be reconstructed\n"
"rather than reconstructing default (rotating) data.\n"
"See \\fBlvmraid\\fP(7) for more information.\n")
arg(refresh_ARG, '\0', "refresh", 0, 0, 0,
"#lvmdevices\n"
"Search for missing PVs on new devices, and update the devices file\n"
@@ -693,9 +763,6 @@ arg(refresh_ARG, '\0', "refresh", 0, 0, 0,
"Also, this operation may be useful if something has gone wrong,\n"
"or if some form of manual LV sharing is being used.\n")
arg(removekey_ARG, '\0', "removekey", string_VAL, 0, 0,
"A persistent reservation key to remove.\n")
arg(removemissing_ARG, '\0', "removemissing", 0, 0, 0,
"Removes all missing PVs from the VG, if there are no LVs allocated\n"
"on them. This resumes normal operation of the VG (new LVs may again\n"
@@ -708,6 +775,14 @@ arg(removemissing_ARG, '\0', "removemissing", 0, 0, 0,
"If LVs spanned several disks, including ones that are lost, salvaging\n"
"some data first may be possible by activating LVs in partial mode.\n")
arg(rebuild_ARG, '\0', "rebuild", pv_VAL, ARG_GROUPABLE, 0,
"Selects a PV to rebuild in a raid LV. Multiple PVs can be rebuilt by\n"
"repeating this option.\n"
"Use this option in place of --resync or --syncaction repair when the\n"
"PVs with corrupted data are known, and their data should be reconstructed\n"
"rather than reconstructing default (rotating) data.\n"
"See \\fBlvmraid\\fP(7) for more information.\n")
arg(repair_ARG, '\0', "repair", 0, 0, 0,
"#lvconvert\n"
"Replace failed PVs in a raid or mirror LV, or run a repair\n"
@@ -775,52 +850,6 @@ arg(segments_ARG, '\0', "segments", 0, 0, 0,
arg(separator_ARG, '\0', "separator", string_VAL, 0, 0,
"String to use to separate each column. Useful if grepping the output.\n")
arg(setautoactivation_ARG, '\0', "setautoactivation", bool_VAL, 0, 0,
"Set the autoactivation property on a VG or LV.\n"
"Display the property with vgs or lvs \"-o autoactivation\".\n"
"When the autoactivation property is disabled, the VG or LV\n"
"will not be activated by a command doing autoactivation\n"
"(vgchange, lvchange, or pvscan using -aay.)\n"
"If autoactivation is disabled on a VG, no LVs will be autoactivated\n"
"in that VG, and the LV autoactivation property has no effect.\n"
"If autoactivation is enabled on a VG, autoactivation can be disabled\n"
"for individual LVs.\n")
arg(setpersist_ARG, '\0', "setpersist", string_VAL, 0, 0,
"#vgcreate\n"
"Set flags to control persistent reservation behavior.\n"
"y: set require and autostart flags.\n"
"require: PR will be required to write or activate VG.\n"
"autostart: PR will be automatically started.\n"
"ptpl: use persist through power loss on devices.\n"
"When autostart is enabled, autoactivation and auto-lockstart\n"
"commands will first start PR.\n"
"lvmlocal.conf pr_key or host_id must be configured to use PR.\n"
"For local VGs, enabling system_id is also recommended.\n"
"#vgchange\n"
"Set or clear flags to control persistent reservation behavior.\n"
"y: set require and autostart flags.\n"
"n: clear require and autostart flags.\n"
"require: set flag, PR will be required to write or activate VG.\n"
"norequire: clear require flag.\n"
"autostart: set flag, PR will be automatically started.\n"
"noautostart: clear autostart flag.\n"
"ptpl: set flag, use persist through power loss on devices.\n"
"noptpl: clear ptpl flag.\n"
"When autostart is enabled, autoactivation and auto-lockstart\n"
"commands will first start PR.\n"
"lvmlocal.conf pr_key or host_id must be configured to use PR.\n"
"For local VGs, enabling system_id is also recommended.\n")
arg(setphysicalvolumesize_ARG, '\0', "setphysicalvolumesize", sizemb_VAL, 0, 0,
"Overrides the automatically detected size of the PV.\n"
"Use with care, or prior to reducing the physical size of the device.\n")
arg(settings_ARG, '\0', "settings", string_VAL, ARG_GROUPABLE, 0,
"Specifies command specific settings in \"Key = Value\" form.\n"
"Combine multiple settings in quotes, or repeat the settings\n"
"option for each.\n")
arg(shared_ARG, '\0', "shared", 0, 0, 0,
"#vgcreate\n"
"Create a shared VG using lvmlockd if LVM is compiled with lockd support.\n"
@@ -839,21 +868,6 @@ arg(shared_ARG, '\0', "shared", 0, 0, 0,
"lvmlockd is not being used on the host.\n"
"See \\fBlvmlockd\\fP(8) for more information about shared VGs.\n")
arg(showdeprecated_ARG, '\0', "showdeprecated", 0, 0, 0,
"Include deprecated configuration settings in the output. These settings\n"
"are deprecated after a certain version. If a concrete version is specified\n"
"with --atversion, deprecated settings are automatically included\n"
"if the specified version is lower than the version in which the settings were\n"
"deprecated. The current and diff types include deprecated settings\n"
"in their output by default, all the other types ignore deprecated settings.\n")
arg(showunsupported_ARG, '\0', "showunsupported", 0, 0, 0,
"Include unsupported configuration settings in the output. These settings\n"
"are either used for debugging or development purposes only, or their support\n"
"is not yet complete and they are not meant to be used in production. The\n"
"current and diff types include unsupported settings in their\n"
"output by default, all the other types ignore unsupported settings.\n")
arg(sinceversion_ARG, '\0', "sinceversion", string_VAL, 0, 0,
"Specify an LVM version in x.y.z format where x is the major version,\n"
"the y is the minor version and z is the patchlevel (e.g. 2.2.106).\n"
@@ -876,6 +890,21 @@ arg(splitsnapshot_ARG, '\0', "splitsnapshot", 0, 0, 0,
"contains the chunks that differ from the origin LV along with metadata\n"
"describing them. This LV can be wiped and then destroyed with lvremove.\n")
arg(showdeprecated_ARG, '\0', "showdeprecated", 0, 0, 0,
"Include deprecated configuration settings in the output. These settings\n"
"are deprecated after a certain version. If a concrete version is specified\n"
"with --atversion, deprecated settings are automatically included\n"
"if the specified version is lower than the version in which the settings were\n"
"deprecated. The current and diff types include deprecated settings\n"
"in their output by default, all the other types ignore deprecated settings.\n")
arg(showunsupported_ARG, '\0', "showunsupported", 0, 0, 0,
"Include unsupported configuration settings in the output. These settings\n"
"are either used for debugging or development purposes only, or their support\n"
"is not yet complete and they are not meant to be used in production. The\n"
"current and diff types include unsupported settings in their\n"
"output by default, all the other types ignore unsupported settings.\n")
arg(startpoll_ARG, '\0', "startpoll", 0, 0, 0,
"Start polling an LV to continue processing a conversion.\n")
@@ -962,40 +991,6 @@ arg(type_ARG, '\0', "type", segtype_VAL, 0, 0,
"--thin, --cache, --vdo).\n"
"Use inferred types with care because it can lead to unexpected results.\n")
arg(configtype_ARG, '\0', "typeconfig", configtype_VAL, 0, 0,
"\\fBcurrent\\fP prints the config settings that would be applied\n"
"to an lvm command (assuming the command does not override them\n"
"on the command line.) This includes:\n"
"settings that have been modified in lvm config files,\n"
"settings that get their default values from config files,\n"
"and default settings that have been uncommented in config files.\n"
"\\fBdefault\\fP prints all settings with their default values.\n"
"Changes made in lvm config files are not reflected in the output.\n"
"Some settings get their default values internally,\n"
"and these settings are printed as comments.\n"
"Other settings get their default values from config files,\n"
"and these settings are not printed as comments.\n"
"\\fBdiff\\fP prints only config settings that have been modified\n"
"from their default values in config files (the difference between\n"
"current and default.)\n"
"\\fBfull\\fP prints every setting uncommented and set to the\n"
"current value, i.e. how it would be used by an lvm command.\n"
"This includes settings modified in config files, settings that usually\n"
"get defaults internally, and settings that get defaults from config files.\n"
"\\fBlist\\fP prints all config names without values.\n"
"\\fBmissing\\fP prints settings that are missing from the\n"
"lvm config files. A missing setting that usually gets its default\n"
"from config files is printed uncommented and set to the internal default.\n"
"Settings that get their default internally and are not set in config files\n"
"are printed commented with the internal default.\n"
"\\fBnew\\fP prints config settings that have been added since\n"
"the lvm version specified by --sinceversion. They are printed\n"
"with their default values.\n"
"\\fBprofilable\\fP prints settings with their default values that can be set from a profile.\n"
"\\fBprofilable-command\\fP prints settings with their default values that can be set from a command profile.\n"
"\\fBprofilable-metadata\\fP prints settings with their default values that can be set from a metadata profile.\n"
"Also see \\fBlvm.conf\\fP(5).\n")
arg(udevoutput_ARG, '\0', "udevoutput", 0, 0, 0,
"Command output is modified to be imported from a udev rule.\n")
@@ -1006,6 +1001,23 @@ arg(uncache_ARG, '\0', "uncache", 0, 0, 0,
"Separates a cache pool from a cache LV, and deletes the unused cache pool LV.\n"
"Before the separation, the cache is flushed. Also see --splitcache.\n")
arg(update_ARG, '\0', "update", 0, 0, 0,
"Update the content of the devices file.\n")
arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0,
"Specifies the cache policy for a cache LV.\n"
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0,
"Specifies tunable kernel options for dm-cache or dm-writecache LVs.\n"
"Use the form 'option=value' or 'option1=value option2=value', or\n"
"repeat --cachesettings for each option being set.\n"
"These settings override the default kernel behaviors which are\n"
"usually adequate. To remove cachesettings and revert to the default\n"
"kernel behaviors, use --cachesettings 'default' for dm-cache or\n"
"an empty string --cachesettings '' for dm-writecache.\n"
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0,
"Internal option used for generating config file during build.\n")
@@ -1021,21 +1033,6 @@ arg(unquoted_ARG, '\0', "unquoted", 0, 0, 0,
"When used with --nameprefixes, output values in the field=value\n"
"pairs are not quoted.\n")
arg(update_ARG, '\0', "update", 0, 0, 0,
"Update the content of the devices file.\n")
arg(updatemetadata_ARG, '\0', "updatemetadata", 0, 0, 0,
"Update VG metadata to correct problems.\n"
"If VG metadata was updated while a PV was missing, and the PV\n"
"reappears with an old version of metadata, then this option\n"
"(or any other command that writes metadata) will update the\n"
"metadata on the previously missing PV. If a PV was removed\n"
"from a VG while it was missing, and the PV reappears, using\n"
"this option will clear the outdated metadata from the previously\n"
"missing PV. If metadata text is damaged on one PV, using this\n"
"option will replace the damaged metadata text. For more severe\n"
"damage, e.g. with headers, see \\fBpvck\\fP(8).\n")
arg(usepolicies_ARG, '\0', "usepolicies", 0, 0, 0,
"Perform an operation according to the policy configured in \\fBlvm.conf\\fP(5)\n"
"or a profile.\n")
@@ -1091,6 +1088,9 @@ arg(vgonline_ARG, '\0', "vgonline", 0, 0, 0,
"The first command to see a complete VG will report it uniquely.\n"
"Other commands to see the complete VG will report it differently.\n")
arg(withsummary_ARG, '\0', "withsummary", 0, 0, 0,
"Display a one line comment for each configuration node.\n")
arg(withcomments_ARG, '\0', "withcomments", 0, 0, 0,
"Display a full comment for each configuration node. For deprecated\n"
"settings, also display comments about deprecation.\n")
@@ -1104,9 +1104,6 @@ arg(withlocalpreamble_ARG, '\0', "withlocalpreamble", 0, 0, 0,
arg(withspaces_ARG, '\0', "withspaces", 0, 0, 0,
"Where appropriate, add more spaces in output for better readability.\n")
arg(withsummary_ARG, '\0', "withsummary", 0, 0, 0,
"Display a one line comment for each configuration node.\n")
arg(withversions_ARG, '\0', "withversions", 0, 0, 0,
"Also display a comment containing the version of introduction for\n"
"each configuration node. If the setting is deprecated, also display\n"
@@ -1144,28 +1141,24 @@ arg(writemostly_ARG, '\0', "writemostly", writemostly_VAL, ARG_GROUPABLE, 0,
* recognizes some of these and prints the option name to include
* the variant, e.g. man page generation prints --[raid]writebehind.
*/
arg(corelog_ARG, '\0', "corelog", 0, 0, 0, NULL)
arg(resizable_ARG, '\0', "resizable", bool_VAL, 0, 0, NULL)
arg(allocation_ARG, '\0', "allocation", bool_VAL, 0, 0, NULL)
arg(available_ARG, '\0', "available", activation_VAL, 0, 0, NULL)
arg(corelog_ARG, '\0', "corelog", 0, 0, 0, NULL)
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_VAL, 0, 0, NULL)
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", sizekb_VAL, 0, 0, NULL)
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", sizekb_VAL, 0, 0, NULL)
arg(raidrebuild_ARG, '\0', "raidrebuild", pv_VAL, ARG_GROUPABLE, 0, NULL)
arg(raidsyncaction_ARG, '\0', "raidsyncaction", syncaction_VAL, 0, 0, NULL)
arg(raidwritebehind_ARG, '\0', "raidwritebehind", number_VAL, 0, 0, NULL)
arg(raidwritemostly_ARG, '\0', "raidwritemostly", writemostly_VAL, ARG_GROUPABLE, 0, NULL)
arg(resizable_ARG, '\0', "resizable", bool_VAL, 0, 0, NULL)
arg(split_ARG, '\0', "split", 0, 0, 0, NULL)
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", sizekb_VAL, 0, 0, NULL)
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", sizekb_VAL, 0, 0, NULL)
arg(raidwritebehind_ARG, '\0', "raidwritebehind", number_VAL, 0, 0, NULL)
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", sizemb_VAL, 0, 0, NULL)
arg(split_ARG, '\0', "split", 0, 0, 0, NULL)
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_VAL, 0, 0, NULL)
/*
* ... and now the short args.
*/
/* Not used */
arg(help2_ARG, '?', "", 0, 0, 0, NULL)
arg(activate_ARG, 'a', "activate", activation_VAL, 0, 0,
"#pvscan\n"
"Auto-activate LVs in a VG when the PVs scanned have completed the VG.\n"
@@ -1238,6 +1231,11 @@ arg(all_ARG, 'a', "all", 0, 0, 0,
"Show information about devices that have not been initialized\n"
"by LVM, i.e. they are not PVs.\n")
arg(autobackup_ARG, 'A', "autobackup", bool_VAL, 0, 0,
"Specifies if metadata should be backed up automatically after a change.\n"
"Enabling this is strongly advised!\n"
"See \\fBvgcfgbackup\\fP(8) for more information.\n")
arg(activevolumegroups_ARG, 'A', "activevolumegroups", 0, 0, 0,
"Only select active VGs. The VG is considered active\n"
"if at least one of its LVs is active.\n")
@@ -1250,16 +1248,18 @@ arg(allpvs_ARG, 'A', "allpvs", 0, 0, 0,
"Show information about PVs outside the devices file.\n"
"Displays the device ID for PVs included in the devices file.\n")
arg(autobackup_ARG, 'A', "autobackup", bool_VAL, 0, 0,
"Specifies if metadata should be backed up automatically after a change.\n"
"Enabling this is strongly advised!\n"
"See \\fBvgcfgbackup\\fP(8) for more information.\n")
arg(background_ARG, 'b', "background", 0, 0, 0,
"If the operation requires polling, this option causes the command to\n"
"return before the operation is complete, and polling is done in the\n"
"background.\n")
arg(basevgname_ARG, 'n', "basevgname", string_VAL, 0, 0,
"By default the snapshot VG will be renamed to the original name plus a\n"
"numeric suffix to avoid duplicate naming (e.g. 'test_vg' would be renamed\n"
"to 'test_vg1'). This option will override the base VG name that is\n"
"used for all VG renames. If a VG already exists with the specified name\n"
"a numeric suffix will be added (like the previous example) to make it unique.\n")
arg(blockdevice_ARG, 'b', "blockdevice", 0, 0, 0,
"No longer used.\n")
@@ -1402,6 +1402,9 @@ arg(history_ARG, 'H', "history", 0, 0, 0,
"(This has no effect unless LVs were removed while\n"
"\\fBlvm.conf\\fP(5) \\fBmetadata/record_lvs_history\\fP was enabled.\n")
/* Not used */
arg(help2_ARG, '?', "", 0, 0, 0, NULL)
arg(import_ARG, 'i', "import", 0, 0, 0,
"Import exported VGs. Otherwise VGs that have been exported\n"
"will not be changed (nor will their associated PVs).\n")
@@ -1430,24 +1433,11 @@ arg(stripesize_ARG, 'I', "stripesize", sizekb_VAL, 0, 0,
"The amount of data that is written to one device before\n"
"moving to the next in a striped LV.\n")
arg(major_ARG, 'j', "major", number_VAL, ARG_GROUPABLE, 0,
"#lvcreate\n"
"#lvchange\n"
"Sets the major number of an LV block device.\n"
"#pvscan\n"
"The major number of a device.\n")
arg(logicalvolume_ARG, 'l', "logicalvolume", uint32_VAL, 0, 0,
"Sets the maximum number of LVs allowed in a VG.\n")
arg(setactivationskip_ARG, 'k', "setactivationskip", bool_VAL, 0, 0,
"Persistently sets (yes) or clears (no) the \"activation skip\" flag on an LV.\n"
"An LV with this flag set is not activated unless the\n"
"--ignoreactivationskip option is used by the activation command.\n"
"This flag is set by default on new thin snapshot LVs.\n"
"The flag is not applied to deactivation.\n"
"The current value of the flag is indicated in the lvs lv_attr bits.\n")
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", 0, 0, 0,
"Ignore the \"activation skip\" LV flag during activation\n"
"to allow LVs with the flag set to be activated.\n")
arg(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", uint32_VAL, 0, 0,
"Sets the maximum number of LVs allowed in a VG.\n")
/*
* The extents_VAL is overridden in configure_command_option_values()
@@ -1505,15 +1495,9 @@ arg(list_ARG, 'l', "list", 0, 0, 0,
"#vgmerge\n"
"Display merged destination VG like vgdisplay -v.\n")
arg(logicalvolume_ARG, 'l', "logicalvolume", uint32_VAL, 0, 0,
"Sets the maximum number of LVs allowed in a VG.\n")
arg(lvmpartition_ARG, 'l', "lvmpartition", 0, 0, 0,
"Only report PVs.\n")
arg(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", uint32_VAL, 0, 0,
"Sets the maximum number of LVs allowed in a VG.\n")
/*
* The sizemb_VAL is overridden in configure_command_option_values()
* according to the command being run. Different commands accept
@@ -1536,6 +1520,32 @@ arg(size_ARG, 'L', "size", sizemb_VAL, 0, 0,
"the value is not an absolute size, but is relative and added or subtracted\n"
"from the current size.\n")
arg(persistent_ARG, 'M', "persistent", bool_VAL, 0, 0,
"When yes, makes the specified minor number persistent.\n")
arg(major_ARG, 'j', "major", number_VAL, ARG_GROUPABLE, 0,
"#lvcreate\n"
"#lvchange\n"
"Sets the major number of an LV block device.\n"
"#pvscan\n"
"The major number of a device.\n")
arg(setactivationskip_ARG, 'k', "setactivationskip", bool_VAL, 0, 0,
"Persistently sets (yes) or clears (no) the \"activation skip\" flag on an LV.\n"
"An LV with this flag set is not activated unless the\n"
"--ignoreactivationskip option is used by the activation command.\n"
"This flag is set by default on new thin snapshot LVs.\n"
"The flag is not applied to deactivation.\n"
"The current value of the flag is indicated in the lvs lv_attr bits.\n")
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", 0, 0, 0,
"Ignore the \"activation skip\" LV flag during activation\n"
"to allow LVs with the flag set to be activated.\n")
arg(integritysettings_ARG, '\0', "integritysettings", string_VAL, ARG_GROUPABLE, 0,
"Specifies tunable kernel options for dm-integrity.\n"
"See \\fBlvmraid\\fP(7) for more information.\n")
arg(maps_ARG, 'm', "maps", 0, 0, 0,
"#lvdisplay\n"
"Display the mapping of logical extents to PVs and physical extents.\n"
@@ -1586,16 +1596,6 @@ arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_VAL, 0, 0,
"\\fBlvm2\\fP (or just \\fB2\\fP) is the current, standard format.\n"
"\\fBlvm1\\fP (or just \\fB1\\fP) is no longer used.\n")
arg(persistent_ARG, 'M', "persistent", bool_VAL, 0, 0,
"When yes, makes the specified minor number persistent.\n")
arg(basevgname_ARG, 'n', "basevgname", string_VAL, 0, 0,
"By default the snapshot VG will be renamed to the original name plus a\n"
"numeric suffix to avoid duplicate naming (e.g. 'test_vg' would be renamed\n"
"to 'test_vg1'). This option will override the base VG name that is\n"
"used for all VG renames. If a VG already exists with the specified name\n"
"a numeric suffix will be added (like the previous example) to make it unique.\n")
arg(name_ARG, 'n', "name", string_VAL, 0, 0,
"#lvcreate\n"
"#lvconvert\n"
@@ -1680,14 +1680,14 @@ arg(resizefs_ARG, 'r', "resizefs", 0, 0, 0,
"mounting behavior, and --nofsck to disable fsck. See --fs for more options\n"
"(--resizefs is equivalent to --fs resize.)\n")
/* Not used */
arg(reset_ARG, 'R', "reset", 0, 0, 0, NULL)
arg(regionsize_ARG, 'R', "regionsize", regionsizemb_VAL, 0, 0,
"Size of each raid or mirror synchronization region.\n"
"\\fBlvm.conf\\fP(5) \\fBactivation/raid_region_size\\fP can be used to\n"
"configure a default.\n")
/* Not used */
arg(reset_ARG, 'R', "reset", 0, 0, 0, NULL)
arg(physicalextentsize_ARG, 's', "physicalextentsize", sizemb_VAL, 0, 0,
"#vgcreate\n"
"Sets the physical extent size of PVs in the VG.\n"
@@ -1708,14 +1708,6 @@ arg(physicalextentsize_ARG, 's', "physicalextentsize", sizemb_VAL, 0, 0,
"contiguous range of extents used in a LV must start\n"
"and end on an extent boundary.\n")
arg(short_ARG, 's', "short", 0, 0, 0,
"#pvdisplay\n"
"Only display the size of the given PVs.\n"
"#vgdisplay\n"
"Give a short listing showing the existence of VGs.\n"
"#pvscan\n"
"Short listing format.\n")
arg(snapshot_ARG, 's', "snapshot", 0, 0, 0,
"#lvcreate\n"
"Create a snapshot. Snapshots provide a \"frozen image\" of an origin LV.\n"
@@ -1747,6 +1739,14 @@ arg(snapshot_ARG, 's', "snapshot", 0, 0, 0,
"Combine a former COW snapshot LV with a former origin LV to reverse\n"
"a previous --splitsnapshot command.\n")
arg(short_ARG, 's', "short", 0, 0, 0,
"#pvdisplay\n"
"Only display the size of the given PVs.\n"
"#vgdisplay\n"
"Give a short listing showing the existence of VGs.\n"
"#pvscan\n"
"Short listing format.\n")
/* Not used */
arg(stdin_ARG, 's', "stdin", 0, 0, 0, NULL)
@@ -1774,6 +1774,18 @@ arg(thin_ARG, 'T', "thin", 0, 0, 0,
"See --type thin, --type thin-pool, and --virtualsize.\n"
"See \\fBlvmthin\\fP(7) for more information about LVM thin provisioning.\n")
arg(updatemetadata_ARG, '\0', "updatemetadata", 0, 0, 0,
"Update VG metadata to correct problems.\n"
"If VG metadata was updated while a PV was missing, and the PV\n"
"reappears with an old version of metadata, then this option\n"
"(or any other command that writes metadata) will update the\n"
"metadata on the previously missing PV. If a PV was removed\n"
"from a VG while it was missing, and the PV reappears, using\n"
"this option will clear the outdated metadata from the previously\n"
"missing PV. If metadata text is damaged on one PV, using this\n"
"option will replace the damaged metadata text. For more severe\n"
"damage, e.g. with headers, see \\fBpvck\\fP(8).\n")
arg(uuid_ARG, 'u', "uuid", 0, 0, 0,
"#pvchange\n"
"Generate new random UUID for specified PVs.\n"
@@ -1799,6 +1811,9 @@ arg(verbose_ARG, 'v', "verbose", 0, ARG_COUNTABLE, 0,
"Set verbose level. Repeat from 1 to 4 times to increase the detail\n"
"of messages sent to stdout and stderr.\n")
/* Not used */
arg(volumegroup_ARG, 'V', "volumegroup", 0, 0, 0, NULL)
arg(virtualsize_ARG, 'V', "virtualsize", sizemb_VAL, 0, 0,
"The virtual size of a new thin LV.\n"
"See \\fBlvmthin\\fP(7) for more information about LVM thin provisioning.\n"
@@ -1813,9 +1828,6 @@ arg(virtualsize_ARG, 'V', "virtualsize", sizemb_VAL, 0, 0,
"Snapshots are less efficient than thin provisioning when creating\n"
"large sparse LVs (GiB).\n")
/* Not used */
arg(volumegroup_ARG, 'V', "volumegroup", 0, 0, 0, NULL)
arg(wipesignatures_ARG, 'W', "wipesignatures", bool_VAL, 0, 0,
"Controls detection and subsequent wiping of signatures on new LVs.\n"
"There is a prompt for each signature detected to confirm its wiping\n"

View File

@@ -1815,7 +1815,7 @@ DESC: Start or stop processing LV conversions.
vgchange --activate Active
OO: --activationmode ActivationMode, --ignoreactivationskip, --partial, --sysinit,
--readonly, --ignorelockingfailure, --monitor Bool, --poll Bool,
--autoactivation String, --persist String, OO_VGCHANGE
--autoactivation String, --persist start, OO_VGCHANGE
OP: VG|Tag|Select ...
IO: --ignoreskippedcluster
ID: vgchange_activate
@@ -1843,6 +1843,11 @@ OO: --select String, --removekey String, --majoritypvs, --force
ID: vgchange_persist
DESC: Perform persistent reservation commands on devices.
vgchange --setlockargs String VG|Tag|Select
OO: --select String
ID: vgchange_setlockargs
DESC: Set or clear lock_args flags to control lock manager behavior.
vgchange --lockstart
OO: --select String, --persist start
OP: VG|Tag|Select ...
@@ -1856,6 +1861,7 @@ ID: vgchange_lockstop
DESC: Stop the lockspace of a shared VG in lvmlockd.
vgchange --locktype LockType VG
OO: --setlockargs String
ID: vgchange_locktype
DESC: Change the lock type for a shared VG.
@@ -1880,7 +1886,7 @@ OO: --addtag Tag, --alloc Alloc, --autobackup Bool, --clustered Bool, --maxlogic
--metadatasize SizeMB, --pvmetadatacopies MetadataCopiesPV, --vgmetadatacopies MetadataCopiesVG,
--reportformat ReportFmt, --dataalignment SizeKB, --dataalignmentoffset SizeKB,
--shared, --systemid String, --locktype LockType, --setautoactivation Bool,
--setpersist String, --persist start
--setpersist String, --persist start, --setlockargs String
ID: vgcreate_general
---

View File

@@ -387,60 +387,24 @@ static uint64_t _lv_to_bits(struct command *cmd, char *name)
static unsigned _find_lvm_command_enum(const char *name)
{
#ifdef MAN_PAGE_GENERATOR
/* Validate cmd_names & command_names arrays are properly sorted.
* Also validate args.h options are sorted according to these rules:
* 1. sorted options without 'short_opt'st
* 2. sorted alias options (option without any description)
* 3. sorted options with and by short opt, long option name is secondary
* (Capital shorts opts are sorted after lowercase variant)
*/
/* Validate cmd_names & command_names arrays are properly sorted */
static int _names_validated = 0;
int i;
int shorts_only = 0;
if (!_names_validated++) {
if (!_names_validated) {
for (i = 1; i < CMD_COUNT - 1; i++)
if (strcmp(cmd_names[i].name, cmd_names[i + 1].name) > 0) {
log_error("File cmds.h has unsorted name entry (%s > %s).",
cmd_names[i].name, cmd_names[i + 1].name);
_names_validated = 0;
log_error("File cmds.h has unsorted name entry %s.",
cmd_names[i].name);
return 0;
}
for (i = 0; i < LVM_COMMAND_COUNT - 1; ++i) /* assume > 1 */
if (strcmp(command_names[i].name, command_names[i + 1].name) > 0) {
log_error("File commands.h has unsorted name entry (%s > %s).",
command_names[i].name, command_names[i + 1].name);
_names_validated = 0;
log_error("File commands.h has unsorted name entry %s.",
command_names[i].name);
return 0;
}
for (i = 0; i < ARG_COUNT - 1; ++i) /* assume > 1 */
if (opt_names[i + 1].short_opt) {
shorts_only = 1;
if (toupper(opt_names[i].short_opt) > toupper(opt_names[i + 1].short_opt) ||
((toupper(opt_names[i].short_opt) == toupper(opt_names[i + 1].short_opt)) &&
(opt_names[i].short_opt < opt_names[i + 1].short_opt))) {
log_error("File args.h has unsorted short option name entry (%c,%s > %c,%s).",
opt_names[i].short_opt, opt_names[i].long_opt,
opt_names[i + 1].short_opt, opt_names[i + 1].long_opt);
_names_validated = 0;
} else if (opt_names[i].short_opt == opt_names[i + 1].short_opt)
goto comp_long;
} else {
if (shorts_only) {
log_error("File args.h has long option listed within the short option name "
"entry (%s).", opt_names[i + 1].long_opt);
_names_validated = 0;
}
comp_long:
if (opt_names[i].desc && opt_names[i + 1].desc &&
strcmp(opt_names[i].long_opt, opt_names[i + 1].long_opt) > 0) {
log_error("File args.h has unsorted long option name entry (%s > %s.",
opt_names[i].long_opt, opt_names[i + 1].long_opt);
_names_validated = 0;
}
}
if (!_names_validated)
return 0;
_names_validated = 1;
}
#endif
if ((name = bsearch(name, command_names[0].name, LVM_COMMAND_COUNT,
@@ -1280,15 +1244,8 @@ static int _long_name_compare(const void *on1, const void *on2)
{
const struct opt_name * const *optname1 = on1;
const struct opt_name * const *optname2 = on2;
int result;
result = strcmp((*optname1)->long_opt + 2, (*optname2)->long_opt + 2);
/* Use opt_enum as tiebreaker for stable sorting when long option names are identical */
if (result == 0)
result = (*optname1)->opt_enum - (*optname2)->opt_enum;
return result;
return strcmp((*optname1)->long_opt + 2, (*optname2)->long_opt + 2);
}
/* Create list of option names for printing alphabetically. */
@@ -1316,44 +1273,6 @@ static int _copy_line(const char **line, size_t max_line, int *position)
return len;
}
/*
* Comparison function for qsort to sort opt_args by opt field.
* This ensures options are ordered by their creation order from args.h.
*/
static int _compare_opt_args(const void *a, const void *b)
{
const struct opt_arg *opt_a = (const struct opt_arg *)a;
const struct opt_arg *opt_b = (const struct opt_arg *)b;
return opt_a->opt - opt_b->opt;
}
/*
* Sort optional_opt_args and required_opt_arg by opts field for
* consistent ordering in man page and help generation.
*/
static void _sort_opt_args(void)
{
struct command *cmd;
unsigned i;
for (i = 0; i < COMMAND_COUNT; i++) {
cmd = &commands[i];
if (cmd->oo_count > 1)
qsort(cmd->optional_opt_args, cmd->oo_count,
sizeof(struct opt_arg), _compare_opt_args);
if (cmd->ro_count > 1)
qsort(cmd->required_opt_args, cmd->ro_count,
sizeof(struct opt_arg), _compare_opt_args);
if (cmd->any_ro_count > 1)
qsort(&cmd->required_opt_args[cmd->ro_count], cmd->any_ro_count,
sizeof(struct opt_arg), _compare_opt_args);
}
}
int define_commands(struct cmd_context *cmdtool, const char *run_name)
{
struct command *cmd = NULL;
@@ -1553,8 +1472,6 @@ int define_commands(struct cmd_context *cmdtool, const char *run_name)
memset(&_oo_lines, 0, sizeof(_oo_lines));
_oo_line_count = 0;
_sort_opt_args();
return 1;
}

View File

@@ -90,6 +90,7 @@ static const struct command_function _command_functions[CMD_COUNT] = {
{ vgchange_systemid_CMD, vgchange_systemid_cmd },
{ vgchange_setpersist_CMD, vgchange_setpersist_cmd },
{ vgchange_persist_CMD, vgchange_persist_cmd },
{ vgchange_setlockargs_CMD, vgchange_setlockargs_cmd },
/* lvdisplay variants */
{ lvdisplay_columns_CMD, lvdisplay_columns_cmd },

View File

@@ -691,22 +691,7 @@ static void _print_man_usage(char *lvmname, struct command *cmd)
if (_is_lvm_all_opt(opt_enum))
continue;
switch (opt_enum) {
case persist_ARG:
/* --persist may require specific argument (printed in bold) */
printf("[\n");
_print_man_option(cmd->name, opt_enum);
if (cmd->optional_opt_args[oo].def.val_bits) {
printf(" ");
_print_def_man(cname, opt_enum, &cmd->optional_opt_args[oo].def, 1, NULL);
}
printf("\n]\n");
break;
default:
_print_bracket_ds_opt_name(opt_enum);
}
_print_bracket_ds_opt_name(opt_enum);
printf(".br\n");
}

View File

@@ -521,7 +521,8 @@ int vgcreate_params_set_defaults(struct cmd_context *cmd,
*/
int vgcreate_params_set_from_args(struct cmd_context *cmd,
struct vgcreate_params *vp_new,
struct vgcreate_params *vp_def)
struct vgcreate_params *vp_def,
struct pvcreate_params *pp)
{
const char *system_id_arg_str;
const char *lock_type = NULL;
@@ -736,6 +737,29 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
vp_new->lock_type = lock_type;
log_debug("Setting lock_type to %s", vp_new->lock_type);
if (arg_is_set(cmd, setlockargs_ARG)) {
const char *set_args;
uint32_t lock_args_flags = 0;
if (!lock_type || strcmp(lock_type, "sanlock")) {
log_error("Using setlockargs requires sanlock lock type for shared VG.");
return 0;
}
if (!(set_args = arg_str_value(cmd, setlockargs_ARG, NULL)))
return_0;
if (!lockd_lockargs_get_user_flags(set_args, &lock_args_flags))
return_0;
if (!pp)
return_0;
if ((lock_args_flags & LOCKARGS_PERSIST) && !(pp->setpersist_flags & (SETPR_Y | SETPR_REQUIRE))) {
log_error("Using --setlockargs persist requires --setpersist y|require.");
return 0;
}
}
return 1;
}

View File

@@ -188,7 +188,8 @@ int vgcreate_params_set_defaults(struct cmd_context *cmd,
struct volume_group *vg);
int vgcreate_params_set_from_args(struct cmd_context *cmd,
struct vgcreate_params *vp_new,
struct vgcreate_params *vp_def);
struct vgcreate_params *vp_def,
struct pvcreate_params *pp);
int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
activation_change_t activate);
int lv_refresh(struct cmd_context *cmd, struct logical_volume *lv);

View File

@@ -175,6 +175,7 @@ int vgchange_lock_start_stop_cmd(struct cmd_context *cmd, int argc, char **argv)
int vgchange_systemid_cmd(struct cmd_context *cmd, int argc, char **argv);
int vgchange_setpersist_cmd(struct cmd_context *cmd, int argc, char **argv);
int vgchange_persist_cmd(struct cmd_context *cmd, int argc, char **argv);
int vgchange_setlockargs_cmd(struct cmd_context *cmd, int argc, char **argv);
const struct opt_name *get_opt_name(int opt);
const struct val_name *get_val_name(int val);

View File

@@ -205,7 +205,6 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
const struct lv_list *lvl;
struct pv_list *pvl;
int do_activate = is_change_activating(activate);
const char *pr_op = NULL;
/*
* We can get here in the odd case where an LV is already active in
@@ -234,23 +233,8 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
}
}
if (arg_is_set(cmd, persist_ARG))
pr_op = arg_str_value(cmd, persist_ARG, NULL);
/*
* vgchange -ay --persist start
* This command bypasses the persist_is_started check in vg_read (disable_pr_required.)
* It is not permitted for shared VGs, where PR start happens before lockstart.
* For non-shared VGs, require a successful persist_start() here before activating.
*/
if (do_activate && pr_op && !strcmp(pr_op, "start") && cmd->disable_pr_required) {
if (vg_is_shared(vg)) {
log_error("Activation with persist start not permitted for shared VG %s.", vg->name);
return 0;;
}
if (!persist_start_include(cmd, vg, (activate == CHANGE_AAY), 0, NULL))
return_0;
}
if (do_activate && !persist_start_include(cmd, vg, (activate == CHANGE_AAY), 0, NULL))
return 0;
/*
* Safe, since we never write out new metadata here. Required for
@@ -300,18 +284,6 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
r = 0;
}
if (!do_activate && pr_op && !strcmp(pr_op, "stop")) {
/* For a shared VG, PR stop happens after lockstop. */
if (vg_is_shared(vg))
log_warn("WARNING: skipping persist stop for shared VG.");
else if (lvs_in_vg_activated(vg))
log_warn("WARNING: skipping persist stop for incomplete deactivation.");
else if (!persist_stop(cmd, vg)) {
log_error("Failed to stop persistent reservation.");
r = 0;
}
}
/*
* Possibly trigger auto-generation of system.devices:
* - if root_dm_uuid contains vg->id, and
@@ -683,6 +655,7 @@ static int _passes_lock_start_filter(struct cmd_context *cmd,
static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg,
struct vgchange_params *vp)
{
uint64_t our_key = 0;
int auto_opt = 0;
int exists = 0;
int r;
@@ -713,12 +686,12 @@ do_start:
if (!persist_start_include(cmd, vg, 0, auto_opt, NULL))
return 0;
if ((vg->pr & (VG_PR_REQUIRE|VG_PR_AUTOSTART)) && !persist_is_started(cmd, vg, 0)) {
if ((vg->pr & (VG_PR_REQUIRE|VG_PR_AUTOSTART)) && !persist_is_started(cmd, vg, 0, &our_key)) {
log_error("VG %s PR should be started before locking (vgchange --persist start)", vg->name);
return 0;
}
r = lockd_start_vg(cmd, vg, &exists);
r = lockd_start_vg(cmd, vg, our_key, &exists);
if (r)
vp->lock_start_count++;
@@ -1127,37 +1100,10 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
if (noupdate)
cmd->ignore_device_name_mismatch = 1;
/*
* PR usage with activation/deactivation.
*/
if (arg_is_set(cmd, activate_ARG)) {
int is_activating = is_change_activating((activation_change_t)arg_uint_value(cmd, activate_ARG, CHANGE_AY));
/* Always allow deactivation without PR being started. */
if (!is_activating)
cmd->disable_pr_required = 1;
/* Either "-ay --persist start", or "-an --persist stop". */
if (arg_is_set(cmd, persist_ARG)) {
const char *pr_op = arg_str_value(cmd, persist_ARG, NULL);
if (strcmp(pr_op, "start") && strcmp(pr_op, "stop")) {
log_error("Invalid --persist usage.");
return ECMD_FAILED;
}
if ((!strcmp(pr_op, "start") && !is_activating) ||
(!strcmp(pr_op, "stop") && is_activating)) {
log_error("Invalid --persist usage.");
return ECMD_FAILED;
}
/*
* Setting disable_pr_required to bypass the
* persist_is_started check in vg_read requires
* persist_start in vgchange_activate.
*/
if (!strcmp(pr_op, "start") && is_activating)
cmd->disable_pr_required = 1;
}
}
/* Allow LVs to be deactivated without PR started. */
if (arg_is_set(cmd, activate_ARG) &&
!is_change_activating((activation_change_t)arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
cmd->disable_pr_required = 1;
/*
* If the devices file includes PVs stacked on LVs, then
@@ -1339,7 +1285,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg,
vg->system_id = NULL;
if (!lockd_init_vg(cmd, vg, lock_type, lv_lock_count)) {
if (!lockd_init_vg(cmd, vg, lock_type, lv_lock_count, arg_str_value(cmd, setlockargs_ARG, NULL))) {
log_error("Failed to initialize lock args for lock type %s", lock_type);
return 0;
}
@@ -1879,7 +1825,7 @@ static int _vgchange_setpersist_single(struct cmd_context *cmd, const char *vg_n
* enabling/starting PR, otherwise enabling/starting PR will
* cause i/o to begin failing on those other hosts.
*/
if (on && vg_is_shared(vg) && !persist_is_started(cmd, vg, 1) &&
if (on && vg_is_shared(vg) && !persist_is_started(cmd, vg, 1, NULL) &&
lockd_vg_is_started(cmd, vg, NULL) && lockd_vg_is_busy(cmd, vg)) {
log_error("VG lockspace should be stopped on all hosts (vgchange --lockstop) before enabling PR.");
return ECMD_FAILED;
@@ -1949,3 +1895,51 @@ int vgchange_setpersist_cmd(struct cmd_context *cmd, int argc, char **argv)
return ret;
}
static int _vgchange_setlockargs_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg,
struct processing_handle *handle)
{
const char *set = arg_str_value(cmd, setlockargs_ARG, NULL);
uint64_t our_key_held = 0;
if (!set)
return_ECMD_FAILED;
/*
* lockd_setlockargs gets exclusive PR (if the VG is using PR),
* stops the lockspace, and sets new vg->lock_args that are
* written below. If lockd_setlockargs got the ex PR, then
* persist_upgrade_stop releases the PR.
*/
if (!lockd_setlockargs(cmd, vg, set, &our_key_held))
return_ECMD_FAILED;
if (!vg_write(vg) || !vg_commit(vg))
return_ECMD_FAILED;
if (our_key_held && !persist_upgrade_stop(cmd, vg, our_key_held))
log_warn("Failed to stop PR.");
persist_key_file_remove(cmd, vg);
log_print_unless_silent("Volume group \"%s\" successfully changed.", vg->name);
return ECMD_PROCESSED;
}
int vgchange_setlockargs_cmd(struct cmd_context *cmd, int argc, char **argv)
{
struct processing_handle *handle;
uint32_t flags = READ_FOR_UPDATE;
int ret;
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
return ECMD_FAILED;
}
ret = process_each_vg(cmd, argc, argv, NULL, NULL, flags, 0, handle, &_vgchange_setlockargs_single);
destroy_processing_handle(cmd, handle);
return ret;
}

View File

@@ -46,13 +46,12 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
pp.pv_names = argv;
pp.vg_name = vg_name;
pp.preserve_existing = 1; /* Don't create a new PV on top of an existing PV like pvcreate does. */
pp.check_consistent_block_size = 1;
if (!vgcreate_params_set_defaults(cmd, &vp_def, NULL))
return EINVALID_CMD_LINE;
vp_def.vg_name = vg_name;
if (!vgcreate_params_set_from_args(cmd, &vp_new, &vp_def))
if (!vgcreate_params_set_from_args(cmd, &vp_new, &vp_def, &pp))
return EINVALID_CMD_LINE;
if (!vgcreate_params_validate(cmd, &vp_new))
@@ -118,8 +117,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
!vg_set_max_pv(vg, vp_new.max_pv) ||
!vg_set_alloc_policy(vg, vp_new.alloc) ||
!vg_set_system_id(vg, vp_new.system_id) ||
!vg_set_mda_copies(vg, vp_new.vgmetadatacopies) ||
!vg_set_persist(vg, pp.setpersist_flags))
!vg_set_persist(vg, pp.setpersist_flags) ||
!vg_set_mda_copies(vg, vp_new.vgmetadatacopies))
goto_bad;
if (arg_is_set(cmd, setautoactivation_ARG) && !arg_int_value(cmd, setautoactivation_ARG, 1))
@@ -161,7 +160,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
* a local VG. lockd_init_vg() then writes the VG a second time with
* both lock_type and lock_args set.
*/
if (!lockd_init_vg(cmd, vg, vp_new.lock_type, 0)) {
if (!lockd_init_vg(cmd, vg, vp_new.lock_type, 0, arg_str_value(cmd, setlockargs_ARG, NULL))) {
log_error("Failed to initialize lock args for lock type %s",
vp_new.lock_type);
vg_remove_pvs(vg);
@@ -188,7 +187,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
goto out;
}
if (!lockd_start_vg(cmd, vg, NULL)) {
if (!lockd_start_vg(cmd, vg, 0, NULL)) {
log_error("Failed to start locking");
goto out;
}

View File

@@ -74,9 +74,6 @@ static int _vgremove_single(struct cmd_context *cmd, const char *vg_name,
!lvremove_single(cmd, vg->pool_metadata_spare_lv, &void_handle))
return_ECMD_FAILED;
if (pr_stop && !persist_vgremove_before(cmd, vg, &pr_devs, &pr_key))
return_ECMD_FAILED;
if (!lockd_free_vg_before(cmd, vg, 0, arg_count(cmd, yes_ARG)))
return_ECMD_FAILED;
@@ -85,6 +82,9 @@ static int _vgremove_single(struct cmd_context *cmd, const char *vg_name,
online_vgremove(vg);
if (pr_stop && !persist_stop_prepare(cmd, vg, &pr_devs, &pr_key))
return_ECMD_FAILED;
vg_remove_pvs(vg);
if (!vg_remove(vg))
@@ -92,8 +92,11 @@ static int _vgremove_single(struct cmd_context *cmd, const char *vg_name,
lockd_free_vg_final(cmd, vg);
if (pr_stop)
persist_vgremove_after(cmd, vg, &pr_devs, pr_key);
if (pr_stop) {
if (!persist_stop_run(cmd, vg, &pr_devs, pr_key))
log_warn("WARNING: persistent reservation not removed from devices.");
persist_key_file_remove(cmd, vg->name);
}
return ECMD_PROCESSED;
}

View File

@@ -609,7 +609,7 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
goto_bad;
}
vp_def.vg_name = vg_name_to;
if (!vgcreate_params_set_from_args(cmd, &vp_new, &vp_def)) {
if (!vgcreate_params_set_from_args(cmd, &vp_new, &vp_def, NULL)) {
r = EINVALID_CMD_LINE;
goto_bad;
}