]> sourceware.org Git - lvm2.git/commitdiff
lvmetad: disable if device scan fails
authorDavid Teigland <teigland@redhat.com>
Fri, 15 Apr 2016 19:19:46 +0000 (14:19 -0500)
committerDavid Teigland <teigland@redhat.com>
Fri, 6 May 2016 14:00:00 +0000 (09:00 -0500)
If a command begins repopulating the lvmetad cache,
and fails part way through, it should set the disabled
state in lvmetad so other commands don't use bad data.
If a subsequent scan succeeds, the disabled state is
cleared.

daemons/lvmetad/lvmetad-client.h
daemons/lvmetad/lvmetad-core.c
lib/cache/lvmetad.c

index dce8a7e49e173c63654529ce6dec6ae337add812..1376e6bfe53c58cf80817317ab0eeb4c09f2004c 100644 (file)
@@ -22,6 +22,7 @@
 #define LVMETAD_DISABLE_REASON_DIRECT          "DIRECT"
 #define LVMETAD_DISABLE_REASON_LVM1            "LVM1"
 #define LVMETAD_DISABLE_REASON_DUPLICATES      "DUPLICATES"
+#define LVMETAD_DISABLE_REASON_SCANERROR       "SCANERROR"
 
 struct volume_group;
 
index 188c9b9d9769ed9e3ce3e293010a23c262ea124e..54ecd4a9ade861c1b5915067fc81ec2d29921a88 100644 (file)
@@ -202,8 +202,9 @@ struct vg_info {
 #define GLFL_DISABLE_REASON_DIRECT     0x00000004
 #define GLFL_DISABLE_REASON_LVM1       0x00000008
 #define GLFL_DISABLE_REASON_DUPLICATES 0x00000010
+#define GLFL_DISABLE_REASON_SCANERROR  0x00000020
 
-#define GLFL_DISABLE_REASON_ALL (GLFL_DISABLE_REASON_DIRECT | GLFL_DISABLE_REASON_LVM1 | GLFL_DISABLE_REASON_DUPLICATES)
+#define GLFL_DISABLE_REASON_ALL (GLFL_DISABLE_REASON_DIRECT | GLFL_DISABLE_REASON_LVM1 | GLFL_DISABLE_REASON_DUPLICATES | GLFL_DISABLE_REASON_SCANERROR)
 
 #define VGFL_INVALID 0x00000001
 
@@ -2512,6 +2513,8 @@ static response set_global_info(lvmetad_state *s, request r)
                        reason_flags |= GLFL_DISABLE_REASON_LVM1;
                if (strstr(reason, LVMETAD_DISABLE_REASON_DUPLICATES))
                        reason_flags |= GLFL_DISABLE_REASON_DUPLICATES;
+               if (strstr(reason, LVMETAD_DISABLE_REASON_SCANERROR))
+                       reason_flags |= GLFL_DISABLE_REASON_SCANERROR;
        }
 
        if (global_invalid != -1) {
@@ -2565,10 +2568,11 @@ static response get_global_info(lvmetad_state *s, request r)
        memset(reason, 0, sizeof(reason));
 
        if (s->flags & GLFL_DISABLE) {
-               snprintf(reason, REASON_BUF_SIZE - 1, "%s%s%s",
+               snprintf(reason, REASON_BUF_SIZE - 1, "%s%s%s%s",
                         (s->flags & GLFL_DISABLE_REASON_DIRECT)     ? LVMETAD_DISABLE_REASON_DIRECT "," : "",
                         (s->flags & GLFL_DISABLE_REASON_LVM1)       ? LVMETAD_DISABLE_REASON_LVM1 "," : "",
-                        (s->flags & GLFL_DISABLE_REASON_DUPLICATES) ? LVMETAD_DISABLE_REASON_DUPLICATES "," : "");
+                        (s->flags & GLFL_DISABLE_REASON_DUPLICATES) ? LVMETAD_DISABLE_REASON_DUPLICATES "," : "",
+                        (s->flags & GLFL_DISABLE_REASON_SCANERROR)  ? LVMETAD_DISABLE_REASON_SCANERROR "," : "");
        }
 
        if (!reason[0])
index 86ccd5927c7105b5c6b983ef94cb0b360da4ebb5..391cbc47021cab4132ad65b17701b39e28907dba 100644 (file)
@@ -1700,11 +1700,6 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
        if (!baton.vg)
                lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
 
-       /*
-        * NB. If this command failed and we are relying on lvmetad to have an
-        * *exact* image of the system, the lvmetad instance that went out of
-        * sync needs to be killed.
-        */
        if (!lvmetad_pv_found((const struct id *) &dev->pvid, dev, lvmcache_fmt(info),
                              label->sector, baton.vg, handler)) {
                release_vg(baton.vg);
@@ -1749,13 +1744,13 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler
        struct dev_iter *iter;
        struct device *dev;
        daemon_reply reply;
-       int r = 1;
        char *future_token;
        const char *reason;
        int was_silent;
        int replacing_other_update = 0;
        int replaced_update = 0;
        int retries = 0;
+       int ret = 1;
 
        if (!lvmetad_used()) {
                log_error("Cannot proceed since lvmetad is not active.");
@@ -1813,7 +1808,7 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler
        log_debug_lvmetad("Telling lvmetad to clear its cache");
        reply = _lvmetad_send(cmd, "pv_clear_all", NULL);
        if (!_lvmetad_handle_reply(reply, "pv_clear_all", "", NULL))
-               r = 0;
+               ret = 0;
        daemon_reply_destroy(reply);
 
        was_silent = silent_mode();
@@ -1821,33 +1816,38 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler
 
        while ((dev = dev_iter_get(iter))) {
                if (sigint_caught()) {
-                       r = 0;
+                       ret = 0;
                        stack;
                        break;
                }
                if (!lvmetad_pvscan_single(cmd, dev, handler, ignore_obsolete))
-                       r = 0;
+                       ret = 0;
        }
 
        init_silent(was_silent);
 
        dev_iter_destroy(iter);
 
+       if (!ret)
+               lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_SCANERROR);
+
        _lvmetad_token = future_token;
-       if (!_token_update(NULL))
+       if (!_token_update(NULL)) {
+               log_error("Failed to update lvmetad token after device scan.");
                return 0;
+       }
 
        /*
         * If lvmetad is disabled, and no lvm1 metadata was seen and no
         * duplicate PVs were seen, then re-enable lvmetad.
         */
-       if (lvmetad_is_disabled(cmd, &reason) &&
+       if (ret && lvmetad_is_disabled(cmd, &reason) &&
            !lvmcache_found_duplicate_pvs() && !_found_lvm1_metadata) {
                log_debug_lvmetad("Enabling lvmetad which was previously disabled.");
                lvmetad_clear_disabled(cmd);
        }
 
-       return r;
+       return ret;
 }
 
 int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler, int do_wait)
@@ -2451,6 +2451,9 @@ int lvmetad_is_disabled(struct cmd_context *cmd, const char **reason)
                } else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_DUPLICATES)) {
                        *reason = "duplicate PVs were found";
 
+               } else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_SCANERROR)) {
+                       *reason = "scanning devices failed";
+
                } else {
                        *reason = "<unknown>";
                }
This page took 0.156036 seconds and 5 git commands to generate.