]> sourceware.org Git - lvm2.git/commitdiff
pvscan: use quick activation only with matching PV device names
authorDavid Teigland <teigland@redhat.com>
Wed, 4 Sep 2019 20:59:49 +0000 (15:59 -0500)
committerDavid Teigland <teigland@redhat.com>
Mon, 30 Sep 2019 16:38:10 +0000 (11:38 -0500)
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.)

tools/pvscan.c

index b025ae3e6b1e20225633f6ff67b25b00dd552ea4..96ef438aacd2d16f3516f22e0815b54604b5ba45 100644 (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;
This page took 0.041884 seconds and 5 git commands to generate.