1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-17 21:44:24 +03:00

Compare commits

...

2 Commits

Author SHA1 Message Date
David Teigland
c93d169857 pvscan: use quick activation only with matching PV device names
When the PV device names in the VG metadata do not match the
current PV device names seen on the system, do not use the
optimized activation function (that avoids extra device scanning.)

When the device names do not match, it's a clue that there could
be duplicate PVs, in which case we want to scan all devicess to
find any duplicates and stop the activation if found.

This does not prevent autoactivating a VG from the incorrect
duplicate PV, because the incorrect duplicate may appear by itself
first.  At that point its duplicate PV does not exist to be seen.
(A future enhancement could use the WWID to strengthen this
detection.)
2019-09-04 15:59:49 -05:00
David Teigland
c3e97e0cb9 metadata: import device name hint from metadata
Start by using it in a comment for a missing PV.
2019-09-04 14:13:14 -05:00
4 changed files with 33 additions and 9 deletions

View File

@@ -179,6 +179,7 @@ static int _read_pv(struct format_instance *fid,
struct physical_volume *pv;
struct pv_list *pvl;
const struct dm_config_value *cv;
const char *device_hint;
uint64_t size, ba_start;
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
@@ -223,6 +224,11 @@ static int _read_pv(struct format_instance *fid,
return 0;
}
if (dm_config_get_str(pvn, "device", &device_hint)) {
if (!(pv->device_hint = dm_pool_strdup(mem, device_hint)))
log_error("Failed to allocate memory for device hint in read_pv.");
}
if (!_read_uint64(pvn, "pe_start", &pv->pe_start)) {
log_error("Couldn't read extent start value (pe_start) "
"for physical volume.");

View File

@@ -4971,7 +4971,10 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const
if (!pvl->pv->dev) {
/* The obvious and common case of a missing device. */
log_warn("WARNING: VG %s is missing PV %s.", vg_name, uuidstr);
if (pvl->pv->device_hint)
log_warn("WARNING: VG %s is missing PV %s (last written to %s).", vg_name, uuidstr, pvl->pv->device_hint);
else
log_warn("WARNING: VG %s is missing PV %s.", vg_name, uuidstr);
missing_pv_dev++;
} else if (pvl->pv->status & MISSING_PV) {

View File

@@ -26,6 +26,7 @@ struct physical_volume {
struct id id;
struct id old_id; /* Set during pvchange -u. */
struct device *dev;
const char *device_hint; /* primary name last time metadata was written */
const struct format_type *fmt;
struct format_instance *fid;

View File

@@ -929,17 +929,19 @@ static int _online_vg_file_create(struct cmd_context *cmd, const char *vgname)
* scan/read in order to process/activate the VG.
*/
static int _get_devs_from_saved_vg(struct cmd_context *cmd, char *vgname,
static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname,
struct dm_list *saved_vgs,
struct dm_list *devs)
{
char path[PATH_MAX];
char file_vgname[NAME_LEN];
char uuidstr[64] __attribute__((aligned(8)));
struct pv_list *pvl;
struct device_list *devl;
struct device *dev;
struct volume_group *vg;
const char *pvid;
const char *name1, *name2;
dev_t devno;
int file_major = 0, file_minor = 0;
@@ -978,6 +980,16 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, char *vgname,
return 0;
}
name1 = dev_name(dev);
name2 = pvl->pv->device_hint;
if (strcmp(name1, name2)) {
if (!id_write_format((const struct id *)pvid, uuidstr, sizeof(uuidstr)))
uuidstr[0] = '\0';
log_print("PVID %s read from %s last written to %s.", uuidstr, name1, name2);
return 0;
}
if (!(devl = zalloc(sizeof(*devl))))
return_0;
@@ -1024,8 +1036,8 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, char *vgname,
* is important when there are many devs.
*/
static int _pvscan_aa_direct(struct cmd_context *cmd, struct pvscan_aa_params *pp, char *vgname,
struct dm_list *saved_vgs)
static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp, const char *vgname,
struct dm_list *saved_vgs, int *no_quick)
{
struct dm_list devs; /* device_list */
struct volume_group *vg;
@@ -1044,7 +1056,8 @@ static int _pvscan_aa_direct(struct cmd_context *cmd, struct pvscan_aa_params *p
* The dev_cache gives us struct devices from the devnums.
*/
if (!_get_devs_from_saved_vg(cmd, vgname, saved_vgs, &devs)) {
log_error("pvscan activation for VG %s failed to find devices.", vgname);
log_print("pvscan[%d] VG %s not using quick activation.", getpid(), vgname);
*no_quick = 1;
return ECMD_FAILED;
}
@@ -1132,6 +1145,7 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
{
struct processing_handle *handle = NULL;
struct dm_str_list *sl, *sl2;
int no_quick = 0;
int ret;
if (dm_list_empty(vgnames)) {
@@ -1169,12 +1183,12 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
if (dm_list_size(vgnames) == 1) {
dm_list_iterate_items(sl, vgnames)
ret = _pvscan_aa_direct(cmd, pp, (char *)sl->str, saved_vgs);
} else {
/* FIXME: suppress label scan in process_each if label scan already done? */
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_ACTIVATE, 0, handle, _pvscan_aa_single);
ret = _pvscan_aa_quick(cmd, pp, sl->str, saved_vgs, &no_quick);
}
if ((dm_list_size(vgnames) > 1) || no_quick)
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_ACTIVATE, 0, handle, _pvscan_aa_single);
destroy_processing_handle(cmd, handle);
return ret;