1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-11-16 04:23:50 +03:00

Compare commits

..

2 Commits

Author SHA1 Message Date
David Teigland
e8854c5d0e command: log_debug all non-default config settings 2025-11-11 16:33:10 -06:00
David Teigland
f36289d568 config: stop logging that a default value is used (other lib) 2025-11-11 14:50:34 -06:00
24 changed files with 381 additions and 760 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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)) {

View File

@@ -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) */
};

View File

@@ -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;
}

View File

@@ -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
.

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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[@]}")'

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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"
# ---------------------------------------------------------------------

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;