]> sourceware.org Git - lvm2.git/blobdiff - lib/cache/lvmetad.c
Scan all devices for lvmetad if 'pvscan --cache' used without device list.
[lvm2.git] / lib / cache / lvmetad.c
index b1e46041c056323ccd09b7d8642e4dec261a37aa..47b71feed307179057835fc14973ff2f815eadeb 100644 (file)
@@ -31,7 +31,7 @@ void lvmetad_init(void)
        if (_using_lvmetad) { /* configured by the toolcontext */
                _lvmetad = lvmetad_open(socket ?: DEFAULT_RUN_DIR "/lvmetad.socket");
                if (_lvmetad.socket_fd < 0 || _lvmetad.error) {
-                       log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to scanning.", strerror(_lvmetad.error));
+                       log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.", strerror(_lvmetad.error));
                        _using_lvmetad = 0;
                }
        }
@@ -39,20 +39,41 @@ void lvmetad_init(void)
 
 /*
  * Helper; evaluate the reply from lvmetad, check for errors, print diagnostics
- * and return a summary success/failure exit code. Frees up the reply resources
- * as well.
+ * and return a summary success/failure exit code.
+ *
+ * If found is set, *found indicates whether or not device exists,
+ * and missing device is not treated as an error.
  */
-static int _lvmetad_handle_reply(daemon_reply reply, const char *action, const char *object) {
-       if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
-               log_error("Request to %s %s in lvmetad has failed. Reason: %s",
-                         action, object, reply.error ? strerror(reply.error) :
-                         daemon_reply_str(reply, "reason", "Unknown."));
-               daemon_reply_destroy(reply);
+static int _lvmetad_handle_reply(daemon_reply reply, const char *action, const char *object,
+                                int *found)
+{
+       if (reply.error) {
+               log_error("Request to %s %s%sin lvmetad gave response %s.",
+                         action, object, *object ? " " : "", strerror(reply.error));
                return 0;
        }
 
-       daemon_reply_destroy(reply);
-       return 1;
+       /* All OK? */
+       if (!strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
+               if (found)
+                       *found = 1;
+               return 1;
+       }
+
+       /* Unknown device permitted? */
+       if (found && !strcmp(daemon_reply_str(reply, "response", ""), "unknown")) {
+               log_very_verbose("Request to %s %s%sin lvmetad did not find object.",
+                                action, object, *object ? " " : "");
+               *found = 0;
+               return 1;
+       }
+
+       log_error("Request to %s %s%sin lvmetad gave response %s. Reason: %s",
+                 action, object, *object ? " " : "", 
+                 daemon_reply_str(reply, "response", "<missing>"),
+                 daemon_reply_str(reply, "reason", "<missing>"));
+
+       return 0;
 }
 
 static int _read_mda(struct lvmcache_info *info,
@@ -187,7 +208,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
                        log_error(INTERNAL_ERROR
                                  "We do not know the format (%s) reported by lvmetad.",
                                  fmt_name);
-                       return NULL;
+                       goto out;
                }
 
                fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
@@ -195,7 +216,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
                fic.context.vg_ref.vg_id = vgid;
 
                if (!(fid = fmt->ops->create_instance(fmt, &fic)))
-                       return_NULL;
+                       goto_out;
 
                if ((pvcn = dm_config_find_node(top, "metadata/physical_volumes")))
                        for (pvcn = pvcn->child; pvcn; pvcn = pvcn->sib)
@@ -203,21 +224,25 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
 
                top->key = name;
                if (!(vg = import_vg_from_config_tree(reply.cft, fid)))
-                       return_NULL;
+                       goto_out;
 
                dm_list_iterate_items(pvl, &vg->pvs) {
                        if ((info = lvmcache_info_from_pvid((const char *)&pvl->pv->id, 0))) {
                                pvl->pv->label_sector = lvmcache_get_label(info)->sector;
                                pvl->pv->dev = lvmcache_device(info);
-                               if (!lvmcache_fid_add_mdas_pv(info, fid))
-                                        return_NULL; /* FIXME error path */
+                               if (!lvmcache_fid_add_mdas_pv(info, fid)) {
+                                       vg = NULL;
+                                       goto_out;       /* FIXME error path */
+                               }
                        } /* else probably missing */
                }
 
                lvmcache_update_vg(vg, 0);
        }
 
+out:
        daemon_reply_destroy(reply);
+
        return vg;
 }
 
@@ -264,12 +289,15 @@ int lvmetad_vg_update(struct volume_group *vg)
        }
 
        reply = daemon_send_simple(_lvmetad, "vg_update", "vgname = %s", vg->name,
-                                            "metadata = %b", strchr(buf, '{'),
-                                  NULL);
+                                  "metadata = %b", strchr(buf, '{'), NULL);
        dm_free(buf);
 
-       if (!_lvmetad_handle_reply(reply, "update VG", vg->name))
+       if (!_lvmetad_handle_reply(reply, "update VG", vg->name, NULL)) {
+               daemon_reply_destroy(reply);
                return 0;
+       }
+
+       daemon_reply_destroy(reply);
 
        n = (vg->fid && vg->fid->metadata_areas_index) ?
                dm_hash_get_first(vg->fid->metadata_areas_index) : NULL;
@@ -304,6 +332,7 @@ int lvmetad_vg_remove(struct volume_group *vg)
 {
        char uuid[64];
        daemon_reply reply;
+       int result;
 
        if (!_using_lvmetad)
                return 1; /* just fake it */
@@ -313,14 +342,18 @@ int lvmetad_vg_remove(struct volume_group *vg)
 
        reply = daemon_send_simple(_lvmetad, "vg_remove", "uuid = %s", uuid, NULL);
 
-       return _lvmetad_handle_reply(reply, "remove VG", vg->name);
+       result = _lvmetad_handle_reply(reply, "remove VG", vg->name, NULL);
+
+       daemon_reply_destroy(reply);
+
+       return result;
 }
 
-int lvmetad_pv_lookup(struct cmd_context *cmd, struct id pvid)
+int lvmetad_pv_lookup(struct cmd_context *cmd, struct id pvid, int *found)
 {
        char uuid[64];
        daemon_reply reply;
-       int result = 1;
+       int result = 0;
        struct dm_config_node *cn;
 
        if (!_using_lvmetad)
@@ -331,40 +364,51 @@ int lvmetad_pv_lookup(struct cmd_context *cmd, struct id pvid)
 
        reply = daemon_send_simple(_lvmetad, "pv_lookup", "uuid = %s", uuid, NULL);
 
-       if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
-               _lvmetad_handle_reply(reply, "lookup PVs", "");
-               return_0;
-       }
+       if (!_lvmetad_handle_reply(reply, "lookup PV", "", found))
+               goto_out;
+
+       if (found && !*found)
+               goto out_success;
 
        if (!(cn = dm_config_find_node(reply.cft->root, "physical_volume")))
-               result = 0;
+               goto_out;
         else if (!_pv_populate_lvmcache(cmd, cn, 0))
-               result = 0;
+               goto_out;
+
+out_success:
+       result = 1;
 
+out:
        daemon_reply_destroy(reply);
+
        return result;
 }
 
-int lvmetad_pv_lookup_by_devt(struct cmd_context *cmd, dev_t device)
+int lvmetad_pv_lookup_by_dev(struct cmd_context *cmd, struct device *dev, int *found)
 {
-       int result = 1;
+       int result = 0;
        daemon_reply reply;
        struct dm_config_node *cn;
 
        if (!_using_lvmetad)
                return_0;
 
-       reply = daemon_send_simple(_lvmetad, "pv_lookup", "device = %d", device, NULL);
+       reply = daemon_send_simple(_lvmetad, "pv_lookup", "device = %d", dev->dev, NULL);
 
-       if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
-               _lvmetad_handle_reply(reply, "lookup PVs", "");
-               return_0;
-       }
+       if (!_lvmetad_handle_reply(reply, "lookup PV", dev_name(dev), found))
+               goto_out;
+
+       if (found && !*found)
+               goto out_success;
 
        cn = dm_config_find_node(reply.cft->root, "physical_volume");
-       if (!cn || !_pv_populate_lvmcache(cmd, cn, device))
-               result = 0;
+       if (!cn || !_pv_populate_lvmcache(cmd, cn, dev->dev))
+               goto_out;
+
+out_success:
+       result = 1;
 
+out:
        daemon_reply_destroy(reply);
        return result;
 }
@@ -379,8 +423,8 @@ int lvmetad_pv_list_to_lvmcache(struct cmd_context *cmd)
 
        reply = daemon_send_simple(_lvmetad, "pv_list", NULL);
 
-       if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
-               _lvmetad_handle_reply(reply, "list PVs", "");
+       if (!_lvmetad_handle_reply(reply, "list PVs", "", NULL)) {
+               daemon_reply_destroy(reply);
                return_0;
        }
 
@@ -389,6 +433,7 @@ int lvmetad_pv_list_to_lvmcache(struct cmd_context *cmd)
                        _pv_populate_lvmcache(cmd, cn, 0);
 
        daemon_reply_destroy(reply);
+
        return 1;
 }
 
@@ -404,8 +449,9 @@ int lvmetad_vg_list_to_lvmcache(struct cmd_context *cmd)
                return 1;
 
        reply = daemon_send_simple(_lvmetad, "vg_list", NULL);
-       if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
-               _lvmetad_handle_reply(reply, "list VGs", "");
+
+       if (!_lvmetad_handle_reply(reply, "list VGs", "", NULL)) {
+               daemon_reply_destroy(reply);
                return_0;
        }
 
@@ -497,6 +543,7 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_
        const char *mdas = NULL;
        char *pvmeta;
        char *buf = NULL;
+       int result;
 
        if (!_using_lvmetad)
                return 1;
@@ -553,23 +600,34 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const struct format_
        }
 
        dm_free(pvmeta);
-       return _lvmetad_handle_reply(reply, "update PV", uuid);
+
+       result = _lvmetad_handle_reply(reply, "update PV", uuid, NULL);
+       daemon_reply_destroy(reply);
+
+       return result;
 }
 
-static int _lvmetad_pv_gone(dev_t device, const char *pv_name)
+int lvmetad_pv_gone(dev_t device, const char *pv_name)
 {
+       int result;
+       int found;
+
        if (!_using_lvmetad)
                return 1;
 
-       daemon_reply reply =
-               daemon_send_simple(_lvmetad, "pv_gone", "device = %d", device, NULL);
+       daemon_reply reply = daemon_send_simple(_lvmetad, "pv_gone", "device = %d", device, NULL);
+
+       result = _lvmetad_handle_reply(reply, "drop PV", pv_name, &found);
+       /* We don't care whether or not the daemon had the PV cached. */
+
+       daemon_reply_destroy(reply);
 
-       return _lvmetad_handle_reply(reply, "drop PV", pv_name);
+       return result;
 }
 
-int lvmetad_pv_gone(struct device *dev)
+int lvmetad_pv_gone_by_dev(struct device *dev)
 {
-       return _lvmetad_pv_gone(dev->dev, dev_name(dev));
+       return lvmetad_pv_gone(dev->dev, dev_name(dev));
 }
 
 int lvmetad_active(void)
@@ -583,7 +641,7 @@ void lvmetad_set_active(int active)
 }
 
 /*
- * The following code implements pvscan --lvmetad.
+ * The following code implements pvscan --cache.
  */
 
 struct _pvscan_lvmetad_baton {
@@ -596,6 +654,7 @@ static int _pvscan_lvmetad_single(struct metadata_area *mda, void *baton)
        struct _pvscan_lvmetad_baton *b = baton;
        struct volume_group *this = mda->ops->vg_read(b->fid, "", mda, 1);
 
+       /* FIXME Also ensure contents match etc. */
        if (!b->vg || this->seqno > b->vg->seqno)
                b->vg = this;
        else if (b->vg)
@@ -604,33 +663,8 @@ static int _pvscan_lvmetad_single(struct metadata_area *mda, void *baton)
        return 1;
 }
 
-static dev_t _parse_devt(const char *str)
-{      /* Oh. */
-       char *where = (char *) str;
-       int major = strtol(str, &where, 10);
-       int minor;
-
-       if (where == str)
-               return -1;
-
-       if (*where != ':')
-               return -1;
-
-       str = ++where;
-       minor = strtol(str, &where, 10);
-
-       if (where == str)
-               return -1;
-
-       if (*where)
-               return -1;
-
-       return MKDEV(major, minor);
-}
-
-int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name)
+int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev)
 {
-       struct device *dev;
        struct label *label;
        struct lvmcache_info *info;
        struct physical_volume pv;
@@ -643,26 +677,9 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, const char *pv_name)
                return 0;
        }
 
-       dev = dev_cache_get(pv_name, NULL);
-       if (!dev && _parse_devt(pv_name) != -1)
-               dev = dev_cache_get_by_devt(_parse_devt(pv_name), NULL);
-
-       if (!dev) {
-               if (_parse_devt(pv_name) == -1) {
-                       log_error("Unrecognised device name %s.  (Use MAJOR:MINOR for new devices.)", pv_name);
-                       return 0;
-               }
-
-               if (!_lvmetad_pv_gone(_parse_devt(pv_name), pv_name))
-                       goto_bad;
-
-               log_print("Device %s not found.  Cleared from lvmetad cache.", pv_name);
-               return 1;
-       }
-
        if (!label_read(dev, &label, 0)) {
                log_print("No PV label found on %s.", dev_name(dev));
-               if (!lvmetad_pv_gone(dev))
+               if (!lvmetad_pv_gone_by_dev(dev))
                        goto_bad;
                return 1;
        }
This page took 0.035651 seconds and 5 git commands to generate.