]> sourceware.org Git - lvm2.git/commitdiff
o split the uuid -> device map out from vgcache
authorJoe Thornber <thornber@redhat.com>
Tue, 15 Jan 2002 10:24:48 +0000 (10:24 +0000)
committerJoe Thornber <thornber@redhat.com>
Tue, 15 Jan 2002 10:24:48 +0000 (10:24 +0000)
o  roll vgcache back to agk's implementation, we'll revisit this as part
   of the cluster integration.

o  change the extra_info field in a label to be a void *

13 files changed:
include/.symlinks
lib/Makefile.in
lib/device/device.h
lib/format1/lvm1_label.c
lib/format1/lvm1_label.h
lib/label/label.c
lib/label/label.h
lib/label/uuid-map.c [new file with mode: 0644]
lib/label/uuid-map.h [new file with mode: 0644]
lib/uuid/uuid.c
lib/uuid/uuid.h
lib/vgcache/vgcache.c
lib/vgcache/vgcache.h

index 9be795da27b91ac01b348e4782ae6a46a467d444..53e5f65927731cab5167401807c4dfc0ceec9b13 100644 (file)
 ../lib/filters/filter-regex.h
 ../lib/filters/filter.h
 ../lib/format1/format1.h
+../lib/format1/lvm1_label.h
 ../lib/format_text/format-text.h
 ../lib/label/label.h
+../lib/label/uuid-map.h
 ../lib/log/log.h
 ../lib/metadata/metadata.h
 ../lib/mm/dbg_malloc.h
index 8f47e083f357064c5a642ec3ad04a21d4a267b67..d43dc315973b9f89c0e93cb6d8d1f73c756921ac 100644 (file)
@@ -36,6 +36,7 @@ SOURCES=\
        format_text/format-text.c \
        format_text/import.c \
        label/label.c \
+       label/uuid-map.c \
        log/log.c \
        metadata/lv_manip.c \
        metadata/merge.c \
index 1042d8c468ac12cdeecddc14566435ab6429375b..427a640fb8295cc31818c1efa33497c5ed88243d 100644 (file)
@@ -22,6 +22,11 @@ struct device {
        int fd;
 };
 
+struct device_list {
+       struct list list;
+       struct device *dev;
+};
+
 /*
  * All io should use these routines.
  */
index 96c5c66ea0a1f62720c918492a3e4d6aed1f4983..6ae1ebaa936a882b2762341484a6723c93173377 100644 (file)
@@ -43,20 +43,25 @@ static int _remove(struct labeller *l, struct device *dev)
 static struct label *_to_label(struct disk_list *dl)
 {
        struct label *l;
+       struct lvm_label_info *info;
 
        if (!(l = dbg_malloc(sizeof(*l)))) {
                log_err("Couldn't allocate label.");
                return NULL;
        }
 
+       if (!(info = (struct lvm_label_info *) dbg_strdup(dl->pv.vg_name))) {
+               dbg_free(l);
+               return NULL;
+       }
+
        memcpy(&l->id, &dl->pvd.pv_uuid, sizeof(l->id));
-       strcpy(l->volume_type, "lvm1");
+       strcpy(l->volume_type, "lvm");
        l->version[0] = 1;
        l->version[0] = 0;
        l->version[0] = 0;
+       l->extra_info = info;
 
-       l->extra_len = 0;
-       l->extra_info = NULL;
        return l;
 }
 
@@ -84,6 +89,12 @@ static int _read(struct labeller *l,
        return r;
 }
 
+static int _destroy_label(struct labeller *l, struct label *label)
+{
+       dbg_free(label->extra_info);
+       dbg_free(label);
+}
+
 static void _destroy(struct labeller *l)
 {
        struct pool *mem = (struct pool *) l->private;
index 210b46c2faa45e527414ac49855b362636a5c128..602f6a2cd932276822c95bd6ba2a4fc1f44ebf1a 100644 (file)
@@ -7,6 +7,15 @@
 #ifndef _LVM_LVM1_LABEL_H
 #define _LVM_LVM1_LABEL_H
 
+/*
+ * This is what the 'extra_info' field of the label will point to
+ * if the label type is lvm1.
+ */
+struct lvm_label_info {
+       char volume_group[0];
+};
+
+
 struct labeller *lvm1_labeller_create(void);
 
 #endif
index 6a02038c75ce8d09cd86b2f919d84f54f8980744..6289adb331f9bcc26fc6a137f58a2b3d3d1e6b6a 100644 (file)
@@ -121,13 +121,17 @@ int label_remove(struct device *dev)
 int label_read(struct device *dev, struct label **result)
 {
        struct labeller *l;
+       int r;
 
        if (!(l = _find_labeller(dev))) {
                stack;
                return 0;
        }
 
-       return l->ops->read(l, dev, result);
+       if ((r = l->ops->read(l, dev, result)))
+               *result->labeller = l;
+
+       return r;
 }
 
 int label_verify(struct device *dev)
index cc24523807c822de863cd7145e32e1023a24b145..911fd0b33b13a7e860dba224d48f951006f00b09 100644 (file)
@@ -16,8 +16,9 @@ struct label {
        char volume_type[32];
        uint32_t version[3];
 
-       size_t extra_len;
-       char *extra_info;
+       void *extra_info;
+
+       struct labeller *labeller;
 };
 
 struct labeller;
@@ -50,6 +51,11 @@ struct label_ops {
         */
        int (*verify)(struct labeller *l, struct device *dev);
 
+       /*
+        * Destroy a previously read label.
+        */
+       int (*destroy_label)(struct labeller *l, struct label *label);
+
        /*
         * Destructor.
         */
@@ -72,7 +78,7 @@ struct labeller *label_get_handler(const char *name);
 int label_remove(struct device *dev);
 int label_read(struct device *dev, struct label **result);
 int label_verify(struct device *dev);
-void label_free(struct label *l);
+void label_destroy(struct label *lab);
 
 /*
  * We'll support two label types: the 'pretend the
diff --git a/lib/label/uuid-map.c b/lib/label/uuid-map.c
new file mode 100644 (file)
index 0000000..8280579
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+ *
+ * This file is released under the LGPL.
+ */
+
+#ifndef _LVM_UUID_MAP_H
+#define _LVM_UUID_MAP_H
+
+#include "uuid-map.h"
+#include "dev-cache.h"
+#include "dbg_malloc.h"
+#include "log.h"
+#include "label.h"
+
+struct uuid_map {
+       struct dev_filter *filter;
+};
+
+
+struct uuid_map *uuid_map_create(struct dev_filter *devices)
+{
+       struct uuid_map *um;
+
+       if (!(um = dbg_malloc(sizeof(*um)))) {
+               log_err("Couldn't allocate uuid_map object.");
+               return NULL;
+       }
+
+       um->filter = devices;
+       return um;
+}
+
+void uuid_map_destroy(struct uuid_map *um)
+{
+       dbg_free(um);
+}
+
+/*
+ * Simple, non-caching implementation to start with.
+ */
+struct device *uuid_map_lookup(struct uuid_map *um, struct id *id)
+{
+       struct dev_iter *iter;
+       struct device *dev;
+       struct label *lab;
+
+       if (!(iter = dev_iter_create(um->filter))) {
+               stack;
+               return NULL;
+       }
+
+       while ((dev = dev_iter_get(iter))) {
+
+               if (!label_read(dev, &lab))
+                       continue;
+
+               if (id_equal(id, &lab->id)) {
+                       label_destroy(lab);
+                       break;
+               }
+
+               label_destroy(lab);
+       }
+
+       dev_iter_destroy(iter);
+       return dev;
+}
+
+#endif
diff --git a/lib/label/uuid-map.h b/lib/label/uuid-map.h
new file mode 100644 (file)
index 0000000..082905d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
+ *
+ * This file is released under the LGPL.
+ */
+
+#ifndef _LVM_UUID_MAP_H
+#define _LVM_UUID_MAP_H
+
+#include "uuid.h"
+#include "dev-cache.h"
+
+/*
+ * Holds a mapping from uuid -> device.
+ */
+struct uuid_map;
+
+struct uuid_map *uuid_map_create(struct dev_filter *devices);
+void uuid_map_destroy(struct uuid_map *um);
+
+/*
+ * Find the device with a particular uuid.
+ */
+struct device *uuid_map_lookup(struct uuid_map *um, struct id *id);
+
+#endif
index e6f09e8dd195e13bfb92be78e2dded873dd757a7..4d1c9abc3866998d349839ac49c8e94c0d804942 100644 (file)
@@ -75,9 +75,9 @@ int id_valid(struct id *id)
        return 1;
 }
 
-int id_cmp(struct id *lhs, struct id *rhs)
+int id_equal(struct id *lhs, struct id *rhs)
 {
-       return memcmp(lhs->uuid, rhs->uuid, sizeof(lhs->uuid));
+       return !memcmp(lhs->uuid, rhs->uuid, sizeof(lhs->uuid));
 }
 
 #define GROUPS (ID_LEN / 4)
index 8e4a3dedd4630a7fde479c7945e9abdfc5171355..f979f3440c9eaa9f528a0103baf791a0039cba21 100644 (file)
@@ -17,7 +17,7 @@ struct id {
 
 int id_create(struct id *id);
 int id_valid(struct id *id);
-int id_cmp(struct id *lhs, struct id *rhs);
+int id_equal(struct id *lhs, struct id *rhs);
 
 /*
  * Fills 'buffer' with a more human readable form
index db682aac6c351966b18b4e750aec3d06623e3218..2ad924e3e4344eef9db562c8614f54ac00214695 100644 (file)
 /*
- * Copyright (C) 2001, 2002 Sistina Software (UK) Limited.
+ * Copyright (C) 2001 Sistina Software (UK) Limited.
  *
  * This file is released under the LGPL.
+ *
  */
 
 #include <stdlib.h>
-
 #include "vgcache.h"
-#include "label.h"
+#include "hash.h"
 #include "dbg_malloc.h"
 #include "log.h"
-#include "lvm1_label.h"
 
+static struct hash_table *_vghash;
+static struct hash_table *_pvhash;
 
-/*
- * Non-caching implementation.
- * FIXME: write caching version, when thought about it a bit more.
- */
-struct vg_cache {
-       struct dev_filter *filter;
-};
+const char *all_devices = "\0";
 
-struct vg_cache *vg_cache_create(struct dev_filter *devices)
+int vgcache_init()
 {
-       struct vg_cache *vgc;
+       if (!(_vghash = hash_create(128)))
+               return 0;
+
+       if (!(_pvhash = hash_create(128)))
+               return 0;
 
-       if (!(vgc = dbg_malloc(sizeof(*vgc)))) {
-               log_err("Couldn't allocate vg_cache object.");
+       return 1;
+}
+
+/* A vg_name of NULL returns all_devices */
+struct list *vgcache_find(const char *vg_name)
+{
+       struct vgname_entry *vgn;
+
+       if (!_vghash)
                return NULL;
-       }
 
-       vgc->filter = devices;
+       if (!vg_name)
+               vg_name = all_devices;
 
-       return vgc;
+       if (!(vgn = hash_lookup(_vghash, vg_name)))
+               return NULL;
+
+       return &vgn->pvdevs;
 }
 
-void vg_cache_destroy(struct vg_cache *vgc)
+void vgcache_del_orphan(struct device *dev)
 {
-       dbg_free(vgc);
+       struct pvdev_list *pvdev;
+
+       if (_pvhash && ((pvdev = hash_lookup(_pvhash, dev_name(dev))))) {
+               list_del(&pvdev->list);
+               hash_remove(_pvhash, dev_name(pvdev->dev));
+               dbg_free(pvdev);
+       }
 }
 
-struct device *vg_cache_find_uuid(struct vg_cache *vgc, struct id *id)
+int vgcache_add_entry(const char *vg_name, struct device *dev)
 {
-       struct dev_iter *iter;
-       struct device *dev;
-       struct label *lab;
+       const char *pv_name;
+       struct vgname_entry *vgn;
+       struct pvdev_list *pvdev;
+       struct list *pvdh, *pvdevs;
+
+       if (!(pvdevs = vgcache_find(vg_name))) {
+               if (!(vgn = dbg_malloc(sizeof(struct vgname_entry)))) {
+                       log_error("struct vgname_entry allocation failed");
+                       return 0;
+               }
 
-       if (!(iter = dev_iter_create(vgc->filter))) {
-               stack;
-               return NULL;
-       }
+               pvdevs = &vgn->pvdevs;
+               list_init(pvdevs);
 
-       while ((dev = dev_iter_get(iter))) {
+               if (!(vgn->vgname = dbg_strdup(vg_name))) {
+                       log_error("vgcache_add: strdup vg_name failed");
+                       return 0;
+               }
 
-               if (label_read(dev, &lab))
-                       continue;
+               if (!hash_insert(_vghash, vg_name, vgn)) {
+                       log_error("vgcache_add: VG hash insertion failed");
+                       return 0;
+               }
+       }
 
-               if (!strcmp(lab->volume_type, "lvm") && id_equal(id, &lab->id))
-                       break;
+       list_iterate(pvdh, pvdevs) {
+               pvdev = list_item(pvdh, struct pvdev_list);
+               if (dev == pvdev->dev)
+                       return 1;
+       }
 
-               label_destroy(lab);
+       /* Remove PV from any existing VG unless an all_devices request */
+       pvdev = NULL;
+       pv_name = dev_name(dev);
+       if (*vg_name && _pvhash && ((pvdev = hash_lookup(_pvhash, pv_name)))) {
+               list_del(&pvdev->list);
+               hash_remove(_pvhash, dev_name(pvdev->dev));
        }
 
-       dev_iter_destroy(iter);
-       return dev;
-}
+       /* Allocate new pvdev_list if there isn't an existing one to reuse */
+       if (!pvdev && !(pvdev = dbg_malloc(sizeof(struct pvdev_list)))) {
+               log_error("struct pvdev_list allocation failed");
+               return 0;
+       }
 
-static void _find_pvs_in_vg(struct vg_cache *vgc, struct pool *mem,
-                           const char *vg, struct dev_iter *iter,
-                           struct list *results)
-{
-       struct device *dev;
-       struct label *lab;
-       struct device_list *dev_list;
-       struct lvm_label_info *info;
+       pvdev->dev = dev;
+       list_add(pvdevs, &pvdev->list);
 
-       while ((dev = dev_iter_get(iter))) {
+       if (*vg_name && _pvhash && !hash_insert(_pvhash, pv_name, pvdev)) {
+               log_error("vgcache_add: PV hash insertion for %s "
+                         "failed", pv_name);
+               return 0;
+       }
 
-               if (!label_read(dev, &lab))
-                       continue;
+       return 1;
+}
 
-               if (strcmp(lab->volume_type, "lvm"))
-                       continue;
+/* vg_name of "\0" is an orphan PV; NULL means only add to all_devices */
+int vgcache_add(const char *vg_name, struct device *dev)
+{
+       if (!_vghash && !vgcache_init())
+               return 0;
 
-               info = (struct lvm_label_info *) lab->extra_info;
+       /* If orphan PV remove it */
+       if (vg_name && !*vg_name)
+               vgcache_del_orphan(dev);
 
-               if (!vg || strcmp(info->volume_group, vg)) {
+       /* Add PV if vg_name supplied */
+       if (vg_name && *vg_name && !vgcache_add_entry(vg_name, dev))
+               return 0;
 
-                       /* add dev to the result list */
-                       if (!(dev_list = pool_alloc(mem, sizeof(*dev_list)))) {
-                               stack;
-                               label_destroy(lab);
-                               return;
-                       }
+       /* Always add to all_devices */
+       return vgcache_add_entry(all_devices, dev);
+}
 
-                       dev_list->dev = dev;
-                       list_add(results, &dev_list->list);
+void vgcache_destroy_entry(struct vgname_entry *vgn)
+{
+       struct list *pvdh;
+       struct pvdev_list *pvdev;
+
+       if (vgn) {
+               pvdh = vgn->pvdevs.n;
+               while (pvdh != &vgn->pvdevs) {
+                       pvdev = list_item(pvdh, struct pvdev_list);
+                       pvdh = pvdh->n;
+                       dbg_free(pvdev);
                }
-
-               label_destroy(lab);
+               dbg_free(vgn->vgname);
        }
+       dbg_free(vgn);
 }
 
-struct list *vg_cache_find_vg(struct vg_cache *vgc, struct pool *mem,
-                             const char *vg)
+void vgcache_del(const char *vg_name)
 {
-       struct dev_iter *iter;
-       struct list *r;
+       struct vgname_entry *vgn;
 
-       if (!(r = pool_alloc(mem, sizeof(r)))) {
-               stack;
-               return NULL;
-       }
-       list_init(r);
+       if (!_vghash)
+               return;
 
-       if (!(iter = dev_iter_create(vgc->filter))) {
-               stack;
-               pool_free(mem, r);
-               return NULL;
-       }
+       if (!vg_name)
+               vg_name = all_devices;
 
-       _find_pvs_in_vg(vgc, mem, vg, iter, r);
+       if (!(vgn = hash_lookup(_vghash, vg_name)))
+               return;
 
-       dev_iter_destroy(iter);
-       return r;
+       hash_remove(_vghash, vg_name);
+       vgcache_destroy_entry(vgn);
 }
 
-int vg_cache_update_vg(struct volume_group *vg)
+void vgcache_destroy()
 {
-       /* no-ops in a non caching version */
-       return 1;
-}
+       if (_vghash) {
+               hash_iterate(_vghash, (iterate_fn)vgcache_destroy_entry);
+               hash_destroy(_vghash);
+               _vghash = NULL;
+       }
 
-int vg_cache_update_device(struct device *dev)
-{
-       /* no-ops in a non caching version */
-       return 1;
+       if (_pvhash) {
+               hash_destroy(_pvhash);
+               _pvhash = NULL;
+       }
 }
index 364c752513976c63245aba3565ebb7d89a94a83d..caa7815e8d1c2a91560cf0957e84c44c8cea894e 100644 (file)
@@ -8,39 +8,29 @@
 #ifndef _LVM_VGCACHE_H
 #define _LVM_VGCACHE_H
 
-#include "vgcache.h"
-#include "list.h"
-#include "uuid.h"
-#include "pool.h"
+#include <sys/types.h>
+#include <asm/page.h>
 #include "dev-cache.h"
-#include "metadata.h"
+#include "list.h"
 
+struct vgname_entry {
+       struct list pvdevs;
+       char *vgname;
+};
 
-/*
- * Maintains a register of LVM specific information about
- * devices.  Makes use of the label code.
- */
-struct vg_cache;
+struct pvdev_list {
+       struct list list;
+       struct device *dev;
+};
 
-struct vg_cache *vg_cache_create(struct dev_filter *devices);
-void vg_cache_destroy(struct vg_cache *vgc);
+int vgcache_init();
+void vgcache_destroy();
 
-/*
- * Find the device with a particular uuid.
- */
-struct device *vg_cache_find_uuid(struct vg_cache *vgc, struct id *id);
+/* Return list of PVs in named VG */
+struct list *vgcache_find(const char *vg_name);
 
-/*
- * Find all devices in a particular volume group.
- */
-struct list *vg_cache_find_vg(struct vg_cache *vgc, struct pool *mem,
-                             const char *vg);
-
-/*
- * Tell the cache about any changes occuring on disk.
- * FIXME: it would be nice to do without these.
- */
-int vg_cache_update_vg(struct volume_group *vg);
-int vg_cache_update_device(struct device *dev);
+/* Add/delete a device */
+int vgcache_add(const char *vg_name, struct device *dev);
+void vgcache_del(const char *vg_name);
 
 #endif
This page took 1.701849 seconds and 5 git commands to generate.