Exemple #1
0
struct volume_group *import_vg_from_config_tree(const struct dm_config_tree *cft,
						struct format_instance *fid)
{
	struct volume_group *vg = NULL;
	struct text_vg_version_ops **vsn;
	int vg_missing;

	_init_text_import();

	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
		if (!(*vsn)->check_version(cft))
			continue;
		/*
		 * The only path to this point uses cached vgmetadata,
		 * so it can use cached PV state too.
		 */
		if (!(vg = (*vsn)->read_vg(fid, cft, 1)))
			stack;
		else if ((vg_missing = vg_missing_pv_count(vg))) {
			log_verbose("There are %d physical volumes missing.",
				    vg_missing);
			vg_mark_partial_lvs(vg, 1);
			/* FIXME: move this code inside read_vg() */
		}
		break;
	}

	return vg;
}
struct volume_group *import_vg_from_buffer(char *buf,
                                           struct format_instance *fid)
{
	struct volume_group *vg = NULL;
	struct config_tree *cft;
	struct text_vg_version_ops **vsn;

	_init_text_import();

	if (!(cft = create_config_tree_from_string(fid->fmt->cmd, buf)))
		return_NULL;

	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
		if (!(*vsn)->check_version(cft))
			continue;
		/*
		 * The only path to this point uses cached vgmetadata,
		 * so it can use cached PV state too.
		 */
		if (!(vg = (*vsn)->read_vg(fid, cft, 1)))
			stack;
		break;
	}

	destroy_config_tree(cft);
	return vg;
}
Exemple #3
0
struct volume_group *text_vg_import_fd(struct format_instance *fid,
				       const char *file,
				       int single_device,
				       struct device *dev,
				       off_t offset, uint32_t size,
				       off_t offset2, uint32_t size2,
				       checksum_fn_t checksum_fn,
				       uint32_t checksum,
				       time_t *when, char **desc)
{
	struct volume_group *vg = NULL;
	struct dm_config_tree *cft;
	struct text_vg_version_ops **vsn;

	_init_text_import();

	*desc = NULL;
	*when = 0;

	if (!(cft = config_open(CONFIG_FILE, file, 0)))
		return_NULL;

	if ((!dev && !config_file_read(cft)) ||
	    (dev && !config_file_read_fd(cft, dev, offset, size,
					 offset2, size2, checksum_fn, checksum))) {
		log_error("Couldn't read volume group metadata.");
		goto out;
	}

	/*
	 * Find a set of version functions that can read this file
	 */
	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
		if (!(*vsn)->check_version(cft))
			continue;

		if (!(vg = (*vsn)->read_vg(fid, cft, single_device)))
			goto_out;

		(*vsn)->read_desc(vg->vgmem, cft, when, desc);
		break;
	}

      out:
	config_destroy(cft);
	return vg;
}
Exemple #4
0
const char *text_vgname_import(const struct format_type *fmt,
			       struct device *dev,
			       off_t offset, uint32_t size,
			       off_t offset2, uint32_t size2,
			       checksum_fn_t checksum_fn, uint32_t checksum,
			       struct id *vgid, uint64_t *vgstatus,
			       char **creation_host)
{
	struct dm_config_tree *cft;
	struct text_vg_version_ops **vsn;
	const char *vgname = NULL;

	_init_text_import();

	if (!(cft = config_open(CONFIG_FILE, NULL, 0)))
		return_NULL;

	if ((!dev && !config_file_read(cft)) ||
	    (dev && !config_file_read_fd(cft, dev, offset, size,
					 offset2, size2, checksum_fn, checksum)))
		goto_out;

	/*
	 * Find a set of version functions that can read this file
	 */
	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
		if (!(*vsn)->check_version(cft))
			continue;

		if (!(vgname = (*vsn)->read_vgname(fmt, cft, vgid, vgstatus,
						   creation_host)))
			goto_out;

		break;
	}

      out:
	config_destroy(cft);
	return vgname;
}
Exemple #5
0
struct volume_group *import_vg_from_buffer(char *buf,
                                           struct format_instance *fid)
{
	struct volume_group *vg = NULL;
	struct config_tree *cft;
	struct text_vg_version_ops **vsn;

	_init_text_import();

	if (!(cft = create_config_tree_from_string(fid->fmt->cmd, buf)))
		return_NULL;

	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
		if (!(*vsn)->check_version(cft))
			continue;
		if (!(vg = (*vsn)->read_vg(fid, cft)))
			stack;
		break;
	}

	destroy_config_tree(cft);
	return vg;
}
Exemple #6
0
/*
 * Find out vgname on a given device.
 */
int text_read_metadata_summary(const struct format_type *fmt,
		       struct device *dev, dev_io_reason_t reason,
		       off_t offset, uint32_t size,
		       off_t offset2, uint32_t size2,
		       checksum_fn_t checksum_fn,
		       int checksum_only,
		       struct lvmcache_vgsummary *vgsummary)
{
	struct dm_config_tree *cft;
	struct text_vg_version_ops **vsn;
	int r = 0;

	_init_text_import();

	if (!(cft = config_open(CONFIG_FILE_SPECIAL, NULL, 0)))
		return_0;

	if (dev) {
		log_debug_metadata("Reading metadata summary from %s at %llu size %d (+%d)",
				   dev_name(dev), (unsigned long long)offset,
				   size, size2);

		if (!config_file_read_fd(cft, dev, reason, offset, size,
					 offset2, size2, checksum_fn,
					 vgsummary->mda_checksum,
					 checksum_only, 1)) {
			/* FIXME: handle errors */
			log_error("Couldn't read volume group metadata from %s.", dev_name(dev));
			goto out;
		}
	} else {
		if (!config_file_read(cft)) {
			log_error("Couldn't read volume group metadata from file.");
			goto out;
		}
	}

	if (checksum_only) {
		/* Checksum matches already-cached content - no need to reparse. */
		log_debug_metadata("Skipped parsing metadata on %s", dev_name(dev));
		r = 1;
		goto out;
	}

	/*
	 * Find a set of version functions that can read this file
	 */
	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
		if (!(*vsn)->check_version(cft))
			continue;

		if (!(*vsn)->read_vgsummary(fmt, cft, vgsummary))
			goto_out;

		r = 1;
		break;
	}

      out:
	config_destroy(cft);
	return r;
}
Exemple #7
0
struct volume_group *text_read_metadata(struct format_instance *fid,
				       const char *file,
				       struct cached_vg_fmtdata **vg_fmtdata,
				       unsigned *use_previous_vg,
				       struct device *dev, int primary_mda,
				       off_t offset, uint32_t size,
				       off_t offset2, uint32_t size2,
				       checksum_fn_t checksum_fn,
				       uint32_t checksum,
				       time_t *when, char **desc)
{
	struct volume_group *vg = NULL;
	struct dm_config_tree *cft;
	struct text_vg_version_ops **vsn;
	int skip_parse;

	/*
	 * This struct holds the checksum and size of the VG metadata
	 * that was read from a previous device.  When we read the VG
	 * metadata from this device, we can skip parsing it into a
	 * cft (saving time) if the checksum of the metadata buffer
	 * we read from this device matches the size/checksum saved in
	 * the mda_header/rlocn struct on this device, and matches the
	 * size/checksum from the previous device.
	 */
	if (vg_fmtdata && !*vg_fmtdata &&
	    !(*vg_fmtdata = dm_pool_zalloc(fid->mem, sizeof(**vg_fmtdata)))) {
		log_error("Failed to allocate VG fmtdata for text format.");
		return NULL;
	}

	_init_text_import();

	*desc = NULL;
	*when = 0;

	if (!(cft = config_open(CONFIG_FILE_SPECIAL, file, 0)))
		return_NULL;

	/* Does the metadata match the already-cached VG? */
	skip_parse = vg_fmtdata && 
		     ((*vg_fmtdata)->cached_mda_checksum == checksum) &&
		     ((*vg_fmtdata)->cached_mda_size == (size + size2));


	if (dev) {
		log_debug_metadata("Reading metadata from %s at %llu size %d (+%d)",
				   dev_name(dev), (unsigned long long)offset,
				   size, size2);

		if (!config_file_read_fd(cft, dev, MDA_CONTENT_REASON(primary_mda), offset, size,
					 offset2, size2, checksum_fn, checksum,
					 skip_parse, 1)) {
			/* FIXME: handle errors */
			log_error("Couldn't read volume group metadata from %s.", dev_name(dev));
			goto out;
		}
	} else {
		if (!config_file_read(cft)) {
			log_error("Couldn't read volume group metadata from file.");
			goto out;
		}
	}

	if (skip_parse) {
		if (use_previous_vg)
			*use_previous_vg = 1;
		log_debug_metadata("Skipped parsing metadata on %s", dev_name(dev));
		goto out;
	}

	/*
	 * Find a set of version functions that can read this file
	 */
	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
		if (!(*vsn)->check_version(cft))
			continue;

		if (!(vg = (*vsn)->read_vg(fid, cft, 0)))
			goto_out;

		(*vsn)->read_desc(vg->vgmem, cft, when, desc);
		break;
	}

	if (vg && vg_fmtdata && *vg_fmtdata) {
		(*vg_fmtdata)->cached_mda_size = (size + size2);
		(*vg_fmtdata)->cached_mda_checksum = checksum;
	}

	if (use_previous_vg)
		*use_previous_vg = 0;

      out:
	config_destroy(cft);
	return vg;
}