[lvm-devel] master - lvm1: Reenable sys ID.

Marian Csontos mcsontos at redhat.com
Tue Feb 24 08:39:51 UTC 2015


Oops, apparently this does not work as expected all the time.
When lvm1 format is used with lvmetad, lvm1_system_id is NULL causing 
segfaults like here:

http://saturnin.lab.eng.brq.redhat.com:8010/lvm2-reports/Fedora_Rawhide_x86_64_KVM/1386/ndev-lvmetad:shell_lvmetad-lvm1.sh.txt

#0  0x00007fcb416417d7 in export_pv (cmd=0x7fcb41bdb030, 
mem=mem at entry=0x7fcb41c32c40, vg=vg at entry=0x7fcb41c33dd0, 
pvd=pvd at entry=0x7fcb41c3be10,
     pv=pv at entry=0x7fcb41c34148) at format1/import-export.c:159

(gdb) l
154                             return_0;
155                     strncpy((char *)pvd->vg_name, pv->vg_name, 
sizeof(pvd->vg_name));
156             }
157
158             /* Preserve existing system_id if it exists */
159             if (vg && *vg->lvm1_system_id)
160                     strncpy((char *)pvd->system_id, 
vg->lvm1_system_id, sizeof(pvd->system_id));
161
162             /* Is VG already exported or being exported? */
163             if (vg && vg_is_exported(vg)) {
(gdb) p *vg

$1 = {cmd = 0x7fcb41bdb030, vgmem = 0x7fcb41c2c6c0, fid = 
0x7fcb41c2b560, vginfo = 0x0, cmd_vgs = 0x0, cmd_missing_vgs = 0, seqno 
= 2,
   vg_ondisk = 0x7fcb41c37de0, cft_precommitted = 0x0, vg_precommitted = 
0x0, alloc = ALLOC_NORMAL, profile = 0x0, status = 780, id = {
     uuid = "fyJ5DLOsqAI3tzK92lgdqO7YFcIA0uZ1"}, name = 0x7fcb41c33efa 
"LVMTEST3295vg1", old_name = 0x0, system_id = 0x7fcb41c33f10 "", 
lvm1_system_id = 0x0,
   extent_size = 8192, extent_count = 28, free_count = 28, max_lv = 255, 
max_pv = 255, pv_count = 4, pvs = {n = 0x7fcb41c34118, p = 0x7fcb41c34598},
   pvs_to_create = {n = 0x7fcb41c33e98, p = 0x7fcb41c33e98}, lvs = {n = 
0x7fcb41c33ea8, p = 0x7fcb41c33ea8}, tags = {n = 0x7fcb41c33eb8, p = 
0x7fcb41c33eb8},
   removed_pvs = {n = 0x7fcb41c33ec8, p = 0x7fcb41c33ec8}, open_mode = 
0, read_status = 0, mda_copies = 0, hostnames = 0x7fcb41c2bd80,
   pool_metadata_spare_lv = 0x0}

agk, do you need to know more?

On 02/24/2015 12:09 AM, Alasdair Kergon wrote:
> Gitweb:        http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=df227be37cb113a1093b2ed092af582c5a900315
> Commit:        df227be37cb113a1093b2ed092af582c5a900315
> Parent:        2fc2928978bb592a6b62a18bbbb0acee10efbfe2
> Author:        Alasdair G Kergon <agk at redhat.com>
> AuthorDate:    Mon Feb 23 23:03:52 2015 +0000
> Committer:     Alasdair G Kergon <agk at redhat.com>
> CommitterDate: Mon Feb 23 23:03:52 2015 +0000
>
> lvm1: Reenable sys ID.
>
> Move the lvm1 sys ID into vg->lvm1_system_id and reenable the #if 0
> LVM1 code.  Still display the new-style system ID in the same
> reporting field, though, as only one can be set.
> Add a format feature flag FMT_SYSTEM_ON_PVS for LVM1 and disallow
> access to LVM1 VGs if a new-style system ID has been set.
> Treat the new vg->system_id as const.
> ---
>   WHATS_NEW                        |    1 +
>   lib/commands/toolcontext.c       |   10 ++++----
>   lib/commands/toolcontext.h       |    2 +-
>   lib/format1/format1.c            |    3 +-
>   lib/format1/import-export.c      |   48 +++++++++++++++-----------------------
>   lib/metadata/metadata-exported.h |    3 ++
>   lib/metadata/metadata.c          |   21 ++++++++++++++--
>   lib/metadata/vg.c                |   13 ++++++++--
>   lib/metadata/vg.h                |    3 +-
>   lib/report/columns.h             |    4 +-
>   lib/report/report.c              |   11 ++++++++
>   11 files changed, 74 insertions(+), 45 deletions(-)
>
> diff --git a/WHATS_NEW b/WHATS_NEW
> index 0ae007d..983189c 100644
> --- a/WHATS_NEW
> +++ b/WHATS_NEW
> @@ -1,5 +1,6 @@
>   Version 2.02.117 -
>   ====================================
> +  Install /etc/lvm/lvmlocal.conf template with local section for systemid.
>     Record creation_host_system_id in lvm2 metadata.
>     Reinstate recursive config file tag section processing. (2.02.99)
>     Add 'lvm systemid' to display the current system ID.
> diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
> index d81de97..7539b4a 100644
> --- a/lib/commands/toolcontext.c
> +++ b/lib/commands/toolcontext.c
> @@ -58,7 +58,7 @@ 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)
> +const char *system_id_from_string(struct cmd_context *cmd, const char *str)
>   {
>   	char *system_id;
>
> @@ -82,12 +82,12 @@ char *system_id_from_string(struct cmd_context *cmd, const char *str)
>   	return system_id;
>   }
>
> -static char *_read_system_id_from_file(struct cmd_context *cmd, const char *file)
> +static const char *_read_system_id_from_file(struct cmd_context *cmd, const char *file)
>   {
>   	char *line = NULL;
>   	size_t line_size;
>   	char *start, *end;
> -	char *system_id = NULL;
> +	const char *system_id = NULL;
>   	FILE *fp;
>
>   	if (!file || !strlen(file) || !file[0])
> @@ -132,13 +132,13 @@ static char *_read_system_id_from_file(struct cmd_context *cmd, const char *file
>   	return system_id;
>   }
>
> -static char *_system_id_from_source(struct cmd_context *cmd, const char *source)
> +static const char *_system_id_from_source(struct cmd_context *cmd, const char *source)
>   {
>   	char filebuf[PATH_MAX];
>   	const char *file;
>   	const char *etc_str;
>   	const char *str;
> -	char *system_id = NULL;
> +	const char *system_id = NULL;
>
>   	if (!strcasecmp(source, "uname")) {
>   		if (cmd->hostname)
> diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
> index 8b3e48e..8b38fb1 100644
> --- a/lib/commands/toolcontext.h
> +++ b/lib/commands/toolcontext.h
> @@ -163,6 +163,6 @@ 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_string(struct cmd_context *cmd, const char *system_id_string);
> +const char *system_id_from_string(struct cmd_context *cmd, const char *str);
>
>   #endif
> diff --git a/lib/format1/format1.c b/lib/format1/format1.c
> index b0943b1..f7df7c3 100644
> --- a/lib/format1/format1.c
> +++ b/lib/format1/format1.c
> @@ -590,7 +590,8 @@ struct format_type *init_format(struct cmd_context *cmd)
>   	fmt->alias = NULL;
>   	fmt->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME;
>   	fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE |
> -			FMT_RESTRICTED_READAHEAD | FMT_OBSOLETE;
> +			FMT_RESTRICTED_READAHEAD | FMT_OBSOLETE |
> +			FMT_SYSTEMID_ON_PVS;
>   	fmt->private = NULL;
>
>   	dm_list_init(&fmt->mda_ops);
> diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c
> index 9318945..a3c060f 100644
> --- a/lib/format1/import-export.c
> +++ b/lib/format1/import-export.c
> @@ -69,14 +69,14 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
>   	memcpy(&pv->vgid, vgd->vg_uuid, sizeof(vg->id));
>
>   	/* Store system_id from first PV if PV belongs to a VG */
> -	if (vg && !*vg->system_id)
> -		strncpy(vg->system_id, (char *)pvd->system_id, NAME_LEN);
> +	if (vg && !*vg->lvm1_system_id)
> +		strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN);
>
>   	if (vg &&
> -	    strncmp(vg->system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))
> +	    strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))
>   		    log_very_verbose("System ID %s on %s differs from %s for "
>   				     "volume group", pvd->system_id,
> -				     pv_dev_name(pv), vg->system_id);
> +				     pv_dev_name(pv), vg->lvm1_system_id);
>
>   	/*
>   	 * If exported, we still need to flag in pv->status too because
> @@ -125,19 +125,17 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
>   	return 1;
>   }
>
> -#if 0
> -static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
> +static int _lvm1_system_id(struct cmd_context *cmd, char *s, const char *prefix)
>   {
>
>   	if (dm_snprintf(s, NAME_LEN, "%s%s%lu",
>   			 prefix, cmd->hostname, time(NULL)) < 0) {
> -		log_error("Generated system_id too long");
> +		log_error("Generated LVM1 format system_id too long");
>   		return 0;
>   	}
>
>   	return 1;
>   }
> -#endif
>
>   int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute__((unused)),
>   	      struct volume_group *vg,
> @@ -158,22 +156,18 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute__((unused
>   	}
>
>   	/* Preserve existing system_id if it exists */
> -#if 0
> -	if (vg && *vg->system_id)
> -		strncpy((char *)pvd->system_id, vg->system_id, sizeof(pvd->system_id));
> -#endif
> +	if (vg && *vg->lvm1_system_id)
> +		strncpy((char *)pvd->system_id, vg->lvm1_system_id, sizeof(pvd->system_id));
>
>   	/* Is VG already exported or being exported? */
>   	if (vg && vg_is_exported(vg)) {
> -#if 0
>   		/* Does system_id need setting? */
> -		if (!*vg->system_id ||
> -		    strncmp(vg->system_id, EXPORTED_TAG,
> +		if (!*vg->lvm1_system_id ||
> +		    strncmp(vg->lvm1_system_id, EXPORTED_TAG,
>   			    sizeof(EXPORTED_TAG) - 1)) {
> -			if (!_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG))
> +			if (!_lvm1_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG))
>   				return_0;
>   		}
> -#endif
>   		if (strlen((char *)pvd->vg_name) + sizeof(EXPORTED_TAG) >
>   		    sizeof(pvd->vg_name)) {
>   			log_error("Volume group name %s too long to export",
> @@ -183,25 +177,23 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute__((unused
>   		strcat((char *)pvd->vg_name, EXPORTED_TAG);
>   	}
>
> -#if 0
>   	/* Is VG being imported? */
> -	if (vg && !vg_is_exported(vg) && *vg->system_id &&
> -	    !strncmp(vg->system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
> -		if (!_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG))
> +	if (vg && !vg_is_exported(vg) && *vg->lvm1_system_id &&
> +	    !strncmp(vg->lvm1_system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
> +		if (!_lvm1_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG))
>   			return_0;
>   	}
>
>   	/* Generate system_id if PV is in VG */
>   	if (!pvd->system_id[0])
> -		if (!_system_id(cmd, (char *)pvd->system_id, ""))
> +		if (!_lvm1_system_id(cmd, (char *)pvd->system_id, ""))
>   			return_0;
>
>   	/* Update internal system_id if we changed it */
>   	if (vg &&
> -	    (!*vg->system_id ||
> -	     strncmp(vg->system_id, (char *)pvd->system_id, sizeof(pvd->system_id))))
> -		    strncpy(vg->system_id, (char *)pvd->system_id, NAME_LEN);
> -#endif
> +	    (!*vg->lvm1_system_id ||
> +	     strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id))))
> +		    strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN);
>
>   	//pvd->pv_major = MAJOR(pv->dev);
>
> @@ -233,11 +225,9 @@ int import_vg(struct dm_pool *mem,
>   	if (!(vg->name = dm_pool_strdup(mem, (char *)dl->pvd.vg_name)))
>   		return_0;
>
> -	if (!(vg->system_id = dm_pool_zalloc(mem, NAME_LEN + 1)))
> +	if (!(vg->lvm1_system_id = dm_pool_zalloc(mem, NAME_LEN + 1)))
>   		return_0;
>
> -	*vg->system_id = '\0';
> -
>   	if (vgd->vg_status & VG_EXPORTED)
>   		vg->status |= EXPORTED_VG;
>
> diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
> index 6631b1f..2dbaaf0 100644
> --- a/lib/metadata/metadata-exported.h
> +++ b/lib/metadata/metadata-exported.h
> @@ -139,6 +139,9 @@
>   #define FMT_CONFIG_PROFILE	0x000000800U	/* Supports configuration profiles? */
>   #define FMT_OBSOLETE		0x000001000U	/* Obsolete format? */
>   #define FMT_NON_POWER2_EXTENTS	0x000002000U	/* Non-power-of-2 extent sizes? */
> +#define FMT_SYSTEMID_ON_PVS	0x000004000U	/* System ID is stored on PVs not VG */
> +
> +#define systemid_on_pvs(vg)	((vg)->fid->fmt->features & FMT_SYSTEMID_ON_PVS)
>
>   /* Mirror conversion type flags */
>   #define MIRROR_BY_SEG		0x00000001U	/* segment-by-segment mirror */
> diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
> index c04b67c..9fb289d 100644
> --- a/lib/metadata/metadata.c
> +++ b/lib/metadata/metadata.c
> @@ -1045,10 +1045,10 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
>   	}
>
>   	vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE);
> -	if (!(vg->system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1)))
> +	vg->system_id = NULL;
> +	if (!(vg->lvm1_system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1)))
>   		goto_bad;
>
> -	*vg->system_id = '\0';
>   	vg->extent_size = DEFAULT_EXTENT_SIZE * 2;
>   	vg->max_lv = DEFAULT_MAX_LV;
>   	vg->max_pv = DEFAULT_MAX_PV;
> @@ -4380,6 +4380,15 @@ static int _access_vg_clustered(struct cmd_context *cmd, struct volume_group *vg
>   static int _access_vg_systemid(struct cmd_context *cmd, struct volume_group *vg)
>   {
>   	/*
> +	 * LVM1 VGs must not be accessed if a new-style LVM2 system ID is set.
> +	 */
> +	if (cmd->system_id && systemid_on_pvs(vg)) {
> +		log_error("Cannot access VG %s with LVM1 system ID \"%s\" when host system ID is set.",
> +			  vg->name, vg->lvm1_system_id);
> +		return 0;
> +	}
> +
> +	/*
>   	 * A VG without a system_id can be accessed by anyone.
>   	 */
>   	if (!vg->system_id || !vg->system_id[0])
> @@ -4436,8 +4445,14 @@ static int _access_vg_systemid(struct cmd_context *cmd, struct volume_group *vg)
>    */
>   static int _access_vg(struct cmd_context *cmd, struct volume_group *vg, uint32_t *failure)
>   {
> -	if (!is_real_vg(vg->name))
> +	if (!is_real_vg(vg->name)) {
> +		/* Disallow use of LVM1 orphans when a host system ID is set. */
> +		if (cmd->system_id && *cmd->system_id && systemid_on_pvs(vg)) {
> +			*failure |= FAILED_SYSTEMID;
> +			return_0;
> +		}
>   		return 1;
> +	}
>
>   	if (!_access_vg_clustered(cmd, vg)) {
>   		*failure |= FAILED_CLUSTERED;
> diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
> index dbc791b..0143b7b 100644
> --- a/lib/metadata/vg.c
> +++ b/lib/metadata/vg.c
> @@ -121,7 +121,7 @@ char *vg_name_dup(const struct volume_group *vg)
>
>   char *vg_system_id_dup(const struct volume_group *vg)
>   {
> -	return dm_pool_strdup(vg->vgmem, vg->system_id);
> +	return dm_pool_strdup(vg->vgmem, vg->system_id ? : vg->lvm1_system_id ? : "");
>   }
>
>   char *vg_uuid_dup(const struct volume_group *vg)
> @@ -605,15 +605,22 @@ int vg_set_clustered(struct volume_group *vg, int clustered)
>
>   int vg_set_system_id(struct volume_group *vg, const char *system_id)
>   {
> -	if (!system_id) {
> +	if (!system_id || !*system_id) {
>   		vg->system_id = NULL;
>   		return 1;
>   	}
>
> +	if (systemid_on_pvs(vg)) {
> +		log_error("Metadata format %s does not support this type of system id.",
> +			  vg->fid->fmt->name);
> +		return 0;
> +	}
> +
>   	if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) {
> -		log_error("vg_set_system_id no mem");
> +		log_error("Failed to allocate memory for system_id in vg_set_system_id.");
>   		return 0;
>   	}
> +
>   	return 1;
>   }
>
> diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
> index 23d60ac..2964b82 100644
> --- a/lib/metadata/vg.h
> +++ b/lib/metadata/vg.h
> @@ -67,7 +67,8 @@ struct volume_group {
>   	struct id id;
>   	const char *name;
>   	const char *old_name;		/* Set during vgrename and vgcfgrestore */
> -	char *system_id;
> +	const char *system_id;
> +	char *lvm1_system_id;
>
>   	uint32_t extent_size;
>   	uint32_t extent_count;
> diff --git a/lib/report/columns.h b/lib/report/columns.h
> index 1dd56ac..a957d98 100644
> --- a/lib/report/columns.h
> +++ b/lib/report/columns.h
> @@ -139,8 +139,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, SIZ, "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 of the VG indicating its owner.", 0)
> -FIELD(VGS, vg, STR, "System ID", system_id, 9, string, vg_systemid, "System ID of the VG indicating its owner.", 0)
> +FIELD(VGS, vg, STR, "SYS ID", cmd, 6, vgsystemid, vg_sysid, "System ID of the VG indicating which host owns it.", 0)
> +FIELD(VGS, vg, STR, "System ID", cmd, 9, vgsystemid, vg_systemid, "System ID of the VG indicating which host owns it.", 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/report.c b/lib/report/report.c
> index cf3d9b6..b5418e5 100644
> --- a/lib/report/report.c
> +++ b/lib/report/report.c
> @@ -984,6 +984,16 @@ static int _vgfree_disp(struct dm_report *rh, struct dm_pool *mem,
>   	return _size64_disp(rh, mem, field, &freespace, private);
>   }
>
> +static int _vgsystemid_disp(struct dm_report *rh, struct dm_pool *mem,
> +			    struct dm_report_field *field,
> +			    const void *data, void *private)
> +{
> +	const struct volume_group *vg = (const struct volume_group *) data;
> +	const char *repstr = vg->system_id ? : vg->lvm1_system_id ? : "";
> +
> +	return _string_disp(rh, mem, field, &repstr, private);
> +}
> +
>   static int _uuid_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
>   		      struct dm_report_field *field,
>   		      const void *data, void *private __attribute__((unused)))
> @@ -1864,6 +1874,7 @@ static struct volume_group _dummy_vg = {
>   	.fid = &_dummy_fid,
>   	.name = "",
>   	.system_id = (char *) "",
> +	.lvm1_system_id = (char *) "",
>   	.pvs = DM_LIST_HEAD_INIT(_dummy_vg.pvs),
>   	.lvs = DM_LIST_HEAD_INIT(_dummy_vg.lvs),
>   	.tags = DM_LIST_HEAD_INIT(_dummy_vg.tags),
>
> --
> lvm-devel mailing list
> lvm-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/lvm-devel
>




More information about the lvm-devel mailing list