]> sourceware.org Git - lvm2.git/commitdiff
report: improve reporting of active state
authorZdenek Kabelac <zkabelac@redhat.com>
Thu, 2 May 2013 16:06:50 +0000 (18:06 +0200)
committerZdenek Kabelac <zkabelac@redhat.com>
Fri, 3 May 2013 13:43:52 +0000 (15:43 +0200)
For reporting stacked or joined devices properly in cluster,
we need to report their activation state according the lock,
which activated this device tree.

This is getting a bit complex - current code tries simple approach -

For snapshot - return status for origin.
For thin pool - return status of the first known active thin volume.
For the rest of them - try to use dependency list of LVs and skip
known execptions.  This should be able to recursively deduce top level
device for given LV.

(in release fix)

lib/metadata/lv.c
lib/metadata/lv.h

index 41de7a5d162f293499d8342d034218e9647766ef..283b8c49869b401df8c820f25c6c59fee71f78f9 100644 (file)
@@ -745,6 +745,12 @@ char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv)
 {
        const char *s;
 
+       if (vg_is_clustered(lv->vg)) {
+               //const struct logical_volume *lvo = lv;
+               lv = lv_lock_holder(lv);
+               //log_debug("Holder for %s => %s.", lvo->name, lv->name);
+       }
+
        if (!lv_is_active(lv))
                s = ""; /* not active */
        else if (!vg_is_clustered(lv->vg))
@@ -755,7 +761,39 @@ char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv)
                        "local exclusive" : "remote exclusive";
        else /* locally active */
                s = lv_is_active_but_not_locally(lv) ?
-                    "remotely" : "locally";
+                       "remotely" : "locally";
 
        return dm_pool_strdup(mem, s);
 }
+
+/* For given LV find recursively the LV which holds lock for it */
+const struct logical_volume *lv_lock_holder(const struct logical_volume *lv)
+{
+       const struct seg_list *sl;
+
+       if (lv_is_cow(lv))
+               return lv_lock_holder(origin_from_cow(lv));
+
+       if (lv_is_thin_pool(lv))
+               /* Find any active LV from the pool */
+               dm_list_iterate_items(sl, &lv->segs_using_this_lv)
+                       if (lv_is_active(sl->seg->lv)) {
+                               log_debug("Thin volume \"%s\" is active.", sl->seg->lv->name);
+                               return sl->seg->lv;
+                       }
+
+       /* For other types, by default look for the first user */
+       dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
+               /* FIXME: complete this exception list */
+               if (lv_is_thin_volume(lv) &&
+                   lv_is_thin_volume(sl->seg->lv) &&
+                   first_seg(lv)->pool_lv == sl->seg->pool_lv)
+                       continue; /* Skip thin snaphost */
+               if (lv_is_external_origin(lv) &&
+                   lv_is_thin_volume(sl->seg->lv))
+                       continue; /* Skip external origin */
+               return lv_lock_holder(sl->seg->lv);
+       }
+
+       return lv;
+}
index bac8bc2ee7ae6e1fa2cd4b57a227c74872612856..ed0d7452dd8937d74a785e250bbbd12ced5538a3 100644 (file)
@@ -90,4 +90,5 @@ const char *lv_layer(const struct logical_volume *lv);
 int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
                     activation_change_t activate);
 char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv);
+const struct logical_volume *lv_lock_holder(const struct logical_volume *lv);
 #endif /* _LVM_LV_H */
This page took 0.042142 seconds and 5 git commands to generate.