mirror of
git://sourceware.org/git/lvm2.git
synced 2025-11-16 04:23:50 +03:00
Compare commits
2 Commits
main
...
dev-dct-lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8854c5d0e | ||
|
|
f36289d568 |
@@ -2725,11 +2725,11 @@ bad:
|
||||
static void _usage(char *prog, FILE *file)
|
||||
{
|
||||
fprintf(file, "Usage:\n"
|
||||
"%s [-d [-d [-d]]] [-e path] [-f] [-g seconds] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
|
||||
"%s [-d [-d [-d]]] [-e path] [-g seconds] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
|
||||
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
|
||||
" -e Select a file path checked on exit\n"
|
||||
" -f Don't fork, run in the foreground\n"
|
||||
" -g Grace period for thread cleanup (0-300 seconds, default: %d)\n"
|
||||
" -f Don't fork, run in the foreground\n"
|
||||
" -h Show this help information\n"
|
||||
" -i Query running instance of dmeventd for info\n"
|
||||
" -l Log to stdout,stderr instead of syslog\n"
|
||||
@@ -2758,8 +2758,17 @@ int main(int argc, char *argv[])
|
||||
optarg = (char*) "";
|
||||
while ((opt = getopt(argc, argv, ":?e:g:fhiVdlR")) != EOF) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
debug_level++;
|
||||
case 'h':
|
||||
_usage(argv[0], stdout);
|
||||
return EXIT_SUCCESS;
|
||||
case '?':
|
||||
_usage(argv[0], stderr);
|
||||
return EXIT_SUCCESS;
|
||||
case 'i':
|
||||
info++;
|
||||
break;
|
||||
case 'R':
|
||||
restart++;
|
||||
break;
|
||||
case 'e':
|
||||
if (strchr(optarg, '"')) {
|
||||
@@ -2768,9 +2777,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
_exit_on=optarg;
|
||||
break;
|
||||
case 'f':
|
||||
_foreground++;
|
||||
break;
|
||||
case 'g':
|
||||
_grace_period = atoi(optarg);
|
||||
if (_grace_period < 0 || _grace_period > 300) {
|
||||
@@ -2778,22 +2784,15 @@ int main(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
_usage(argv[0], stdout);
|
||||
return EXIT_SUCCESS;
|
||||
case 'i':
|
||||
info++;
|
||||
case 'f':
|
||||
_foreground++;
|
||||
break;
|
||||
case 'd':
|
||||
debug_level++;
|
||||
break;
|
||||
case 'l':
|
||||
use_syslog = 0;
|
||||
break;
|
||||
case '?':
|
||||
/* getopt() returns '?' for unknown option */
|
||||
_usage(argv[0], stderr);
|
||||
return EXIT_SUCCESS;
|
||||
case 'R':
|
||||
restart++;
|
||||
break;
|
||||
case 'V':
|
||||
printf("dmeventd version: %s\n", DM_LIB_VERSION);
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#include "lib/metadata/metadata.h"
|
||||
#include "lib/config/defaults.h"
|
||||
#include "lib/config/config.h"
|
||||
#include "lib/misc/lvm-string.h"
|
||||
#include "lib/activate/activate.h"
|
||||
#include "lib/filters/filter.h"
|
||||
@@ -33,6 +34,7 @@
|
||||
#include "lib/format_text/archiver.h"
|
||||
#include "lib/lvmpolld/lvmpolld-client.h"
|
||||
#include "lib/device/device_id.h"
|
||||
#include "include/lvm-version.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -654,6 +656,43 @@ static void _init_device_ids_refresh(struct cmd_context *cmd)
|
||||
cmd->device_ids_check_hostname = 1;
|
||||
}
|
||||
|
||||
void log_debug_config(struct cmd_context *cmd)
|
||||
{
|
||||
struct config_def_tree_spec tree_spec = {0};
|
||||
struct cft_check_handle *handle = NULL;
|
||||
unsigned int major, minor, patchlevel;
|
||||
|
||||
/* Parse version from LVM_VERSION string */
|
||||
if (sscanf(LVM_VERSION, "%u.%u.%u", &major, &minor, &patchlevel) != 3) {
|
||||
major = 0;
|
||||
minor = 0;
|
||||
patchlevel = 0;
|
||||
}
|
||||
|
||||
tree_spec.cmd = cmd;
|
||||
tree_spec.type = CFG_DEF_TREE_CURRENT;
|
||||
tree_spec.current_cft = cmd->cft;
|
||||
tree_spec.version = vsn(major, minor, patchlevel);
|
||||
tree_spec.log_debug = 1;
|
||||
|
||||
/* Check config to mark differences from defaults */
|
||||
if (!(handle = get_config_tree_check_handle(cmd, cmd->cft)))
|
||||
return;
|
||||
|
||||
handle->force_check = 1;
|
||||
handle->suppress_messages = 1;
|
||||
handle->skip_if_checked = 0;
|
||||
handle->check_diff = 1;
|
||||
|
||||
if (!config_def_check(handle))
|
||||
return;
|
||||
|
||||
tree_spec.check_status = handle->status;
|
||||
|
||||
/* Write config via log_debug */
|
||||
config_write(cmd->cft, &tree_spec, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static int _process_config(struct cmd_context *cmd)
|
||||
{
|
||||
mode_t old_umask;
|
||||
|
||||
@@ -316,6 +316,8 @@ int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache);
|
||||
int init_connections(struct cmd_context *cmd);
|
||||
int init_run_by_dmeventd(struct cmd_context *cmd);
|
||||
|
||||
void log_debug_config(struct cmd_context *cmd);
|
||||
|
||||
/*
|
||||
* A config context is a very light weight cmd struct that
|
||||
* is only used for reading config settings from lvm.conf,
|
||||
|
||||
@@ -1693,6 +1693,57 @@ struct out_baton {
|
||||
|
||||
#define MAX_COMMENT_LINE 512
|
||||
|
||||
static void _out_line(struct out_baton *out, const char *fmt, ...)
|
||||
__attribute__ ((format(printf, 2, 3)));
|
||||
|
||||
static void _out_line(struct out_baton *out, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[4096];
|
||||
const char *p;
|
||||
size_t len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (out->tree_spec->log_debug) {
|
||||
if (vsnprintf(buf, sizeof(buf), fmt, ap) >= 0) {
|
||||
/* Skip section headers and brackets for log_debug output */
|
||||
p = buf;
|
||||
/* Skip leading whitespace */
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
|
||||
/* Skip empty lines */
|
||||
if (*p == '\0' || *p == '\n')
|
||||
goto out;
|
||||
|
||||
/* Skip closing brackets */
|
||||
if (*p == '}') {
|
||||
va_end(ap);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Skip lines ending with opening bracket (section headers) */
|
||||
len = strlen(p);
|
||||
if (len > 0 && p[len - 1] == '\n')
|
||||
len--;
|
||||
while (len > 0 && (p[len - 1] == ' ' || p[len - 1] == '\t'))
|
||||
len--;
|
||||
if (len > 1 && p[len - 1] == '{')
|
||||
goto out;
|
||||
|
||||
/* Print without leading whitespace and without trailing newline */
|
||||
if (len > 0 && p[len] == '\n')
|
||||
log_debug("%.*s", (int)len, p);
|
||||
else
|
||||
log_debug("%s", p);
|
||||
}
|
||||
} else {
|
||||
vfprintf(out->fp, fmt, ap);
|
||||
}
|
||||
out:
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static int _copy_one_line(const char *comment, char *line, int *pos, int len)
|
||||
{
|
||||
int p;
|
||||
@@ -1766,11 +1817,11 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
|
||||
|
||||
if (out->tree_spec->withsummary || out->tree_spec->withcomments) {
|
||||
_cfg_def_make_path(path, sizeof(path), cfg_def->id, cfg_def, 1);
|
||||
fprintf(out->fp, "\n");
|
||||
fprintf(out->fp, "%s# Configuration %s %s.\n", line, node_type_name, path);
|
||||
_out_line(out, "\n");
|
||||
_out_line(out, "%s# Configuration %s %s.\n", line, node_type_name, path);
|
||||
|
||||
if (out->tree_spec->withcomments && is_deprecated && cfg_def->deprecation_comment)
|
||||
fprintf(out->fp, "%s# %s", line, cfg_def->deprecation_comment);
|
||||
_out_line(out, "%s# %s", line, cfg_def->deprecation_comment);
|
||||
|
||||
if (cfg_def->comment) {
|
||||
int pos = 0;
|
||||
@@ -1780,7 +1831,7 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
|
||||
continue;
|
||||
commentline[0] = '\0';
|
||||
}
|
||||
fprintf(out->fp, "%s#%s%s\n", line, commentline[0] ? " " : "", commentline);
|
||||
_out_line(out, "%s#%s%s\n", line, commentline[0] ? " " : "", commentline);
|
||||
/* withsummary prints only the first comment line. */
|
||||
if (!out->tree_spec->withcomments)
|
||||
break;
|
||||
@@ -1788,37 +1839,37 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
|
||||
}
|
||||
|
||||
if (is_deprecated)
|
||||
fprintf(out->fp, "%s# This configuration %s is deprecated.\n", line, node_type_name);
|
||||
_out_line(out, "%s# This configuration %s is deprecated.\n", line, node_type_name);
|
||||
|
||||
if (cfg_def->flags & CFG_ADVANCED)
|
||||
fprintf(out->fp, "%s# This configuration %s is advanced.\n", line, node_type_name);
|
||||
_out_line(out, "%s# This configuration %s is advanced.\n", line, node_type_name);
|
||||
|
||||
if (cfg_def->flags & CFG_UNSUPPORTED)
|
||||
fprintf(out->fp, "%s# This configuration %s is not officially supported.\n", line, node_type_name);
|
||||
_out_line(out, "%s# This configuration %s is not officially supported.\n", line, node_type_name);
|
||||
|
||||
if (cfg_def->flags & CFG_NAME_VARIABLE)
|
||||
fprintf(out->fp, "%s# This configuration %s has variable name.\n", line, node_type_name);
|
||||
_out_line(out, "%s# This configuration %s has variable name.\n", line, node_type_name);
|
||||
|
||||
if (cfg_def->flags & CFG_DEFAULT_UNDEFINED)
|
||||
fprintf(out->fp, "%s# This configuration %s does not have a default value defined.\n", line, node_type_name);
|
||||
_out_line(out, "%s# This configuration %s does not have a default value defined.\n", line, node_type_name);
|
||||
|
||||
if (cfg_def->flags & CFG_DEFAULT_COMMENTED)
|
||||
fprintf(out->fp, "%s# This configuration %s has an automatic default value.\n", line, node_type_name);
|
||||
_out_line(out, "%s# This configuration %s has an automatic default value.\n", line, node_type_name);
|
||||
|
||||
if ((out->tree_spec->type == CFG_DEF_TREE_FULL) &&
|
||||
(out->tree_spec->check_status[cn->id] & CFG_USED))
|
||||
fprintf(out->fp, "%s# Value defined in existing configuration has been used for this setting.\n", line);
|
||||
_out_line(out, "%s# Value defined in existing configuration has been used for this setting.\n", line);
|
||||
}
|
||||
|
||||
if (out->tree_spec->withversions) {
|
||||
if (!_get_config_node_version(cfg_def->since_version, version))
|
||||
return_0;
|
||||
fprintf(out->fp, "%s# Available since version %s.\n", line, version);
|
||||
_out_line(out, "%s# Available since version %s.\n", line, version);
|
||||
|
||||
if (is_deprecated) {
|
||||
if (!_get_config_node_version(cfg_def->deprecated_since_version, version))
|
||||
return_0;
|
||||
fprintf(out->fp, "%s# Deprecated since version %s.\n", line, version);
|
||||
_out_line(out, "%s# Deprecated since version %s.\n", line, version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1866,7 +1917,7 @@ static int _out_line_fn(const struct dm_config_node *cn, const char *line, void
|
||||
if (out->tree_spec->withsummary && cfg_def->comment)
|
||||
_copy_one_line(cfg_def->comment, summary, &pos, strlen(cfg_def->comment));
|
||||
|
||||
fprintf(out->fp, "%s%s%s%s%s%s%s\n", config_path,
|
||||
_out_line(out, "%s%s%s%s%s%s%s\n", config_path,
|
||||
*summary || out->tree_spec->withversions ? " - ": "",
|
||||
*summary ? summary : "",
|
||||
*summary ? " " : "",
|
||||
@@ -1907,7 +1958,7 @@ static int _out_line_fn(const struct dm_config_node *cn, const char *line, void
|
||||
/* print with # at the front to comment out the line */
|
||||
if (_should_print_cfg_with_undef_def_val(out, cfg_def, cn)) {
|
||||
space_prefix_len = strspn(line, "\t ");
|
||||
fprintf(out->fp, "%.*s%s%s\n", space_prefix_len, line, "# ",
|
||||
_out_line(out, "%.*s%s%s\n", space_prefix_len, line, "# ",
|
||||
line + space_prefix_len);
|
||||
}
|
||||
return 1;
|
||||
@@ -1915,7 +1966,7 @@ static int _out_line_fn(const struct dm_config_node *cn, const char *line, void
|
||||
|
||||
/* print the line as it is */
|
||||
if (_should_print_cfg_with_undef_def_val(out, cfg_def, cn))
|
||||
fprintf(out->fp, "%s\n", line);
|
||||
_out_line(out, "%s\n", line);
|
||||
|
||||
if (out->tree_spec->valuesonly && !(cfg_def->type & CFG_TYPE_SECTION) && space_prefix_len)
|
||||
dm_pool_free(out->mem, (char *) line);
|
||||
@@ -1945,7 +1996,11 @@ int config_write(struct dm_config_tree *cft,
|
||||
int free_fp = 1;
|
||||
int r = 1;
|
||||
|
||||
if (!file) {
|
||||
if (tree_spec->log_debug) {
|
||||
/* When using log_debug, we don't need a file pointer */
|
||||
baton.fp = NULL;
|
||||
free_fp = 0;
|
||||
} else if (!file) {
|
||||
baton.fp = stdout;
|
||||
file = "stdout";
|
||||
free_fp = 0;
|
||||
@@ -1954,12 +2009,13 @@ int config_write(struct dm_config_tree *cft,
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_verbose("Dumping configuration to %s", file);
|
||||
if (!tree_spec->log_debug)
|
||||
log_verbose("Dumping configuration to %s", file);
|
||||
|
||||
if (tree_spec->withgeneralpreamble)
|
||||
fprintf(baton.fp, CFG_PREAMBLE_GENERAL);
|
||||
_out_line(&baton, CFG_PREAMBLE_GENERAL);
|
||||
if (tree_spec->withlocalpreamble)
|
||||
fprintf(baton.fp, CFG_PREAMBLE_LOCAL);
|
||||
_out_line(&baton, CFG_PREAMBLE_LOCAL);
|
||||
|
||||
if (!argc) {
|
||||
if (!dm_config_write_node_out(cft->root, &_out_spec, &baton)) {
|
||||
|
||||
@@ -177,6 +177,7 @@ struct config_def_tree_spec {
|
||||
unsigned withgeneralpreamble:1; /* include preamble for a general config file */
|
||||
unsigned withlocalpreamble:1; /* include preamble for a local config file */
|
||||
unsigned valuesonly:1; /* print only values without keys */
|
||||
unsigned log_debug:1; /* use log_debug() instead of file output */
|
||||
uint8_t *check_status; /* status of last tree check (currently needed for CFG_DEF_TREE_MISSING only) */
|
||||
};
|
||||
|
||||
|
||||
@@ -1069,9 +1069,6 @@ static const char *_find_config_str(const void *start, node_lookup_fn find_fn,
|
||||
log_warn("WARNING: Ignoring unsupported value for %s.", path);
|
||||
}
|
||||
|
||||
if (fail)
|
||||
log_very_verbose("%s not found in config: defaulting to %s",
|
||||
path, fail);
|
||||
return fail;
|
||||
}
|
||||
|
||||
@@ -1097,8 +1094,6 @@ static int64_t _find_config_int64(const void *start, node_lookup_fn find,
|
||||
return n->v->v.i;
|
||||
}
|
||||
|
||||
log_very_verbose("%s not found in config: defaulting to %" PRId64,
|
||||
path, fail);
|
||||
return fail;
|
||||
}
|
||||
|
||||
@@ -1112,9 +1107,6 @@ static float _find_config_float(const void *start, node_lookup_fn find,
|
||||
return n->v->v.f;
|
||||
}
|
||||
|
||||
log_very_verbose("%s not found in config: defaulting to %f",
|
||||
path, fail);
|
||||
|
||||
return fail;
|
||||
|
||||
}
|
||||
@@ -1169,9 +1161,6 @@ static int _find_config_bool(const void *start, node_lookup_fn find,
|
||||
}
|
||||
}
|
||||
|
||||
log_very_verbose("%s not found in config: defaulting to %d",
|
||||
path, fail);
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
|
||||
@@ -183,11 +183,11 @@ the device IDs. LVM commands automatically update this information if it
|
||||
changes. This includes the last known device name, and the PV UUID (PVID)
|
||||
from the LVM disk header.
|
||||
.P
|
||||
Check if the devices file content needs to be updated:
|
||||
To check if devices file content needs to be updated, run:
|
||||
.br
|
||||
.B lvmdevices --check
|
||||
.P
|
||||
Update devices file fields that are outdated:
|
||||
To update devices file fields that may be outdated, run:
|
||||
.br
|
||||
.B lvmdevices --update
|
||||
.P
|
||||
@@ -219,36 +219,26 @@ PART: the partition number if a PV exists on a partition.
|
||||
.P
|
||||
.SS device ID refresh
|
||||
.
|
||||
When LVM writes system.devices, it includes a local machine ID in the
|
||||
system.devices file (as PRODUCT_UUID or HOSTNAME.) When LVM reads
|
||||
system.devices, it compares this saved machine ID value to the current
|
||||
machine. This allows lvm to detect when system.devices has been copied
|
||||
or restored onto a different machine. When this happens, lvm switches
|
||||
its method for locating the PVs in system.devices, and locates PVs based
|
||||
on their PVID rather than the device ID (this involves scanning all devices
|
||||
on the system.) If a PVID is found on a device with a different device ID,
|
||||
then the device ID in system.devices is automatically updated to the new
|
||||
device ID.
|
||||
When LVM writes system.devices, it includes an ID of the machine running
|
||||
the command (see PRODUCT_UUID or HOSTNAME above.) When LVM reads
|
||||
system.devices, it compares the saved value to the current machine's value
|
||||
to detect if system.devices has been copied from another machine. When the
|
||||
saved and current values differ, it indicates that PVs may have been copied or
|
||||
restored onto new devices on a new machine. When this happens, lvm will
|
||||
search for new devices that hold the PVIDs listed in system.devices. If a
|
||||
PVID is found on a new device, lvm updates the device ID in system.devices
|
||||
to match the new location for the PV. The command lvmdevices --check
|
||||
--refresh can also be used to do this manually.
|
||||
.P
|
||||
While this refresh process is triggered automatically by a new machine
|
||||
ID, it can also be performed manually with the following commands:
|
||||
.P
|
||||
Check if system.devices would be updated with new device IDs:
|
||||
.br
|
||||
.B lvmdevices --check --refresh
|
||||
.P
|
||||
Update system.devices with new device IDs if PVs are found on new devices:
|
||||
.br
|
||||
.B lvmdevices --update --refresh
|
||||
.P
|
||||
The machine ID used in system.devices will be either the DMI product_uuid from
|
||||
The machine identifier used in system.devices will be either the DMI
|
||||
product_uuid from
|
||||
.IR /sys/devices/virtual/dmi/id/product_uuid ,
|
||||
or the hostname from
|
||||
.BR uname (2).
|
||||
See
|
||||
.BR lvm.conf (5)
|
||||
.B device_ids_refresh_checks
|
||||
to configure this.
|
||||
.B device_ids_refresh_checks to
|
||||
configure this.
|
||||
.P
|
||||
.SS custom devices files
|
||||
.
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
.OPA adddev
|
||||
\fIPV\fP
|
||||
..
|
||||
.de O_addid
|
||||
.OPA addid
|
||||
\fIString\fP
|
||||
..
|
||||
.de O_addpvid
|
||||
.OPA addpvid
|
||||
\fIString\fP
|
||||
@@ -58,10 +54,6 @@
|
||||
.OPA deldev
|
||||
\fIString\fP
|
||||
..
|
||||
.de O_delid
|
||||
.OPA delid
|
||||
\fIString\fP
|
||||
..
|
||||
.de O_delnotfound
|
||||
.OPS delnotfound
|
||||
..
|
||||
@@ -85,10 +77,6 @@
|
||||
.OPA driverloaded
|
||||
\fBy\fP|\fBn\fP
|
||||
..
|
||||
.de O_force
|
||||
.OPA f force
|
||||
\&\.\|.\|.\&
|
||||
..
|
||||
.de O_help
|
||||
.OPS h help
|
||||
..
|
||||
@@ -96,10 +84,6 @@
|
||||
.OPA journal
|
||||
\fIString\fP
|
||||
..
|
||||
.de O_listids
|
||||
.OPA listids
|
||||
\fIPV\fP
|
||||
..
|
||||
.de O_lockopt
|
||||
.OPA lockopt
|
||||
\fIString\fP
|
||||
@@ -158,8 +142,6 @@ lvmdevices \(em Manage the devices file
|
||||
.PD 0
|
||||
.O_adddev
|
||||
.br
|
||||
.O_addid
|
||||
.br
|
||||
.O_addpvid
|
||||
.br
|
||||
.O_check
|
||||
@@ -172,8 +154,6 @@ lvmdevices \(em Manage the devices file
|
||||
.br
|
||||
.O_deldev
|
||||
.br
|
||||
.O_delid
|
||||
.br
|
||||
.O_delnotfound
|
||||
.br
|
||||
.O_delpvid
|
||||
@@ -186,14 +166,10 @@ lvmdevices \(em Manage the devices file
|
||||
.br
|
||||
.O_driverloaded
|
||||
.br
|
||||
.O_force
|
||||
.br
|
||||
.O_help
|
||||
.br
|
||||
.O_journal
|
||||
.br
|
||||
.O_listids
|
||||
.br
|
||||
.O_lockopt
|
||||
.br
|
||||
.O_longhelp
|
||||
@@ -229,126 +205,75 @@ lvmdevices \(em Manage the devices file
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
.
|
||||
The LVM devices file is the list of devices that lvm commands will use.
|
||||
It is located at \fI#DEFAULT_SYS_DIR#/devices/system.devices\fP.
|
||||
The \fBlvmdevices\fP(8) command manages the file, and is used to
|
||||
add, remove and list devices.
|
||||
The LVM devices file lists devices that lvm can use. The default file is
|
||||
\fI#DEFAULT_SYS_DIR#/devices/system.devices\fP, and the \fBlvmdevices\fP(8) command is used to
|
||||
add or remove device entries. If the file does not exist, or if lvm.conf
|
||||
includes use_devicesfile=0, then lvm will not use a devices file.
|
||||
.P
|
||||
.SS Listing devices
|
||||
.
|
||||
Run the lvmdevices command with no options or arguments to display the
|
||||
entries in system.devices:
|
||||
.br
|
||||
.B lvmdevices
|
||||
To use a device with lvm, add it to the devices file with the command
|
||||
lvmdevices --adddev, and to prevent lvm from seeing or using a device,
|
||||
remove it from the devices file with lvmdevices --deldev. The
|
||||
vgimportdevices(8) command adds all PVs from a VG to the devices file,
|
||||
and updates the VG metadata to include device IDs of the PVs.
|
||||
.P
|
||||
Each line begins with a current device name from the system, followed by
|
||||
its device ID from the devices file, followed by other device details used by lvm.
|
||||
A line begins with "Device none" if no device on the system matches the device ID.
|
||||
(Viewing the system.devices file directly does not indicate if a device is present
|
||||
on the system.)
|
||||
Commands that add new devices to the devices file necessarily look outside
|
||||
the existing devices file to find the devices being added. pvcreate,
|
||||
vgcreate, and vgextend also look outside the devices file to create new
|
||||
PVs and add those PVs to the devices file.
|
||||
.P
|
||||
.SS Adding devices
|
||||
.
|
||||
To use a device with lvm, add it to the devices file with one of the
|
||||
following commands.
|
||||
LVM records devices in the devices file using hardware-specific IDs, such
|
||||
as the WWID, and attempts to use subsystem-specific IDs for virtual device
|
||||
types (which also aim to be as unique and stable as possible.) These
|
||||
device IDs are also written in the VG metadata. When no hardware or
|
||||
virtual ID is available, lvm falls back using the unstable device name as
|
||||
the device ID. When devnames are used as IDs, lvm performs extra scanning
|
||||
to find devices if their devname changes, e.g. after reboot.
|
||||
.P
|
||||
Add a device by referencing its device path:
|
||||
.br
|
||||
.B lvmdevices --adddev
|
||||
.I device
|
||||
When proper device IDs are used, an lvm command will not look at devices
|
||||
outside the devices file, but when devnames are used as a fallback, lvm
|
||||
will scan devices outside the devices file to locate PVs on renamed
|
||||
devices. A config setting search_for_devnames can be used to control the
|
||||
scanning for renamed devname entries.
|
||||
.P
|
||||
Add a device by referencing its PVID:
|
||||
.br
|
||||
.B lvmdevices --addpvid
|
||||
.I PVID
|
||||
Related to the devices file, the command option --devices <devnames>
|
||||
allows a list of devices to be specified for the command to use,
|
||||
overriding the devices file. The listed devices act as a sort of devices
|
||||
file in terms of limiting which devices lvm will see and use. Devices
|
||||
that are not listed will appear to be missing to the lvm command.
|
||||
.P
|
||||
Add a device by referencing its device ID:
|
||||
.br
|
||||
.B lvmdevices --addid
|
||||
.I IDNAME
|
||||
.B --deviceidtype
|
||||
.I IDTYPE
|
||||
Multiple devices files can be kept in \fI#DEFAULT_SYS_DIR#/devices\fP, which
|
||||
allows lvm to be used with different sets of devices. For example, system
|
||||
devices do not need to be exposed to a specific application, and the
|
||||
application can use lvm on its own devices that are not exposed to the
|
||||
system. The option --devicesfile <filename> is used to select the devices
|
||||
file to use with the command. Without the option set, the default system
|
||||
devices file is used.
|
||||
.P
|
||||
Add all of the PVs in a VG:
|
||||
.br
|
||||
.B vgimportdevices
|
||||
.I VG
|
||||
Setting --devicesfile "" causes lvm to not use a devices file.
|
||||
.P
|
||||
Add all of the PVs in all visible VGs:
|
||||
.br
|
||||
.B vgimportdevices -a
|
||||
With no devices file, lvm will use any device on the system, and applies
|
||||
the filter to limit the full set of system devices. With a devices file,
|
||||
the regex filter is not used, and the filter settings in lvm.conf or the
|
||||
command line are ignored. The vgimportdevices command is one exception
|
||||
which does apply the regex filter when looking for a VG to import.
|
||||
.P
|
||||
.B pvcreate,
|
||||
.B vgcreate,
|
||||
and
|
||||
.B vgextend
|
||||
also look outside of the existing devices file to find the target device,
|
||||
and automatically add it to the devices file.
|
||||
If a devices file exists, lvm will use it, even if it's empty. An empty
|
||||
devices file means lvm will see no devices.
|
||||
.P
|
||||
.SS Removing devices
|
||||
.
|
||||
Removing a device from the devices file will prevent lvm from
|
||||
seeing or using that device. Remove a device with one of the
|
||||
following commands.
|
||||
If the system devices file does not yet exist, the pvcreate or vgcreate
|
||||
commands will create it if they see no existing VGs on the system.
|
||||
lvmdevices --addev and vgimportdevices will always create a new devices file
|
||||
if it does not yet exist.
|
||||
.P
|
||||
Remove a device by referencing its device path:
|
||||
.br
|
||||
.B lvmdevices --deldev
|
||||
.I device
|
||||
It is recommended to use lvm commands to make changes to the devices file to
|
||||
ensure proper updates.
|
||||
.P
|
||||
Remove a device by referencing its PVID:
|
||||
.br
|
||||
.B lvmdevices --delpvid
|
||||
.I PVID
|
||||
The device ID and device ID type are included in the VG metadata and can
|
||||
be reported with pvs -o deviceid,deviceidtype. (Note that the lvmdevices
|
||||
command does not update VG metadata, but subsequent lvm commands modifying
|
||||
the metadata will include the device ID.)
|
||||
.P
|
||||
Remove a device by referencing its device ID:
|
||||
.br
|
||||
.B lvmdevices --delid
|
||||
.I IDNAME
|
||||
.B --deviceidtype
|
||||
.I IDTYPE
|
||||
.P
|
||||
.SS device IDs
|
||||
.
|
||||
LVM identifies devices in the devices file using hardware-specific IDs,
|
||||
such as the WWID or serial number. Subsystem-specific IDs are used for
|
||||
virtual device types, which also aim to be unique and stable.
|
||||
When no hardware or subsystem ID is available, lvm falls back using the
|
||||
device name as the device ID. Using device names as IDs is not optimal
|
||||
because they are not stable, and will often change after reboot. When
|
||||
device names are used as IDs, lvm must perform extra device scanning
|
||||
to locate devices if the device name changes.
|
||||
.P
|
||||
When stable device IDs are used, lvm will not access devices outside of
|
||||
those listed in the devices file. When device names are used as IDs, lvm
|
||||
will scan devices outside the devices file to locate PVs on devices that
|
||||
changed names. The config setting search_for_devnames can be used to
|
||||
control lvm's behavior in locating renamed devname entries.
|
||||
.P
|
||||
A device ID has two parts: an IDTYPE and an IDNAME.
|
||||
.P
|
||||
The IDTYPE specifies the origin of the ID, and the IDNAME is the
|
||||
actual identifier. There is a predefined set of IDTYPEs listed
|
||||
in the next section. A devices file entry must have one of these
|
||||
ID types. When adding a device to the devices file, lvm automatically
|
||||
chooses the best IDTYPE, which can be overridden with the --deviceidtype
|
||||
option (this is not generally recommended.)
|
||||
.P
|
||||
To display all of the possible device IDs for a device, or the value
|
||||
of one specific type, use the commands:
|
||||
.P
|
||||
.br
|
||||
.B lvmdevices --listids
|
||||
.I device
|
||||
.br
|
||||
.B lvmdevices --listids
|
||||
.I device
|
||||
.B --deviceidtype
|
||||
.I IDTYPE
|
||||
.P
|
||||
.SS device ID types
|
||||
.
|
||||
The available device ID types are:
|
||||
Possible device ID types are:
|
||||
.br
|
||||
.IP \[bu] 2
|
||||
.B sys_wwid
|
||||
@@ -384,181 +309,38 @@ is used for loop devices, the backing file name reported by sysfs.
|
||||
.IP \[bu]
|
||||
.B devname
|
||||
the device name is used if no other type applies.
|
||||
.IP \[bu]
|
||||
.B nvme_uuid, nvme_nguid, nvme_eui64
|
||||
are not generally used, but may appear for nvme devices that report
|
||||
invalid wwid values.
|
||||
.P
|
||||
.SS sysfs files
|
||||
Most of the device ID types read the device ID value from sysfs.
|
||||
Those sysfs values can also be read directly from the following paths:
|
||||
The default choice for device ID type can be overridden using lvmdevices
|
||||
--addev --deviceidtype <type>. If the specified type is available for the
|
||||
device it will be used, otherwise the device will be added using the type
|
||||
that would otherwise be chosen.
|
||||
.P
|
||||
.nf
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/device/wwid
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/device/serial
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/wwid
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/device/vpd_pg83 (binary)
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/device/vpd_pg80 (binary)
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/dm/uuid (lvm reads via ioctl)
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/md/uuid
|
||||
/sys/dev/block/\fImajor\fP:\fIminor\fP/loop/backing_file
|
||||
.fi
|
||||
.P
|
||||
(Some sysfs values are modified before being used as the device ID,
|
||||
e.g. spaces omitted or replaced with underscores.)
|
||||
.P
|
||||
.SS devices file contents
|
||||
LVM commands run by dmeventd will use the devices file
|
||||
\fI#DEFAULT_SYS_DIR#/devices/dmeventd.devices\fP if it exists,
|
||||
otherwise system.devices is used. VGs that require the dmeventd
|
||||
service should be included in system.devices, even if they are
|
||||
included in dmeventd.devices.
|
||||
.
|
||||
LVM writes some additional information to the devices file in addition to
|
||||
the device IDs. LVM commands automatically update this information if it
|
||||
changes. This includes the last known device name, and the PV UUID (PVID)
|
||||
from the LVM disk header.
|
||||
.P
|
||||
Check if the devices file content needs to be updated:
|
||||
.br
|
||||
.B lvmdevices --check
|
||||
.P
|
||||
Update devices file fields that are outdated:
|
||||
.br
|
||||
.B lvmdevices --update
|
||||
.P
|
||||
The devices file is meant to be edited by lvm commands, not by the user.
|
||||
The devices file contains a HASH value which lvm uses to detect if the
|
||||
file has been modified since lvm last wrote it.
|
||||
When lvm updates the devices file, the previous version is moved to
|
||||
/etc/lvm/devices/backup/.
|
||||
.P
|
||||
The following fields can be found in the devices file:
|
||||
.br
|
||||
VERSION: incremented for each file update.
|
||||
.br
|
||||
PRODUCT_UUID: a unique machine ID used to detect if the system.devices
|
||||
file has been moved to a new machine, and may require updating.
|
||||
When not available, HOSTNAME is used.
|
||||
.P
|
||||
Device entry fields:
|
||||
.br
|
||||
IDTYPE: indicates the source of the device ID value in IDNAME.
|
||||
.br
|
||||
IDNAME: the unique device ID value.
|
||||
.br
|
||||
DEVNAME: the most recent device name associated with the device ID.
|
||||
.br
|
||||
PVID: the LVM PV UUID from the LVM disk header.
|
||||
.br
|
||||
PART: the partition number if a PV exists on a partition.
|
||||
.P
|
||||
.SS device ID refresh
|
||||
.SS Device ID refresh
|
||||
.
|
||||
When LVM writes system.devices, it includes a local machine ID in the
|
||||
system.devices file (as PRODUCT_UUID or HOSTNAME.) When LVM reads
|
||||
system.devices, it compares this saved machine ID value to the current
|
||||
machine. This allows lvm to detect when system.devices has been copied
|
||||
or restored onto a different machine. When this happens, lvm switches
|
||||
its method for locating the PVs in system.devices, and locates PVs based
|
||||
on their PVID rather than the device ID (this involves scanning all devices
|
||||
on the system.) If a PVID is found on a device with a different device ID,
|
||||
then the device ID in system.devices is automatically updated to the new
|
||||
device ID.
|
||||
A machine identifier is saved in the devices file, and is used to detect
|
||||
when the devices file has been created by a different machine. If the
|
||||
devices file was created by a different machine, it indicates that PVs may
|
||||
have been copied or restored onto new devices on a new machine. In this
|
||||
case, lvm will search for the PVs listed in system.devices on new devices.
|
||||
If found, the device IDs will be updated in system.devices for the
|
||||
existing PVIDs (assuming the original device IDs are also no longer
|
||||
found.)
|
||||
.P
|
||||
While this refresh process is triggered automatically by a new machine
|
||||
ID, it can also be performed manually with the following commands:
|
||||
.P
|
||||
Check if system.devices would be updated with new device IDs:
|
||||
.br
|
||||
.B lvmdevices --check --refresh
|
||||
.P
|
||||
Update system.devices with new device IDs if PVs are found on new devices:
|
||||
.br
|
||||
.B lvmdevices --update --refresh
|
||||
.P
|
||||
The machine ID used in system.devices will be either the DMI product_uuid from
|
||||
The machine identifier used in system.devices will be either the DMI
|
||||
product_uuid from
|
||||
.IR /sys/devices/virtual/dmi/id/product_uuid ,
|
||||
or the hostname from
|
||||
.BR uname (2).
|
||||
See
|
||||
.BR lvm.conf (5)
|
||||
.B device_ids_refresh_checks
|
||||
to configure this.
|
||||
.P
|
||||
.SS custom devices files
|
||||
.
|
||||
Multiple devices files can be kept in #DEFAULT_SYS_DIR#/devices, which
|
||||
allows lvm to be used with different sets of devices. For example, a
|
||||
given application may not need to access the system's devices, and the
|
||||
system may not need to access the application's devices. In this case,
|
||||
system.devices could list only the system's devices and
|
||||
<application>.devices file could list only the application's devices. The
|
||||
option --devicesfile <filename> is used to select the devices file to use
|
||||
with the command. Without the option set, the default system.devices file
|
||||
is used.
|
||||
.P
|
||||
If the special devices file \fI#DEFAULT_SYS_DIR#/devices/dmeventd.devices\fP
|
||||
exists, then dmeventd uses dmeventd.devices instead of system.devices.
|
||||
Using dmeventd.devices is necessary if VGs from separate devices files
|
||||
require the services of dmeventd. In this case, dmeventd.devices should
|
||||
list devices from all of the VGs that require dmeventd.
|
||||
.P
|
||||
.SS disabling and overriding
|
||||
.
|
||||
There are multiple ways that the devices file feature can be disabled
|
||||
or overridden:
|
||||
.P
|
||||
.IP \[bu] 2
|
||||
no system.devices
|
||||
.br
|
||||
If the system.devices file does not exist, then the devices file feature
|
||||
is disabled.
|
||||
.IP \[bu] 2
|
||||
.B use_devicesfile=0
|
||||
.br
|
||||
If lvm.conf use_devicesfile is set to 0, then the devices file feature
|
||||
is disabled, even if the system.devices file exists.
|
||||
.br
|
||||
.IP \[bu] 2
|
||||
.B --devicesfile\ ""
|
||||
.br
|
||||
If an empty devices file name is specified on the command line, then
|
||||
that command will not use a devices file.
|
||||
.br
|
||||
.IP \[bu] 2
|
||||
.B --devices
|
||||
.I device
|
||||
.br
|
||||
If specific devices are named on the command line with --devices,
|
||||
then the command will not use a devices file, and will only access
|
||||
the named devices.
|
||||
.IP \[bu] 2
|
||||
.B pvs -A
|
||||
.br
|
||||
If given the -A or --allpvs option, the \fBpvs\fP(8) command will
|
||||
not use a devices file.
|
||||
.P
|
||||
When the devices file is disabled, lvm commands revert to using the
|
||||
lvm.conf filter.
|
||||
When the devices file is used, lvm commands ignore the lvm.conf
|
||||
filter setting, except for vgimportdevices which does apply the
|
||||
regex filter to the set of devices on the system when looking for
|
||||
VGs to import to the devices file.
|
||||
.P
|
||||
.SS VG metadata
|
||||
.
|
||||
LVM commands that write VG metadata will include the device ID of each
|
||||
PV in the VG metadata. The device ID can be displayed with the options:
|
||||
.P
|
||||
.B pvs -o deviceidtype,deviceid
|
||||
.P
|
||||
(Note that the lvmdevices command does not update VG metadata, but
|
||||
subsequent lvm commands modifying the metadata will include the device
|
||||
ID.)
|
||||
.P
|
||||
.SS creating the devices file
|
||||
.P
|
||||
If the system.devices file does not yet exist, the pvcreate or vgcreate
|
||||
commands will create it only if they see no existing VGs on the system.
|
||||
lvmdevices --adddev and vgimportdevices will always create a new devices file
|
||||
if it does not yet exist.
|
||||
.P
|
||||
.B device_ids_refresh_checks to
|
||||
configure this.
|
||||
.
|
||||
.SH USAGE
|
||||
.
|
||||
@@ -597,10 +379,6 @@ Update the devices file to fix incorrect values.
|
||||
.O_update
|
||||
.RS
|
||||
[
|
||||
.O_force
|
||||
]
|
||||
.br
|
||||
[
|
||||
.O_delnotfound
|
||||
]
|
||||
.br
|
||||
@@ -670,48 +448,6 @@ Remove the devices file entry for the given PVID.
|
||||
.RS
|
||||
[ COMMON_OPTIONS ]
|
||||
.RE
|
||||
.
|
||||
.P
|
||||
\(em
|
||||
.P
|
||||
.
|
||||
Find the device with the given device_id and add it to the devices file.
|
||||
.P
|
||||
.B lvmdevices
|
||||
.O_addid
|
||||
.O_deviceidtype
|
||||
.RS
|
||||
[ COMMON_OPTIONS ]
|
||||
.RE
|
||||
.
|
||||
.P
|
||||
\(em
|
||||
.P
|
||||
.
|
||||
Remove the devices file entry with the given device_id.
|
||||
.P
|
||||
.B lvmdevices
|
||||
.O_delid
|
||||
.O_deviceidtype
|
||||
.RS
|
||||
[ COMMON_OPTIONS ]
|
||||
.RE
|
||||
.
|
||||
.P
|
||||
\(em
|
||||
.P
|
||||
.
|
||||
Print device_id types and values available for the device.
|
||||
.P
|
||||
.B lvmdevices
|
||||
.O_listids
|
||||
.RS
|
||||
[
|
||||
.O_deviceidtype
|
||||
]
|
||||
.br
|
||||
[ COMMON_OPTIONS ]
|
||||
.RE
|
||||
.P
|
||||
\(em
|
||||
.P
|
||||
@@ -799,10 +535,6 @@ Common options for lvm:
|
||||
Add a device to the devices file.
|
||||
.
|
||||
.TP
|
||||
.O_addid
|
||||
Find the device with the given device_id and add it to the devices file.
|
||||
.
|
||||
.TP
|
||||
.O_addpvid
|
||||
Find a device with the PVID and add the device to the devices file.
|
||||
.
|
||||
@@ -835,10 +567,6 @@ When used alone, --deldev specifies a device name.
|
||||
When used with --deviceidtype, --deldev specifies a device id.
|
||||
.
|
||||
.TP
|
||||
.O_delid
|
||||
Remove the device with the specified device ID from the devices file.
|
||||
.
|
||||
.TP
|
||||
.O_delnotfound
|
||||
Remove devices file entries with no matching device.
|
||||
.
|
||||
@@ -873,11 +601,6 @@ If set to no, the command will not attempt to use device-mapper.
|
||||
For testing and debugging.
|
||||
.
|
||||
.TP
|
||||
.O_force
|
||||
Override various checks, confirmations and protections.
|
||||
Use with extreme caution.
|
||||
.
|
||||
.TP
|
||||
.O_help
|
||||
Display help text.
|
||||
.
|
||||
@@ -891,10 +614,6 @@ output: record the default command output.
|
||||
debug: record full command debugging.
|
||||
.
|
||||
.TP
|
||||
.O_listids
|
||||
Print a list of device IDs available for the device.
|
||||
.
|
||||
.TP
|
||||
.O_lockopt
|
||||
Used to pass options for special cases to lvmlockd.
|
||||
See \fBlvmlockd\fP(8) for more information.
|
||||
|
||||
@@ -35,19 +35,6 @@ Note that this new process cannot support the original LVM1
|
||||
type of on-disk metadata. Metadata can be converted using
|
||||
\fBvgconvert\fP(8).
|
||||
.P
|
||||
By default, pvmove will mirror an entire LV segment at once. If the process
|
||||
is interrupted (e.g. by a system crash or power failure) before the segment
|
||||
is fully mirrored, the entire segment must be mirrored again when pvmove is
|
||||
restarted. For very large segments, this can result in significant rework.
|
||||
The \fBallocation/pvmove_max_segment_size_mb\fP setting in \fBlvm.conf\fP(5)
|
||||
can be used to limit the maximum size of data mirrored in a single operation.
|
||||
When set to a non-zero value, pvmove will split large segments into smaller
|
||||
chunks of the specified size (in MiB), mirror each chunk, and update metadata
|
||||
between chunks. This ensures that at most one chunk needs to be re-mirrored
|
||||
after an interruption. For example, setting this to 10240 will limit each
|
||||
mirroring operation to 10 GiB. The default value of 0 means no limit - entire
|
||||
segments are mirrored at once.
|
||||
.P
|
||||
If the \fB--atomic\fP option is used, a slightly different approach is
|
||||
used for the move. Again, a temporary 'pvmove' LV is created to store the
|
||||
details of all the data movements required. This temporary LV contains
|
||||
|
||||
@@ -25,10 +25,8 @@ expect_failure() {
|
||||
|
||||
check_daemon_in_builddir() {
|
||||
# skip if we don't have our own daemon...
|
||||
if [[ -z "${installed_testsuite+varset}" ]]; then
|
||||
(which "$1" 2>/dev/null | grep -q "$abs_builddir") || \
|
||||
skip "$1 is not in executed path."
|
||||
fi
|
||||
[[ -z "${installed_testsuite+varset}" ]] && \
|
||||
(which "$1" 2>/dev/null | grep "$abs_builddir" >/dev/null ) || skip "$1 is not in executed path."
|
||||
rm -f debug.log strace.log
|
||||
}
|
||||
|
||||
@@ -205,7 +203,7 @@ prepare_clvmd() {
|
||||
}
|
||||
|
||||
prepare_dmeventd() {
|
||||
[[ -n "${RUNNING_DMEVENTD-}" ]] && skip "Cannot test dmeventd with real dmeventd ($RUNNING_DMEVENTD) running."
|
||||
[[ -n "$RUNNING_DMEVENTD" ]] && skip "Cannot test dmeventd with real dmeventd ($RUNNING_DMEVENTD) running."
|
||||
|
||||
check_daemon_in_builddir dmeventd
|
||||
lvmconf "activation/monitoring = 1"
|
||||
@@ -265,7 +263,7 @@ lvmpolld_talk() {
|
||||
}
|
||||
|
||||
lvmpolld_dump() {
|
||||
(echo 'request="dump"'; echo '##') | lvmpolld_talk "${@-}"
|
||||
(echo 'request="dump"'; echo '##') | lvmpolld_talk "$@"
|
||||
}
|
||||
|
||||
prepare_lvmdbusd() {
|
||||
@@ -479,7 +477,7 @@ teardown_devs() {
|
||||
fi
|
||||
|
||||
# NOTE: SCSI_DEBUG_DEV test must come before the LOOP test because
|
||||
# aux prepare_scsi_debug_dev() also sets LOOP to short-circuit aux prepare_loop()
|
||||
# prepare_scsi_debug_dev() also sets LOOP to short-circuit prepare_loop()
|
||||
if [[ -f SCSI_DEBUG_DEV ]]; then
|
||||
udev_wait
|
||||
if [[ "${LVM_TEST_PARALLEL:-0}" -ne 1 ]]; then
|
||||
@@ -517,7 +515,7 @@ kill_sleep_kill_() {
|
||||
local pid
|
||||
|
||||
if [[ -s "$pidfile" ]]; then
|
||||
pid=( $(< "$pidfile") ) || true
|
||||
pid=( $(< "$pidfile") )
|
||||
rm -f "$pidfile"
|
||||
[[ "$pidfile" = "LOCAL_LVMDBUSD" ]] && killall -9 lvmdbusd || true
|
||||
kill -TERM "${pid[@]}" 2>/dev/null || return 0
|
||||
@@ -549,7 +547,7 @@ kill_tagged_processes() {
|
||||
kill -TERM "$pid" 2>/dev/null || true
|
||||
fi
|
||||
pids+=( "$pid" )
|
||||
done < <(print_procs_by_tag_ "${@-}")
|
||||
done < <(print_procs_by_tag_ "$@")
|
||||
|
||||
[[ ${#pids[@]} -eq 0 ]] && return
|
||||
|
||||
@@ -646,7 +644,7 @@ teardown() {
|
||||
|
||||
# Check if this test is leaking some 'symlinks' with our name (udev)
|
||||
LEAKED_LINKS=( $(find /dev -path "/dev/mapper/${PREFIX}*" -type l -exec test ! -e {} \; -print -o \
|
||||
-path "/dev/${PREFIX}*/" -type l -exec test ! -e {} \; -print 2>/dev/null) ) || true
|
||||
-path "/dev/${PREFIX}*/" -type l -exec test ! -e {} \; -print 2>/dev/null || true) )
|
||||
|
||||
[[ "${#LEAKED_LINKS[@]}" -eq 0 ]] || echo "## removing stray symlinks the names beginning with ${PREFIX}"
|
||||
|
||||
@@ -664,7 +662,7 @@ teardown() {
|
||||
find /dev -type d -name "${LEAKED_PREFIX}*" -empty -delete 2>/dev/null || true
|
||||
|
||||
# Fail test with leaked links as most likely somewhere is missing synchronization...
|
||||
[[ "${#LEAKED_LINKS[@]}" -eq 0 ]] || die "Test leaked these symlinks ${LEAKED_LINKS[*]}"
|
||||
[[ "${#LEAKED_LINKS[@]}" -eq 0 ]] || die "Test leaked these symlinks ${LEAKED_LINKS[@]}"
|
||||
}
|
||||
|
||||
prepare_loop() {
|
||||
@@ -743,7 +741,7 @@ prepare_real_devs() {
|
||||
|
||||
if [[ -n "${LVM_TEST_DEVICE_LIST-}" ]]; then
|
||||
local count=0
|
||||
while read -r path; do
|
||||
while read path; do
|
||||
REAL_DEVICES[count]=$path
|
||||
count=$(( count + 1 ))
|
||||
extend_filter "a|$path|"
|
||||
@@ -1800,7 +1798,7 @@ thin_restore_needs_more_volumes() {
|
||||
|
||||
udev_wait() {
|
||||
local arg="--timeout=15"
|
||||
[[ -n "${1-}" ]] && arg="--exit-if-exists=${1-}"
|
||||
[[ -n "${1-}" ]] && arg="--exit-if-exists=$1"
|
||||
|
||||
if [[ ! -f UDEV_PID ]]; then
|
||||
pgrep udev >UDEV_PID 2>/dev/null || return 0
|
||||
|
||||
@@ -201,7 +201,7 @@ in_sync() {
|
||||
local ignore_a=${3:-0}
|
||||
local dm_name="$1-$2"
|
||||
|
||||
a=( $(dmsetup status "$dm_name") ) || \
|
||||
a=( $(dmsetup status "$dm_name") ) || \
|
||||
die "Unable to get sync status of $1"
|
||||
|
||||
if [[ "${a[2]}" = "snapshot-origin" ]]; then
|
||||
@@ -443,8 +443,7 @@ raid_leg_status() {
|
||||
|
||||
# Ignore inconsistent raid status 0/xxxxx idle
|
||||
for i in {100..0} ; do
|
||||
st=( $(dmsetup status --noflush "$1-$2") ) || \
|
||||
die "Unable to get status of $vg/$lv1"
|
||||
st=( $(dmsetup status --noflush "$1-$2") ) || die "Unable to get status of $vg/$lv1"
|
||||
case "${st[7]}" in
|
||||
"resync"|"recover") [ "${st[5]}" = "$3" ] && return 0 ;;
|
||||
esac
|
||||
|
||||
@@ -141,7 +141,7 @@ STACKTRACE() {
|
||||
local cores=()
|
||||
local IFS=$IFS_NL
|
||||
cores=( $(find . "$(dirname "$(sysctl -n kernel.core_pattern)")" \
|
||||
"/var/lib/systemd/coredump/" -name 'core*' -newer TESTNAME 2>/dev/null) ) || true
|
||||
"/var/lib/systemd/coredump/" -name 'core*' -newer TESTNAME 2>/dev/null || true ) )
|
||||
|
||||
for i in "${cores[@]-}"; do
|
||||
bin=$(gdb -batch -c "$i" 2>&1 | grep "generated by" | \
|
||||
@@ -263,13 +263,13 @@ skip() {
|
||||
}
|
||||
|
||||
get_real_devs() {
|
||||
REAL_DEVICES=( $(< REAL_DEVICES) ) || true
|
||||
REAL_DEVICES=( $(<REAL_DEVICES) )
|
||||
export REAL_DEVICES
|
||||
}
|
||||
|
||||
get_devs() {
|
||||
local IFS=$IFS_NL
|
||||
DEVICES=( $(< DEVICES) ) || true
|
||||
DEVICES=( $(<DEVICES) )
|
||||
export DEVICES
|
||||
# local DEVS=( $(<DEVICES) )
|
||||
# eval "$1"'=("${DEVS[@]}")'
|
||||
|
||||
@@ -366,7 +366,7 @@ vgs -o+uuid |tee out
|
||||
grep $vg1 out
|
||||
grep $UUID1 out
|
||||
grep $UUID2 out
|
||||
not grep $UUID3 out
|
||||
not group $UUID3 out
|
||||
vgs --foreign -o+uuid |tee out
|
||||
grep $vg1 out
|
||||
grep $UUID1 out
|
||||
@@ -443,8 +443,8 @@ vgs -o+uuid |tee out
|
||||
grep $vg1 out
|
||||
grep $UUID1 out
|
||||
grep $UUID2 out
|
||||
not grep $UUID3 out
|
||||
not grep $UUID4 out
|
||||
not group $UUID3 out
|
||||
not group $UUID4 out
|
||||
vgs --foreign -o+uuid |tee out
|
||||
grep $vg1 out
|
||||
grep $UUID1 out
|
||||
@@ -527,9 +527,9 @@ grep $vg1 out
|
||||
grep $UUID1 out
|
||||
grep $UUID2 out
|
||||
grep $UUID3 out
|
||||
not grep $UUID4 out
|
||||
not grep $UUID5 out
|
||||
not grep $UUID6 out
|
||||
not group $UUID4 out
|
||||
not group $UUID5 out
|
||||
not group $UUID6 out
|
||||
vgs --foreign -o+uuid |tee out
|
||||
grep $vg1 out
|
||||
grep $UUID1 out
|
||||
|
||||
@@ -36,21 +36,6 @@ function _test_regionsize
|
||||
fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
||||
}
|
||||
|
||||
function _not_test_regionsize
|
||||
{
|
||||
local type=$1
|
||||
local regionsize=$2
|
||||
local regionsize_str=$3
|
||||
local vg=$4
|
||||
local lv=$5
|
||||
|
||||
#FIXME not lvconvert --type "$type" --yes -R "$regionsize" "$vg/$lv"
|
||||
not check lv_field $vg/$lv regionsize "$regionsize_str"
|
||||
|
||||
not lvconvert --regionsize "$regionsize" "$vg/$lv" 2>err
|
||||
not grep "is already" err
|
||||
}
|
||||
|
||||
function _test_regionsizes
|
||||
{
|
||||
# FIXME: have to provide raid type or region size ain't set until cli validation merged
|
||||
@@ -59,10 +44,10 @@ function _test_regionsizes
|
||||
# Test RAID regionsize changes
|
||||
_test_regionsize "$type" 128K "128.00k" $vg $lv1
|
||||
_test_regionsize "$type" 256K "256.00k" $vg $lv1
|
||||
_not_test_regionsize "$type" 1K "1.00k" $vg $lv1
|
||||
not _test_regionsize "$type" 1K "1.00k" $vg $lv1
|
||||
_test_regionsize "$type" 1m "1.00m" $vg $lv1
|
||||
_not_test_regionsize "$type" 1G "1.00g" $vg $lv1
|
||||
_not_test_regionsize "$type" 16K "16.00k" $vg $lv1
|
||||
not _test_regionsize "$type" 1G "1.00g" $vg $lv1
|
||||
not _test_regionsize "$type" 16K "16.00k" $vg $lv1
|
||||
}
|
||||
|
||||
# Create 3-way raid1
|
||||
|
||||
@@ -168,37 +168,14 @@ function _check_size
|
||||
test "$(blockdev --getsz "/dev/$vg/$lv")" -eq "$(_get_size $vg $lv "$data_stripes")"
|
||||
}
|
||||
|
||||
function _not_check_size
|
||||
{
|
||||
local vg=$1
|
||||
local lv=$2
|
||||
local data_stripes=$3
|
||||
|
||||
# Compare size of LV with calculated one
|
||||
[[ "$(blockdev --getsz "/dev/$vg/$lv")" -ne "$(_get_size $vg $lv "$data_stripes")" ]]
|
||||
}
|
||||
|
||||
function _check_size_timeout
|
||||
{
|
||||
local i
|
||||
|
||||
for i in $(seq 0 $((CHECK_SIZE_TIMEOUT * 20)))
|
||||
do
|
||||
sleep .05
|
||||
_check_size "$@" && return
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function _not_check_size_timeout
|
||||
{
|
||||
local i
|
||||
|
||||
for i in $(seq 0 $((CHECK_SIZE_TIMEOUT * 20)))
|
||||
do
|
||||
sleep .05
|
||||
_not_check_size "$@"
|
||||
done
|
||||
|
||||
return 1
|
||||
@@ -265,26 +242,6 @@ function _reshape_layout
|
||||
fi
|
||||
}
|
||||
|
||||
function _not_reshape_layout
|
||||
{
|
||||
local raid_type=$1
|
||||
local data_stripes=$2
|
||||
local vg=$3
|
||||
local lv=$4
|
||||
local wait_for_reshape=$5
|
||||
local ignore_a_chars=$6
|
||||
shift 6
|
||||
local stripes
|
||||
|
||||
stripes=$(_total_stripes "$raid_type" "$data_stripes")
|
||||
|
||||
# FIXME: replace this hack with --noudevsync with slowdown of 'write'
|
||||
# areas used for reshape operation.
|
||||
# ATM: command used to be 'sleeping' waiting for a cookie - delayed by udev
|
||||
not lvconvert -y --ty "$raid_type" --stripes "$data_stripes" "${UDEVOPTS[@]}" $vg/$lv "$@"
|
||||
check lv_first_seg_field $vg/$lv1 segtype "$raid_type"
|
||||
}
|
||||
|
||||
function _add_stripes
|
||||
{
|
||||
local raid_type=$1
|
||||
@@ -300,7 +257,7 @@ function _add_stripes
|
||||
_reshape_layout "$raid_type" "$data_stripes" $vg $lv 0 1 --stripesize "$stripesize"
|
||||
|
||||
# Size has to be inconsistent until reshape finishes
|
||||
_not_check_size $vg $lv "$data_stripes" || die "LV size should be small"
|
||||
not _check_size $vg $lv "$data_stripes" || die "LV size should be small"
|
||||
|
||||
_restore_dev "$dev1"
|
||||
|
||||
@@ -312,7 +269,7 @@ function _add_stripes
|
||||
aux wait_for_sync $vg $lv 0
|
||||
|
||||
# Now size consistency has to be fine
|
||||
# FIXME _not_check_size_timeout $vg $lv "$data_stripes" || die "LV size should be grown"
|
||||
not _check_size_timeout $vg $lv "$data_stripes" || die "LV size should be grown"
|
||||
|
||||
# Check, use grown capacity for the filesystem and check again
|
||||
if [ "$SKIP_RESIZE" -eq 0 ]
|
||||
@@ -351,7 +308,7 @@ function _remove_stripes
|
||||
_reshape_layout "$raid_type" "$data_stripes" $vg $lv 0 1 --force --stripesize "$stripesize"
|
||||
|
||||
# Size has to be inconsistent, as to be removed legs still exist
|
||||
_not_check_size $vg $lv "$cur_data_stripes" || die "LV size should be reduced but not rimage count"
|
||||
not _check_size $vg $lv "$cur_data_stripes" || die "LV size should be reduced but not rimage count"
|
||||
|
||||
_restore_dev "$dev1"
|
||||
|
||||
@@ -362,7 +319,7 @@ function _remove_stripes
|
||||
_skip_or_fsck "$DM_DEV_DIR/$vg/$lv"
|
||||
|
||||
# Have to remove freed legs before another restriping conversion. Will fail while reshaping is ongoing as stripes are still in use
|
||||
_not_reshape_layout "$raid_type" $(( data_stripes + 1 )) $vg $lv 0 1 --force
|
||||
not _reshape_layout "$raid_type" $(( data_stripes + 1 )) $vg $lv 0 1 --force
|
||||
aux wait_for_sync $vg $lv 1
|
||||
|
||||
# Remove freed legs as they are now idle has to succeed without --force
|
||||
|
||||
@@ -81,44 +81,19 @@ function _lvconvert
|
||||
fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
||||
}
|
||||
|
||||
function _not_lvconvert
|
||||
{
|
||||
local req_level=$1
|
||||
local level=$2
|
||||
local data_stripes=$3
|
||||
local stripes=$4
|
||||
local vg=$5
|
||||
local lv=$6
|
||||
local region_size=${7-}
|
||||
local R=""
|
||||
|
||||
[ -n "$region_size" ] && R="-R $region_size"
|
||||
|
||||
not lvconvert -y --ty $req_level $R $vg/$lv
|
||||
|
||||
# Verify conversion did NOT happen - fields should NOT match requested values
|
||||
not check lv_first_seg_field $vg/$lv segtype "$level"
|
||||
not check lv_first_seg_field $vg/$lv data_stripes $data_stripes
|
||||
not check lv_first_seg_field $vg/$lv stripes $stripes
|
||||
|
||||
[ -n "$region_size" ] && \
|
||||
not check lv_field $vg/$lv regionsize $region_size
|
||||
if [ "$wait_and_check" -eq 1 ]
|
||||
then
|
||||
not fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
||||
not aux wait_for_sync $vg $lv
|
||||
fi
|
||||
not fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
||||
}
|
||||
|
||||
function _reshape_layout
|
||||
{
|
||||
local type=$1
|
||||
local data_stripes=$2
|
||||
local stripes=$3
|
||||
local vg=$4
|
||||
local lv=$5
|
||||
local opts="${@:6}"
|
||||
shift
|
||||
local data_stripes=$1
|
||||
shift
|
||||
local stripes=$1
|
||||
shift
|
||||
local vg=$1
|
||||
shift
|
||||
local lv=$1
|
||||
shift
|
||||
local opts="$*"
|
||||
local ignore_a_chars=0
|
||||
|
||||
[[ "$opts" =~ "--stripes" ]] && ignore_a_chars=1
|
||||
@@ -131,25 +106,6 @@ function _reshape_layout
|
||||
fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
||||
}
|
||||
|
||||
function _not_reshape_layout
|
||||
{
|
||||
local type=$1
|
||||
local data_stripes=$2
|
||||
local stripes=$3
|
||||
local vg=$4
|
||||
local lv=$5
|
||||
local opts="${@:6}"
|
||||
|
||||
not lvconvert -y --ty $type $opts $vg/$lv
|
||||
|
||||
# Verify reshape did NOT happen - fields should NOT match requested values
|
||||
not check lv_first_seg_field $vg/$lv segtype "$type"
|
||||
not check lv_first_seg_field $vg/$lv data_stripes $data_stripes
|
||||
not check lv_first_seg_field $vg/$lv stripes $stripes
|
||||
not aux wait_for_sync $vg $lv $ignore_a_chars
|
||||
not fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
||||
}
|
||||
|
||||
# Delay leg so that rebuilding status characters
|
||||
# can be read before resync finished too quick.
|
||||
# aux delay_dev "$dev1" 1
|
||||
@@ -169,8 +125,7 @@ _reshape_layout raid5_ls 3 4 $vg $lv1 --stripesize 256K
|
||||
check lv_first_seg_field $vg/$lv1 stripesize "256.00k"
|
||||
|
||||
# Convert raid5(_n) -> striped testing raid5_ls gets rejected
|
||||
# FIXME
|
||||
# _not_lvconvert striped raid5_ls 3 3 $vg $lv1 "512.00k"
|
||||
not _lvconvert striped striped 3 3 $vg $lv1 "512.00k"
|
||||
_reshape_layout raid5_n 3 4 $vg $lv1
|
||||
_lvconvert striped striped 3 3 $vg $lv1
|
||||
|
||||
@@ -273,7 +228,7 @@ _lvconvert raid10 raid10 4 8 $vg $lv1
|
||||
|
||||
# Convert raid10 to 10 stripes and 64K stripesize
|
||||
# FIXME: change once we support odd numbers of raid10 stripes
|
||||
# _not_reshape_layout raid10 4 9 $vg $lv1 --stripes 9 --stripesize 64K
|
||||
not _reshape_layout raid10 4 9 $vg $lv1 --stripes 9 --stripesize 64K
|
||||
_reshape_layout raid10 10 20 $vg $lv1 --stripes 10 --stripesize 64K
|
||||
check lv_first_seg_field $vg/$lv1 stripesize "64.00k"
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ function _lvconvert
|
||||
[ "${level:0:7}" = "striped" ] && wait_and_check=0
|
||||
[ "${level:0:5}" = "raid0" ] && wait_and_check=0
|
||||
|
||||
lvconvert -y --ty "$req_level" $R $vg/$lv
|
||||
lvconvert -y --ty $req_level $R $vg/$lv
|
||||
detect_error_leak_
|
||||
|
||||
check lv_field $vg/$lv segtype "$level"
|
||||
@@ -76,50 +76,31 @@ function _lvconvert
|
||||
fsck -fn "$DM_DEV_DIR/$vg/$lv"
|
||||
}
|
||||
|
||||
function _not_lvconvert
|
||||
{
|
||||
local req_level=$1
|
||||
local level=$2
|
||||
local data_stripes=$3
|
||||
local stripes=$4
|
||||
local vg=$5
|
||||
local lv=$6
|
||||
local region_size=${7-}
|
||||
local wait_and_check=1
|
||||
local R=""
|
||||
|
||||
[ -n "$region_size" ] && R="-R $region_size"
|
||||
[ "${level:0:7}" = "striped" ] && wait_and_check=0
|
||||
[ "${level:0:5}" = "raid0" ] && wait_and_check=0
|
||||
|
||||
not lvconvert -y --ty "$req_level" $R $vg/$lv
|
||||
}
|
||||
|
||||
function _invalid_raid5_conversions
|
||||
{
|
||||
local vg=$1
|
||||
local lv=$2
|
||||
|
||||
#FIXME!!! _not_lvconvert striped 4 4 $vg $lv1
|
||||
#FIXME!!! _not_lvconvert raid0 raid0 4 4 $vg $lv1
|
||||
_not_lvconvert raid0_meta raid0_meta 4 4 $vg $lv1
|
||||
_not_lvconvert raid4 raid4 4 5 $vg $lv1
|
||||
_not_lvconvert raid5_ls raid5_ls 4 5 $vg $lv1
|
||||
_not_lvconvert raid5_rs raid5_rs 4 5 $vg $lv1
|
||||
_not_lvconvert raid5_la raid5_la 4 5 $vg $lv1
|
||||
_not_lvconvert raid5_ra raid5_ra 4 5 $vg $lv1
|
||||
_not_lvconvert raid6_zr raid6_zr 4 6 $vg $lv1
|
||||
_not_lvconvert raid6_nr raid6_nr 4 6 $vg $lv1
|
||||
_not_lvconvert raid6_nc raid6_nc 4 6 $vg $lv1
|
||||
_not_lvconvert raid6_n_6 raid6_n_6 4 6 $vg $lv1
|
||||
_not_lvconvert raid6 raid6_n_6 4 6 $vg $lv1
|
||||
not _lvconvert striped 4 4 $vg $lv1
|
||||
not _lvconvert raid0 raid0 4 4 $vg $lv1
|
||||
not _lvconvert raid0_meta raid0_meta 4 4 $vg $lv1
|
||||
not _lvconvert raid4 raid4 4 5 $vg $lv1
|
||||
not _lvconvert raid5_ls raid5_ls 4 5 $vg $lv1
|
||||
not _lvconvert raid5_rs raid5_rs 4 5 $vg $lv1
|
||||
not _lvconvert raid5_la raid5_la 4 5 $vg $lv1
|
||||
not _lvconvert raid5_ra raid5_ra 4 5 $vg $lv1
|
||||
not _lvconvert raid6_zr raid6_zr 4 6 $vg $lv1
|
||||
not _lvconvert raid6_nr raid6_nr 4 6 $vg $lv1
|
||||
not _lvconvert raid6_nc raid6_nc 4 6 $vg $lv1
|
||||
not _lvconvert raid6_n_6 raid6_n_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6 raid6_n_6 4 6 $vg $lv1
|
||||
}
|
||||
|
||||
# Check raid6 conversion constraints for 2 stripes
|
||||
for type in striped raid0 raid0_meta
|
||||
do
|
||||
_lvcreate $type 2 2 4m $vg $lv1
|
||||
#FIXME _not_lvconvert raid6 raid6_n_6 2 4 $vg $lv1
|
||||
not _lvconvert raid6 raid6_n_6 2 4 $vg $lv1
|
||||
_lvconvert raid6 raid5_n 2 3 $vg $lv1
|
||||
_lvconvert raid6 raid5_n 3 4 $vg $lv1
|
||||
_lvconvert raid6 raid6_n_6 3 5 $vg $lv1
|
||||
@@ -214,7 +195,7 @@ _lvcreate raid4 3 4 8M $vg $lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
|
||||
# Convert raid4 -> striped
|
||||
#FIXME _not_lvconvert striped striped 3 3 $vg $lv1 "512.00k"
|
||||
not _lvconvert striped striped 3 3 $vg $lv1 512k
|
||||
_lvconvert striped striped 3 3 $vg $lv1
|
||||
|
||||
# Convert striped -> raid4
|
||||
@@ -247,7 +228,7 @@ _lvconvert raid0_meta raid0_meta 3 3 $vg $lv1
|
||||
_lvconvert raid5 raid5_n 3 4 $vg $lv1
|
||||
|
||||
# Convert raid4 -> raid0_meta
|
||||
#FIXME _not_lvconvert raid0_meta raid0_meta 3 3 $vg $lv1 "256.00k"
|
||||
not _lvconvert raid0_meta raid0_meta 3 3 $vg $lv1 256k
|
||||
_lvconvert raid0_meta raid0_meta 3 3 $vg $lv1
|
||||
|
||||
# Convert raid0_meta -> raid4
|
||||
@@ -296,14 +277,14 @@ _lvconvert raid0_meta raid0_meta 3 3 $vg $lv1
|
||||
_lvconvert raid6 raid6_n_6 3 5 $vg $lv1
|
||||
|
||||
# Convert raid6_n_6 -> striped
|
||||
#FIXME _not_lvconvert striped striped 3 3 $vg $lv1 "128.00k"
|
||||
not _lvconvert striped striped 3 3 $vg $lv1 128k
|
||||
_lvconvert striped striped 3 3 $vg $lv1
|
||||
|
||||
# Convert striped -> raid10
|
||||
_lvconvert raid10 raid10 3 6 $vg $lv1
|
||||
|
||||
# Convert raid10 -> raid0
|
||||
#FIXME _not_lvconvert raid0 raid0 3 3 $vg $lv1 "64.00k"
|
||||
not _lvconvert raid0 raid0 3 3 $vg $lv1 64k
|
||||
_lvconvert raid0 raid0 3 3 $vg $lv1
|
||||
|
||||
# Convert raid0 -> raid10
|
||||
@@ -322,61 +303,59 @@ _lvconvert raid0_meta raid0_meta 3 3 $vg $lv1
|
||||
_lvconvert raid10 raid10 3 6 $vg $lv1
|
||||
|
||||
# Convert raid10 -> striped
|
||||
#FIXME !!!! _not_lvconvert striped striped 3 3 $vg $lv1 "256.00k"
|
||||
not _lvconvert striped striped 3 3 $vg $lv1 256k
|
||||
_lvconvert striped striped 3 3 $vg $lv1
|
||||
|
||||
# Clean up
|
||||
lvremove -y $vg
|
||||
|
||||
|
||||
#!!!!FIXME FIXME FIXME
|
||||
# Create + convert 4-way raid5 variations
|
||||
_lvcreate raid5 4 5 8M $vg $lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
#FIXME _invalid_raid5_conversions $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_invalid_raid5_conversions $vg $lv1
|
||||
not _lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_lvconvert raid6_ls_6 raid6_ls_6 4 6 $vg $lv1
|
||||
_lvconvert raid5_ls raid5_ls 4 5 $vg $lv1
|
||||
lvremove -y $vg
|
||||
|
||||
_lvcreate raid5_ls 4 5 8M $vg $lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
#FIXME _invalid_raid5_conversions $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_invalid_raid5_conversions $vg $lv1
|
||||
not _lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_lvconvert raid6_ls_6 raid6_ls_6 4 6 $vg $lv1
|
||||
_lvconvert raid5_ls raid5_ls 4 5 $vg $lv1
|
||||
lvremove -y $vg
|
||||
|
||||
_lvcreate raid5_rs 4 5 8M $vg $lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
#FIXME _invalid_raid5_conversions $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_invalid_raid5_conversions $vg $lv1
|
||||
not _lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
_lvconvert raid5_rs raid5_rs 4 5 $vg $lv1
|
||||
lvremove -y $vg
|
||||
|
||||
_lvcreate raid5_la 4 5 8M $vg $lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
#FIXME _invalid_raid5_conversions $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_ls_6 raid6_ls_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_invalid_raid5_conversions $vg $lv1
|
||||
not _lvconvert raid6_ls_6 raid6_ls_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
_lvconvert raid5_la raid5_la 4 5 $vg $lv1
|
||||
lvremove -y $vg
|
||||
|
||||
_lvcreate raid5_ra 4 5 8M $vg $lv1
|
||||
aux wait_for_sync $vg $lv1
|
||||
#FIXME _invalid_raid5_conversions $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_ls_6 raid6_ls_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
#FIXME _not_lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
_invalid_raid5_conversions $vg $lv1
|
||||
not _lvconvert raid6_ls_6 raid6_ls_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_rs_6 raid6_rs_6 4 6 $vg $lv1
|
||||
not _lvconvert raid6_la_6 raid6_la_6 4 6 $vg $lv1
|
||||
_lvconvert raid6_ra_6 raid6_ra_6 4 6 $vg $lv1
|
||||
_lvconvert raid5_ra raid5_ra 4 5 $vg $lv1
|
||||
lvremove -y $vg
|
||||
|
||||
@@ -16,41 +16,29 @@
|
||||
|
||||
. lib/inittest --skip-with-lvmpolld
|
||||
|
||||
_init_lv() {
|
||||
init_lv_() {
|
||||
mkswap "$DM_DEV_DIR/$vg/$lv1"
|
||||
}
|
||||
|
||||
_is_swap() {
|
||||
test_blkid_() {
|
||||
local type
|
||||
# for empty devices without any types blkid exits with return code 2
|
||||
type=$(blkid -s TYPE -o value -c /dev/null "$DM_DEV_DIR/$vg/$lv1") || true
|
||||
type=$(blkid -s TYPE -o value -c /dev/null "$DM_DEV_DIR/$vg/$lv1")
|
||||
test "$type" = "swap"
|
||||
}
|
||||
|
||||
_is_not_swap() {
|
||||
local type
|
||||
# for empty devices without any types blkid exits with return code 2
|
||||
type=$(blkid -s TYPE -o value -c /dev/null "$DM_DEV_DIR/$vg/$lv1") || true
|
||||
[[ "$type" != "swap" ]]
|
||||
}
|
||||
|
||||
_was_wiping() {
|
||||
test_msg_() {
|
||||
grep "Wiping swap signature" out
|
||||
}
|
||||
|
||||
_was_not_wiping() {
|
||||
not grep "Wiping swap signature" out
|
||||
}
|
||||
|
||||
aux prepare_vg
|
||||
|
||||
# lvcreate wipes signatures when found on newly created LV - test this on "swap".
|
||||
# Test all combinations with -Z{y|n} and -W{y|n} and related lvm.conf settings.
|
||||
|
||||
lvcreate -l1 -n $lv1 $vg
|
||||
_init_lv
|
||||
init_lv_
|
||||
# This system has unusable blkid (does not recognize small swap, needs fix...)
|
||||
_is_swap || skip
|
||||
test_blkid_ || skip
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
# Zeroing stops the command when there is a failure (write error in this case)
|
||||
@@ -63,79 +51,74 @@ aux enable_dev "$dev1"
|
||||
aux lvmconf "allocation/wipe_signatures_when_zeroing_new_lvs = 0"
|
||||
|
||||
lvcreate -y -Zn -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_not_wiping
|
||||
_is_swap
|
||||
not test_msg_
|
||||
test_blkid_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zn -Wn -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_not_wiping
|
||||
_is_swap
|
||||
not test_msg_
|
||||
test_blkid_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zn -Wy -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zy -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_not_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
not test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zy -Wn -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_not_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
not test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zy -Wy -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
|
||||
aux lvmconf "allocation/wipe_signatures_when_zeroing_new_lvs = 1"
|
||||
|
||||
lvcreate -y -Zn -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_not_wiping
|
||||
_is_swap
|
||||
not test_msg_
|
||||
test_blkid_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zn -Wn -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_not_wiping
|
||||
_is_swap
|
||||
not test_msg_
|
||||
test_blkid_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zn -Wy -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zy -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zy -Wn -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_not_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
not test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
lvcreate -y -Zy -Wy -l1 -n $lv1 $vg 2>&1 | tee out
|
||||
_was_wiping
|
||||
_is_not_swap
|
||||
_init_lv
|
||||
test_msg_
|
||||
not test_blkid_
|
||||
init_lv_
|
||||
lvremove -f $vg/$lv1
|
||||
|
||||
vgremove -f $vg
|
||||
|
||||
aux udev_wait
|
||||
|
||||
aux udev_wait
|
||||
|
||||
aux udev_wait
|
||||
|
||||
@@ -337,13 +337,11 @@ test_2way_mirror_plus_2_fail_3_()
|
||||
|
||||
aux disable_dev "${list_pvs[@]}"
|
||||
vgreduce --removemissing --force $vg
|
||||
lvs -a -o+devices,segtype $vg
|
||||
lvs -a -o+devices $vg
|
||||
eval dev=\$dev$n
|
||||
mimages_are_on_ $lv1 "$dev" && die "Mimages of $lv1 is using $dev"
|
||||
not mimages_are_on_ $lv1 "$dev"
|
||||
lv_is_on_ $lv1 "$dev"
|
||||
if [[ $(get lv_field $vg/$lv1 "segtype") = "mirror" ]]; then
|
||||
mirrorlog_is_on_ $lv1 "$dev5" && die "Mirror log of $lv1 is still using $dev5"
|
||||
fi
|
||||
not mirrorlog_is_on_ $lv1 "$dev5"
|
||||
}
|
||||
|
||||
for n in $(seq 1 4); do
|
||||
@@ -369,7 +367,7 @@ mirrorlog_is_on_ $lv1 "$dev5"
|
||||
aux disable_dev "$dev5"
|
||||
vgreduce --removemissing --force $vg
|
||||
mimages_are_on_ $lv1 "$dev1" "$dev2"
|
||||
mirrorlog_is_on_ $lv1 "$dev5" && die "Mirror log of $lv1 is using $dev5"
|
||||
not mirrorlog_is_on_ $lv1 "$dev5"
|
||||
recover_vg_ "$dev5"
|
||||
|
||||
#COMM "fail mirror log of 3-way (1 converting) mirrored LV"
|
||||
@@ -381,7 +379,7 @@ mirrorlog_is_on_ $lv1 "$dev5"
|
||||
aux disable_dev "$dev5"
|
||||
vgreduce --removemissing --force $vg
|
||||
mimages_are_on_ $lv1 "$dev1" "$dev2" "$dev3"
|
||||
mirrorlog_is_on_ $lv1 "$dev5" && die "Mirror log of $lv1 is using $dev5"
|
||||
not mirrorlog_is_on_ $lv1 "$dev5"
|
||||
recover_vg_ "$dev5"
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
@@ -58,16 +58,6 @@ sel() {
|
||||
return 1
|
||||
}
|
||||
|
||||
grep "out of supported range" "$ERR_LOG_FILE" >/dev/null && {
|
||||
echo " >>> Selection out of supported range hit!"
|
||||
return 1
|
||||
}
|
||||
|
||||
grep "found in selection is reserved" "$ERR_LOG_FILE" > /dev/null && {
|
||||
echo " >>> Use of reserved selection value hit!"
|
||||
return 1
|
||||
}
|
||||
|
||||
items_found=$(wc -l < "$OUT_LOG_FILE")
|
||||
|
||||
# the number of lines on output must match
|
||||
@@ -116,7 +106,7 @@ sel pv 'tags=["pv_tag3" && "pv_tag2" && "pv_tag1"]' "$dev1"
|
||||
sel pv 'tags=["pv_tag4" || "pv_tag3" || "pv_tag1" || "pv_tag2"]' "$dev1" "$dev6"
|
||||
sel pv 'tags!=["pv_tag1"]' "$dev1" "$dev2" "$dev3" "$dev4" "$dev5" "$dev6"
|
||||
# check mixture of && and || - this is not allowed
|
||||
sel pv 'tags=["pv_tag1" && "pv_tag2" || "pv_tag3"]' && die "Mixture of && and || shall not pass."
|
||||
not sel pv 'tags=["pv_tag1" && "pv_tag2" || "pv_tag3"]'
|
||||
# check selection with blank value
|
||||
sel lv 'tags=""' xyz orig snap
|
||||
sel lv 'tags={}' xyz orig snap
|
||||
@@ -187,7 +177,7 @@ sel lv 'snap_percent=100' snap
|
||||
# % char is accepted as suffix for percent values
|
||||
sel lv 'snap_percent=100%' snap
|
||||
# percent values over 100% are not accepted
|
||||
sel lv 'snap_percent=101%' && die "Percent values over 100% shall not pass."
|
||||
not sel lv 'snap_percent=101%'
|
||||
|
||||
#########################
|
||||
# REGEX FIELD SELECTION #
|
||||
@@ -211,7 +201,7 @@ sel vg 'vg_mda_copies=2' $vg1
|
||||
# when comparing ranges - unmanaged is mapped onto 2^64 - 1 internally,
|
||||
# so we need to skip this internal value if it matches with selection criteria!
|
||||
sel vg 'vg_mda_copies>=2' $vg1
|
||||
sel vg 'vg_mda_copies=18446744073709551615' && die "vg_mda_copies over 2^64 - 1 shall not pass."
|
||||
not sel vg 'vg_mda_copies=18446744073709551615'
|
||||
|
||||
sel lv 'lv_read_ahead=auto' vol1 vol2 orig snap
|
||||
sel lv 'lv_read_ahead=256k' abc xyz
|
||||
|
||||
@@ -99,11 +99,8 @@ fill 64k $vg1/snap50
|
||||
lvcreate -s -l 25%ORIGIN -n snap25 $vg1/$lv
|
||||
fill 32k $vg1/snap25
|
||||
|
||||
# This feature works properly only with newer targets
|
||||
if aux target_at_least dm-snapshot 1 10 0 ; then
|
||||
# Check we do not provide too much extra space
|
||||
fill 33k $vg1/snap25 && die "Snapshot should not be able to fit 33k!"
|
||||
fi
|
||||
# Check we do not provide too much extra space
|
||||
not fill 33k $vg1/snap25
|
||||
|
||||
lvs -a $vg1
|
||||
lvremove -f $vg1
|
||||
@@ -118,6 +115,19 @@ lvchange -an $vg1
|
||||
# On cluster snapshot gets exclusive activation
|
||||
lvchange -ay $vg1
|
||||
check lv_field $vg1/$lv1 lv_active "$CHECK_ACTIVE"
|
||||
|
||||
# Test removal of opened (but unmounted) snapshot (device busy) for a while
|
||||
SLEEP_PID=$(aux hold_device_open $vg1 $lv1 60)
|
||||
|
||||
# Opened virtual snapshot device is not removable
|
||||
# it should retry device removal for a few seconds
|
||||
not lvremove -f $vg1/$lv1
|
||||
|
||||
kill $SLEEP_PID
|
||||
SLEEP_PID=
|
||||
# Wait for killed task, so there is no device holder
|
||||
wait
|
||||
|
||||
lvremove -f $vg1/$lv1
|
||||
check lv_not_exists $vg1 $lv1
|
||||
|
||||
@@ -170,19 +180,10 @@ lvremove -f $vg1
|
||||
# This test expects extent size 1K
|
||||
aux lvmconf "allocation/wipe_signatures_when_zeroing_new_lvs = 1"
|
||||
lvcreate -aey -L4 -n $lv $vg1
|
||||
$MKFS "$DM_DEV_DIR/$vg1/$lv"
|
||||
|
||||
lvcreate -c 8 -s -L1 -n snap $vg1/$lv
|
||||
# Populate snapshot
|
||||
#dd if=/dev/urandom of="$DM_DEV_DIR/$vg1/$lv" bs=4096 count=10
|
||||
|
||||
mkdir mnt
|
||||
mount "$DM_DEV_DIR/$vg1/snap" mnt
|
||||
# Opened virtual snapshot device is not removable
|
||||
# it should retry device removal for a few seconds
|
||||
not lvremove -f $vg1/snap
|
||||
umount mnt
|
||||
|
||||
$MKFS "$DM_DEV_DIR/$vg1/$lv"
|
||||
lvremove -f $vg1/snap
|
||||
|
||||
# Undeleted header would trigger attempt to access
|
||||
|
||||
@@ -118,18 +118,10 @@ is_lv_opened_ "$vg/$lv2" || \
|
||||
die "$mntusedir is not mounted here (sleep already expired??)"
|
||||
|
||||
# Kill device holding process
|
||||
kill "$PID_SLEEP"
|
||||
wait "$PID_SLEEP" || true
|
||||
kill $PID_SLEEP
|
||||
wait
|
||||
|
||||
for i in $(seq 1 12) ; do
|
||||
is_lv_opened_ "$vg/$lv2" || break
|
||||
sleep 1
|
||||
echo $i
|
||||
done
|
||||
|
||||
is_lv_opened_ "$vg/$lv2" && {
|
||||
mount | grep "$lv2"
|
||||
not is_lv_opened_ "$vg/$lv2" || {
|
||||
mount
|
||||
die "$mntusedir should have been unmounted by dmeventd!"
|
||||
}
|
||||
|
||||
exit 0 # -> cleanup_mounted_and_teardown
|
||||
|
||||
@@ -3165,6 +3165,8 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||
log_debug("Version: %s", LVM_VERSION);
|
||||
log_debug("Parsing: %s", cmd->cmd_line);
|
||||
|
||||
log_debug_config(cmd);
|
||||
|
||||
if (!(cmd->command = _find_command(cmd, cmd->name, &argc, argv)))
|
||||
return EINVALID_CMD_LINE;
|
||||
|
||||
|
||||
@@ -733,7 +733,7 @@ static int _vgchange_lock_stop(struct cmd_context *cmd, struct volume_group *vg)
|
||||
return_0;
|
||||
|
||||
/* stop is the only --persist value that's accepted */
|
||||
if (arg_is_set(cmd, persist_ARG) && (vg->pr & VG_PR_REQUIRE) && !persist_stop(cmd, vg))
|
||||
if (arg_is_set(cmd, persist_ARG) && !persist_stop(cmd, vg))
|
||||
log_warn("WARNING: PR stop failed, see lvmpersist stop.");
|
||||
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user