mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
device_id: update stacked PVs for vgchange uuid
If a VG uuid is changed, update the device_id of any PVs stacked on LVs in the changed VG.
This commit is contained in:
parent
939b4bc587
commit
8e62cbb18e
@ -856,6 +856,17 @@ int device_ids_use_devname(struct cmd_context *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _device_ids_use_lvmlv(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
struct dev_use *du;
|
||||||
|
|
||||||
|
dm_list_iterate_items(du, &cmd->use_devices) {
|
||||||
|
if (du->idtype == DEV_ID_TYPE_LVMLV_UUID)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev)
|
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev)
|
||||||
{
|
{
|
||||||
struct dev_use *du;
|
struct dev_use *du;
|
||||||
@ -1299,6 +1310,57 @@ void device_id_pvremove(struct cmd_context *cmd, struct device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, struct id *old_vg_id)
|
||||||
|
{
|
||||||
|
struct dev_use *du;
|
||||||
|
struct lv_list *lvl;
|
||||||
|
char old_vgid[ID_LEN+1] = { 0 };
|
||||||
|
char new_vgid[ID_LEN+1] = { 0 };
|
||||||
|
char old_idname[PATH_MAX];
|
||||||
|
int update = 0;
|
||||||
|
|
||||||
|
if (!cmd->enable_devices_file)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Without this setting there is no stacking LVs on PVs. */
|
||||||
|
if (!cmd->scan_lvs)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Check if any devices file entries are stacked on LVs. */
|
||||||
|
if (!_device_ids_use_lvmlv(cmd))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
memcpy(old_vgid, old_vg_id, ID_LEN);
|
||||||
|
memcpy(new_vgid, &vg->id, ID_LEN);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for each LV in VG, if there is a du for that LV (meaning a PV exists
|
||||||
|
* on the LV), then update the du idname, replacing the old vgid with
|
||||||
|
* the new vgid.
|
||||||
|
*/
|
||||||
|
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||||
|
memset(old_idname, 0, sizeof(old_idname));
|
||||||
|
memcpy(old_idname, "LVM-", 4);
|
||||||
|
memcpy(old_idname+4, old_vgid, ID_LEN);
|
||||||
|
memcpy(old_idname+4+ID_LEN, &lvl->lv->lvid.id[1], ID_LEN);
|
||||||
|
|
||||||
|
if ((du = _get_du_for_device_id(cmd, DEV_ID_TYPE_LVMLV_UUID, old_idname))) {
|
||||||
|
log_debug("device_id update %s pvid %s vgid %s to %s",
|
||||||
|
du->devname ?: ".", du->pvid ?: ".", old_vgid, new_vgid);
|
||||||
|
memcpy(du->idname+4, new_vgid, ID_LEN);
|
||||||
|
update = 1;
|
||||||
|
|
||||||
|
if (du->dev && du->dev->id && (du->dev->id->idtype == DEV_ID_TYPE_LVMLV_UUID))
|
||||||
|
memcpy(du->dev->id->idname+4, new_vgid, ID_LEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update)
|
||||||
|
device_ids_write(cmd);
|
||||||
|
out:
|
||||||
|
unlock_devices_file(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
static int _idtype_compatible_with_major_number(struct cmd_context *cmd, int idtype, int major)
|
static int _idtype_compatible_with_major_number(struct cmd_context *cmd, int idtype, int major)
|
||||||
{
|
{
|
||||||
if (idtype == DEV_ID_TYPE_MPATH_UUID ||
|
if (idtype == DEV_ID_TYPE_MPATH_UUID ||
|
||||||
|
@ -36,6 +36,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
|
|||||||
int device_ids_version_unchanged(struct cmd_context *cmd);
|
int device_ids_version_unchanged(struct cmd_context *cmd);
|
||||||
void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, 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);
|
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);
|
||||||
|
|
||||||
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
|
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
|
||||||
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
|
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
|
||||||
|
@ -608,6 +608,25 @@ rm "$DFDIR/test.devices"
|
|||||||
vgcreate --devicesfile test.devices $vg3 "$dev3"
|
vgcreate --devicesfile test.devices $vg3 "$dev3"
|
||||||
grep "$dev3" "$DFDIR/test.devices"
|
grep "$dev3" "$DFDIR/test.devices"
|
||||||
|
|
||||||
|
# vgchange uuid handles stacked PVs on VGs
|
||||||
|
|
||||||
|
wipe_all
|
||||||
|
rm -f "$DF"
|
||||||
|
vgcreate $vg1 "$dev1"
|
||||||
|
lvcreate -l8 -n $lv1 $vg1
|
||||||
|
aux lvmconf 'devices/scan_lvs = 1'
|
||||||
|
pvcreate "$DM_DEV_DIR/$vg1/$lv1"
|
||||||
|
pvs "$DM_DEV_DIR/$vg1/$lv1"
|
||||||
|
grep "$DM_DEV_DIR/$vg1/$lv1" $DF
|
||||||
|
vgchange -an $vg1
|
||||||
|
vgchange --uuid $vg1
|
||||||
|
vgchange -ay $vg1
|
||||||
|
pvs "$DM_DEV_DIR/$vg1/$lv1"
|
||||||
|
vgchange -an $vg1
|
||||||
|
not pvs "$DM_DEV_DIR/$vg1/$lv1"
|
||||||
|
aux lvmconf 'devices/scan_lvs = 0'
|
||||||
|
vgremove -y $vg1
|
||||||
|
|
||||||
#
|
#
|
||||||
# verify --devicesfile and --devices are not affected by a filter
|
# verify --devicesfile and --devices are not affected by a filter
|
||||||
# This is last because it sets lvm.conf filter and
|
# This is last because it sets lvm.conf filter and
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
#include "lib/device/device_id.h"
|
||||||
|
|
||||||
struct vgchange_params {
|
struct vgchange_params {
|
||||||
int lock_start_count;
|
int lock_start_count;
|
||||||
@ -412,12 +413,15 @@ static int _vgchange_uuid(struct cmd_context *cmd __attribute__((unused)),
|
|||||||
struct volume_group *vg)
|
struct volume_group *vg)
|
||||||
{
|
{
|
||||||
struct lv_list *lvl;
|
struct lv_list *lvl;
|
||||||
|
struct id old_vg_id;
|
||||||
|
|
||||||
if (lvs_in_vg_activated(vg)) {
|
if (lvs_in_vg_activated(vg)) {
|
||||||
log_error("Volume group has active logical volumes");
|
log_error("Volume group has active logical volumes");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(&old_vg_id, &vg->id, ID_LEN);
|
||||||
|
|
||||||
if (!id_create(&vg->id)) {
|
if (!id_create(&vg->id)) {
|
||||||
log_error("Failed to generate new random UUID for VG %s.",
|
log_error("Failed to generate new random UUID for VG %s.",
|
||||||
vg->name);
|
vg->name);
|
||||||
@ -428,6 +432,12 @@ static int _vgchange_uuid(struct cmd_context *cmd __attribute__((unused)),
|
|||||||
memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id));
|
memcpy(&lvl->lv->lvid, &vg->id, sizeof(vg->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any LVs in this VG have PVs stacked on them, then
|
||||||
|
* update the device_id of the stacked PV.
|
||||||
|
*/
|
||||||
|
device_id_update_vg_uuid(cmd, vg, &old_vg_id);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -802,6 +812,14 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
if (noupdate)
|
if (noupdate)
|
||||||
cmd->ignore_device_name_mismatch = 1;
|
cmd->ignore_device_name_mismatch = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the devices file includes PVs stacked on LVs, then
|
||||||
|
* vgchange --uuid may need to update the devices file.
|
||||||
|
* No PV-on-LV stacked is done without scan_lvs set.
|
||||||
|
*/
|
||||||
|
if (arg_is_set(cmd, uuid_ARG) && cmd->scan_lvs)
|
||||||
|
cmd->edit_devices_file = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Include foreign VGs that contain active LVs.
|
* Include foreign VGs that contain active LVs.
|
||||||
* That shouldn't happen in general, but if it does by some
|
* That shouldn't happen in general, but if it does by some
|
||||||
|
Loading…
Reference in New Issue
Block a user