예제 #1
0
static int
vhd_print_bat_str(vhd_context_t *vhd)
{
	int i, err, total_blocks, bitmap_size;
	char *bitmap;
	ssize_t n;

	err = 0;

	if (!vhd_type_dynamic(vhd))
		return -EINVAL;

	total_blocks = vhd->footer.curr_size / vhd->header.block_size;
	bitmap_size = total_blocks >> 3;
	if (bitmap_size << 3 < total_blocks)
		bitmap_size++;

	bitmap = malloc(bitmap_size);
	if (!bitmap)
		return -ENOMEM;
	memset(bitmap, 0, bitmap_size);

	for (i = 0; i < total_blocks; i++) {
		if (vhd->bat.bat[i] != DD_BLK_UNUSED)
			set_bit(bitmap, i);
	}

	n = write(STDOUT_FILENO, bitmap, bitmap_size);
	if (n < 0)
		err = -errno;

	free(bitmap);

	return err;
}
예제 #2
0
int get_footer(server *srv, chunkqueue *cq, vhd_state_t *state, off_t *curr_off)
{
	int err;
	vhd_context_t *vhd = &state->vhd;

	err = fill(srv, cq, &vhd->footer, sizeof(vhd_footer_t), 0, curr_off);
	if (err)
		return err;

	if (*curr_off < 0 + sizeof(vhd_footer_t))
		return 0;

	DEBUGLOG("s", "Footer all in");
	vhd_footer_in(&vhd->footer);
	err = vhd_validate_footer(&vhd->footer);
	if (err)
		LOG("sd", "ERROR: VHD footer invalid:", err);

	if (!vhd_type_dynamic(vhd)) {
		LOG("s", "ERROR: static VHDs are not supported");
		err = -EINVAL;
	}

	return err;
}
예제 #3
0
static int
vhd_print_headers(vhd_context_t *vhd, int hex)
{
	int err;

	vhd_print_footer(&vhd->footer, hex);

	if (vhd_type_dynamic(vhd)) {
		vhd_print_header(vhd, &vhd->header, hex);

		if (vhd->footer.type == HD_TYPE_DIFF)
			vhd_print_parent_locators(vhd, hex);

		if (vhd_has_batmap(vhd)) {
			err = vhd_get_batmap(vhd);
			if (err) {
				printf("failed to get batmap header\n");
				return err;
			}

			vhd_print_batmap_header(vhd, &vhd->batmap, hex);
		}
	}

	return 0;
}
예제 #4
0
static int
vhd_journal_add_footer(vhd_journal_t *j)
{
	int err;
	off64_t off;
	vhd_context_t *vhd;
	vhd_footer_t footer;

	vhd = &j->vhd;

	err = vhd_seek(vhd, 0, SEEK_END);
	if (err)
		return err;

	off = vhd_position(vhd);
	if (off == (off64_t)-1)
		return -errno;

	err = vhd_read_footer_at(vhd, &footer, off - sizeof(vhd_footer_t));
	if (err)
		return err;

	vhd_footer_out(&footer);
	err = vhd_journal_update(j, off - sizeof(vhd_footer_t),
				 (char *)&footer,
				 sizeof(vhd_footer_t),
				 VHD_JOURNAL_ENTRY_TYPE_FOOTER_P);
	if (err)
		return err;

	if (!vhd_type_dynamic(vhd))
		return 0;

	err = vhd_read_footer_at(vhd, &footer, 0);
	if (err)
		return err;

	vhd_footer_out(&footer);
	err = vhd_journal_update(j, 0,
				 (char *)&footer,
				 sizeof(vhd_footer_t),
				 VHD_JOURNAL_ENTRY_TYPE_FOOTER_C);

	return err;
}
예제 #5
0
파일: libvhd-journal.c 프로젝트: Xilinx/xen
static int
vhd_journal_add_metadata(vhd_journal_t *j)
{
	int err;
	off_t eof;
	vhd_context_t *vhd;

	vhd = &j->vhd;

	err = vhd_journal_add_footer(j);
	if (err)
		return err;

	if (!vhd_type_dynamic(vhd))
		return 0;

	err = vhd_journal_add_header(j);
	if (err)
		return err;

	err = vhd_journal_add_locators(j);
	if (err)
		return err;

	err = vhd_journal_add_bat(j);
	if (err)
		return err;

	if (vhd_has_batmap(vhd)) {
		err = vhd_journal_add_batmap(j);
		if (err)
			return err;
	}

	j->header.journal_data_offset = j->header.journal_eof;
	return vhd_journal_write_header(j, &j->header);
}
예제 #6
0
static int
vhd_journal_restore_metadata(vhd_journal_t *j)
{
	off64_t off;
	char **locators;
	vhd_footer_t copy;
	vhd_context_t *vhd;
	int i, locs, hlocs, err;

	vhd      = &j->vhd;
	locs     = 0;
	hlocs    = 0;
	locators = NULL;

	err = vhd_journal_seek(j, sizeof(vhd_journal_header_t), SEEK_SET);
	if (err)
		return err;

	err  = vhd_journal_read_footer(j, &vhd->footer);
	if (err)
		return err;

	if (!vhd_type_dynamic(vhd))
		goto restore;

	err  = vhd_journal_read_footer_copy(j, &copy);
	if (err)
		return err;

	err  = vhd_journal_read_header(j, &vhd->header);
	if (err)
		return err;

	for (hlocs = 0, i = 0; i < vhd_parent_locator_count(vhd); i++) {
		if (vhd_validate_platform_code(vhd->header.loc[i].code))
			return err;

		if (vhd->header.loc[i].code != PLAT_CODE_NONE)
			hlocs++;
	}

	if (hlocs) {
		err  = vhd_journal_read_locators(j, &locators, &locs);
		if (err)
			return err;

		if (hlocs != locs) {
			err = -EINVAL;
			goto out;
		}
	}

	err  = vhd_journal_read_bat(j, &vhd->bat);
	if (err)
		goto out;

	if (vhd_has_batmap(vhd)) {
		err  = vhd_journal_read_batmap(j, &vhd->batmap);
		if (err)
			goto out;
	}

restore:
	off  = vhd_journal_position(j);
	if (off == (off64_t)-1)
		return -errno;

	if (j->header.journal_data_offset != off)
		return -EINVAL;

	err  = vhd_journal_restore_footer(j, &vhd->footer);
	if (err)
		goto out;

	if (!vhd_type_dynamic(vhd))
		goto out;

	err  = vhd_journal_restore_footer_copy(j, &copy);
	if (err)
		goto out;

	err  = vhd_journal_restore_header(j, &vhd->header);
	if (err)
		goto out;

	if (locs) {
		err = vhd_journal_restore_locators(j, locators, locs);
		if (err)
			goto out;
	}

	err  = vhd_journal_restore_bat(j, &vhd->bat);
	if (err)
		goto out;

	if (vhd_has_batmap(vhd)) {
		err  = vhd_journal_restore_batmap(j, &vhd->batmap);
		if (err)
			goto out;
	}

	err = 0;

out:
	if (locators) {
		for (i = 0; i < locs; i++)
			free(locators[i]);
		free(locators);
	}

	if (!err && !vhd->is_block)
		err = ftruncate(vhd->fd,
			  j->header.vhd_footer_offset +
			  sizeof(vhd_footer_t));

	return err;
}
예제 #7
0
int
vhd_journal_add_block(vhd_journal_t *j, uint32_t block, char mode)
{
	int err;
	char *buf;
	off64_t off;
	size_t size;
	uint64_t blk;
	vhd_context_t *vhd;

	buf = NULL;
	vhd = &j->vhd;

	if (!vhd_type_dynamic(vhd))
		return -EINVAL;

	err = vhd_get_bat(vhd);
	if (err)
		return err;

	if (block >= vhd->bat.entries)
		return -ERANGE;

	blk = vhd->bat.bat[block];
	if (blk == DD_BLK_UNUSED)
		return 0;

	off = vhd_sectors_to_bytes(blk);

	if (mode & VHD_JOURNAL_METADATA) {
		size = vhd_sectors_to_bytes(vhd->bm_secs);

		err  = vhd_read_bitmap(vhd, block, &buf);
		if (err)
			return err;

		err  = vhd_journal_update(j, off, buf, size,
					  VHD_JOURNAL_ENTRY_TYPE_DATA);

		free(buf);

		if (err)
			return err;
	}

	if (mode & VHD_JOURNAL_DATA) {
		off += vhd_sectors_to_bytes(vhd->bm_secs);
		size = vhd_sectors_to_bytes(vhd->spb);

		err  = vhd_read_block(vhd, block, &buf);
		if (err)
			return err;

		err  = vhd_journal_update(j, off, buf, size,
					  VHD_JOURNAL_ENTRY_TYPE_DATA);
		free(buf);

		if (err)
			return err;
	}

	return vhd_journal_sync(j);
}
예제 #8
0
int
vhd_util_set_field(int argc, char **argv)
{
	long value;
	int err, c;
	vhd_context_t vhd;
	char *name, *field;

	err   = -EINVAL;
	value = 0;
	name  = NULL;
	field = NULL;

	if (!argc || !argv)
		goto usage;

	optind = 0;
	while ((c = getopt(argc, argv, "n:f:v:h")) != -1) {
		switch (c) {
		case 'n':
			name = optarg;
			break;
		case 'f':
			field = optarg;
			break;
		case 'v':
			err   = 0;
			value = strtol(optarg, NULL, 10);
			break;
		case 'h':
		default:
			goto usage;
		}
	}

	if (!name || !field || optind != argc || err)
		goto usage;

	if (strnlen(field, 25) >= 25) {
		printf("invalid field\n");
		goto usage;
	}

	if (strcmp(field, "hidden") && strcmp(field, "marker")) {
		printf("invalid field %s\n", field);
		goto usage;
	}

	if (value < 0 || value > 255) {
		printf("invalid value %ld\n", value);
		goto usage;
	}

	err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
	if (err) {
		printf("error opening %s: %d\n", name, err);
		return err;
	}

	if (!strcmp(field, "hidden")) {
		vhd.footer.hidden = (char)value;
		err = vhd_write_footer(&vhd, &vhd.footer);
		if (err == -ENOSPC && vhd_type_dynamic(&vhd) && value)
			/* if no space to write the primary footer, at least write the 
			 * backup footer so that it's possible to delete the VDI */
			err = vhd_write_footer_at(&vhd, &vhd.footer, 0);
	} else {
		err = vhd_set_marker(&vhd, (char)value);
	}
		
 	vhd_close(&vhd);
	return err;

usage:
	printf("options: <-n name> <-f field> <-v value> [-h help]\n");
	return -EINVAL;
}