1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-04-01 18:50:41 +03:00

scan: use separate fd for bcache

Create a new dev->bcache_fd that the scanning code owns
and is in charge of opening/closing.  This prevents other
parts of lvm code (which do various open/close) from
interfering with the bcache fd.  A number of dev_open
and dev_close are removed from the reading path since
the read path now uses the bcache.

With that in place, open(O_EXCL) for pvcreate/pvremove
can then be fixed.  That wouldn't work previously because
of other open fds.
This commit is contained in:
David Teigland 2018-02-13 08:58:35 -06:00
parent 4343280ebc
commit 6c67c7557c
10 changed files with 187 additions and 139 deletions

12
lib/cache/lvmetad.c vendored
View File

@ -2551,11 +2551,18 @@ static int _lvmetad_get_pv_cache_list(struct cmd_context *cmd, struct dm_list *p
*/
static void _update_pv_in_udev(struct cmd_context *cmd, dev_t devt)
{
struct device *dev;
log_debug_devs("device %d:%d open to update udev",
/*
* FIXME: this is diabled as part of removing dev_opens
* to integrate bcache. If this is really needed, we
* can do a separate open/close here.
*/
log_debug_devs("SKIP device %d:%d open to update udev",
(int)MAJOR(devt), (int)MINOR(devt));
#if 0
struct device *dev;
if (!(dev = dev_cache_get_by_devt(devt, cmd->lvmetad_filter))) {
log_error("_update_pv_in_udev no dev found");
return;
@ -2568,6 +2575,7 @@ static void _update_pv_in_udev(struct cmd_context *cmd, dev_t devt)
if (!dev_close(dev))
stack;
#endif
}
/*

View File

@ -534,11 +534,11 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
return 0;
}
if (!bcache_read_bytes(scan_bcache, dev->fd, offset, size, buf))
if (!bcache_read_bytes(scan_bcache, dev->bcache_fd, offset, size, buf))
goto out;
if (size2) {
if (!bcache_read_bytes(scan_bcache, dev->fd, offset2, size2, buf + size))
if (!bcache_read_bytes(scan_bcache, dev->bcache_fd, offset2, size2, buf + size))
goto out;
}

View File

@ -330,6 +330,8 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size)
static int _dev_get_size_dev(struct device *dev, uint64_t *size)
{
const char *name = dev_name(dev);
int fd = dev->bcache_fd;
int do_close = 0;
if (dev->size_seqno == _dev_size_seqno) {
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
@ -338,12 +340,16 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
return 1;
}
if (!dev_open_readonly(dev))
return_0;
if (fd <= 0) {
if (!dev_open_readonly(dev))
return_0;
fd = dev_fd(dev);
do_close = 1;
}
if (ioctl(dev_fd(dev), BLKGETSIZE64, size) < 0) {
if (ioctl(fd, BLKGETSIZE64, size) < 0) {
log_sys_error("ioctl BLKGETSIZE64", name);
if (!dev_close(dev))
if (do_close && !dev_close(dev))
log_sys_error("close", name);
return 0;
}
@ -352,7 +358,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
dev->size = *size;
dev->size_seqno = _dev_size_seqno;
if (!dev_close(dev))
if (do_close && !dev_close(dev))
log_sys_error("close", name);
log_very_verbose("%s: size is %" PRIu64 " sectors", name, *size);
@ -629,17 +635,12 @@ int dev_open_readonly_quiet(struct device *dev)
int dev_test_excl(struct device *dev)
{
int flags;
int r;
int flags = 0;
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
flags |= O_EXCL;
flags |= O_RDWR;
r = dev_open_flags(dev, flags, 1, 1);
if (r)
dev_close_immediate(dev);
return r;
return dev_open_flags(dev, flags, 1, 1);
}
static void _close(struct device *dev)
@ -659,7 +660,6 @@ static void _close(struct device *dev)
static int _dev_close(struct device *dev, int immediate)
{
if (dev->fd < 0) {
log_error("Attempt to close device '%s' "
"which is not open.", dev_name(dev));

View File

@ -32,6 +32,7 @@
#define DEV_ASSUMED_FOR_LV 0x00000200 /* Is device assumed for an LV */
#define DEV_NOT_O_NOATIME 0x00000400 /* Don't use O_NOATIME */
#define DEV_IN_BCACHE 0x00000800 /* dev fd is open and used in bcache */
#define DEV_BCACHE_EXCL 0x00001000 /* bcache_fd should be open EXCL */
/*
* Support for external device info.
@ -66,6 +67,7 @@ struct device {
int phys_block_size;
int block_size;
int read_ahead;
int bcache_fd;
uint32_t flags;
unsigned size_seqno;
uint64_t size;

View File

@ -320,7 +320,7 @@ static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev
log_debug_metadata("Reading mda header sector from %s at %llu",
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
if (!bcache_read_bytes(scan_bcache, dev_area->dev->fd, dev_area->start, MDA_HEADER_SIZE, mdah)) {
if (!bcache_read_bytes(scan_bcache, dev_area->dev->bcache_fd, dev_area->start, MDA_HEADER_SIZE, mdah)) {
log_error("Failed to read metadata area header on %s at %llu",
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
return 0;
@ -462,7 +462,7 @@ static struct raw_locn *_read_metadata_location_vg(struct device_area *dev_area,
*/
memset(vgnamebuf, 0, sizeof(vgnamebuf));
bcache_read_bytes(scan_bcache, dev_area->dev->fd, dev_area->start + rlocn->offset, NAME_LEN, vgnamebuf);
bcache_read_bytes(scan_bcache, dev_area->dev->bcache_fd, dev_area->start + rlocn->offset, NAME_LEN, vgnamebuf);
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{'))
@ -510,18 +510,12 @@ static int _raw_holds_vgname(struct format_instance *fid,
int noprecommit = 0;
struct mda_header *mdah;
if (!dev_open_readonly(dev_area->dev))
return_0;
if (!(mdah = raw_read_mda_header(fid->fmt, dev_area, 0)))
return_0;
if (_read_metadata_location_vg(dev_area, mdah, 0, vgname, &noprecommit))
r = 1;
if (!dev_close(dev_area->dev))
stack;
return r;
}
@ -595,14 +589,8 @@ static struct volume_group *_vg_read_raw(struct format_instance *fid,
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct volume_group *vg;
if (!dev_open_readonly(mdac->area.dev))
return_NULL;
vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 0, mda_is_primary(mda));
if (!dev_close(mdac->area.dev))
stack;
return vg;
}
@ -615,14 +603,8 @@ static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct volume_group *vg;
if (!dev_open_readonly(mdac->area.dev))
return_NULL;
vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 1, mda_is_primary(mda));
if (!dev_close(mdac->area.dev))
stack;
return vg;
}
@ -653,9 +635,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!found)
return 1;
if (!dev_open(mdac->area.dev))
return_0;
if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
goto_out;
@ -694,6 +673,9 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
label_scan_invalidate(mdac->area.dev);
if (!dev_open(mdac->area.dev))
return_0;
/* Write text out, circularly */
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
(size_t) (mdac->rlocn.size - new_wrap), MDA_CONTENT_REASON(mda_is_primary(mda)),
@ -879,9 +861,6 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
int r = 0;
int noprecommit = 0;
if (!dev_open(mdac->area.dev))
return_0;
if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
goto_out;
@ -895,6 +874,9 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
rlocn->checksum = 0;
rlocn_set_ignored(mdah->raw_locns, mda_is_ignored(mda));
if (!dev_open(mdac->area.dev))
return_0;
if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mda_is_primary(mda), mdac->area.start,
mdah)) {
dm_pool_free(fid->fmt->cmd->mem, mdah);
@ -1227,7 +1209,7 @@ int read_metadata_location_summary(const struct format_type *fmt,
return 0;
}
bcache_read_bytes(scan_bcache, dev_area->dev->fd, dev_area->start + rlocn->offset, NAME_LEN, buf);
bcache_read_bytes(scan_bcache, dev_area->dev->bcache_fd, dev_area->start + rlocn->offset, NAME_LEN, buf);
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
len < (NAME_LEN - 1))
@ -1338,15 +1320,9 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
dm_list_iterate_items(rl, raw_list) {
log_debug_metadata("Scanning independent dev %s", dev_name(rl->dev_area.dev));
/* FIXME We're reading mdah twice here... */
if (!dev_open_readonly(rl->dev_area.dev)) {
stack;
continue;
}
if (!(mdah = raw_read_mda_header(fmt, &rl->dev_area, 0))) {
stack;
goto close_dev;
continue;
}
if (read_metadata_location_summary(fmt, mdah, 0, &rl->dev_area, &vgsummary, NULL)) {
@ -1356,9 +1332,6 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
lvmcache_set_independent_location(vg->name);
}
}
close_dev:
if (!dev_close(rl->dev_area.dev))
stack;
}
return 1;
@ -1488,9 +1461,6 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
if (!lvmcache_update_das(info, pv))
return_0;
if (!dev_open(pv->dev))
return_0;
baton.pv = pv;
baton.fmt = fmt;
@ -1502,8 +1472,6 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
if (!label_write(pv->dev, label)) {
stack;
if (!dev_close(pv->dev))
stack;
return 0;
}
@ -1513,9 +1481,6 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
* update the cache afterwards?
*/
if (!dev_close(pv->dev))
return_0;
return 1;
}

View File

@ -338,12 +338,6 @@ static int _read_mda_header_and_metadata(struct metadata_area *mda, void *baton)
* TODO: make lvmcache smarter and move this cache logic there
*/
if (!dev_open_readonly(mdac->area.dev)) {
mda_set_ignored(mda, 1);
stack;
return 1;
}
if (!(mdah = raw_read_mda_header(fmt, &mdac->area, mda_is_primary(mda)))) {
stack;
goto close_dev;
@ -355,23 +349,16 @@ static int _read_mda_header_and_metadata(struct metadata_area *mda, void *baton)
log_debug_metadata("Ignoring mda on device %s at offset " FMTu64,
dev_name(mdac->area.dev),
mdac->area.start);
if (!dev_close(mdac->area.dev))
stack;
return 1;
}
if (read_metadata_location_summary(fmt, mdah, mda_is_primary(mda), &mdac->area, &vgsummary,
&mdac->free_sectors) &&
!lvmcache_update_vgname_and_id(p->info, &vgsummary)) {
if (!dev_close(mdac->area.dev))
stack;
return_0;
}
close_dev:
if (!dev_close(mdac->area.dev))
stack;
return 1;
}

View File

@ -116,6 +116,8 @@ int label_remove(struct device *dev)
log_very_verbose("Scanning for labels to wipe from %s", dev_name(dev));
label_scan_invalidate(dev);
if (!dev_open(dev))
return_0;
@ -125,8 +127,6 @@ int label_remove(struct device *dev)
*/
dev_flush(dev);
label_scan_invalidate(dev);
if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, DEV_IO_LABEL, readbuf)) {
log_debug_devs("%s: Failed to read label area", dev_name(dev));
goto out;
@ -396,6 +396,71 @@ static int _process_block(struct device *dev, struct block *bb, int *is_lvm_devi
return ret;
}
static int _scan_dev_open(struct device *dev)
{
const char *name;
int flags = 0;
int fd;
if (dev->flags & DEV_IN_BCACHE) {
log_error("scan_dev_open %s DEV_IN_BCACHE already set", dev_name(dev));
dev->flags &= ~DEV_IN_BCACHE;
}
if (dev->bcache_fd > 0) {
log_error("scan_dev_open %s already open with fd %d",
dev_name(dev), dev->bcache_fd);
return 0;
}
if (!(name = dev_name_confirmed(dev, 1))) {
log_error("scan_dev_open %s no name", dev_name(dev));
return 0;
}
flags |= O_RDWR;
flags |= O_DIRECT;
flags |= O_NOATIME;
if (dev->flags & DEV_BCACHE_EXCL)
flags |= O_EXCL;
fd = open(name, flags, 0777);
if (fd < 0) {
if ((errno == EBUSY) && (flags & O_EXCL)) {
log_error("Can't open %s exclusively. Mounted filesystem?",
dev_name(dev));
} else {
log_error("scan_dev_open %s failed errno %d", dev_name(dev), errno);
}
return 0;
}
dev->flags |= DEV_IN_BCACHE;
dev->bcache_fd = fd;
return 1;
}
static int _scan_dev_close(struct device *dev)
{
if (!(dev->flags & DEV_IN_BCACHE))
log_error("scan_dev_close %s no DEV_IN_BCACHE set", dev_name(dev));
dev->flags &= ~DEV_IN_BCACHE;
dev->flags &= ~DEV_BCACHE_EXCL;
if (dev->bcache_fd < 0) {
log_error("scan_dev_close %s already closed", dev_name(dev));
return 0;
}
if (close(dev->bcache_fd))
log_warn("close %s errno %d", dev_name(dev), errno);
dev->bcache_fd = -1;
return 1;
}
/*
* Read or reread label/metadata from selected devs.
*
@ -407,7 +472,7 @@ static int _process_block(struct device *dev, struct block *bb, int *is_lvm_devi
* its info is removed from lvmcache.
*/
static int _scan_list(struct dm_list *devs)
static int _scan_list(struct dm_list *devs, int *failed)
{
struct dm_list wait_devs;
struct dm_list done_devs;
@ -439,19 +504,16 @@ static int _scan_list(struct dm_list *devs)
if (!rem_prefetches)
break;
/*
* The in-bcache flag corresponds with this dev_open.
* Clearing the in-bcache flag should be paired with
* a dev_close. (This dev may already be in bcache.)
*/
if (!_in_bcache(devl->dev)) {
if (!dev_open_readonly(devl->dev)) {
if (!_scan_dev_open(devl->dev)) {
log_debug_devs("%s: Failed to open device.", dev_name(devl->dev));
dm_list_del(&devl->list);
scan_failed_count++;
continue;
}
}
bcache_prefetch(scan_bcache, devl->dev->fd, 0);
bcache_prefetch(scan_bcache, devl->dev->bcache_fd, 0);
rem_prefetches--;
@ -462,12 +524,12 @@ static int _scan_list(struct dm_list *devs)
dm_list_iterate_items_safe(devl, devl2, &wait_devs) {
bb = NULL;
if (!bcache_get(scan_bcache, devl->dev->fd, 0, 0, &bb)) {
if (!bcache_get(scan_bcache, devl->dev->bcache_fd, 0, 0, &bb)) {
log_debug_devs("%s: Failed to scan device.", dev_name(devl->dev));
scan_failed_count++;
scan_failed = 1;
} else {
log_debug_devs("Processing data from device %s fd %d block %p", dev_name(devl->dev), devl->dev->fd, bb);
log_debug_devs("Processing data from device %s fd %d block %p", dev_name(devl->dev), devl->dev->bcache_fd, bb);
_process_block(devl->dev, bb, &is_lvm_device);
scan_lvm_count++;
scan_failed = 0;
@ -483,12 +545,8 @@ static int _scan_list(struct dm_list *devs)
* drop it from bcache.
*/
if (scan_failed || !is_lvm_device) {
devl->dev->flags &= ~DEV_IN_BCACHE;
bcache_invalidate_fd(scan_bcache, devl->dev->fd);
dev_close(devl->dev);
} else {
/* The device must be kept open while it's in bcache. */
devl->dev->flags |= DEV_IN_BCACHE;
bcache_invalidate_fd(scan_bcache, devl->dev->bcache_fd);
_scan_dev_close(devl->dev);
}
dm_list_del(&devl->list);
@ -498,12 +556,13 @@ static int _scan_list(struct dm_list *devs)
if (!dm_list_empty(devs))
goto scan_more;
/* FIXME: let the caller know if some lvm devices failed to be scanned. */
log_debug_devs("Scanned %d devices: %d for lvm, %d failed.",
dm_list_size(&done_devs), scan_lvm_count, scan_failed_count);
return 0;
if (failed)
*failed = scan_failed_count;
return 1;
}
/*
@ -548,8 +607,10 @@ int label_scan(struct cmd_context *cmd)
* label_scan should not generally be called a second time,
* so this will usually not be true.
*/
if (_in_bcache(dev))
bcache_invalidate_fd(scan_bcache, dev->fd);
if (_in_bcache(dev)) {
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
};
dev_iter_destroy(iter);
@ -573,7 +634,9 @@ int label_scan(struct cmd_context *cmd)
return 0;
}
return _scan_list(&all_devs);
_scan_list(&all_devs, NULL);
return 1;
}
/*
@ -589,19 +652,48 @@ int label_scan_devs(struct cmd_context *cmd, struct dm_list *devs)
struct device_list *devl;
dm_list_iterate_items(devl, devs) {
if (_in_bcache(devl->dev))
bcache_invalidate_fd(scan_bcache, devl->dev->fd);
if (_in_bcache(devl->dev)) {
bcache_invalidate_fd(scan_bcache, devl->dev->bcache_fd);
_scan_dev_close(devl->dev);
}
}
return _scan_list(devs);
_scan_list(devs, NULL);
/* FIXME: this function should probably fail if any devs couldn't be scanned */
return 1;
}
int label_scan_devs_excl(struct dm_list *devs)
{
struct device_list *devl;
int failed = 0;
dm_list_iterate_items(devl, devs) {
if (_in_bcache(devl->dev)) {
bcache_invalidate_fd(scan_bcache, devl->dev->bcache_fd);
_scan_dev_close(devl->dev);
}
/*
* With this flag set, _scan_dev_open() done by
* _scan_list() will do open EXCL
*/
devl->dev->flags |= DEV_BCACHE_EXCL;
}
_scan_list(devs, &failed);
if (failed)
return 0;
return 1;
}
void label_scan_invalidate(struct device *dev)
{
if (_in_bcache(dev)) {
dev->flags &= ~DEV_IN_BCACHE;
bcache_invalidate_fd(scan_bcache, dev->fd);
dev_close(dev);
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
}
@ -645,7 +737,7 @@ int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector
{
struct dm_list one_dev;
struct device_list *devl;
int ret;
int failed = 0;
/* scanning is done by list, so make a single item list for this dev */
if (!(devl = dm_zalloc(sizeof(*devl))))
@ -654,10 +746,12 @@ int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector
dm_list_init(&one_dev);
dm_list_add(&one_dev, &devl->list);
if (_in_bcache(dev))
bcache_invalidate_fd(scan_bcache, dev->fd);
if (_in_bcache(dev)) {
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
ret = _scan_list(&one_dev);
_scan_list(&one_dev, &failed);
/*
* FIXME: this ugliness of returning a pointer to the label is
@ -671,7 +765,9 @@ int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector
*labelp = lvmcache_get_label(info);
}
return ret;
if (failed)
return 0;
return 1;
}
/*

View File

@ -104,6 +104,7 @@ extern struct bcache *scan_bcache;
int label_scan(struct cmd_context *cmd);
int label_scan_devs(struct cmd_context *cmd, struct dm_list *devs);
int label_scan_devs_excl(struct dm_list *devs);
void label_scan_invalidate(struct device *dev);
void label_scan_destroy(struct cmd_context *cmd);
int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector);

View File

@ -241,6 +241,7 @@ static int _pvcreate_check(struct cmd_context *cmd, const char *name,
name);
goto out;
}
dev_close(dev);
if (!wipe_known_signatures(cmd, dev, name,
TYPE_LVM1_MEMBER | TYPE_LVM2_MEMBER,

View File

@ -5082,16 +5082,6 @@ static int _pvcreate_check_single(struct cmd_context *cmd,
log_debug("Checking pvcreate arg %s which has existing PVID: %.32s.",
pv_dev_name(pv), pv->dev->pvid[0] ? pv->dev->pvid : "<none>");
/*
* This test will fail if the device belongs to an MD array.
*/
if (!dev_test_excl(pv->dev)) {
/* FIXME Detect whether device-mapper itself is still using it */
log_error("Can't open %s exclusively. Mounted filesystem?",
pv_dev_name(pv));
dm_list_move(&pp->arg_fail, &pd->list);
return 1;
}
/*
* Don't allow using a device with duplicates.
@ -5223,14 +5213,6 @@ static int _pv_confirm_single(struct cmd_context *cmd,
if (!found)
return 1;
/* Repeat the same from check_single. */
if (!dev_test_excl(pv->dev)) {
/* FIXME Detect whether device-mapper itself is still using it */
log_error("Can't open %s exclusively. Mounted filesystem?",
pv_dev_name(pv));
goto fail;
}
/*
* What kind of device is this: an orphan PV, an uninitialized/unused
* device, a PV used in a VG.
@ -5323,16 +5305,6 @@ static int _pvremove_check_single(struct cmd_context *cmd,
log_debug("Checking device %s for pvremove %.32s.",
pv_dev_name(pv), pv->dev->pvid[0] ? pv->dev->pvid : "");
/*
* This test will fail if the device belongs to an MD array.
*/
if (!dev_test_excl(pv->dev)) {
/* FIXME Detect whether device-mapper itself is still using it */
log_error("Can't open %s exclusively. Mounted filesystem?",
pv_dev_name(pv));
dm_list_move(&pp->arg_fail, &pd->list);
return 1;
}
/*
* Is there a pv here already?
@ -5458,8 +5430,10 @@ int pvcreate_each_device(struct cmd_context *cmd,
struct volume_group *orphan_vg;
struct dm_list remove_duplicates;
struct dm_list arg_sort;
struct dm_list rescan_devs;
struct pv_list *pvl;
struct pv_list *vgpvl;
struct device_list *devl;
const char *pv_name;
int consistent = 0;
int must_use_all = (cmd->cname->flags & MUST_USE_ALL_ARGS);
@ -5470,6 +5444,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
dm_list_init(&remove_duplicates);
dm_list_init(&arg_sort);
dm_list_init(&rescan_devs);
handle->custom_handle = pp;
@ -5715,6 +5690,19 @@ int pvcreate_each_device(struct cmd_context *cmd,
do_command:
dm_list_iterate_items(pd, &pp->arg_process) {
if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
goto bad;
devl->dev = pd->dev;
dm_list_add(&rescan_devs, &devl->list);
}
log_debug("Rescanning devices with exclusive open");
if (!label_scan_devs_excl(&rescan_devs)) {
log_debug("Failed to rescan devs excl");
goto bad;
}
/*
* Reorder arg_process entries to match the original order of args.
*/