Exemple #1
0
int config_file_read(struct dm_config_tree *cft)
{
	const char *filename = NULL;
	struct config_file *cf = dm_config_get_custom(cft);
	struct stat info;
	int r;

	if (!config_file_check(cft, &filename, &info))
		return_0;

	/* Nothing to do.  E.g. empty file. */
	if (!filename)
		return 1;

	if (!cf->dev) {
		if (!(cf->dev = dev_create_file(filename, NULL, NULL, 1)))
			return_0;

		if (!dev_open_readonly_buffered(cf->dev))
			return_0;
	}

	r = config_file_read_fd(cft, cf->dev, 0, (size_t) info.st_size, 0, 0,
				(checksum_fn_t) NULL, 0);

	if (!cf->keep_open) {
		if (!dev_close(cf->dev))
			stack;
		cf->dev = NULL;
	}

	return r;
}
Exemple #2
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 #3
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 #4
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 #5
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;
}