mirror of
git://sourceware.org/git/lvm2.git
synced 2025-09-23 17:44:22 +03:00
Compare commits
2 Commits
master
...
dev-dct-se
Author | SHA1 | Date | |
---|---|---|---|
|
60270a4288 | ||
|
813d333e0c |
@@ -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
|
||||
=====================================
|
||||
|
@@ -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.
|
||||
|
@@ -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"])
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
@@ -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;
|
||||
|
264
daemons/lvmlockd/lvmlockd-helper.c
Normal file
264
daemons/lvmlockd/lvmlockd-helper.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
@@ -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, §or_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, §or_size, &align_size, &align_mb, &ss_flags, &rs_flags, NULL);
|
||||
rv = read_lockspace_info(disk_path, 1, §or_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, §or_size, &align_size, &align_mb, &ss_flags, &rs_flags, &hs);
|
||||
rv = read_lockspace_info(disk_path, lms->ss.host_id, §or_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, §or_size, &align_size);
|
||||
rv = read_info_file(ls->vg_name, &host_id, &generation, §or_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, §or_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;
|
||||
}
|
||||
|
||||
|
@@ -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!
|
||||
|
||||
|
||||
|
@@ -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")
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -341,3 +341,4 @@ void split_line(char *buf, int *argc, char **argv, int max_args, char sep)
|
||||
}
|
||||
*argc = i;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
@@ -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
|
||||
[
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
[
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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\ .\|.\|.\& ]
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 ]
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
[
|
||||
|
@@ -140,11 +140,11 @@ LVs allocated on it.
|
||||
]
|
||||
.br
|
||||
[
|
||||
.O_reportformat
|
||||
.O_setphysicalvolumesize
|
||||
]
|
||||
.br
|
||||
[
|
||||
.O_setphysicalvolumesize
|
||||
.O_reportformat
|
||||
]
|
||||
.br
|
||||
[ COMMON_OPTIONS ]
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
[
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
[
|
||||
|
@@ -162,7 +162,7 @@ Export specified VGs.
|
||||
]
|
||||
.br
|
||||
[
|
||||
\fB--persist\fP \fBstop\fP
|
||||
.O_persist
|
||||
]
|
||||
.br
|
||||
[ COMMON_OPTIONS ]
|
||||
|
@@ -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
|
||||
|
@@ -152,7 +152,7 @@ Import specified VGs.
|
||||
]
|
||||
.br
|
||||
[
|
||||
\fB--persist\fP \fBstart\fP
|
||||
.O_persist
|
||||
]
|
||||
.br
|
||||
[ COMMON_OPTIONS ]
|
||||
|
@@ -136,11 +136,11 @@ changes the associated VG and PV UUIDs.
|
||||
\fIPV\fP\ .\|.\|.\&
|
||||
.RS
|
||||
[
|
||||
.O_import
|
||||
.O_basevgname
|
||||
]
|
||||
.br
|
||||
[
|
||||
.O_basevgname
|
||||
.O_import
|
||||
]
|
||||
.br
|
||||
[
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
500
tools/args.h
500
tools/args.h
@@ -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"
|
||||
|
@@ -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
|
||||
|
||||
---
|
||||
|
103
tools/command.c
103
tools/command.c
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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 },
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
124
tools/vgchange.c
124
tools/vgchange.c
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user