Example #1
0
static int
tapdisk_image_open_parent(td_image_t *image, td_image_t **_parent)
{
	td_image_t *parent = NULL;
	td_disk_id_t id;
	int err;

	memset(&id, 0, sizeof(id));
	id.flags = image->flags;

	err = td_get_parent_id(image, &id);
	if (err == TD_NO_PARENT) {
		err = 0;
		goto out;
	}
	if (err)
		return err;

	err = tapdisk_image_open(id.type, id.name, id.flags, &parent);
	if (err)
		return err;

out:
	*_parent = parent;
	return 0;
}
Example #2
0
static int
__tapdisk_image_open_chain(int type, const char *name, int flags,
			   struct list_head *_head, int prt_devnum)
{
	struct list_head head = LIST_HEAD_INIT(head);
	td_image_t *image;
	int err;

	err = tapdisk_image_open(type, name, flags, &image);
	if (err)
		goto fail;

	list_add_tail(&image->next, &head);

	if (unlikely(prt_devnum >= 0)) {
		char dev[32];
		snprintf(dev, sizeof(dev),
			 "%s%d", BLKTAP2_IO_DEVICE, prt_devnum);
		err = tapdisk_image_open(DISK_TYPE_AIO, dev,
					 flags|TD_OPEN_RDONLY, &image);
		if (err)
			goto fail;

		list_add_tail(&image->next, &head);
		goto done;
	}

	err = tapdisk_image_open_parents(image);
	if (err)
		goto fail;

done:
	list_splice(&head, _head);
	return 0;

fail:
	tapdisk_image_close_chain(&head);
	return err;
}
Example #3
0
int
tapdisk_vbd_add_secondary(td_vbd_t *vbd)
{
	td_image_t *leaf, *second = NULL;
	const char *path;
	int type, err;

	DPRINTF("Adding secondary image: %s\n", vbd->secondary_name);

	type = tapdisk_disktype_parse_params(vbd->secondary_name, &path);
	if (type < 0)
		return type;

	leaf = tapdisk_vbd_first_image(vbd);
	if (!leaf) {
		err = -EINVAL;
		goto fail;
	}

	err = tapdisk_image_open(type, path, leaf->flags, &second);
	if (err)
		goto fail;

	if (second->info.size != leaf->info.size) {
		EPRINTF("Secondary image size %"PRIu64" != image size %"PRIu64"\n",
			second->info.size, leaf->info.size);
		err = -EINVAL;
		goto fail;
	}

	vbd->secondary = second;
	leaf->flags |= TD_IGNORE_ENOSPC;
	if (td_flag_test(vbd->flags, TD_OPEN_STANDBY)) {
		DPRINTF("In standby mode\n");
		vbd->secondary_mode = TD_VBD_SECONDARY_STANDBY;
	} else {
		DPRINTF("In mirror mode\n");
		vbd->secondary_mode = TD_VBD_SECONDARY_MIRROR;
		/* we actually need this image to also be part of the chain, 
		 * since it may already contain data */
		list_add(&second->next, &leaf->next);
	}

	DPRINTF("Added secondary image\n");
	return 0;

fail:
	if (second)
		tapdisk_image_close(second);
	return err;
}
Example #4
0
static int
tapdisk_image_open_x_chain(const char *path, struct list_head *_head)
{
	struct list_head head = LIST_HEAD_INIT(head);
	td_image_t *image = NULL, *next;
	regex_t _im, *im = NULL, _ws, *ws = NULL;
	FILE *s;
	int err;

	s = fopen(path, "r");
	if (!s) {
		err = -errno;
		goto fail;
	}

	err = regcomp(&_ws, "^[:space:]*$", REG_NOSUB);
	if (err)
		goto fail;
	ws = &_ws;

	err = regcomp(&_im,
		      "^([^:]+):([^ \t]+)([ \t]+([a-z,]+))?",
		      REG_EXTENDED|REG_NEWLINE);
	if (err)
		goto fail;
	im = &_im;

	do {
		char line[512], *l;
		regmatch_t match[5];
		char *typename, *path, *args = NULL;
		unsigned long flags;
		int type;

		l = fgets(line, sizeof(line), s);
		if (!l)
			break;

		err = regexec(im, line, ARRAY_SIZE(match), match, 0);
		if (err) {
			err = regexec(ws, line, ARRAY_SIZE(match), match, 0);
			if (!err)
				continue;
			err = -EINVAL;
			goto fail;
		}

		line[match[1].rm_eo] = 0;
		typename = line + match[1].rm_so;

		line[match[2].rm_eo] = 0;
		path = line + match[2].rm_so;

		if (match[4].rm_so >= 0) {
			line[match[4].rm_eo] = 0;
			args = line + match[4].rm_so;
		}

		type = tapdisk_disktype_find(typename);
		if (type < 0) {
			err = type;
			goto fail;
		}

		flags = 0;

		if (args) {
			err = tapdisk_image_parse_flags(args, &flags);
			if (err)
				goto fail;
		}

		err = tapdisk_image_open(type, path, flags, &image);
		if (err)
			goto fail;

		list_add_tail(&image->next, &head);
	} while (1);

	if (!image) {
		err = -EINVAL;
		goto fail;
	}

	err = tapdisk_image_open_parents(image);
	if (err)
		goto fail;

	list_splice(&head, _head);
out:
	if (im)
		regfree(im);
	if (ws)
		regfree(ws);
	if (s)
		fclose(s);

	return err;

fail:
	tapdisk_for_each_image_safe(image, next, &head)
		tapdisk_image_free(image);

	goto out;
}