1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-13 23:51:53 +03:00

device_id: handle duplicate serial numbers

Handle multiple devices using the same serial number as
their device id.  After matching devices to devices file
entries, if there is a discrepency between the ondisk PVID
and the devices file PVID, then rematch devices to
devices file entries using PVID, looking at all disks
on the system with the same serial number.
This commit is contained in:
David Teigland 2022-10-31 16:14:01 -05:00
parent bdab36cf3f
commit 761b922178
7 changed files with 1185 additions and 2 deletions

16
lib/cache/lvmcache.c vendored
View File

@ -1634,6 +1634,22 @@ int lvmcache_label_scan(struct cmd_context *cmd)
if (!label_scan(cmd))
return_0;
/*
* device_ids_validate() found devices using a sys_serial device id
* which had a PVID on disk that did not match the PVID in the devices
* file. Serial numbers may not always be unique, so any device with
* the same serial number is found and searched for the correct PVID.
* If the PVID is found on a device that has not been scanned, then
* it needs to be scanned so it can be used.
*/
if (!dm_list_empty(&cmd->device_ids_check_serial)) {
struct dm_list scan_devs;
dm_list_init(&scan_devs);
device_ids_check_serial(cmd, &scan_devs, NULL, 0);
if (!dm_list_empty(&scan_devs))
label_scan_devs(cmd, cmd->filter, &scan_devs);
}
/*
* When devnames are used as device ids (which is dispreferred),
* changing/unstable devnames can lead to entries in the devices file

View File

@ -215,6 +215,7 @@ struct cmd_context {
struct dm_list use_devices; /* struct dev_use for each entry in devices file */
const char *md_component_checks;
const char *search_for_devnames; /* config file setting */
struct dm_list device_ids_check_serial;
const char *devicesfile; /* from --devicesfile option */
struct dm_list deviceslist; /* from --devices option, struct dm_str_list */

View File

@ -118,6 +118,11 @@ struct dev_use {
char *pvid;
};
struct dev_use_list {
struct dm_list list;
struct dev_use *du;
};
/*
* All devices in LVM will be represented by one of these.
* pointer comparisons are valid.

View File

@ -22,6 +22,8 @@
#include "lib/metadata/metadata.h"
#include "lib/format_text/layout.h"
#include "lib/cache/lvmcache.h"
#include "lib/datastruct/str_list.h"
#include "lib/metadata/metadata-exported.h"
#include <sys/stat.h>
#include <fcntl.h>
@ -752,6 +754,35 @@ const char *dev_idname_for_metadata(struct cmd_context *cmd, struct device *dev)
return dev->id->idname;
}
static const char *_dev_idname(struct device *dev, uint16_t idtype)
{
struct dev_id *id;
dm_list_iterate_items(id, &dev->ids) {
if (id->idtype != idtype)
continue;
if (!id->idname)
continue;
return id->idname;
}
return NULL;
}
static int _dev_has_id(struct device *dev, uint16_t idtype, const char *idname)
{
struct dev_id *id;
dm_list_iterate_items(id, &dev->ids) {
if (id->idtype != idtype)
continue;
if (!id->idname)
continue;
if (!strcmp(idname, id->idname))
return 1;
}
return 0;
}
static void _copy_idline_str(char *src, char *dst, int len)
{
char *s, *d = dst;
@ -2077,6 +2108,62 @@ void device_ids_match(struct cmd_context *cmd)
}
}
static void _get_devs_with_serial_numbers(struct cmd_context *cmd, struct dm_list *serial_str_list, struct dm_list *devs)
{
struct dev_iter *iter;
struct device *dev;
struct device_list *devl;
struct dev_id *id;
const char *idname;
if (!(iter = dev_iter_create(NULL, 0)))
return;
while ((dev = dev_iter_get(cmd, iter))) {
/* if serial has already been read for this dev then use it */
dm_list_iterate_items(id, &dev->ids) {
if (id->idtype == DEV_ID_TYPE_SYS_SERIAL) {
if (str_list_match_item(serial_str_list, id->idname)) {
if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
goto next_dev;
devl->dev = dev;
dm_list_add(devs, &devl->list);
}
goto next_dev;
}
}
/* just copying the no-data filters in similar device_ids_find_renamed_devs */
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "sysfs"))
continue;
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "type"))
continue;
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "usable"))
continue;
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "mpath"))
continue;
if ((idname = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_SERIAL))) {
if (str_list_match_item(serial_str_list, idname)) {
if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
goto next_dev;
if (!(id = zalloc(sizeof(struct dev_id))))
goto next_dev;
id->idtype = DEV_ID_TYPE_SYS_SERIAL;
id->idname = (char *)idname;
id->dev = dev;
dm_list_add(&dev->ids, &id->list);
devl->dev = dev;
dm_list_add(devs, &devl->list);
} else {
free((char *)idname);
}
}
next_dev:
continue;
}
dev_iter_destroy(iter);
}
/*
* This is called after devices are scanned to compare what was found on disks
* vs what's in the devices file. The devices file could be outdated and need
@ -2145,6 +2232,19 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
checked++;
/*
* If the PVID doesn't match, don't assume that the serial
* number is correct, since serial numbers may not be unique.
* Search for the PVID on other devs in device_ids_check_serial.
*/
if ((du->idtype == DEV_ID_TYPE_SYS_SERIAL) &&
(!du->pvid || memcmp(dev->pvid, du->pvid, ID_LEN))) {
log_debug("suspect device id serial %s for %s", du->idname, dev_name(dev));
str_list_add(cmd->mem, &cmd->device_ids_check_serial, dm_pool_strdup(cmd->mem, du->idname));
*device_ids_invalid = 1;
continue;
}
/*
* If the du pvid from the devices file does not match the
* pvid read from disk, replace the du pvid with the pvid from
@ -2362,6 +2462,282 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
}
}
static struct device_id_list *_device_id_list_find_dev(struct dm_list *list, struct device *dev)
{
struct device_id_list *dil;
dm_list_iterate_items(dil, list) {
if (dil->dev == dev)
return dil;
}
return NULL;
}
/*
* Validate entries with suspect sys_serial values. A sys_serial du (devices
* file entry) matched a device with the same serial number, but the PVID did
* not match. Check if multiple devices have the same serial number, and if so
* pair the devs to the du's based on PVID. This requires searching all devs
* for the given serial number, and then reading the PVID from all those devs.
* This may involve reading labels from devs outside the devices file.
* (This could also be done for duplicate wwids if needed.)
*/
void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs,
int *update_needed, int noupdate)
{
struct dm_list dus_check; /* dev_use_list */
struct dm_list devs_check; /* device_list */
struct dm_list prev_devs; /* device_id_list */
struct dev_use_list *dul;
struct device_list *devl, *devl2;
struct device_id_list *dil;
struct device *dev;
struct dev_use *du;
char *tmpdup;
int update_file = 0;
int has_pvid;
int found;
int count;
dm_list_init(&dus_check);
dm_list_init(&devs_check);
dm_list_init(&prev_devs);
/*
* Create list of du's with a suspect serial number. These du's will
* be rematched to a device using pvid. The device_ids_check_serial
* list was created by device_ids_validate() when it found that the
* PVID on the dev did not match the PVID in the du that was paired
* with the dev.
*/
dm_list_iterate_items(du, &cmd->use_devices) {
if (du->dev && (du->idtype == DEV_ID_TYPE_SYS_SERIAL) &&
str_list_match_item(&cmd->device_ids_check_serial, du->idname)) {
if (!(dul = dm_pool_zalloc(cmd->mem, sizeof(*dul))))
continue;
dul->du = du;
dm_list_add(&dus_check, &dul->list);
}
}
/*
* Create list of devs on the system with suspect serial numbers.
* Read the serial number of each dev in dev cache, and return
* devs that match the suspect serial numbers.
*/
log_debug("Finding all devs with suspect serial numbers.");
_get_devs_with_serial_numbers(cmd, &cmd->device_ids_check_serial, &devs_check);
/*
* Read the PVID from any devs_check entries that have not been scanned
* yet (this is where some devs outside the devices file may be read.)
* If the dev has no PVID or is excluded by filters, then there's no
* point in trying to match it to one of the dus_check entries.
*/
log_debug("Reading and filtering %d devs with suspect serial numbers.", dm_list_size(&devs_check));
dm_list_iterate_items_safe(devl, devl2, &devs_check) {
const char *idname;
if (!(idname = _dev_idname(devl->dev, DEV_ID_TYPE_SYS_SERIAL))) {
log_debug("serial missing for %s", dev_name(devl->dev));
continue;
}
if (devl->dev->flags & DEV_SCAN_FOUND_LABEL) {
log_debug("serial %s pvid %s %s", idname, devl->dev->pvid, dev_name(devl->dev));
continue;
}
if (devl->dev->flags & DEV_SCAN_FOUND_NOLABEL) {
log_debug("serial %s nolabel %s", idname, dev_name(devl->dev));
continue;
}
dev = devl->dev;
has_pvid = 0;
label_read_pvid(dev, &has_pvid);
if (!has_pvid) {
log_debug("serial %s no pvid %s", idname, dev_name(devl->dev));
dm_list_del(&devl->list);
continue;
}
/* data-based filters use data read by label_read_pvid */
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "partitioned") ||
!cmd->filter->passes_filter(cmd, cmd->filter, dev, "signature") ||
!cmd->filter->passes_filter(cmd, cmd->filter, dev, "md") ||
!cmd->filter->passes_filter(cmd, cmd->filter, dev, "fwraid")) {
log_debug("serial %s pvid %s filtered %s", idname, devl->dev->pvid, dev_name(devl->dev));
dm_list_del(&devl->list);
}
}
log_debug("Checking %d PVs with suspect serial numbers.", dm_list_size(&devs_check));
/*
* Unpair du's and dev's that were matched using suspect serial numbers
* so that things can be matched again using PVID. If current pairings
* are correct they will just be matched again. Save the previous
* pairings so that we can detect when a wrong pairing was corrected.
*/
dm_list_iterate_items(dul, &dus_check) {
if (!dul->du->dev)
continue;
/* save previously matched devs so they can be dropped from
lvmcache at the end if they are no longer used */
if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil))))
continue;
du = dul->du;
dil->dev = du->dev;
memcpy(dil->pvid, du->pvid, ID_LEN);
dm_list_add(&prev_devs, &dil->list);
du->dev->flags &= ~DEV_MATCHED_USE_ID;
du->dev = NULL;
}
/*
* Match du to a dev based on PVID.
*/
dm_list_iterate_items(dul, &dus_check) {
log_debug("Matching suspect serial device id %s PVID %s prev %s",
dul->du->idname, dul->du->pvid, dul->du->devname);
found = 0;
dm_list_iterate_items(devl, &devs_check) {
if (!memcmp(dul->du->pvid, devl->dev->pvid, ID_LEN)) {
/* pair dev and du */
du = dul->du;
dev = devl->dev;
du->dev = dev;
dev->flags |= DEV_MATCHED_USE_ID;
log_debug("Match suspect serial device id %s PVID %s to %s",
du->idname, du->pvid, dev_name(dev));
/* update file if this dev pairing is new or different */
if (!(dil = _device_id_list_find_dev(&prev_devs, dev)))
update_file = 1;
else if (memcmp(dil->pvid, du->pvid, ID_LEN))
update_file = 1;
found = 1;
break;
}
}
if (!found)
log_debug("Match PVID failed in %d devs checked.", dm_list_size(&devs_check));
}
/*
* Handle du's with suspect serial numbers that did not have a match
* based on PVID in the previous loop. If the du matches a device
* based on the serial number, and there is only one instance of that
* serial number on the system, then assume that the PVID in the
* devices file is outdated and pair the du and dev, and update the
* PVID in the devices file. (This is what's done for du and dev with
* matching wwid but unmatching PVID.)
*/
dm_list_iterate_items(dul, &dus_check) {
du = dul->du;
/* matched in previous loop using pvid */
if (du->dev)
continue;
log_debug("Matching suspect serial device id %s unmatched PVID %s prev %s",
du->idname, du->pvid, du->devname);
dev = NULL;
count = 0;
/* count the number of devs using this serial number */
dm_list_iterate_items(devl, &devs_check) {
if (_dev_has_id(devl->dev, DEV_ID_TYPE_SYS_SERIAL, du->idname)) {
dev = devl->dev;
count++;
}
if (count > 1)
break;
}
if (count != 1) {
log_warn("No device matches devices file PVID %s with duplicate serial number %s previously %s.",
du->pvid, du->idname, du->devname);
continue;
}
log_warn("Device %s with serial number %s has PVID %s (devices file %s)",
dev_name(dev), du->idname, dev->pvid, du->pvid ?: "none");
if (!(tmpdup = strdup(dev->pvid)))
continue;
free(du->pvid);
du->pvid = tmpdup;
du->dev = dev;
dev->flags |= DEV_MATCHED_USE_ID;
update_file = 1;
}
/*
* label_scan() was done based on the original du/dev matches, so if
* there were some changes made to the du/dev matches above, then we
* may need to correct the results of the label_scan:
*
* . if some devices were scanned in label_scan, but those devs are no
* longer matched to any du, then we need to clear the scanned info
* from those devs from lvmcache.
*
* . if some devices were not scanned in label_scan, but those devs are
* now matched to a du, then we need to run label_scan on those devs to
* populate lvmcache with info from them (the caller does this.)
*/
/*
* Find devs that were previously matched to a du but now are not.
* Clear the filter state and lvmcache info for them.
*/
dm_list_iterate_items(dil, &prev_devs) {
if (!get_du_for_dev(cmd, dil->dev)) {
log_debug("Drop incorrectly matched serial %s", dev_name(dil->dev));
cmd->filter->wipe(cmd, cmd->filter, dil->dev, NULL);
lvmcache_del_dev(dil->dev);
}
}
/*
* Find devs that are now matched to a du but were not previously
* scanned by label_scan (DEV_SCAN_FOUND_LABEL). The caller will
* call label_scan on the devs returned in the list.
*/
dm_list_iterate_items(dul, &dus_check) {
if (!(dev = dul->du->dev))
continue;
if (!(dev->flags & DEV_SCAN_FOUND_LABEL)) {
if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
continue;
devl->dev = dev;
dm_list_add(scan_devs, &devl->list);
}
}
/*
* Look for dus_check entries that were originally matched to a dev
* but now are not. Warn about these like device_ids_match() would.
*/
dm_list_iterate_items(dul, &dus_check) {
if (!dul->du->dev) {
du = dul->du;
log_warn("Devices file %s %s PVID %s not found.",
idtype_to_str(du->idtype),
du->idname ?: "none",
du->pvid ?: "none");
if (du->devname) {
free(du->devname);
du->devname = NULL;
update_file = 1;
}
}
}
if (update_file && update_needed)
*update_needed = 1;
if (update_file && !noupdate)
_device_ids_update_try(cmd);
}
/*
* Devices with IDNAME=devname that are mistakenly included by filter-deviceid
* due to a devname change are fully scanned and added to lvmcache.
@ -2903,6 +3279,7 @@ void unlock_devices_file(struct cmd_context *cmd)
void devices_file_init(struct cmd_context *cmd)
{
dm_list_init(&cmd->use_devices);
dm_list_init(&cmd->device_ids_check_serial);
}
void devices_file_exit(struct cmd_context *cmd)

View File

@ -35,6 +35,7 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev);
void device_ids_match_device_list(struct cmd_context *cmd);
void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int *device_ids_invalid, int noupdate);
int device_ids_version_unchanged(struct cmd_context *cmd);
void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs, int *update_needed, int noupdate);
void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate);
const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_t idtype);
void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, struct id *old_vg_id);

View File

@ -0,0 +1,777 @@
#!/usr/bin/env bash
# Copyright (C) 2020 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
test_description='device id wwid from vpd_pg83'
. lib/inittest
test "$DM_DEV_DIR" = "/dev" || skip "Only works with /dev access -> make check LVM_TEST_DEVDIR=/dev"
aux lvmconf 'devices/use_devicesfile = 1'
# requires trailing / to match dm
aux lvmconf 'devices/device_id_sysfs_dir = "/test/sys/"'
SYS_DIR="/test/sys"
# The string format of the serial numbers
# encoded in the pg80 files
SERIAL1=003dd33a331c183c2300e1d883604609
SERIAL2=003dd33a441c183c2300e1d883604609
SERIAL3=003dd33a551c183c2300e1d883604609
SERIAL4=003dd33a661c183c2300e1d883604609
create_base() {
mkdir -p $SYS_DIR/dev/block
mkdir -p $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device
mkdir -p $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device
mkdir -p $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device
mkdir -p $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device
# Create four different pg80 serial numbers that
# can be assigned to devs
echo -n "0080 0020 3030 3364 6433 3361 3333 3163 \
3138 3363 3233 3030 6531 6438 3833 3630 3436 3039" | xxd -r -p > pg80_1
echo -n "0080 0020 3030 3364 6433 3361 3434 3163 \
3138 3363 3233 3030 6531 6438 3833 3630 3436 3039" | xxd -r -p > pg80_2
echo -n "0080 0020 3030 3364 6433 3361 3535 3163 \
3138 3363 3233 3030 6531 6438 3833 3630 3436 3039" | xxd -r -p > pg80_3
echo -n "0080 0020 3030 3364 6433 3361 3636 3163 \
3138 3363 3233 3030 6531 6438 3833 3630 3436 3039" | xxd -r -p > pg80_4
}
remove_base() {
rm -rf $SYS_DIR
}
modprobe brd
sleep 2
remove_base
dev1=/dev/ram0
dev2=/dev/ram1
dev3=/dev/ram2
dev4=/dev/ram3
DFDIR="$LVM_SYSTEM_DIR/devices"
mkdir -p "$DFDIR" || true
DF="$DFDIR/system.devices"
ORIG="$DFDIR/orig.devices"
touch $DF
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
vgcreate $vg1 "$dev1"
MAJOR1=`pvs "$dev1" --noheading -o major | tr -d - | awk '{print $1}'`
MINOR1=`pvs "$dev1" --noheading -o minor | tr -d - | awk '{print $1}'`
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
vgcreate $vg2 "$dev2"
MAJOR2=`pvs "$dev2" --noheading -o major | tr -d - | awk '{print $1}'`
MINOR2=`pvs "$dev2" --noheading -o minor | tr -d - | awk '{print $1}'`
OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
vgcreate $vg3 "$dev3"
MAJOR3=`pvs "$dev3" --noheading -o major | tr -d - | awk '{print $1}'`
MINOR3=`pvs "$dev3" --noheading -o minor | tr -d - | awk '{print $1}'`
OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
vgcreate $vg4 "$dev4"
MAJOR4=`pvs "$dev4" --noheading -o major | tr -d - | awk '{print $1}'`
MINOR4=`pvs "$dev4" --noheading -o minor | tr -d - | awk '{print $1}'`
OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
create_base
# get serial number from pg80
cp pg80_1 $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/vpd_pg80
cp pg80_2 $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/vpd_pg80
cp pg80_3 $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/vpd_pg80
cp pg80_4 $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/vpd_pg80
rm $DF
lvmdevices --adddev "$dev1"
grep $SERIAL1 $DF
lvmdevices --adddev "$dev2"
grep $SERIAL2 $DF
lvmdevices --adddev "$dev3"
grep $SERIAL3 $DF
lvmdevices --adddev "$dev4"
grep $SERIAL4 $DF
cat $DF
cp $DF $ORIG
pvs
# run command to update metadata so deviceids are written to metadata
vgchange --addtag x $vg1
vgchange --addtag x $vg2
vgchange --addtag x $vg3
vgchange --addtag x $vg4
pvs -o uuid,deviceidtype,deviceid "$dev1" |tee out
grep $OPVID1 out
grep sys_serial out
grep $SERIAL1 out
pvs -o uuid,deviceidtype,deviceid "$dev2" |tee out
grep $OPVID2 out
grep sys_serial out
grep $SERIAL2 out
# get serial number from device/serial
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
rm $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/vpd_pg80
rm $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/vpd_pg80
rm $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/vpd_pg80
rm $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/vpd_pg80
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo $SERIAL3 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo $SERIAL4 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
pvcreate $dev1
pvcreate $dev2
pvcreate $dev3
pvcreate $dev4
grep $SERIAL1 $DF
grep $SERIAL2 $DF
grep $SERIAL3 $DF
grep $SERIAL4 $DF
# all pvs have the same serial number
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
vgcreate $vg1 $dev1
vgcreate $vg2 $dev2
vgcreate $vg3 $dev3
vgcreate $vg4 $dev4
cp $DF $ORIG
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
grep $PVID1 $DF |tee out
grep $SERIAL1 out
grep $dev1 out
grep $PVID2 $DF |tee out
grep $SERIAL1 out
grep $dev2 out
grep $PVID3 $DF |tee out
grep $SERIAL1 out
grep $dev3 out
grep $PVID4 $DF |tee out
grep $SERIAL1 out
grep $dev4 out
pvs -o+uuid,deviceidtype,deviceid |tee out
grep $dev1 out
grep $dev2 out
grep $dev3 out
grep $dev4 out
grep $OPVID1 out
grep $OPVID2 out
grep $OPVID3 out
grep $OPVID4 out
grep $vg1 out
grep $vg2 out
grep $vg3 out
grep $vg4 out
grep sys_serial out
grep $SERIAL1 out
pvs -o+uuid,deviceid $dev1 |tee out
grep $OPVID1 out
grep $SERIAL1 out
grep $vg1 out
pvs -o+uuid,deviceid $dev2 |tee out
grep $OPVID2 out
grep $SERIAL1 out
grep $vg2 out
pvs -o+uuid,deviceid $dev3 |tee out
grep $OPVID3 out
grep $SERIAL1 out
grep $vg3 out
pvs -o+uuid,deviceid $dev4 |tee out
grep $OPVID4 out
grep $SERIAL1 out
grep $vg4 out
# all pvs have the same serial number, df devnames are stale
# edit DF to make devnames stale
cp $ORIG orig
sed -e "s|DEVNAME=$dev1|DEVNAME=tmpnm|" orig > tmp1
sed -e "s|DEVNAME=$dev2|DEVNAME=$dev1|" tmp1 > tmp2
sed -e "s|DEVNAME=tmpnm|DEVNAME=$dev2|" tmp2 > tmp3
sed -e "s|DEVNAME=$dev3|DEVNAME=tmpnm|" tmp3 > tmp4
sed -e "s|DEVNAME=$dev4|DEVNAME=$dev3|" tmp4 > tmp5
sed -e "s|DEVNAME=tmpnm|DEVNAME=$dev4|" tmp5 > "$DF"
cat "$DF"
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
grep $dev1 out |tee out1
grep $dev2 out |tee out2
grep $dev3 out |tee out3
grep $dev4 out |tee out4
grep $OPVID1 out1
grep $OPVID2 out2
grep $OPVID3 out3
grep $OPVID4 out4
grep $SERIAL1 out1
grep $SERIAL1 out2
grep $SERIAL1 out3
grep $SERIAL1 out4
grep $PVID1 $DF |tee out
grep $SERIAL1 out
grep $dev1 out
grep $PVID2 $DF |tee out
grep $SERIAL1 out
grep $dev2 out
grep $PVID3 $DF |tee out
grep $SERIAL1 out
grep $dev3 out
grep $PVID4 $DF |tee out
grep $SERIAL1 out
grep $dev4 out
pvs -o+uuid,deviceid "$dev1"|tee out1
pvs -o+uuid,deviceid "$dev2"|tee out2
pvs -o+uuid,deviceid "$dev3"|tee out3
pvs -o+uuid,deviceid "$dev4"|tee out4
grep $OPVID1 out1
grep $OPVID2 out2
grep $OPVID3 out3
grep $OPVID4 out4
# all pvs have the same serial number,
# dev1 and dev2 have devnames swapped,
# dev3 has stale PVID in the DF.
# lvm fixes the stale devnames but does not fix the stale PVID
# because of the duplicate serial numbers, so dev3 is not found
cp $ORIG orig
sed -e "s|DEVNAME=$dev1|DEVNAME=tmpnm|" orig > tmp1
sed -e "s|DEVNAME=$dev2|DEVNAME=$dev1|" tmp1 > tmp2
sed -e "s|PVID=$PVID4|PVID=4SqT4onBxSiv4dot0GRDPtrWqOlrOPH1|" tmp2 > "$DF"
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
not grep $dev4 out
not grep $OPVID4 out
grep $dev1 out |tee out1
grep $dev2 out |tee out2
grep $dev3 out |tee out3
grep $OPVID1 out1
grep $OPVID2 out2
grep $OPVID3 out3
not pvs "$dev4"
# dev1&2 have same serial, dev3&4 have same serial
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
vgcreate $vg1 $dev1
vgcreate $vg2 $dev2
vgcreate $vg3 $dev3
vgcreate $vg4 $dev4
cp $DF $ORIG
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
grep $PVID1 $DF |tee out
grep $SERIAL1 out
grep $dev1 out
grep $PVID2 $DF |tee out
grep $SERIAL1 out
grep $dev2 out
grep $PVID3 $DF |tee out
grep $SERIAL2 out
grep $dev3 out
grep $PVID4 $DF |tee out
grep $SERIAL2 out
grep $dev4 out
pvs -o+uuid,deviceidtype,deviceid |tee out
grep $dev1 out
grep $dev2 out
grep $dev3 out
grep $dev4 out
grep $OPVID1 out
grep $OPVID2 out
grep $OPVID3 out
grep $OPVID4 out
grep $vg1 out
grep $vg2 out
grep $vg3 out
grep $vg4 out
grep sys_serial out
grep $SERIAL1 out
grep $SERIAL2 out
pvs -o+uuid,deviceid $dev1 |tee out
grep $OPVID1 out
grep $SERIAL1 out
grep $vg1 out
pvs -o+uuid,deviceid $dev2 |tee out
grep $OPVID2 out
grep $SERIAL1 out
grep $vg2 out
pvs -o+uuid,deviceid $dev3 |tee out
grep $OPVID3 out
grep $SERIAL2 out
grep $vg3 out
pvs -o+uuid,deviceid $dev4 |tee out
grep $OPVID4 out
grep $SERIAL2 out
grep $vg4 out
# dev1&2 have serial1 and dev3&4 have serial2, swap devnames
# edit DF to make devnames stale
cp $ORIG orig
sed -e "s|DEVNAME=$dev1|DEVNAME=tmpnm|" orig > tmp1
sed -e "s|DEVNAME=$dev3|DEVNAME=$dev1|" tmp1 > tmp2
sed -e "s|DEVNAME=tmpnm|DEVNAME=$dev3|" tmp2 > tmp3
sed -e "s|DEVNAME=$dev2|DEVNAME=tmpnm|" tmp3 > tmp4
sed -e "s|DEVNAME=$dev4|DEVNAME=$dev2|" tmp4 > tmp5
sed -e "s|DEVNAME=tmpnm|DEVNAME=$dev4|" tmp5 > "$DF"
cat "$DF"
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
grep $dev1 out |tee out1
grep $dev2 out |tee out2
grep $dev3 out |tee out3
grep $dev4 out |tee out4
grep $OPVID1 out1
grep $OPVID2 out2
grep $OPVID3 out3
grep $OPVID4 out4
grep $SERIAL1 out1
grep $SERIAL1 out2
grep $SERIAL2 out3
grep $SERIAL2 out4
grep $PVID1 $DF |tee out
grep $SERIAL1 out
grep $dev1 out
grep $PVID2 $DF |tee out
grep $SERIAL1 out
grep $dev2 out
grep $PVID3 $DF |tee out
grep $SERIAL2 out
grep $dev3 out
grep $PVID4 $DF |tee out
grep $SERIAL2 out
grep $dev4 out
pvs -o+uuid,deviceid "$dev1"|tee out1
pvs -o+uuid,deviceid "$dev2"|tee out2
pvs -o+uuid,deviceid "$dev3"|tee out3
pvs -o+uuid,deviceid "$dev4"|tee out4
grep $OPVID1 out1
grep $SERIAL1 out1
grep $OPVID2 out2
grep $SERIAL1 out2
grep $OPVID3 out3
grep $SERIAL2 out3
grep $OPVID4 out4
grep $SERIAL2 out4
# all devs have same serial, dev1&4 are pvs, dev2&3 are not pvs
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
vgcreate $vg1 $dev1
vgcreate $vg4 $dev4
cp $DF $ORIG
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
grep $PVID1 $DF |tee out
grep $SERIAL1 out
grep $dev1 out
grep $PVID4 $DF |tee out
grep $SERIAL1 out
grep $dev4 out
pvs -o+uuid,deviceidtype,deviceid |tee out
grep $dev1 out
grep $dev4 out
grep $OPVID1 out
grep $OPVID4 out
grep $vg1 out
grep $vg4 out
grep sys_serial out
grep $SERIAL1 out
pvs -o+uuid,deviceid $dev1 |tee out
grep $OPVID1 out
grep $SERIAL1 out
grep $vg1 out
not pvs -o+uuid,deviceid $dev2
not pvs -o+uuid,deviceid $dev3
pvs -o+uuid,deviceid $dev4 |tee out
grep $OPVID4 out
grep $SERIAL1 out
grep $vg4 out
# edit DF to make devnames stale
cp $ORIG orig
sed -e "s|DEVNAME=$dev1|DEVNAME=$dev2|" orig > tmp1
sed -e "s|DEVNAME=$dev4|DEVNAME=$dev3|" tmp1 > "$DF"
cat "$DF"
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
grep $dev1 out |tee out1
grep $dev4 out |tee out4
grep $OPVID1 out1
grep $OPVID4 out4
grep $SERIAL1 out1
grep $SERIAL1 out4
grep $PVID1 $DF |tee out
grep $SERIAL1 out
grep $dev1 out
grep $PVID4 $DF |tee out
grep $SERIAL1 out
grep $dev4 out
pvs -o+uuid,deviceid "$dev1"|tee out1
pvs -o+uuid,deviceid "$dev4"|tee out4
grep $OPVID1 out1
grep $SERIAL1 out1
grep $OPVID4 out4
grep $SERIAL1 out4
# one pv with serial, three other non-pvs with same serial
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
vgcreate $vg2 $dev2
cp $DF $ORIG
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
grep $PVID2 $DF |tee out
grep $SERIAL1 out
grep $dev2 out
pvs -o+uuid,deviceidtype,deviceid |tee out
grep $dev2 out
grep sys_serial out
grep $SERIAL1 out
not grep $dev1 out
not grep $dev3 out
not grep $dev4 out
# edit DF to make devname stale
cp $ORIG orig
sed -e "s|DEVNAME=$dev2|DEVNAME=$dev3|" orig > "$DF"
cat "$DF"
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
grep $dev2 out
grep $OPVID2 out
grep $SERIAL1 out
grep $dev2 "$DF"
# different serial numbers, stale pvid and devname in df,
# lvm corrects pvid in df because serial number is unique
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo $SERIAL3 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo $SERIAL4 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
vgcreate $vg1 $dev1
vgcreate $vg2 $dev2
vgcreate $vg3 $dev3
vgcreate $vg4 $dev4
cp $DF $ORIG
grep $SERIAL1 $DF
grep $SERIAL2 $DF
grep $SERIAL3 $DF
grep $SERIAL4 $DF
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
pvs -o+uuid,deviceid
cp $ORIG orig
sed -e "s|PVID=$PVID1|PVID=bad14onBxSiv4dot0GRDPtrWqOlr1bad|" orig > tmp1
sed -e "s|PVID=$PVID3|PVID=bad24onBxSiv4dot0GRDPtrWqOlr2bad|" tmp1 > tmp2
sed -e "s|DEVNAME=$dev1|DEVNAME=.|" tmp2 > "$DF"
cat $DF
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
grep $dev1 out |tee out1
grep $dev2 out |tee out2
grep $dev3 out |tee out3
grep $dev4 out |tee out4
grep $OPVID1 out1
grep $OPVID2 out2
grep $OPVID3 out3
grep $OPVID4 out4
grep $vg1 out1
grep $vg2 out2
grep $vg3 out3
grep $vg4 out4
grep $SERIAL1 out1
grep $SERIAL2 out2
grep $SERIAL3 out3
grep $SERIAL4 out4
grep $PVID1 $DF |tee out
grep $SERIAL1 out
grep $dev1 out
grep $PVID2 $DF |tee out
grep $SERIAL2 out
grep $dev2 out
grep $PVID3 $DF |tee out
grep $SERIAL3 out
grep $dev3 out
grep $PVID4 $DF |tee out
grep $SERIAL4 out
grep $dev4 out
# duplicate serial on two pvs, two pvs with devname type, all devnames stale
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo "" > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo "" > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
vgcreate $vg1 $dev1
vgcreate $vg2 $dev2
vgcreate $vg3 $dev3
vgcreate $vg4 $dev4
cp $DF $ORIG
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
cat $DF
pvs -o+uuid,deviceid
cp $ORIG orig
sed -e "s|DEVNAME=$dev1|DEVNAME=tmpnm|" orig > tmp1
sed -e "s|DEVNAME=$dev3|DEVNAME=$dev1|" tmp1 > tmp2
sed -e "s|DEVNAME=tmpnm|DEVNAME=$dev3|" tmp2 > tmp3
sed -e "s|DEVNAME=$dev2|DEVNAME=tmpnm|" tmp3 > tmp4
sed -e "s|DEVNAME=$dev4|DEVNAME=$dev2|" tmp4 > tmp5
sed -e "s|DEVNAME=tmpnm|DEVNAME=$dev4|" tmp5 > "$DF"
cat $DF
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
grep $dev1 out |tee out1
grep $dev2 out |tee out2
grep $dev3 out |tee out3
grep $dev4 out |tee out4
grep $OPVID1 out1
grep $OPVID2 out2
grep $OPVID3 out3
grep $OPVID4 out4
grep $vg1 out1
grep $vg2 out2
grep $vg3 out3
grep $vg4 out4
grep $SERIAL1 out1
grep $SERIAL1 out2
cat $DF
grep $PVID1 $DF |tee out1
grep $PVID2 $DF |tee out2
grep $PVID3 $DF |tee out3
grep $PVID4 $DF |tee out4
grep $dev1 out1
grep $SERIAL1 out1
grep $dev2 out2
grep $SERIAL1 out2
grep $dev3 out3
grep $dev4 out4
# two pvs with duplicate serial and stale devname, one pv with unique serial and stale pvid
aux wipefs_a $dev1
aux wipefs_a $dev2
aux wipefs_a $dev3
aux wipefs_a $dev4
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
echo $SERIAL3 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
rm $DF
touch $DF
vgcreate $vg1 $dev1
vgcreate $vg2 $dev2
vgcreate $vg3 $dev3
cp $DF $ORIG
PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
cat $DF
pvs -o+uuid,deviceid
cp $ORIG orig
sed -e "s|DEVNAME=$dev1|DEVNAME=$dev4|" orig > tmp1
sed -e "s|DEVNAME=$dev2|DEVNAME=$dev1|" tmp1 > tmp2
sed -e "s|PVID=$dev3|PVID=bad14onBxSiv4dot0GRDPtrWqOlr1bad|" tmp2 > $DF
cat $DF
# pvs should report the correct info and fix the DF
pvs -o+uuid,deviceid |tee out
grep $dev1 out |tee out1
grep $dev2 out |tee out2
grep $dev3 out |tee out3
grep $OPVID1 out1
grep $OPVID2 out2
grep $OPVID3 out3
grep $vg1 out1
grep $vg2 out2
grep $vg3 out3
grep $SERIAL1 out1
grep $SERIAL1 out2
grep $SERIAL3 out3
cat $DF
grep $PVID1 $DF |tee out1
grep $PVID2 $DF |tee out2
grep $PVID3 $DF |tee out3
grep $dev1 out1
grep $SERIAL1 out1
grep $dev2 out2
grep $SERIAL1 out2
grep $dev3 out3
grep $SERIAL3 out3
remove_base
rmmod brd

View File

@ -124,6 +124,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
{
struct dm_list search_pvids;
struct dm_list found_devs;
struct dm_list scan_devs;
struct device_id_list *dil;
struct device_list *devl;
struct device *dev;
@ -132,6 +133,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
dm_list_init(&search_pvids);
dm_list_init(&found_devs);
dm_list_init(&scan_devs);
if (!setup_devices_file(cmd))
return ECMD_FAILED;
@ -186,6 +188,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
int update_set = arg_is_set(cmd, update_ARG);
int search_count = 0;
int update_needed = 0;
int serial_update_needed = 0;
int invalid = 0;
unlink_searched_devnames(cmd);
@ -273,6 +276,9 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
}
}
if (!dm_list_empty(&cmd->device_ids_check_serial))
device_ids_check_serial(cmd, &scan_devs, &serial_update_needed, 1);
/*
* Find and fix any devname entries that have moved to a
* renamed device.
@ -288,7 +294,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
}
if (arg_is_set(cmd, update_ARG)) {
if (update_needed || !dm_list_empty(&found_devs)) {
if (update_needed || serial_update_needed || !dm_list_empty(&found_devs)) {
if (!device_ids_write(cmd))
goto_bad;
log_print("Updated devices file to version %s", devices_file_version());
@ -301,7 +307,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
* needs updates, i.e. running --update would make
* changes.
*/
if (update_needed) {
if (update_needed || serial_update_needed) {
log_error("Updates needed for devices file.");
goto bad;
}