mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Merge branch '2018-05-29-radix-tree-iterate' into 2018-05-23-radix-tree-remove
This commit is contained in:
commit
0181c77e3f
52
.gitignore
vendored
52
.gitignore
vendored
@ -79,5 +79,55 @@ test/lib/vgrename
|
|||||||
test/lib/vgs
|
test/lib/vgs
|
||||||
test/lib/vgscan
|
test/lib/vgscan
|
||||||
test/lib/vgsplit
|
test/lib/vgsplit
|
||||||
|
test/api/lvtest.t
|
||||||
|
test/api/pe_start.t
|
||||||
|
test/api/percent.t
|
||||||
|
test/api/python_lvm_unit.py
|
||||||
|
test/api/test
|
||||||
|
test/api/thin_percent.t
|
||||||
|
test/api/vglist.t
|
||||||
|
test/api/vgtest.t
|
||||||
|
test/lib/aux
|
||||||
|
test/lib/check
|
||||||
|
test/lib/clvmd
|
||||||
|
test/lib/dm-version-expected
|
||||||
|
test/lib/dmeventd
|
||||||
|
test/lib/dmsetup
|
||||||
|
test/lib/dmstats
|
||||||
|
test/lib/fail
|
||||||
|
test/lib/flavour-ndev-cluster
|
||||||
|
test/lib/flavour-ndev-cluster-lvmpolld
|
||||||
|
test/lib/flavour-ndev-lvmetad
|
||||||
|
test/lib/flavour-ndev-lvmetad-lvmpolld
|
||||||
|
test/lib/flavour-ndev-lvmpolld
|
||||||
|
test/lib/flavour-ndev-vanilla
|
||||||
|
test/lib/flavour-udev-cluster
|
||||||
|
test/lib/flavour-udev-cluster-lvmpolld
|
||||||
|
test/lib/flavour-udev-lvmetad
|
||||||
|
test/lib/flavour-udev-lvmetad-lvmpolld
|
||||||
|
test/lib/flavour-udev-lvmlockd-dlm
|
||||||
|
test/lib/flavour-udev-lvmlockd-sanlock
|
||||||
|
test/lib/flavour-udev-lvmlockd-test
|
||||||
|
test/lib/flavour-udev-lvmpolld
|
||||||
|
test/lib/flavour-udev-vanilla
|
||||||
|
test/lib/fsadm
|
||||||
|
test/lib/get
|
||||||
|
test/lib/inittest
|
||||||
|
test/lib/invalid
|
||||||
|
test/lib/lvm
|
||||||
|
test/lib/lvm-wrapper
|
||||||
|
test/lib/lvmchange
|
||||||
|
test/lib/lvmdbusd.profile
|
||||||
|
test/lib/lvmetad
|
||||||
|
test/lib/lvmpolld
|
||||||
|
test/lib/not
|
||||||
|
test/lib/paths
|
||||||
|
test/lib/paths-common
|
||||||
|
test/lib/runner
|
||||||
|
test/lib/should
|
||||||
|
test/lib/test
|
||||||
|
test/lib/thin-performance.profile
|
||||||
|
test/lib/utils
|
||||||
|
test/lib/version-expected
|
||||||
|
test/unit/dmraid_t.c
|
||||||
test/unit/unit-test
|
test/unit/unit-test
|
||||||
|
@ -1 +1 @@
|
|||||||
1.02.147-git (2017-12-18)
|
1.02.147-git (2018-05-24)
|
||||||
|
23
WHATS_NEW
23
WHATS_NEW
@ -1,16 +1,22 @@
|
|||||||
Version 2.02.178 -
|
Version 2.02.178 -
|
||||||
=====================================
|
====================================
|
||||||
|
Use versionsort to fix archive file expiry beyond 100000 files.
|
||||||
|
|
||||||
|
Version 2.02.178-rc1 - 24th May 2018
|
||||||
|
====================================
|
||||||
|
Add libaio dependency for build.
|
||||||
Remove lvm1 and pool format handling and add filter to ignore them.
|
Remove lvm1 and pool format handling and add filter to ignore them.
|
||||||
Move some filter checks to after disks are read.
|
Move some filter checks to after disks are read.
|
||||||
Rework disk scanning and when it is used.
|
Rework disk scanning and when it is used.
|
||||||
Add new io layer and shift code to using it.
|
Add new io layer and shift code to using it.
|
||||||
lvconvert: don't return success on degraded -m raid1 conversion
|
Fix lvconvert's return code on degraded -m raid1 conversion.
|
||||||
--enable-testing switch for ./configure has been removed.
|
--enable-testing switch for ./configure has been removed.
|
||||||
--with-snapshots switch for ./configure has been removed.
|
--with-snapshots switch for ./configure has been removed.
|
||||||
--with-mirrors switch for ./configure has been removed.
|
--with-mirrors switch for ./configure has been removed.
|
||||||
--with-raid switch for ./configure has been removed.
|
--with-raid switch for ./configure has been removed.
|
||||||
--with-thin switch for ./configure has been removed.
|
--with-thin switch for ./configure has been removed.
|
||||||
--with-cache switch for ./configure has been removed.
|
--with-cache switch for ./configure has been removed.
|
||||||
|
Include new unit-test framework and unit tests.
|
||||||
Extend validation of region_size for mirror segment.
|
Extend validation of region_size for mirror segment.
|
||||||
Reload whole device stack when reinitilizing mirror log.
|
Reload whole device stack when reinitilizing mirror log.
|
||||||
Mirrors without monitoring are WARNING and not blocking on error.
|
Mirrors without monitoring are WARNING and not blocking on error.
|
||||||
@ -34,8 +40,8 @@ Version 2.02.178 -
|
|||||||
Enhance mirror log initialization for old mirror target.
|
Enhance mirror log initialization for old mirror target.
|
||||||
Skip private crypto and stratis devices.
|
Skip private crypto and stratis devices.
|
||||||
Skip frozen raid devices from scanning.
|
Skip frozen raid devices from scanning.
|
||||||
Activate RAID SubLVs on read_only_volume_list readwrite
|
Activate RAID SubLVs on read_only_volume_list readwrite.
|
||||||
Offer convenience type raid5_n converting to raid10
|
Offer convenience type raid5_n converting to raid10.
|
||||||
Automatically avoid reading invalid snapshots during device scan.
|
Automatically avoid reading invalid snapshots during device scan.
|
||||||
Ensure COW device is writable even for read-only thick snapshots.
|
Ensure COW device is writable even for read-only thick snapshots.
|
||||||
Support activation of component LVs in read-only mode.
|
Support activation of component LVs in read-only mode.
|
||||||
@ -53,20 +59,13 @@ Version 2.02.178 -
|
|||||||
Improve validation of created strings in vgimportclone.
|
Improve validation of created strings in vgimportclone.
|
||||||
Add missing initialisation of mem pool in systemd generator.
|
Add missing initialisation of mem pool in systemd generator.
|
||||||
Do not reopen output streams for multithreaded users of liblvm.
|
Do not reopen output streams for multithreaded users of liblvm.
|
||||||
Use versionsort to fix archive file expiry beyond 100000 files.
|
|
||||||
Add devices/use_aio, aio_max, aio_memory to configure AIO limits.
|
|
||||||
Support asynchronous I/O when scanning devices.
|
|
||||||
Detect asynchronous I/O capability in configure or accept --disable-aio.
|
|
||||||
Add AIO_SUPPORTED_CODE_PATH to indicate whether AIO may be used.
|
|
||||||
Configure ensures /usr/bin dir is checked for dmpd tools.
|
Configure ensures /usr/bin dir is checked for dmpd tools.
|
||||||
Restore pvmove support for wide-clustered active volumes (2.02.177).
|
Restore pvmove support for wide-clustered active volumes (2.02.177).
|
||||||
Avoid non-exclusive activation of exclusive segment types.
|
Avoid non-exclusive activation of exclusive segment types.
|
||||||
Fix trimming sibling PVs when doing a pvmove of raid subLVs.
|
Fix trimming sibling PVs when doing a pvmove of raid subLVs.
|
||||||
Preserve exclusive activation during thin snaphost merge.
|
Preserve exclusive activation during thin snaphost merge.
|
||||||
Suppress some repeated reads of the same disk data at the device layer.
|
|
||||||
Avoid exceeding array bounds in allocation tag processing.
|
Avoid exceeding array bounds in allocation tag processing.
|
||||||
Refactor metadata reading code to use callback functions.
|
Add --lockopt to common options and add option to skip selected locks.
|
||||||
Move memory allocation for the key dev_reads into the device layer.
|
|
||||||
|
|
||||||
Version 2.02.177 - 18th December 2017
|
Version 2.02.177 - 18th December 2017
|
||||||
=====================================
|
=====================================
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
Version 1.02.147 -
|
Version 1.02.147 -
|
||||||
=====================================
|
====================================
|
||||||
|
|
||||||
|
Version 1.02.147-rc1 - 24th May 2018
|
||||||
|
====================================
|
||||||
Reuse uname() result for mirror target.
|
Reuse uname() result for mirror target.
|
||||||
Recognize also mounted btrfs through dm_device_has_mounted_fs().
|
Recognize also mounted btrfs through dm_device_has_mounted_fs().
|
||||||
Add missing log_error() into dm_stats_populate() returning 0.
|
Add missing log_error() into dm_stats_populate() returning 0.
|
||||||
|
@ -75,17 +75,21 @@ struct node256 {
|
|||||||
struct radix_tree {
|
struct radix_tree {
|
||||||
unsigned nr_entries;
|
unsigned nr_entries;
|
||||||
struct value root;
|
struct value root;
|
||||||
|
radix_value_dtr dtr;
|
||||||
|
void *dtr_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
struct radix_tree *radix_tree_create(void)
|
struct radix_tree *radix_tree_create(radix_value_dtr dtr, void *dtr_context)
|
||||||
{
|
{
|
||||||
struct radix_tree *rt = malloc(sizeof(*rt));
|
struct radix_tree *rt = malloc(sizeof(*rt));
|
||||||
|
|
||||||
if (rt) {
|
if (rt) {
|
||||||
rt->nr_entries = 0;
|
rt->nr_entries = 0;
|
||||||
rt->root.type = UNSET;
|
rt->root.type = UNSET;
|
||||||
|
rt->dtr = dtr;
|
||||||
|
rt->dtr_context = dtr_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
@ -154,9 +158,9 @@ static void _free_node(struct value v, radix_value_dtr dtr, void *context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void radix_tree_destroy(struct radix_tree *rt, radix_value_dtr dtr, void *context)
|
void radix_tree_destroy(struct radix_tree *rt)
|
||||||
{
|
{
|
||||||
_free_node(rt->root, dtr, context);
|
_free_node(rt->root, rt->dtr, rt->dtr_context);
|
||||||
free(rt);
|
free(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ union radix_value {
|
|||||||
uint64_t n;
|
uint64_t n;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radix_tree *radix_tree_create(void);
|
|
||||||
|
|
||||||
typedef void (*radix_value_dtr)(void *context, union radix_value v);
|
typedef void (*radix_value_dtr)(void *context, union radix_value v);
|
||||||
|
|
||||||
// dtr may be NULL
|
// dtr will be called on any deleted entries. dtr may be NULL.
|
||||||
void radix_tree_destroy(struct radix_tree *rt, radix_value_dtr dtr, void *context);
|
struct radix_tree *radix_tree_create(radix_value_dtr dtr, void *dtr_context);
|
||||||
|
void radix_tree_destroy(struct radix_tree *rt);
|
||||||
|
|
||||||
unsigned radix_tree_size(struct radix_tree *rt);
|
unsigned radix_tree_size(struct radix_tree *rt);
|
||||||
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value v);
|
bool radix_tree_insert(struct radix_tree *rt, uint8_t *kb, uint8_t *ke, union radix_value v);
|
||||||
|
53
doc/release-notes/2.02.178
Normal file
53
doc/release-notes/2.02.178
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Version 2.02.178
|
||||||
|
================
|
||||||
|
|
||||||
|
There are going to be some large changes to the lvm2 codebase
|
||||||
|
over the next year or so. Starting with this release. These
|
||||||
|
changes should be internal rather than having a big effect on
|
||||||
|
the command line. Inevitably these changes will increase the
|
||||||
|
chance of bugs, so please be on the alert.
|
||||||
|
|
||||||
|
|
||||||
|
Remove support for obsolete metadata formats
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
Support for the GFS pool format, and format used by the
|
||||||
|
original 1990's version of LVM1 have been removed.
|
||||||
|
|
||||||
|
Use asynchronous IO
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Almost all IO uses libaio now.
|
||||||
|
|
||||||
|
Rewrite label scanning
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Dave Teigland has reworked the label scanning and metadata reading
|
||||||
|
logic to minimise the amount of IOs issued. Combined with the aio changes
|
||||||
|
this can greatly improve scanning speed for some systems.
|
||||||
|
|
||||||
|
./configure options
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
We're going to try and remove as many options from ./configure as we
|
||||||
|
can. Each option multiplies the number of possible configurations
|
||||||
|
that we should test (this testing is currently not occurring).
|
||||||
|
|
||||||
|
The first batch to be removed are:
|
||||||
|
|
||||||
|
--enable-testing
|
||||||
|
--with-snapshots
|
||||||
|
--with-mirrors
|
||||||
|
--with-raid
|
||||||
|
--with-thin
|
||||||
|
--with-cache
|
||||||
|
|
||||||
|
Stable targets that are in the upstream kernel will just be supported.
|
||||||
|
|
||||||
|
In future optional target flags will be given in two situations:
|
||||||
|
|
||||||
|
1) The target is experimental, or not upstream at all (eg, vdo).
|
||||||
|
2) The target is deprecated and support will be removed at some future date.
|
||||||
|
|
||||||
|
This decision could well be contentious, so could distro maintainers feel
|
||||||
|
free to comment.
|
@ -1080,6 +1080,8 @@ void dev_cache_scan(void)
|
|||||||
{
|
{
|
||||||
struct dir_list *dl;
|
struct dir_list *dl;
|
||||||
|
|
||||||
|
log_debug_devs("Creating list of system devices.");
|
||||||
|
|
||||||
_cache.has_scanned = 1;
|
_cache.has_scanned = 1;
|
||||||
|
|
||||||
_insert_dirs(&_cache.dirs);
|
_insert_dirs(&_cache.dirs);
|
||||||
|
@ -135,8 +135,8 @@ static struct dm_list *_scan_archive(struct dm_pool *mem,
|
|||||||
|
|
||||||
dm_list_init(results);
|
dm_list_init(results);
|
||||||
|
|
||||||
/* Sort fails beyond 5-digit indexes */
|
/* Use versionsort to handle numbers beyond 5 digits */
|
||||||
if ((count = scandir(dir, &dirent, NULL, alphasort)) < 0) {
|
if ((count = scandir(dir, &dirent, NULL, versionsort)) < 0) {
|
||||||
log_error("Couldn't scan the archive directory (%s).", dir);
|
log_error("Couldn't scan the archive directory (%s).", dir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,11 @@ static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
|||||||
|
|
||||||
static int _scan_dev_open(struct device *dev)
|
static int _scan_dev_open(struct device *dev)
|
||||||
{
|
{
|
||||||
|
struct dm_list *name_list;
|
||||||
|
struct dm_str_list *name_sl;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
struct stat sbuf;
|
||||||
|
int retried = 0;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -435,20 +439,30 @@ static int _scan_dev_open(struct device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (dev->flags & DEV_IN_BCACHE) {
|
if (dev->flags & DEV_IN_BCACHE) {
|
||||||
log_error("scan_dev_open %s DEV_IN_BCACHE already set", dev_name(dev));
|
/* Shouldn't happen */
|
||||||
|
log_error("Device open %s has DEV_IN_BCACHE already set", dev_name(dev));
|
||||||
dev->flags &= ~DEV_IN_BCACHE;
|
dev->flags &= ~DEV_IN_BCACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->bcache_fd > 0) {
|
if (dev->bcache_fd > 0) {
|
||||||
log_error("scan_dev_open %s already open with fd %d",
|
/* Shouldn't happen */
|
||||||
|
log_error("Device open %s already open with fd %d",
|
||||||
dev_name(dev), dev->bcache_fd);
|
dev_name(dev), dev->bcache_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(name = dev_name_confirmed(dev, 1))) {
|
/*
|
||||||
log_error("scan_dev_open %s no name", dev_name(dev));
|
* All the names for this device (major:minor) are kept on
|
||||||
|
* dev->aliases, the first one is the primary/preferred name.
|
||||||
|
*/
|
||||||
|
if (!(name_list = dm_list_first(&dev->aliases))) {
|
||||||
|
/* Shouldn't happen */
|
||||||
|
log_error("Device open %s %d:%d has no path names.",
|
||||||
|
dev_name(dev), (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
name_sl = dm_list_item(name_list, struct dm_str_list);
|
||||||
|
name = name_sl->str;
|
||||||
|
|
||||||
flags |= O_RDWR;
|
flags |= O_RDWR;
|
||||||
flags |= O_DIRECT;
|
flags |= O_DIRECT;
|
||||||
@ -457,6 +471,8 @@ static int _scan_dev_open(struct device *dev)
|
|||||||
if (dev->flags & DEV_BCACHE_EXCL)
|
if (dev->flags & DEV_BCACHE_EXCL)
|
||||||
flags |= O_EXCL;
|
flags |= O_EXCL;
|
||||||
|
|
||||||
|
retry_open:
|
||||||
|
|
||||||
fd = open(name, flags, 0777);
|
fd = open(name, flags, 0777);
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@ -464,7 +480,48 @@ static int _scan_dev_open(struct device *dev)
|
|||||||
log_error("Can't open %s exclusively. Mounted filesystem?",
|
log_error("Can't open %s exclusively. Mounted filesystem?",
|
||||||
dev_name(dev));
|
dev_name(dev));
|
||||||
} else {
|
} else {
|
||||||
log_error("scan_dev_open %s failed errno %d", dev_name(dev), errno);
|
int major, minor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shouldn't happen, if it does, print stat info to help figure
|
||||||
|
* out what's wrong.
|
||||||
|
*/
|
||||||
|
|
||||||
|
major = (int)MAJOR(dev->dev);
|
||||||
|
minor = (int)MINOR(dev->dev);
|
||||||
|
|
||||||
|
log_error("Device open %s %d:%d failed errno %d", name, major, minor, errno);
|
||||||
|
|
||||||
|
if (stat(name, &sbuf)) {
|
||||||
|
log_debug_devs("Device open %s %d:%d stat failed errno %d",
|
||||||
|
name, major, minor, errno);
|
||||||
|
} else if (sbuf.st_rdev != dev->dev) {
|
||||||
|
log_debug_devs("Device open %s %d:%d stat %d:%d does not match.",
|
||||||
|
name, major, minor,
|
||||||
|
(int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: do we want to try opening this device using
|
||||||
|
* one of the other path aliases for the same
|
||||||
|
* major:minor from dev->aliases? We could iterate
|
||||||
|
* through those aliases to try opening each of them to
|
||||||
|
* find one that works. What are the consequences of
|
||||||
|
* using a different, non-preferred alias to a device?
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!retried) {
|
||||||
|
/*
|
||||||
|
* FIXME: remove this, the theory for this retry is that
|
||||||
|
* there may be a udev race that we can sometimes mask by
|
||||||
|
* retrying. This is here until we can figure out if it's
|
||||||
|
* needed and if so fix the real problem.
|
||||||
|
*/
|
||||||
|
usleep(5000);
|
||||||
|
log_debug_devs("Device open %s retry", dev_name(dev));
|
||||||
|
retried = 1;
|
||||||
|
goto retry_open;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -509,9 +566,10 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
|||||||
{
|
{
|
||||||
struct dm_list wait_devs;
|
struct dm_list wait_devs;
|
||||||
struct dm_list done_devs;
|
struct dm_list done_devs;
|
||||||
|
struct dm_list reopen_devs;
|
||||||
struct device_list *devl, *devl2;
|
struct device_list *devl, *devl2;
|
||||||
struct block *bb;
|
struct block *bb;
|
||||||
int scan_open_errors = 0;
|
int retried_open = 0;
|
||||||
int scan_read_errors = 0;
|
int scan_read_errors = 0;
|
||||||
int scan_process_errors = 0;
|
int scan_process_errors = 0;
|
||||||
int scan_failed_count = 0;
|
int scan_failed_count = 0;
|
||||||
@ -524,6 +582,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
|||||||
|
|
||||||
dm_list_init(&wait_devs);
|
dm_list_init(&wait_devs);
|
||||||
dm_list_init(&done_devs);
|
dm_list_init(&done_devs);
|
||||||
|
dm_list_init(&reopen_devs);
|
||||||
|
|
||||||
log_debug_devs("Scanning %d devices for VG info", dm_list_size(devs));
|
log_debug_devs("Scanning %d devices for VG info", dm_list_size(devs));
|
||||||
|
|
||||||
@ -547,9 +606,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
|||||||
if (!_scan_dev_open(devl->dev)) {
|
if (!_scan_dev_open(devl->dev)) {
|
||||||
log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
|
log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
|
||||||
dm_list_del(&devl->list);
|
dm_list_del(&devl->list);
|
||||||
dm_list_add(&done_devs, &devl->list);
|
dm_list_add(&reopen_devs, &devl->list);
|
||||||
scan_open_errors++;
|
|
||||||
scan_failed_count++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -612,8 +669,44 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
|||||||
if (!dm_list_empty(devs))
|
if (!dm_list_empty(devs))
|
||||||
goto scan_more;
|
goto scan_more;
|
||||||
|
|
||||||
log_debug_devs("Scanned devices: open errors %d read errors %d process errors %d",
|
/*
|
||||||
scan_open_errors, scan_read_errors, scan_process_errors);
|
* We're done scanning all the devs. If we failed to open any of them
|
||||||
|
* the first time through, refresh device paths and retry. We failed
|
||||||
|
* to open the devs on the reopen_devs list.
|
||||||
|
*
|
||||||
|
* FIXME: it's not clear if or why this helps.
|
||||||
|
*
|
||||||
|
* FIXME: should we delete the first path name from dev->aliases that
|
||||||
|
* we failed to open the first time before retrying? If that path
|
||||||
|
* still exists on the system, dev_cache_scan should put it back, but
|
||||||
|
* if it doesn't exist we don't want to try using it again.
|
||||||
|
*/
|
||||||
|
if (!dm_list_empty(&reopen_devs)) {
|
||||||
|
if (retried_open) {
|
||||||
|
/* Don't try again. */
|
||||||
|
scan_failed_count += dm_list_size(&reopen_devs);
|
||||||
|
dm_list_splice(&done_devs, &reopen_devs);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
retried_open = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This will search the system's /dev for new path names and
|
||||||
|
* could help us reopen the device if it finds a new preferred
|
||||||
|
* path name for this dev's major:minor. It does that by
|
||||||
|
* inserting a new preferred path name on dev->aliases. open
|
||||||
|
* uses the first name from that list.
|
||||||
|
*/
|
||||||
|
log_debug_devs("Scanning refreshing device paths.");
|
||||||
|
dev_cache_scan();
|
||||||
|
|
||||||
|
/* Put devs that failed to open back on the original list to retry. */
|
||||||
|
dm_list_splice(devs, &reopen_devs);
|
||||||
|
goto scan_more;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
log_debug_devs("Scanned devices: read errors %d process errors %d failed %d",
|
||||||
|
scan_read_errors, scan_process_errors, scan_failed_count);
|
||||||
|
|
||||||
if (failed)
|
if (failed)
|
||||||
*failed = scan_failed_count;
|
*failed = scan_failed_count;
|
||||||
|
@ -123,7 +123,7 @@ Command is executed with environmental variable
|
|||||||
in this environment will not try to interact with dmeventd.
|
in this environment will not try to interact with dmeventd.
|
||||||
To see the fullness of a thin pool command may check these
|
To see the fullness of a thin pool command may check these
|
||||||
two environmental variables
|
two environmental variables
|
||||||
\fBDMEVENTD_THIN_POOL_DATA\fP and \fBDMEVENTD_THIN_POOL_DATA\fP.
|
\fBDMEVENTD_THIN_POOL_DATA\fP and \fBDMEVENTD_THIN_POOL_METADATA\fP.
|
||||||
Command can also read status with tools like \fBlvs\fP(8).
|
Command can also read status with tools like \fBlvs\fP(8).
|
||||||
.
|
.
|
||||||
.SH ENVIRONMENT VARIABLES
|
.SH ENVIRONMENT VARIABLES
|
||||||
@ -134,7 +134,7 @@ Variable is set by thin plugin and is available to executed program. Value prese
|
|||||||
actual usage of thin pool data volume. Variable is not set when error event
|
actual usage of thin pool data volume. Variable is not set when error event
|
||||||
is processed.
|
is processed.
|
||||||
.TP
|
.TP
|
||||||
.B DMEVENTD_THIN_POOL_DATA
|
.B DMEVENTD_THIN_POOL_METADATA
|
||||||
Variable is set by thin plugin and is available to executed program. Value present
|
Variable is set by thin plugin and is available to executed program. Value present
|
||||||
actual usage of thin pool metadata volume. Variable is not set when error event
|
actual usage of thin pool metadata volume. Variable is not set when error event
|
||||||
is processed.
|
is processed.
|
||||||
|
@ -8,11 +8,22 @@ vgexport - Unregister volume group(s) from the system
|
|||||||
[ \fIoption_args\fP ]
|
[ \fIoption_args\fP ]
|
||||||
.br
|
.br
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
vgexport makes inactive VGs unknown to the system. In this state, all the
|
vgexport changes a VG into the exported state, which ensures that the VG
|
||||||
PVs in the VG can be moved to a different system, from which
|
and its disks are not being used, and cannot be used until the VG is
|
||||||
\fBvgimport\fP(8) can then be run.
|
imported by \fBvgimport\fP(8). Putting a VG into an unusable, offline
|
||||||
|
state can be useful when doing things like moving a VG's disks to another
|
||||||
|
system. Exporting a VG provides some protection from its LVs being
|
||||||
|
accidentally used, or being used by an automated system before it's ready.
|
||||||
|
|
||||||
Most LVM tools ignore exported VGs.
|
A VG cannot be exported until all of its LVs are inactive.
|
||||||
|
|
||||||
|
LVM commands will ignore an exported VG or report an error if a command
|
||||||
|
tries to use it.
|
||||||
|
|
||||||
|
For an exported VG, the vgs command will display \"x\" in the third VG
|
||||||
|
attribute, and the pvs command will display \"x\" in the second PV
|
||||||
|
attribute. Both vgs and pvs will display \"exported\" from the export
|
||||||
|
report field.
|
||||||
|
|
||||||
vgexport clears the VG system ID, and vgimport sets the VG system ID to
|
vgexport clears the VG system ID, and vgimport sets the VG system ID to
|
||||||
match the host running vgimport (if the host has a system ID).
|
match the host running vgimport (if the host has a system ID).
|
||||||
|
@ -755,11 +755,14 @@ prepare_md_dev() {
|
|||||||
local coption="--chunk"
|
local coption="--chunk"
|
||||||
local maj
|
local maj
|
||||||
local mddev
|
local mddev
|
||||||
|
local mddir="md/"
|
||||||
|
local mdname
|
||||||
|
local mddevdir
|
||||||
maj=$(mdadm --version 2>&1) || skip "mdadm tool is missing!"
|
maj=$(mdadm --version 2>&1) || skip "mdadm tool is missing!"
|
||||||
|
|
||||||
cleanup_md_dev
|
cleanup_md_dev
|
||||||
|
|
||||||
rm -f debug.log strace.log MD_DEV MD_DEV_PV MD_DEVICES
|
rm -f debug.log strace.log
|
||||||
|
|
||||||
case "$level" in
|
case "$level" in
|
||||||
"1") coption="--bitmap-chunk" ;;
|
"1") coption="--bitmap-chunk" ;;
|
||||||
@ -770,9 +773,11 @@ prepare_md_dev() {
|
|||||||
# - newer mdadm _completely_ defers to udev to create the associated device node
|
# - newer mdadm _completely_ defers to udev to create the associated device node
|
||||||
maj=${maj##*- v}
|
maj=${maj##*- v}
|
||||||
maj=${maj%%.*}
|
maj=${maj%%.*}
|
||||||
[ "$maj" -ge 3 ] && \
|
[ "$maj" -ge 3 ] || mddir=""
|
||||||
mddev=/dev/md/md_lvm_test0 || \
|
|
||||||
mddev=/dev/md_lvm_test0
|
mdname="md_lvm_test0"
|
||||||
|
mddev="/dev/${mddir}$mdname"
|
||||||
|
mddevdir="$DM_DEV_DIR/$mddir"
|
||||||
|
|
||||||
mdadm --create --metadata=1.0 "$mddev" --auto=md --level "$level" $with_bitmap "$coption"="$rchunk" --raid-devices="$rdevs" "${@:4}" || {
|
mdadm --create --metadata=1.0 "$mddev" --auto=md --level "$level" $with_bitmap "$coption"="$rchunk" --raid-devices="$rdevs" "${@:4}" || {
|
||||||
# Some older 'mdadm' version managed to open and close devices internaly
|
# Some older 'mdadm' version managed to open and close devices internaly
|
||||||
@ -791,10 +796,11 @@ prepare_md_dev() {
|
|||||||
|
|
||||||
# LVM/DM will see this device
|
# LVM/DM will see this device
|
||||||
case "$DM_DEV_DIR" in
|
case "$DM_DEV_DIR" in
|
||||||
"/dev") readlink -f "$mddev" ;;
|
"/dev") readlink -f "$mddev" > MD_DEV_PV ;;
|
||||||
*) cp -LR "$mddev" "$DM_DEV_DIR"
|
*) mkdir -p "$mddevdir"
|
||||||
echo "$DM_DEV_DIR/md_lvm_test0" ;;
|
cp -LR "$mddev" "$mddevdir"
|
||||||
esac > MD_DEV_PV
|
echo "${mddevdir}${mdname}" > MD_DEV_PV ;;
|
||||||
|
esac
|
||||||
echo "$mddev" > MD_DEV
|
echo "$mddev" > MD_DEV
|
||||||
notify_lvmetad "$(< MD_DEV_PV)"
|
notify_lvmetad "$(< MD_DEV_PV)"
|
||||||
printf "%s\n" "${@:4}" > MD_DEVICES
|
printf "%s\n" "${@:4}" > MD_DEVICES
|
||||||
@ -809,12 +815,14 @@ cleanup_md_dev() {
|
|||||||
local IFS=$IFS_NL
|
local IFS=$IFS_NL
|
||||||
local dev
|
local dev
|
||||||
local mddev
|
local mddev
|
||||||
|
local mddev_pv
|
||||||
mddev=$(< MD_DEV)
|
mddev=$(< MD_DEV)
|
||||||
|
mddev_pv=$(< MD_DEV_PV)
|
||||||
udev_wait
|
udev_wait
|
||||||
mdadm --stop "$mddev" || true
|
mdadm --stop "$mddev" || true
|
||||||
test "$DM_DEV_DIR" != "/dev" && rm -f "$DM_DEV_DIR/$(basename "$mddev")"
|
notify_lvmetad "$mddev_pv"
|
||||||
notify_lvmetad "$(< MD_DEV_PV)"
|
|
||||||
udev_wait # wait till events are process, not zeroing to early
|
udev_wait # wait till events are process, not zeroing to early
|
||||||
|
test "$DM_DEV_DIR" != "/dev" && rm -rf "${mddev_pv%/*}"
|
||||||
for dev in $(< MD_DEVICES); do
|
for dev in $(< MD_DEVICES); do
|
||||||
mdadm --zero-superblock "$dev" || true
|
mdadm --zero-superblock "$dev" || true
|
||||||
notify_lvmetad "$dev"
|
notify_lvmetad "$dev"
|
||||||
@ -1167,7 +1175,7 @@ extend_filter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend_filter_LVMTEST() {
|
extend_filter_LVMTEST() {
|
||||||
extend_filter "a|$DM_DEV_DIR/$PREFIX|"
|
extend_filter "a|$DM_DEV_DIR/$PREFIX|" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
hide_dev() {
|
hide_dev() {
|
||||||
|
@ -25,8 +25,7 @@ aux prepare_devs 2
|
|||||||
aux prepare_md_dev 0 64 2 "$dev1" "$dev2"
|
aux prepare_md_dev 0 64 2 "$dev1" "$dev2"
|
||||||
|
|
||||||
aux lvmconf 'devices/md_component_detection = 1'
|
aux lvmconf 'devices/md_component_detection = 1'
|
||||||
aux extend_filter_LVMTEST
|
aux extend_filter_LVMTEST "a|/dev/md|"
|
||||||
aux extend_filter "a|/dev/md.*|"
|
|
||||||
|
|
||||||
pvdev=$(< MD_DEV_PV)
|
pvdev=$(< MD_DEV_PV)
|
||||||
|
|
||||||
|
94
test/shell/pvcreate-md-fake-hdr.sh
Normal file
94
test/shell/pvcreate-md-fake-hdr.sh
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (C) 2018 Red Hat, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
# of the GNU General Public License v.2.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: once code get fixed, add matching 'check' calls
|
||||||
|
SKIP_WITH_LVMLOCKD=1
|
||||||
|
SKIP_WITH_LVMPOLLD=1
|
||||||
|
|
||||||
|
. lib/inittest
|
||||||
|
|
||||||
|
test -f /proc/mdstat && grep -q raid1 /proc/mdstat || \
|
||||||
|
modprobe raid1 || skip
|
||||||
|
|
||||||
|
aux lvmconf 'devices/md_component_detection = 1'
|
||||||
|
aux extend_filter_LVMTEST "a|/dev/md|"
|
||||||
|
|
||||||
|
aux prepare_devs 4
|
||||||
|
|
||||||
|
vgcreate $vg "$dev3" "$dev4"
|
||||||
|
|
||||||
|
# create 2 disk MD raid1 array
|
||||||
|
# by default using metadata format 1.0 with data at the end of device
|
||||||
|
aux prepare_md_dev 1 64 2 "$dev1" "$dev2"
|
||||||
|
|
||||||
|
mddev=$(< MD_DEV)
|
||||||
|
pvdev=$(< MD_DEV_PV)
|
||||||
|
sleep 3
|
||||||
|
mdadm --stop "$mddev"
|
||||||
|
|
||||||
|
# copy fake PV/VG header PV3 -> PV2 (which is however md raid1 leg)
|
||||||
|
dd if="$dev3" of="$dev2" bs=64k count=1 conv=fdatasync
|
||||||
|
|
||||||
|
# remove VG on PV3 & PV4
|
||||||
|
vgremove -f $vg
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
aux udev_wait
|
||||||
|
# too bad 'dd' wakes up md array reassembling
|
||||||
|
should not mdadm --detail "$mddev"
|
||||||
|
should not mdadm --stop "$mddev"
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
# print what blkid thinks about each PV
|
||||||
|
for i in "$dev1" "$dev2" "$dev3" "$dev4"
|
||||||
|
do
|
||||||
|
blkid -c /dev/null -w /dev/null "$i" || echo "Unknown signature"
|
||||||
|
done
|
||||||
|
|
||||||
|
# expect open count for each PV to be 0
|
||||||
|
dmsetup info -c
|
||||||
|
|
||||||
|
pvs -vvvv "$dev2" "$dev3" || true
|
||||||
|
|
||||||
|
# still expect open count for each PV to be 0
|
||||||
|
dmsetup info -c
|
||||||
|
|
||||||
|
pvs -vvvv "$dev3" "$dev2" || true
|
||||||
|
|
||||||
|
# and again we expect open count for each PV to be 0
|
||||||
|
dmsetup info -c
|
||||||
|
dmsetup table
|
||||||
|
|
||||||
|
# even after 3 second of possible hidden raid array assembling
|
||||||
|
sleep 3
|
||||||
|
dmsetup info -c
|
||||||
|
|
||||||
|
# if for any reason array went up - stop it again
|
||||||
|
if mdadm --detail "$mddev" ; then
|
||||||
|
mdadm --stop "$mddev"
|
||||||
|
aux udev_wait
|
||||||
|
should not mdadm --detail "$mddev"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# now reassemble array from PV1 & PV2
|
||||||
|
mdadm --assemble --verbose "$mddev" "$dev1" "$dev2"
|
||||||
|
aux udev_wait
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# and let 'fake hdr' to be fixed from master/primary leg
|
||||||
|
# (when mdadm supports repair)
|
||||||
|
if mdadm --action=repair "$mddev" ; then
|
||||||
|
sleep 1
|
||||||
|
# should be showing correctly PV3 & PV4
|
||||||
|
pvs
|
||||||
|
fi
|
@ -83,13 +83,19 @@ EOF
|
|||||||
if aux kernel_at_least 2 6 33 ; then
|
if aux kernel_at_least 2 6 33 ; then
|
||||||
# in case the system is running without devtmpfs /dev
|
# in case the system is running without devtmpfs /dev
|
||||||
# wait here for created device node on tmpfs
|
# wait here for created device node on tmpfs
|
||||||
test "$DM_DEV_DIR" != "/dev" && cp -LR "${mddev}p1" "$DM_DEV_DIR"
|
test "$DM_DEV_DIR" = "/dev" || cp -LR "${mddev}p1" "${pvdev%/*}"
|
||||||
|
|
||||||
pvcreate --metadatasize 128k "${pvdev}p1"
|
pvcreate --metadatasize 128k "${pvdev}p1"
|
||||||
|
|
||||||
maj=$(($(stat -L --printf=0x%t "${mddev}p1")))
|
maj=$(($(stat -L --printf=0x%t "${mddev}p1")))
|
||||||
min=$(($(stat -L --printf=0x%T "${mddev}p1")))
|
min=$(($(stat -L --printf=0x%T "${mddev}p1")))
|
||||||
|
|
||||||
|
ls /sys/dev/block/$maj:$min/
|
||||||
|
ls /sys/dev/block/$maj:$min/holders/
|
||||||
|
cat /sys/dev/block/$maj:$min/dev
|
||||||
|
cat /sys/dev/block/$maj:$min/stat
|
||||||
|
cat /sys/dev/block/$maj:$min/size
|
||||||
|
|
||||||
sysfs_alignment_offset="/sys/dev/block/$maj:$min/alignment_offset"
|
sysfs_alignment_offset="/sys/dev/block/$maj:$min/alignment_offset"
|
||||||
[ -f "$sysfs_alignment_offset" ] && \
|
[ -f "$sysfs_alignment_offset" ] && \
|
||||||
alignment_offset=$(< "$sysfs_alignment_offset") || \
|
alignment_offset=$(< "$sysfs_alignment_offset") || \
|
||||||
@ -100,20 +106,25 @@ EOF
|
|||||||
check pv_field "${pvdev}p1" pe_start $pv_align --units b --nosuffix
|
check pv_field "${pvdev}p1" pe_start $pv_align --units b --nosuffix
|
||||||
|
|
||||||
pvremove "${pvdev}p1"
|
pvremove "${pvdev}p1"
|
||||||
test "$DM_DEV_DIR" != "/dev" && rm -f "$DM_DEV_DIR/${mddev}p1"
|
test "$DM_DEV_DIR" = "/dev" || rm -f "${pvdev}p1"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Test newer topology-aware alignment detection w/ --dataalignment override
|
# Test newer topology-aware alignment detection w/ --dataalignment override
|
||||||
if aux kernel_at_least 2 6 33 ; then
|
if aux kernel_at_least 2 6 33 ; then
|
||||||
# make sure we're clean for another test
|
# make sure we're clean for another test
|
||||||
dd if=/dev/zero of="$mddev" bs=512 count=1
|
dd if=/dev/zero of="$mddev" bs=512 count=4 conv=fdatasync
|
||||||
|
partprobe -s "$mddev"
|
||||||
aux prepare_md_dev 0 1024 2 "$dev1" "$dev2"
|
aux prepare_md_dev 0 1024 2 "$dev1" "$dev2"
|
||||||
pvdev=$(< MD_DEV_PV)
|
pvdev=$(< MD_DEV_PV)
|
||||||
|
|
||||||
# optimal_io_size=2097152, minimum_io_size=1048576
|
# optimal_io_size=2097152, minimum_io_size=1048576
|
||||||
pvcreate --metadatasize 128k \
|
pvcreate --metadatasize 128k \
|
||||||
--config 'devices { md_chunk_alignment=0 }' "$pvdev"
|
--config 'devices { md_chunk_alignment=0 }' "$pvdev"
|
||||||
|
|
||||||
|
# to see the processing of scanning
|
||||||
|
pvs -vvvv
|
||||||
|
|
||||||
check pv_field "$pvdev" pe_start "2.00m"
|
check pv_field "$pvdev" pe_start "2.00m"
|
||||||
|
|
||||||
# now verify pe_start alignment override using --dataalignment
|
# now verify pe_start alignment override using --dataalignment
|
||||||
|
@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
static void *rt_init(void)
|
static void *rt_init(void)
|
||||||
{
|
{
|
||||||
struct radix_tree *rt = radix_tree_create();
|
struct radix_tree *rt = radix_tree_create(NULL, NULL);
|
||||||
T_ASSERT(rt);
|
T_ASSERT(rt);
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt_exit(void *fixture)
|
static void rt_exit(void *fixture)
|
||||||
{
|
{
|
||||||
radix_tree_destroy(fixture, NULL, NULL);
|
radix_tree_destroy(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_create_destroy(void *fixture)
|
static void test_create_destroy(void *fixture)
|
||||||
|
Loading…
Reference in New Issue
Block a user