summaryrefslogtreecommitdiff
path: root/lib/metadata
diff options
context:
space:
mode:
Diffstat (limited to 'lib/metadata')
-rw-r--r--lib/metadata/metadata-exported.h2
-rw-r--r--lib/metadata/metadata.c96
-rw-r--r--lib/metadata/vg.c16
-rw-r--r--lib/metadata/vg.h1
4 files changed, 108 insertions, 7 deletions
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index bf6f1c122..7c2dcefb2 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -161,6 +161,7 @@
#define FAILED_CLUSTERED 0x00000040U
#define FAILED_ALLOCATION 0x00000080U
#define FAILED_EXIST 0x00000100U
+#define FAILED_SYSTEMID 0x00000200U
#define SUCCESS 0x00000000U
#define VGMETADATACOPIES_ALL UINT32_MAX
@@ -1145,6 +1146,7 @@ struct vgcreate_params {
alloc_policy_t alloc;
int clustered; /* FIXME: put this into a 'status' variable instead? */
uint32_t vgmetadatacopies;
+ const char *system_id;
};
int validate_major_minor(const struct cmd_context *cmd,
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 9308cb739..2057ada66 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4223,6 +4223,94 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
return (struct volume_group *)vg;
}
+static int allow_system_id(struct cmd_context *cmd, const char *system_id)
+{
+ const struct dm_config_node *cn;
+ const struct dm_config_value *cv;
+ const char *str;
+
+ if (!(cn = find_config_tree_node(cmd, local_allow_system_id_CFG, NULL)))
+ return 0;
+
+ for (cv = cn->v; cv; cv = cv->next) {
+ if (cv->type == DM_CFG_EMPTY_ARRAY)
+ break;
+ if (cv->type != DM_CFG_STRING) {
+ log_error("Ignoring invalid string in allow_system_id list");
+ continue;
+ }
+ str = cv->v.str;
+ if (!*str) {
+ log_error("Ignoring empty string in config file");
+ continue;
+ }
+
+ if (!strcmp(str, system_id))
+ return 1;
+ }
+
+ return 0;
+}
+
+static int _access_vg_clustered(struct cmd_context *cmd, struct volume_group *vg)
+{
+ if (vg_is_clustered(vg) && !locking_is_clustered()) {
+ if (!cmd->ignore_clustered_vgs)
+ log_error("Skipping clustered volume group %s", vg->name);
+ else
+ log_verbose("Skipping clustered volume group %s", vg->name);
+ return 0;
+ }
+ return 1;
+}
+
+static int _access_vg_systemid(struct cmd_context *cmd, struct volume_group *vg)
+{
+ if (cmd->skip_systemid_check)
+ return 1;
+
+ if (vg->system_id && vg->system_id[0] && cmd->unknown_system_id)
+ goto fail;
+
+ if (vg->system_id && vg->system_id[0] && cmd->system_id && cmd->system_id[0]) {
+ if (!strcmp(vg->system_id, cmd->system_id))
+ return 1;
+ if (allow_system_id(cmd, vg->system_id))
+ return 1;
+ goto fail;
+ }
+
+ return 1;
+
+fail:
+ if (find_config_tree_bool(cmd, log_silent_other_systemid_CFG, NULL))
+ return 0;
+ log_warn("Cannot access VG %s with system id \"%s\" from local system id \"%s\"",
+ vg->name, vg->system_id, cmd->system_id ?: "unknown");
+ return 0;
+}
+
+/*
+ * FIXME: move _vg_bad_status_bits() checks in here.
+ */
+static int _access_vg(struct cmd_context *cmd, struct volume_group *vg, uint32_t *failure)
+{
+ if (!is_real_vg(vg->name))
+ return 1;
+
+ if (!_access_vg_clustered(cmd, vg)) {
+ *failure |= FAILED_CLUSTERED;
+ return 0;
+ }
+
+ if (!_access_vg_systemid(cmd, vg)) {
+ *failure |= FAILED_SYSTEMID;
+ return 0;
+ }
+
+ return 1;
+}
+
/*
* Consolidated locking, reading, and status flag checking.
*
@@ -4282,14 +4370,8 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
goto bad;
}
- if (vg_is_clustered(vg) && !locking_is_clustered()) {
- if (!cmd->ignore_clustered_vgs)
- log_error("Skipping clustered volume group %s", vg->name);
- else
- log_verbose("Skipping clustered volume group %s", vg->name);
- failure |= FAILED_CLUSTERED;
+ if (!_access_vg(cmd, vg, &failure))
goto bad;
- }
/* consistent == 0 when VG is not found, but failed == FAILED_NOTFOUND */
if (!consistent && !failure) {
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 71b894b8f..57c9acfd9 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -603,6 +603,22 @@ int vg_set_clustered(struct volume_group *vg, int clustered)
return 1;
}
+/* The input string has already been validated. */
+
+int vg_set_system_id(struct volume_group *vg, const char *system_id)
+{
+ if (!system_id) {
+ vg->system_id = NULL;
+ return 1;
+ }
+
+ if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) {
+ log_error("vg_set_system_id no mem");
+ return 0;
+ }
+ return 1;
+}
+
char *vg_attr_dup(struct dm_pool *mem, const struct volume_group *vg)
{
char *repstr;
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index fffe9a7d5..23d60acdd 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -144,6 +144,7 @@ uint32_t vg_seqno(const struct volume_group *vg);
uint64_t vg_status(const struct volume_group *vg);
int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc);
int vg_set_clustered(struct volume_group *vg, int clustered);
+int vg_set_system_id(struct volume_group *vg, const char *system_id);
uint64_t vg_size(const struct volume_group *vg);
uint64_t vg_free(const struct volume_group *vg);
uint64_t vg_extent_size(const struct volume_group *vg);