summaryrefslogtreecommitdiff
path: root/lib/commands
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2014-10-10 15:46:35 -0500
committerDavid Teigland <teigland@redhat.com>2014-10-17 16:58:50 -0500
commit3e7915b20aa95759c7e4b92b8cf58de336ac6182 (patch)
tree681d2b3b8c4199d10b9af6008f5dee88e30ccdc5 /lib/commands
parent4461c624bc59ddca60f4bbf1eb447d64c8d4aeb2 (diff)
downloadlvm2-dev-dct-systemid2.tar.gz
system_id: use for VG ownershipdev-dct-systemid2
See included lvmsystemid(7) for full description.
Diffstat (limited to 'lib/commands')
-rw-r--r--lib/commands/toolcontext.c139
-rw-r--r--lib/commands/toolcontext.h6
2 files changed, 141 insertions, 4 deletions
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index e38aa5634..924c7b217 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -55,6 +55,89 @@
static const size_t linebuffer_size = 4096;
+
+/* Copy the input string, removing invalid characters. */
+
+char *system_id_from_string(struct cmd_context *cmd, const char *str)
+{
+ char *system_id;
+
+ if (!(system_id = dm_pool_zalloc(cmd->mem, strlen(str) + 1)))
+ return NULL;
+
+ copy_valid_chars(str, system_id);
+
+ if (!system_id[0])
+ return NULL;
+
+ return system_id;
+}
+
+static char *_read_system_id_from_file(struct cmd_context *cmd, const char *file)
+{
+ char line[NAME_LEN + 1];
+ FILE *fp;
+
+ if (!file || !strlen(file) || !file[0])
+ return NULL;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return NULL;
+
+ memset(line, 0, sizeof(line));
+
+ while (fgets(line, NAME_LEN, fp)) {
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ fclose(fp);
+ return system_id_from_string(cmd, line);
+ }
+
+ fclose(fp);
+ return NULL;
+}
+
+char *system_id_from_source(struct cmd_context *cmd, const char *source)
+{
+ struct utsname uts;
+ char filebuf[PATH_MAX];
+ const char *file;
+ const char *etc_str;
+ const char *str;
+ char *system_id = NULL;
+
+ if (!strcmp(source, "uname")) {
+ if (!uname(&uts) && strncmp(uts.nodename, "localhost", 9))
+ system_id = system_id_from_string(cmd, uts.nodename);
+ goto out;
+ }
+
+ /* lvm.conf and lvm-local.conf are merged into one config tree */
+ if (!strcmp(source, "lvmlocal")) {
+ if ((str = find_config_tree_str(cmd, local_system_id_CFG, NULL)))
+ system_id = system_id_from_string(cmd, str);
+ goto out;
+ }
+
+ if (!strcmp(source, "machineid")) {
+ memset(filebuf, 0, sizeof(filebuf));
+ etc_str = find_config_tree_str(cmd, global_etc_CFG, NULL);
+ if (dm_snprintf(filebuf, sizeof(filebuf), "%s/machine-id", etc_str) >= 0)
+ system_id = _read_system_id_from_file(cmd, filebuf);
+ goto out;
+ }
+
+ if (!strcmp(source, "file")) {
+ file = find_config_tree_str(cmd, global_system_id_file_CFG, NULL);
+ system_id = _read_system_id_from_file(cmd, file);
+ goto out;
+ }
+out:
+ return system_id;
+}
+
static int _get_env_vars(struct cmd_context *cmd)
{
const char *e;
@@ -561,7 +644,7 @@ static int _init_tags(struct cmd_context *cmd, struct dm_config_tree *cft)
return 1;
}
-static int _load_config_file(struct cmd_context *cmd, const char *tag)
+static int _load_config_file(struct cmd_context *cmd, const char *tag, int local)
{
static char config_file[PATH_MAX] = "";
const char *filler = "";
@@ -569,6 +652,10 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
if (*tag)
filler = "_";
+ else if (local) {
+ filler = "-";
+ tag = "local";
+ }
if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
cmd->system_dir, filler, tag) < 0) {
@@ -596,7 +683,13 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
return 1;
}
-/* Find and read first config file */
+/*
+ * Find and read lvm.conf and lvm-local.conf
+ *
+ * lvm-local.conf is independent of any tag-based configs
+ * because it uses "-" instead of "_".
+ */
+
static int _init_lvm_conf(struct cmd_context *cmd)
{
/* No config file if LVM_SYSTEM_DIR is empty */
@@ -608,9 +701,11 @@ static int _init_lvm_conf(struct cmd_context *cmd)
return 1;
}
- if (!_load_config_file(cmd, ""))
+ if (!_load_config_file(cmd, "", 0))
return_0;
+ _load_config_file(cmd, "", 1);
+
return 1;
}
@@ -621,7 +716,7 @@ static int _init_tag_configs(struct cmd_context *cmd)
/* Tag list may grow while inside this loop */
dm_list_iterate_items(sl, &cmd->tags) {
- if (!_load_config_file(cmd, sl->str))
+ if (!_load_config_file(cmd, sl->str, 0))
return_0;
}
@@ -1335,6 +1430,39 @@ static int _init_hostname(struct cmd_context *cmd)
return 1;
}
+static int _init_system_id(struct cmd_context *cmd)
+{
+ const char *source;
+ int local_set;
+
+ cmd->system_id = NULL;
+
+ local_set = !!find_config_tree_str(cmd, local_system_id_CFG, NULL);
+
+ source = find_config_tree_str(cmd, global_system_id_source_CFG, NULL);
+ if (!source)
+ source = "none";
+
+ /* Defining local system_id but not using it is probably a config mistake. */
+ if (local_set && strcmp(source, "lvmlocal"))
+ log_warn("Local system_id is not used by system_id_source %s.", source);
+
+ if (!strcmp(source, "none"))
+ return 1;
+
+ if ((cmd->system_id = system_id_from_source(cmd, source)))
+ return 1;
+
+ /*
+ * The source failed to resolve a system_id. In this case allow
+ * VGs with no system_id to be accessed, but not VGs with a system_id.
+ */
+
+ log_warn("No system_id found from system_id_source %s.", source);
+ cmd->unknown_system_id = 1;
+ return 1;
+}
+
static int _init_backup(struct cmd_context *cmd)
{
uint32_t days, min;
@@ -1563,6 +1691,9 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (!_init_profiles(cmd))
goto_out;
+ if (!_init_system_id(cmd))
+ goto_out;
+
if (!(cmd->dev_types = create_dev_types(cmd->proc_dir,
find_config_tree_node(cmd, devices_types_CFG, NULL))))
goto_out;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index d99cc280b..4c2f89b24 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -71,6 +71,7 @@ struct cmd_context {
struct dm_list formats; /* Available formats */
struct dm_list segtypes; /* Available segment types */
+ const char *system_id;
const char *hostname;
const char *kernel_vsn;
@@ -95,6 +96,8 @@ struct cmd_context {
unsigned threaded:1; /* Set if running within a thread e.g. clvmd */
unsigned independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
+ unsigned unknown_system_id:1;
+ unsigned skip_systemid_check:1;
struct dev_types *dev_types;
@@ -160,4 +163,7 @@ int init_lvmcache_orphans(struct cmd_context *cmd);
struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format);
+char *system_id_from_source(struct cmd_context *cmd, const char *system_id_source);
+char *system_id_from_string(struct cmd_context *cmd, const char *system_id_string);
+
#endif