diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/commands/toolcontext.c | 139 | ||||
-rw-r--r-- | lib/commands/toolcontext.h | 6 | ||||
-rw-r--r-- | lib/config/config_settings.h | 8 | ||||
-rw-r--r-- | lib/config/defaults.h | 1 | ||||
-rw-r--r-- | lib/metadata/metadata-exported.h | 2 | ||||
-rw-r--r-- | lib/metadata/metadata.c | 96 | ||||
-rw-r--r-- | lib/metadata/vg.c | 16 | ||||
-rw-r--r-- | lib/metadata/vg.h | 1 | ||||
-rw-r--r-- | lib/misc/lvm-string.c | 35 | ||||
-rw-r--r-- | lib/misc/lvm-string.h | 2 | ||||
-rw-r--r-- | lib/report/columns.h | 3 | ||||
-rw-r--r-- | lib/report/properties.c | 2 |
12 files changed, 299 insertions, 12 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 diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h index a6c1d1b04..85974b78f 100644 --- a/lib/config/config_settings.h +++ b/lib/config/config_settings.h @@ -82,6 +82,7 @@ cfg_section(metadata_CFG_SECTION, "metadata", root_CFG_SECTION, CFG_ADVANCED, vs cfg_section(report_CFG_SECTION, "report", root_CFG_SECTION, CFG_ADVANCED | CFG_PROFILABLE, vsn(1, 0, 0), NULL) cfg_section(dmeventd_CFG_SECTION, "dmeventd", root_CFG_SECTION, 0, vsn(1, 2, 3), NULL) cfg_section(tags_CFG_SECTION, "tags", root_CFG_SECTION, 0, vsn(1, 0, 18), NULL) +cfg_section(local_CFG_SECTION, "local", root_CFG_SECTION, 0, vsn(2, 2, 112), NULL) cfg(config_checks_CFG, "checks", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 99), "Configuration tree check on each LVM command execution.") cfg(config_abort_on_errors_CFG, "abort_on_errors", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2,2,99), "Abort LVM command execution if configuration is invalid.") @@ -141,6 +142,7 @@ cfg(log_prefix_CFG, "prefix", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, cfg(log_activation_CFG, "activation", log_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL) cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL) cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sactivation#Sallocation#Slvmetad#Smetadata#Scache#Slocking", vsn(2, 2, 99), NULL) +cfg(log_silent_other_systemid_CFG, "silent_other_systemid", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SILENT, vsn(2, 2, 112), NULL) cfg(backup_backup_CFG, "backup", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_BACKUP_ENABLED, vsn(1, 0, 0), NULL) cfg_runtime(backup_backup_dir_CFG, "backup_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), NULL) @@ -162,6 +164,7 @@ cfg(global_format_CFG, "format", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL) cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL) cfg(global_proc_CFG, "proc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PROC_DIR, vsn(1, 0, 0), NULL) +cfg(global_etc_CFG, "etc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ETC_DIR, vsn(2, 2, 112), NULL) cfg(global_locking_type_CFG, "locking_type", global_CFG_SECTION, 0, CFG_TYPE_INT, 1, vsn(1, 0, 0), NULL) cfg(global_wait_for_locks_CFG, "wait_for_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_WAIT_FOR_LOCKS, vsn(2, 2, 50), NULL) cfg(global_fallback_to_clustered_locking_CFG, "fallback_to_clustered_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING, vsn(2, 2, 42), NULL) @@ -188,6 +191,8 @@ cfg_array(global_cache_check_options_CFG, "cache_check_options", global_CFG_SECT cfg(global_cache_dump_executable_CFG, "cache_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_DUMP_CMD, vsn(2, 2, 108), NULL) cfg(global_cache_repair_executable_CFG, "cache_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_REPAIR_CMD, vsn(2, 2, 108), NULL) cfg_array(global_cache_repair_options_CFG, "cache_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_REPAIR_OPTIONS, vsn(2, 2, 108), NULL) +cfg(global_system_id_source_CFG, "system_id_source", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 112), NULL) +cfg(global_system_id_file_CFG, "system_id_file", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 112), NULL) cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION_CHECKS, vsn(2, 2, 86), NULL) cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL) @@ -272,4 +277,7 @@ cfg(tags_hosttags_CFG, "hosttags", tags_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_H cfg_section(tag_CFG_SUBSECTION, "tag", tags_CFG_SECTION, CFG_NAME_VARIABLE | CFG_DEFAULT_UNDEFINED, vsn(1, 0, 18), NULL) cfg(tag_host_list_CFG, "host_list", tag_CFG_SUBSECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL) +cfg(local_system_id_CFG, "system_id", local_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 112), NULL) +cfg_array(local_allow_system_id_CFG, "allow_system_id", local_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 112), NULL) + cfg(CFG_COUNT, NULL, root_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(0, 0, 0), NULL) diff --git a/lib/config/defaults.h b/lib/config/defaults.h index 2cb1e5aa9..30f09a369 100644 --- a/lib/config/defaults.h +++ b/lib/config/defaults.h @@ -29,6 +29,7 @@ #define DEFAULT_DEV_DIR "/dev" #define DEFAULT_PROC_DIR "/proc" +#define DEFAULT_ETC_DIR "/etc" #define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 1 #define DEFAULT_SYSFS_SCAN 1 #define DEFAULT_MD_COMPONENT_DETECTION 1 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); diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c index 84c870837..f4c7110a0 100644 --- a/lib/misc/lvm-string.c +++ b/lib/misc/lvm-string.c @@ -101,6 +101,41 @@ int validate_name(const char *n) return (_validate_name(n) == NAME_VALID) ? 1 : 0; } +/* + * Copy valid characters from source to destination. + * Invalid characters are skipped. Copying is stopped + * when NAME_LEN characters have been copied. + */ + +void copy_valid_chars(const char *src, char *dst) +{ + const char *s = src; + char *d = dst; + int len = 0; + int i; + char c; + + if (!s || !*s) + return; + + for (i = 0; i < strlen(src); i++) { + c = *s; + + if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+') { + s++; + continue; + } + + *d = *s; + d++; + s++; + len++; + + if (len == NAME_LEN) + break; + } +} + static const char *_lvname_has_reserved_prefix(const char *lvname) { static const char _prefixes[][12] = { diff --git a/lib/misc/lvm-string.h b/lib/misc/lvm-string.h index 6a13e9ea4..0615f41cd 100644 --- a/lib/misc/lvm-string.h +++ b/lib/misc/lvm-string.h @@ -44,6 +44,8 @@ int validate_name(const char *n); name_error_t validate_name_detailed(const char *n); int validate_tag(const char *n); +void copy_valid_chars(const char *src, char *dst); + int apply_lvname_restrictions(const char *name); int is_reserved_lvname(const char *name); diff --git a/lib/report/columns.h b/lib/report/columns.h index a2f34f928..a7cc82816 100644 --- a/lib/report/columns.h +++ b/lib/report/columns.h @@ -130,7 +130,8 @@ FIELD(VGS, vg, STR, "AllocPol", cmd, 10, vgallocationpolicy, vg_allocation_polic FIELD(VGS, vg, BIN, "Clustered", cmd, 10, vgclustered, vg_clustered, "Set if VG is clustered.", 0) FIELD(VGS, vg, SIZ, "VSize", cmd, 5, vgsize, vg_size, "Total size of VG in current units.", 0) FIELD(VGS, vg, NUM, "VFree", cmd, 5, vgfree, vg_free, "Total amount of free space in current units.", 0) -FIELD(VGS, vg, STR, "SYS ID", system_id, 6, string, vg_sysid, "System ID indicating when and where it was created.", 0) +FIELD(VGS, vg, STR, "SYS ID", system_id, 6, string, vg_sysid, "System ID of the VG.", 0) +FIELD(VGS, vg, STR, "System ID", system_id, 9, string, vg_systemid, "System ID of the VG.", 0) FIELD(VGS, vg, SIZ, "Ext", extent_size, 3, size32, vg_extent_size, "Size of Physical Extents in current units.", 0) FIELD(VGS, vg, NUM, "#Ext", extent_count, 4, uint32, vg_extent_count, "Total number of Physical Extents.", 0) FIELD(VGS, vg, NUM, "Free", free_count, 4, uint32, vg_free_count, "Total number of unallocated Physical Extents.", 0) diff --git a/lib/report/properties.c b/lib/report/properties.c index 8f4f47250..e14b2d2c9 100644 --- a/lib/report/properties.c +++ b/lib/report/properties.c @@ -320,6 +320,8 @@ GET_VG_NUM_PROPERTY_FN(vg_free, (SECTOR_SIZE * vg_free(vg))) #define _vg_free_set prop_not_implemented_set GET_VG_STR_PROPERTY_FN(vg_sysid, vg_system_id_dup(vg)) #define _vg_sysid_set prop_not_implemented_set +GET_VG_STR_PROPERTY_FN(vg_systemid, vg_system_id_dup(vg)) +#define _vg_systemid_set prop_not_implemented_set GET_VG_NUM_PROPERTY_FN(vg_extent_size, (SECTOR_SIZE * vg->extent_size)) #define _vg_extent_size_set prop_not_implemented_set GET_VG_NUM_PROPERTY_FN(vg_extent_count, vg->extent_count) |