summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2016-06-08 16:28:16 -0500
committerDavid Teigland <teigland@redhat.com>2016-06-09 11:44:42 -0500
commit21d9df6c6fd950da38da54f1cbc834a5a2b30efd (patch)
treeb9974475e6b487d9348af825ebdcca66901d1144
parent6bd891865b12aa15b076ae2f7fddd1f9ba6d8469 (diff)
downloadlvm2-21d9df6c6fd950da38da54f1cbc834a5a2b30efd.tar.gz
vgcfgrestore: improve lvmetad handling
Previously, vgcfgrestore would attempt to vg_remove the existing VG from lvmetad and then vg_update to add the restored VG. But, if there was a failure in the command or with vg_update, the lvmetad cache would be left incorrect. Now, disable lvmetad before the restore begins, and then rescan to populate lvmetad from disk after restore has written the new VG to disk.
-rw-r--r--daemons/lvmetad/lvmetad-client.h1
-rw-r--r--daemons/lvmetad/lvmetad-core.c10
-rw-r--r--lib/cache/lvmetad.c3
-rw-r--r--lib/format_text/archiver.c27
-rw-r--r--lib/format_text/archiver.h4
-rw-r--r--tools/vgcfgrestore.c32
-rw-r--r--tools/vgconvert.c2
7 files changed, 46 insertions, 33 deletions
diff --git a/daemons/lvmetad/lvmetad-client.h b/daemons/lvmetad/lvmetad-client.h
index b352c0449..dd6a379ad 100644
--- a/daemons/lvmetad/lvmetad-client.h
+++ b/daemons/lvmetad/lvmetad-client.h
@@ -24,6 +24,7 @@
#define LVMETAD_DISABLE_REASON_DIRECT "DIRECT"
#define LVMETAD_DISABLE_REASON_LVM1 "LVM1"
#define LVMETAD_DISABLE_REASON_DUPLICATES "DUPLICATES"
+#define LVMETAD_DISABLE_REASON_VGRESTORE "VGRESTORE"
struct volume_group;
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 52387b1e5..1ec9e3bf2 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -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_VGRESTORE 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_VGRESTORE)
#define VGFL_INVALID 0x00000001
@@ -2347,6 +2348,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_VGRESTORE))
+ reason_flags |= GLFL_DISABLE_REASON_VGRESTORE;
}
if (global_invalid != -1) {
@@ -2404,10 +2407,11 @@ static response get_global_info(lvmetad_state *s, request r)
pid = (int)daemon_request_int(r, "pid", 0);
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_VGRESTORE) ? LVMETAD_DISABLE_REASON_VGRESTORE "," : "");
}
if (!reason[0])
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 7cd3fac50..04140db7b 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -2685,6 +2685,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_VGRESTORE)) {
+ *reason = "vgcfgrestore is restoring VG metadata";
+
} else {
*reason = "<unknown>";
}
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 85a43f542..2f7220036 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -18,11 +18,9 @@
#include "format-text.h"
#include "lvm-string.h"
#include "lvmcache.h"
-#include "lvmetad.h"
#include "memlock.h"
#include "toolcontext.h"
#include "locking.h"
-#include "lvmetad-client.h"
#include <unistd.h>
@@ -360,9 +358,7 @@ static int _restore_vg_should_write_pv(struct physical_volume *pv, int do_pvcrea
/* ORPHAN and VG locks held before calling this */
int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg,
- int drop_lvmetad,
- int do_pvcreate,
- struct pv_create_args *pva)
+ int do_pvcreate, struct pv_create_args *pva)
{
struct dm_list new_pvs;
struct pv_list *pvl, *new_pvl;
@@ -374,25 +370,6 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg,
uint32_t tmp_extent_size;
/*
- * lvmetad does not handle a VG being restored, which would require
- * vg_remove of the existing VG, then vg_update of the restored VG. A
- * command failure after removing the existing from lvmetad would not
- * be easily recovered from. So, disable the lvmetad cache before
- * doing the restore. After the VG is restored on disk, rescan
- * metadata from disk to populate lvmetad from scratch which will pick
- * up the VG that was restored on disk.
- */
- if (lvmetad_used()) {
- /*
- * lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_VGRESTORE);
- *
- * FIXME: set a flag to pass back through the callers saying a
- * rescan should be done at the end of the command to
- * repopulate lvmetad.
- */
- }
-
- /*
* FIXME: Check that the PVs referenced in the backup are
* not members of other existing VGs.
*/
@@ -560,7 +537,7 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
missing_pvs = vg_missing_pv_count(vg);
if (missing_pvs == 0)
- r = backup_restore_vg(cmd, vg, 1, 0, NULL);
+ r = backup_restore_vg(cmd, vg, 0, NULL);
else
log_error("Cannot restore Volume Group %s with %i PVs "
"marked as missing.", vg->name, missing_pvs);
diff --git a/lib/format_text/archiver.h b/lib/format_text/archiver.h
index 82f7620f7..e9497519d 100644
--- a/lib/format_text/archiver.h
+++ b/lib/format_text/archiver.h
@@ -53,9 +53,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
const char *vg_name, const char *file);
int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg,
- int drop_lvmetad,
- int do_pvcreate,
- struct pv_create_args *pva);
+ int do_pvcreate, struct pv_create_args *pva);
int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
const char *file, int force);
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
index 49cc92a12..f8101bd65 100644
--- a/tools/vgcfgrestore.c
+++ b/tools/vgcfgrestore.c
@@ -14,10 +14,12 @@
*/
#include "tools.h"
+#include "lvmetad-client.h"
int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
{
const char *vg_name = NULL;
+ int lvmetad_rescan = 0;
if (argc == 1) {
vg_name = skip_dev_dir(cmd, argv[0], NULL);
@@ -44,7 +46,21 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
return ECMD_PROCESSED;
}
- lvmcache_seed_infos_from_lvmetad(cmd);
+ /*
+ * lvmetad does not handle a VG being restored, which would require
+ * vg_remove of the existing VG, then vg_update of the restored VG. A
+ * command failure after removing the existing VG from lvmetad would
+ * not be easily recovered from. So, disable the lvmetad cache before
+ * doing the restore. After the VG is restored on disk, rescan
+ * metadata from disk to populate lvmetad from scratch which will pick
+ * up the VG that was restored on disk.
+ */
+
+ if (lvmetad_used()) {
+ lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_VGRESTORE);
+ lvmetad_disconnect();
+ lvmetad_rescan = 1;
+ }
if (!lock_vol(cmd, vg_name, LCK_VG_WRITE, NULL)) {
log_error("Unable to lock volume group %s", vg_name);
@@ -74,5 +90,19 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
unlock_vg(cmd, NULL, VG_ORPHANS);
unlock_vg(cmd, NULL, vg_name);
+
+ if (lvmetad_rescan) {
+ if (!lvmetad_connect(cmd)) {
+ log_warn("WARNING: Failed to connect to lvmetad.");
+ log_warn("WARNING: Update lvmetad with pvscan --cache.");
+ goto out;
+ }
+ if (!lvmetad_pvscan_all_devs(cmd, 1)) {
+ log_warn("WARNING: Failed to scan devices.");
+ log_warn("WARNING: Update lvmetad with pvscan --cache.");
+ goto out;
+ }
+ }
+out:
return ECMD_PROCESSED;
}
diff --git a/tools/vgconvert.c b/tools/vgconvert.c
index 6ae675f6d..b02702e5b 100644
--- a/tools/vgconvert.c
+++ b/tools/vgconvert.c
@@ -126,7 +126,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
log_verbose("Writing metadata for VG %s using format %s", vg_name,
cmd->fmt->name);
- if (!backup_restore_vg(cmd, vg, 0, 1, &pva)) {
+ if (!backup_restore_vg(cmd, vg, 1, &pva)) {
log_error("Conversion failed for volume group %s.", vg_name);
log_error("Use pvcreate and vgcfgrestore to repair from "
"archived metadata.");