You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by an...@apache.org on 2012/08/03 22:33:55 UTC
[4/5] remove vhd-tools directory
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-check.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-check.c b/tools/vhd-tools/vhd/lib/vhd-util-check.c
deleted file mode 100644
index afb591e..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-check.c
+++ /dev/null
@@ -1,980 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-
-#include "libvhd.h"
-#include "vhd-util.h"
-
-// allow the VHD timestamp to be at most this many seconds into the future to
-// account for time skew with NFS servers
-#define TIMESTAMP_MAX_SLACK 1800
-
-static int
-vhd_util_check_zeros(void *buf, size_t size)
-{
- int i;
- char *p;
-
- p = buf;
- for (i = 0; i < size; i++)
- if (p[i])
- return i;
-
- return 0;
-}
-
-static int
-vhd_util_check_footer_opened(vhd_footer_t *footer)
-{
- int i, n;
- uint32_t *buf;
-
- buf = (uint32_t *)footer;
- n = sizeof(*footer) / sizeof(uint32_t);
-
- for (i = 0; i < n; i++)
- if (buf[i] != 0xc7c7c7c7)
- return 0;
-
- return 1;
-}
-
-static char *
-vhd_util_check_validate_footer(vhd_footer_t *footer)
-{
- int size;
- uint32_t checksum, now;
-
- size = sizeof(footer->cookie);
- if (memcmp(footer->cookie, HD_COOKIE, size))
- return "invalid cookie";
-
- checksum = vhd_checksum_footer(footer);
- if (checksum != footer->checksum) {
- if (footer->hidden &&
- !strncmp(footer->crtr_app, "tap", 3) &&
- (footer->crtr_ver == VHD_VERSION(0, 1) ||
- footer->crtr_ver == VHD_VERSION(1, 1))) {
- char tmp = footer->hidden;
- footer->hidden = 0;
- checksum = vhd_checksum_footer(footer);
- footer->hidden = tmp;
-
- if (checksum == footer->checksum)
- goto ok;
- }
-
- return "invalid checksum";
- }
-
-ok:
- if (!(footer->features & HD_RESERVED))
- return "invalid 'reserved' feature";
-
- if (footer->features & ~(HD_TEMPORARY | HD_RESERVED))
- return "invalid extra features";
-
- if (footer->ff_version != HD_FF_VERSION)
- return "invalid file format version";
-
- if (footer->type != HD_TYPE_DYNAMIC &&
- footer->type != HD_TYPE_DIFF &&
- footer->data_offset != ~(0ULL))
- return "invalid data offset";
-/*
- now = vhd_time(time(NULL));
- if (footer->timestamp > now + TIMESTAMP_MAX_SLACK)
- return "creation time in future";
-*/
- if (!strncmp(footer->crtr_app, "tap", 3) &&
- footer->crtr_ver > VHD_CURRENT_VERSION)
- return "unsupported tap creator version";
-
- if (vhd_chs(footer->curr_size) < footer->geometry)
- return "geometry too large";
-
- if (footer->type != HD_TYPE_FIXED &&
- footer->type != HD_TYPE_DYNAMIC &&
- footer->type != HD_TYPE_DIFF)
- return "invalid type";
-
- if (footer->saved && footer->saved != 1)
- return "invalid 'saved' state";
-
- if (footer->hidden && footer->hidden != 1)
- return "invalid 'hidden' state";
-
- if (vhd_util_check_zeros(footer->reserved,
- sizeof(footer->reserved)))
- return "invalid 'reserved' bits";
-
- return NULL;
-}
-
-static char *
-vhd_util_check_validate_header(int fd, vhd_header_t *header)
-{
- off_t eof;
- int i, cnt, size;
- uint32_t checksum;
-
- size = sizeof(header->cookie);
- if (memcmp(header->cookie, DD_COOKIE, size))
- return "invalid cookie";
-
- checksum = vhd_checksum_header(header);
- if (checksum != header->checksum)
- return "invalid checksum";
-
- if (header->hdr_ver != 0x00010000)
- return "invalid header version";
-
- if (header->data_offset != ~(0ULL))
- return "invalid data offset";
-
- eof = lseek(fd, 0, SEEK_END);
- if (eof == (off_t)-1)
- return "error finding eof";
-
- if (header->table_offset <= 0 ||
- header->table_offset % 512 ||
- (header->table_offset +
- (header->max_bat_size * sizeof(uint32_t)) >
- eof - sizeof(vhd_footer_t)))
- return "invalid table offset";
-
- for (cnt = 0, i = 0; i < sizeof(header->block_size) * 8; i++)
- if ((header->block_size >> i) & 1)
- cnt++;
-
- if (cnt != 1)
- return "invalid block size";
-
- if (header->res1)
- return "invalid reserved bits";
-
- if (vhd_util_check_zeros(header->res2, sizeof(header->res2)))
- return "invalid reserved bits";
-
- return NULL;
-}
-
-static char *
-vhd_util_check_validate_differencing_header(vhd_context_t *vhd)
-{
- vhd_header_t *header;
-
- header = &vhd->header;
-
- if (vhd->footer.type == HD_TYPE_DIFF) {
- char *parent;
- uint32_t now;
-
- now = vhd_time(time(NULL));
- if (header->prt_ts > now + TIMESTAMP_MAX_SLACK)
- return "parent creation time in future";
-
- if (vhd_header_decode_parent(vhd, header, &parent))
- return "invalid parent name";
-
- free(parent);
- } else {
- if (vhd_util_check_zeros(header->prt_name,
- sizeof(header->prt_name)))
- return "invalid non-null parent name";
-
- if (vhd_util_check_zeros(header->loc, sizeof(header->loc)))
- return "invalid non-null parent locators";
-
- if (!blk_uuid_is_nil(&header->prt_uuid))
- return "invalid non-null parent uuid";
-
- if (header->prt_ts)
- return "invalid non-zero parent timestamp";
- }
-
- return NULL;
-}
-
-static char *
-vhd_util_check_validate_batmap(vhd_context_t *vhd, vhd_batmap_t *batmap)
-{
- int size;
- off_t eof;
- uint32_t checksum;
-
- size = sizeof(batmap->header.cookie);
- if (memcmp(batmap->header.cookie, VHD_BATMAP_COOKIE, size))
- return "invalid cookie";
-
- if (batmap->header.batmap_version > VHD_BATMAP_CURRENT_VERSION)
- return "unsupported batmap version";
-
- checksum = vhd_checksum_batmap(batmap);
- if (checksum != batmap->header.checksum)
- return "invalid checksum";
-
- if (!batmap->header.batmap_size)
- return "invalid size zero";
-
- eof = lseek(vhd->fd, 0, SEEK_END);
- if (eof == (off_t)-1)
- return "error finding eof";
-
- if (!batmap->header.batmap_offset ||
- batmap->header.batmap_offset % 512)
- return "invalid batmap offset";
-
- if ((batmap->header.batmap_offset +
- vhd_sectors_to_bytes(batmap->header.batmap_size)) >
- eof - sizeof(vhd_footer_t))
- return "invalid batmap size";
-
- return NULL;
-}
-
-static char *
-vhd_util_check_validate_parent_locator(vhd_context_t *vhd,
- vhd_parent_locator_t *loc)
-{
- off_t eof;
-
- if (vhd_validate_platform_code(loc->code))
- return "invalid platform code";
-
- if (loc->code == PLAT_CODE_NONE) {
- if (vhd_util_check_zeros(loc, sizeof(*loc)))
- return "non-zero locator";
-
- return NULL;
- }
-
- if (!loc->data_offset)
- return "invalid data offset";
-
- if (!loc->data_space)
- return "invalid data space";
-
- if (!loc->data_len)
- return "invalid data length";
-
- eof = lseek(vhd->fd, 0, SEEK_END);
- if (eof == (off_t)-1)
- return "error finding eof";
-
- if (loc->data_offset + vhd_parent_locator_size(loc) >
- eof - sizeof(vhd_footer_t))
- return "invalid size";
-
- if (loc->res)
- return "invalid reserved bits";
-
- return NULL;
-}
-
-static const char *
-vhd_util_check_validate_parent(vhd_context_t *vhd, const char *ppath)
-{
- const char *msg;
- vhd_context_t parent;
- uint32_t status;
-
- msg = NULL;
-
- if (vhd_parent_raw(vhd))
- return msg;
-
- if (vhd_open(&parent, ppath,
- VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED))
- return "error opening parent";
-
- if (blk_uuid_compare(&vhd->header.prt_uuid, &parent.footer.uuid)) {
- msg = "invalid parent uuid";
- goto out;
- }
-
-out:
- vhd_close(&parent);
- return msg;
-}
-
-static int
-vhd_util_check_footer(int fd, vhd_footer_t *footer, int ignore)
-{
- size_t size;
- int err, opened;
- char *msg, *buf;
- off_t eof, off;
- vhd_footer_t primary, backup;
-
- memset(&primary, 0, sizeof(primary));
- memset(&backup, 0, sizeof(backup));
-
- err = posix_memalign((void **)&buf, VHD_SECTOR_SIZE, sizeof(primary));
- if (err) {
- printf("error allocating buffer: %d\n", err);
- return -err;
- }
-
- memset(buf, 0, sizeof(primary));
-
- eof = lseek(fd, 0, SEEK_END);
- if (eof == (off_t)-1) {
- err = -errno;
- printf("error calculating end of file: %d\n", err);
- goto out;
- }
-
- size = ((eof % 512) ? 511 : 512);
- eof = lseek(fd, eof - size, SEEK_SET);
- if (eof == (off_t)-1) {
- err = -errno;
- printf("error calculating end of file: %d\n", err);
- goto out;
- }
-
- err = read(fd, buf, 512);
- if (err != size) {
- err = (errno ? -errno : -EIO);
- printf("error reading primary footer: %d\n", err);
- goto out;
- }
-
- memcpy(&primary, buf, sizeof(primary));
- opened = vhd_util_check_footer_opened(&primary);
- vhd_footer_in(&primary);
-
- msg = vhd_util_check_validate_footer(&primary);
- if (msg) {
- if (opened && ignore)
- goto check_backup;
-
- err = -EINVAL;
- printf("primary footer invalid: %s\n", msg);
- goto out;
- }
-
- if (primary.type == HD_TYPE_FIXED) {
- err = 0;
- goto out;
- }
-
-check_backup:
- off = lseek(fd, 0, SEEK_SET);
- if (off == (off_t)-1) {
- err = -errno;
- printf("error seeking to backup footer: %d\n", err);
- goto out;
- }
-
- size = 512;
- memset(buf, 0, sizeof(primary));
-
- err = read(fd, buf, size);
- if (err != size) {
- err = (errno ? -errno : -EIO);
- printf("error reading backup footer: %d\n", err);
- goto out;
- }
-
- memcpy(&backup, buf, sizeof(backup));
- vhd_footer_in(&backup);
-
- msg = vhd_util_check_validate_footer(&backup);
- if (msg) {
- err = -EINVAL;
- printf("backup footer invalid: %s\n", msg);
- goto out;
- }
-
- if (memcmp(&primary, &backup, sizeof(primary))) {
- if (opened && ignore) {
- memcpy(&primary, &backup, sizeof(primary));
- goto ok;
- }
-
- if (backup.hidden &&
- !strncmp(backup.crtr_app, "tap", 3) &&
- (backup.crtr_ver == VHD_VERSION(0, 1) ||
- backup.crtr_ver == VHD_VERSION(1, 1))) {
- char cmp, tmp = backup.hidden;
- backup.hidden = 0;
- cmp = memcmp(&primary, &backup, sizeof(primary));
- backup.hidden = tmp;
- if (!cmp)
- goto ok;
- }
-
- err = -EINVAL;
- printf("primary and backup footers do not match\n");
- goto out;
- }
-
-ok:
- err = 0;
- memcpy(footer, &primary, sizeof(primary));
-
-out:
- free(buf);
- return err;
-}
-
-static int
-vhd_util_check_header(int fd, vhd_footer_t *footer)
-{
- int err;
- off_t off;
- char *msg, *buf;
- vhd_header_t header;
-
- err = posix_memalign((void **)&buf, VHD_SECTOR_SIZE, sizeof(header));
- if (err) {
- printf("error allocating header: %d\n", err);
- return err;
- }
-
- off = footer->data_offset;
- off = lseek(fd, off, SEEK_SET);
- if (off == (off_t)-1) {
- err = -errno;
- printf("error seeking to header: %d\n", err);
- goto out;
- }
-
- err = read(fd, buf, sizeof(header));
- if (err != sizeof(header)) {
- err = (errno ? -errno : -EIO);
- printf("error reading header: %d\n", err);
- goto out;
- }
-
- memcpy(&header, buf, sizeof(header));
- vhd_header_in(&header);
-
- msg = vhd_util_check_validate_header(fd, &header);
- if (msg) {
- err = -EINVAL;
- printf("header is invalid: %s\n", msg);
- goto out;
- }
-
- err = 0;
-
-out:
- free(buf);
- return err;
-}
-
-static int
-vhd_util_check_differencing_header(vhd_context_t *vhd)
-{
- char *msg;
-
- msg = vhd_util_check_validate_differencing_header(vhd);
- if (msg) {
- printf("differencing header is invalid: %s\n", msg);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-vhd_util_check_bat(vhd_context_t *vhd)
-{
- off_t eof, eoh;
- int i, j, err, block_size;
-
- err = vhd_seek(vhd, 0, SEEK_END);
- if (err) {
- printf("error calculating eof: %d\n", err);
- return err;
- }
-
- eof = vhd_position(vhd);
- if (eof == (off_t)-1) {
- printf("error calculating eof: %d\n", -errno);
- return -errno;
- }
-
- /* adjust eof for vhds with short footers */
- if (eof % 512) {
- if (eof % 512 != 511) {
- printf("invalid file size: 0x%"PRIx64"\n", eof);
- return -EINVAL;
- }
-
- eof++;
- }
-
- err = vhd_get_bat(vhd);
- if (err) {
- printf("error reading bat: %d\n", err);
- return err;
- }
-
- err = vhd_end_of_headers(vhd, &eoh);
- if (err) {
- printf("error calculating end of metadata: %d\n", err);
- return err;
- }
-
- eof -= sizeof(vhd_footer_t);
- eof >>= VHD_SECTOR_SHIFT;
- eoh >>= VHD_SECTOR_SHIFT;
- block_size = vhd->spb + vhd->bm_secs;
-
- for (i = 0; i < vhd->header.max_bat_size; i++) {
- uint32_t off = vhd->bat.bat[i];
- if (off == DD_BLK_UNUSED)
- continue;
-
- if (off < eoh) {
- printf("block %d (offset 0x%x) clobbers headers\n",
- i, off);
- return -EINVAL;
- }
-
- if (off + block_size > eof) {
- printf("block %d (offset 0x%x) clobbers footer\n",
- i, off);
- return -EINVAL;
- }
-
- for (j = 0; j < vhd->header.max_bat_size; j++) {
- uint32_t joff = vhd->bat.bat[j];
-
- if (i == j)
- continue;
-
- if (joff == DD_BLK_UNUSED)
- continue;
-
- if (off == joff)
- err = -EINVAL;
-
- if (off > joff && off < joff + block_size)
- err = -EINVAL;
-
- if (off + block_size > joff &&
- off + block_size < joff + block_size)
- err = -EINVAL;
-
- if (err) {
- printf("block %d (offset 0x%x) clobbers "
- "block %d (offset 0x%x)\n",
- i, off, j, joff);
- return err;
- }
- }
- }
-
- return 0;
-}
-
-static int
-vhd_util_check_batmap(vhd_context_t *vhd)
-{
- char *msg;
- int i, err;
-
- err = vhd_get_bat(vhd);
- if (err) {
- printf("error reading bat: %d\n", err);
- return err;
- }
-
- err = vhd_get_batmap(vhd);
- if (err) {
- printf("error reading batmap: %d\n", err);
- return err;
- }
-
- msg = vhd_util_check_validate_batmap(vhd, &vhd->batmap);
- if (msg) {
- printf("batmap is invalid: %s\n", msg);
- return -EINVAL;
- }
-
- for (i = 0; i < vhd->header.max_bat_size; i++) {
- if (!vhd_batmap_test(vhd, &vhd->batmap, i))
- continue;
-
- if (vhd->bat.bat[i] == DD_BLK_UNUSED) {
- printf("batmap shows unallocated block %d full\n", i);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int
-vhd_util_check_parent_locators(vhd_context_t *vhd)
-{
- int i, n, err;
- vhd_parent_locator_t *loc;
- char *file, *ppath, *location, *pname;
- const char *msg;
- int mac, macx, w2ku, w2ru, wi2r, wi2k, found;
-
- mac = 0;
- macx = 0;
- w2ku = 0;
- w2ru = 0;
- wi2r = 0;
- wi2k = 0;
- found = 0;
- pname = NULL;
- ppath = NULL;
- location = NULL;
-
- err = vhd_header_decode_parent(vhd, &vhd->header, &pname);
- if (err) {
- printf("error decoding parent name: %d\n", err);
- return err;
- }
-
- n = sizeof(vhd->header.loc) / sizeof(vhd->header.loc[0]);
- for (i = 0; i < n; i++) {
- ppath = NULL;
- location = NULL;
- loc = vhd->header.loc + i;
-
- msg = vhd_util_check_validate_parent_locator(vhd, loc);
- if (msg) {
- err = -EINVAL;
- printf("invalid parent locator %d: %s\n", i, msg);
- goto out;
- }
-
- if (loc->code == PLAT_CODE_NONE)
- continue;
-
- switch (loc->code) {
- case PLAT_CODE_MACX:
- if (macx++)
- goto dup;
- break;
-
- case PLAT_CODE_MAC:
- if (mac++)
- goto dup;
- break;
-
- case PLAT_CODE_W2KU:
- if (w2ku++)
- goto dup;
- break;
-
- case PLAT_CODE_W2RU:
- if (w2ru++)
- goto dup;
- break;
-
- case PLAT_CODE_WI2R:
- if (wi2r++)
- goto dup;
- break;
-
- case PLAT_CODE_WI2K:
- if (wi2k++)
- goto dup;
- break;
-
- default:
- err = -EINVAL;
- printf("invalid platform code for locator %d\n", i);
- goto out;
- }
-
- if (loc->code != PLAT_CODE_MACX &&
- loc->code != PLAT_CODE_W2RU &&
- loc->code != PLAT_CODE_W2KU)
- continue;
-
- err = vhd_parent_locator_read(vhd, loc, &ppath);
- if (err) {
- printf("error reading parent locator %d: %d\n", i, err);
- goto out;
- }
-
- file = basename(ppath);
- if (strcmp(pname, file)) {
- err = -EINVAL;
- printf("parent locator %d name (%s) does not match "
- "header name (%s)\n", i, file, pname);
- goto out;
- }
-
- err = vhd_find_parent(vhd, ppath, &location);
- if (err) {
- printf("error resolving %s: %d\n", ppath, err);
- goto out;
- }
-
- err = access(location, R_OK);
- if (err && loc->code == PLAT_CODE_MACX) {
- err = -errno;
- printf("parent locator %d points to missing file %s "
- "(resolved to %s)\n", i, ppath, location);
- goto out;
- }
-
- msg = vhd_util_check_validate_parent(vhd, location);
- if (msg) {
- err = -EINVAL;
- printf("invalid parent %s: %s\n", location, msg);
- goto out;
- }
-
- found++;
- free(ppath);
- free(location);
- ppath = NULL;
- location = NULL;
-
- continue;
-
- dup:
- printf("duplicate platform code in locator %d: 0x%x\n",
- i, loc->code);
- err = -EINVAL;
- goto out;
- }
-
- if (!found) {
- err = -EINVAL;
- printf("could not find parent %s\n", pname);
- goto out;
- }
-
- err = 0;
-
-out:
- free(pname);
- free(ppath);
- free(location);
- return err;
-}
-
-static void
-vhd_util_dump_headers(const char *name)
-{
- char *argv[] = { "read", "-p", "-n", (char *)name };
- int argc = sizeof(argv) / sizeof(argv[0]);
-
- printf("%s appears invalid; dumping metadata\n", name);
- vhd_util_read(argc, argv);
-}
-
-static int
-vhd_util_check_vhd(const char *name, int ignore)
-{
- int fd, err;
- vhd_context_t vhd;
- struct stat stats;
- vhd_footer_t footer;
-
- fd = -1;
- memset(&vhd, 0, sizeof(vhd));
- memset(&footer, 0, sizeof(footer));
-
- err = stat(name, &stats);
- if (err == -1) {
- printf("cannot stat %s: %d\n", name, errno);
- return -errno;
- }
-
- if (!S_ISREG(stats.st_mode) && !S_ISBLK(stats.st_mode)) {
- printf("%s is not a regular file or block device\n", name);
- return -EINVAL;
- }
-
- fd = open(name, O_RDONLY | O_DIRECT | O_LARGEFILE);
- if (fd == -1) {
- printf("error opening %s\n", name);
- return -errno;
- }
-
- err = vhd_util_check_footer(fd, &footer, ignore);
- if (err)
- goto out;
-
- if (footer.type != HD_TYPE_DYNAMIC && footer.type != HD_TYPE_DIFF)
- goto out;
-
- err = vhd_util_check_header(fd, &footer);
- if (err)
- goto out;
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
- if (err)
- goto out;
-
- err = vhd_util_check_differencing_header(&vhd);
- if (err)
- goto out;
-
- err = vhd_util_check_bat(&vhd);
- if (err)
- goto out;
-
- if (vhd_has_batmap(&vhd)) {
- err = vhd_util_check_batmap(&vhd);
- if (err)
- goto out;
- }
-
- if (vhd.footer.type == HD_TYPE_DIFF) {
- err = vhd_util_check_parent_locators(&vhd);
- if (err)
- goto out;
- }
-
- err = 0;
- printf("%s is valid\n", name);
-
-out:
- if (err)
- vhd_util_dump_headers(name);
- if (fd != -1)
- close(fd);
- vhd_close(&vhd);
- return err;
-}
-
-static int
-vhd_util_check_parents(const char *name, int ignore)
-{
- int err;
- vhd_context_t vhd;
- char *cur, *parent;
-
- cur = (char *)name;
-
- for (;;) {
- err = vhd_open(&vhd, cur,
- VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
- if (err)
- goto out;
-
- if (vhd.footer.type != HD_TYPE_DIFF || vhd_parent_raw(&vhd)) {
- vhd_close(&vhd);
- goto out;
- }
-
- err = vhd_parent_locator_get(&vhd, &parent);
- vhd_close(&vhd);
-
- if (err) {
- printf("error getting parent: %d\n", err);
- goto out;
- }
-
- if (cur != name)
- free(cur);
- cur = parent;
-
- err = vhd_util_check_vhd(cur, ignore);
- if (err)
- goto out;
- }
-
-out:
- if (err)
- printf("error checking parents: %d\n", err);
- if (cur != name)
- free(cur);
- return err;
-}
-
-int
-vhd_util_check(int argc, char **argv)
-{
- char *name;
- vhd_context_t vhd;
- int c, err, ignore, parents;
-
- if (!argc || !argv) {
- err = -EINVAL;
- goto usage;
- }
-
- ignore = 0;
- parents = 0;
- name = NULL;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:iph")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 'i':
- ignore = 1;
- break;
- case 'p':
- parents = 1;
- break;
- case 'h':
- err = 0;
- goto usage;
- default:
- err = -EINVAL;
- goto usage;
- }
- }
-
- if (!name || optind != argc) {
- err = -EINVAL;
- goto usage;
- }
-
- err = vhd_util_check_vhd(name, ignore);
- if (err)
- goto out;
-
- if (parents)
- err = vhd_util_check_parents(name, ignore);
-
-out:
- return err;
-
-usage:
- printf("options: -n <file> [-i ignore missing primary footers] "
- "[-p check parents] [-h help]\n");
- return err;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-coalesce.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-coalesce.c b/tools/vhd-tools/vhd/lib/vhd-util-coalesce.c
deleted file mode 100644
index f0ee869..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-coalesce.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "libvhd.h"
-
-static int
-__raw_io_write(int fd, char* buf, uint64_t sec, uint32_t secs)
-{
- off_t off;
- size_t ret;
-
- errno = 0;
- off = lseek(fd, vhd_sectors_to_bytes(sec), SEEK_SET);
- if (off == (off_t)-1) {
- printf("raw parent: seek(0x%08"PRIx64") failed: %d\n",
- vhd_sectors_to_bytes(sec), -errno);
- return -errno;
- }
-
- ret = write(fd, buf, vhd_sectors_to_bytes(secs));
- if (ret == vhd_sectors_to_bytes(secs))
- return 0;
-
- printf("raw parent: write of 0x%"PRIx64" returned %zd, errno: %d\n",
- vhd_sectors_to_bytes(secs), ret, -errno);
- return (errno ? -errno : -EIO);
-}
-
-/*
- * Use 'parent' if the parent is VHD, and 'parent_fd' if the parent is raw
- */
-static int
-vhd_util_coalesce_block(vhd_context_t *vhd, vhd_context_t *parent,
- int parent_fd, uint64_t block)
-{
- int i, err;
- char *buf, *map;
- uint64_t sec, secs;
-
- buf = NULL;
- map = NULL;
- sec = block * vhd->spb;
-
- if (vhd->bat.bat[block] == DD_BLK_UNUSED)
- return 0;
-
- err = posix_memalign((void **)&buf, 4096, vhd->header.block_size);
- if (err)
- return -err;
-
- err = vhd_io_read(vhd, buf, sec, vhd->spb);
- if (err)
- goto done;
-
- if (vhd_has_batmap(vhd) && vhd_batmap_test(vhd, &vhd->batmap, block)) {
- if (parent->file)
- err = vhd_io_write(parent, buf, sec, vhd->spb);
- else
- err = __raw_io_write(parent_fd, buf, sec, vhd->spb);
- goto done;
- }
-
- err = vhd_read_bitmap(vhd, block, &map);
- if (err)
- goto done;
-
- for (i = 0; i < vhd->spb; i++) {
- if (!vhd_bitmap_test(vhd, map, i))
- continue;
-
- for (secs = 0; i + secs < vhd->spb; secs++)
- if (!vhd_bitmap_test(vhd, map, i + secs))
- break;
-
- if (parent->file)
- err = vhd_io_write(parent,
- buf + vhd_sectors_to_bytes(i),
- sec + i, secs);
- else
- err = __raw_io_write(parent_fd,
- buf + vhd_sectors_to_bytes(i),
- sec + i, secs);
- if (err)
- goto done;
-
- i += secs;
- }
-
- err = 0;
-
-done:
- free(buf);
- free(map);
- return err;
-}
-
-int
-vhd_util_coalesce(int argc, char **argv)
-{
- int err, c;
- uint64_t i;
- char *name, *pname;
- vhd_context_t vhd, parent;
- int parent_fd = -1;
- int pflag = 0;
- name = NULL;
- pname = NULL;
- parent.file = NULL;
-
- if (!argc || !argv)
- goto usage;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:p:h")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 'p':
- pflag = 1;
- pname = optarg;
- break;
-
- case 'h':
- default:
- goto usage;
- }
- }
-
- if (!name || optind != argc)
- goto usage;
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDONLY);
- if (err) {
- printf("error opening %s: %d\n", name, err);
- return err;
- }
-
- if (pname == NULL) {
- err = vhd_parent_locator_get(&vhd, &pname);
- if (err) {
- printf("error finding %s parent: %d\n", name, err);
- vhd_close(&vhd);
- return err;
- }
- }
-
- if (vhd_parent_raw(&vhd)) {
- parent_fd = open(pname, O_RDWR | O_DIRECT | O_LARGEFILE, 0644);
- if (parent_fd == -1) {
- err = -errno;
- printf("failed to open parent %s: %d\n", pname, err);
- vhd_close(&vhd);
- return err;
- }
- } else {
- err = vhd_open(&parent, pname, VHD_OPEN_RDWR);
- if (err) {
- printf("error opening %s: %d\n", pname, err);
- free(pname);
- vhd_close(&vhd);
- return err;
- }
- }
-
- err = vhd_get_bat(&vhd);
- if (err)
- goto done;
-
- if (vhd_has_batmap(&vhd)) {
- err = vhd_get_batmap(&vhd);
- if (err)
- goto done;
- }
-
- for (i = 0; i < vhd.bat.entries; i++) {
- err = vhd_util_coalesce_block(&vhd, &parent, parent_fd, i);
- if (err)
- goto done;
- }
-
- err = 0;
-
- done:
- if (pflag==0) {
- free(pname);
- }
- vhd_close(&vhd);
- if (parent.file)
- vhd_close(&parent);
- else
- close(parent_fd);
- return err;
-
-usage:
- printf("options: <-n name> [ -p parent name] [-h help]\n");
- return -EINVAL;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-create.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-create.c b/tools/vhd-tools/vhd/lib/vhd-util-create.c
deleted file mode 100644
index a9bdf05..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-create.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "libvhd.h"
-
-int
-vhd_util_create(int argc, char **argv)
-{
- char *name;
- uint64_t size;
- int c, sparse, err;
- vhd_flag_creat_t flags;
-
- err = -EINVAL;
- size = 0;
- sparse = 1;
- name = NULL;
- flags = 0;
-
- if (!argc || !argv)
- goto usage;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:s:rh")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 's':
- err = 0;
- size = strtoull(optarg, NULL, 10);
- break;
- case 'r':
- sparse = 0;
- break;
- case 'h':
- default:
- goto usage;
- }
- }
-
- if (err || !name || optind != argc)
- goto usage;
-
- return vhd_create(name, size << 20,
- (sparse ? HD_TYPE_DYNAMIC : HD_TYPE_FIXED),
- flags);
-
-usage:
- printf("options: <-n name> <-s size (MB)> [-r reserve] [-h help]\n");
- return -EINVAL;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-fill.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-fill.c b/tools/vhd-tools/vhd/lib/vhd-util-fill.c
deleted file mode 100644
index afbfcce..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-fill.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "libvhd.h"
-
-int
-vhd_util_fill(int argc, char **argv)
-{
- int err, c;
- char *buf, *name;
- vhd_context_t vhd;
- uint64_t i, sec, secs;
-
- buf = NULL;
- name = NULL;
-
- if (!argc || !argv)
- goto usage;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:h")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 'h':
- default:
- goto usage;
- }
- }
-
- if (!name || optind != argc)
- goto usage;
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
- if (err) {
- printf("error opening %s: %d\n", name, err);
- return err;
- }
-
- err = vhd_get_bat(&vhd);
- if (err)
- goto done;
-
- err = posix_memalign((void **)&buf, 4096, vhd.header.block_size);
- if (err) {
- err = -err;
- goto done;
- }
-
- sec = 0;
- secs = vhd.header.block_size >> VHD_SECTOR_SHIFT;
-
- for (i = 0; i < vhd.header.max_bat_size; i++) {
- err = vhd_io_read(&vhd, buf, sec, secs);
- if (err)
- goto done;
-
- err = vhd_io_write(&vhd, buf, sec, secs);
- if (err)
- goto done;
-
- sec += secs;
- }
-
- err = 0;
-
- done:
- free(buf);
- vhd_close(&vhd);
- return err;
-
-usage:
- printf("options: <-n name> [-h help]\n");
- return -EINVAL;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-modify.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-modify.c b/tools/vhd-tools/vhd/lib/vhd-util-modify.c
deleted file mode 100644
index b563d6a..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-modify.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Altering operations:
- *
- * 1. Change the parent pointer to another file.
- * 2. Change the size of the file containing the VHD image. This does NOT
- * affect the VHD disk capacity, only the physical size of the file containing
- * the VHD. Naturally, it is not possible to set the file size to be less than
- * the what VHD utilizes.
- * The operation doesn't actually change the file size, but it writes the
- * footer in the right location such that resizing the file (manually, as a
- * separate step) will produce the correct results. If the new file size is
- * greater than the current file size, the file must first be expanded and then
- * altered with this operation. If the new size is smaller than the current
- * size, the VHD must first be altered with this operation and then the file
- * must be shrunk. Failing to resize the file will result in a corrupted VHD.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "libvhd.h"
-
-TEST_FAIL_EXTERN_VARS;
-
-int
-vhd_util_modify(int argc, char **argv)
-{
- char *name;
- vhd_context_t vhd;
- int err, c, size, parent, parent_raw;
- off_t newsize = 0;
- char *newparent = NULL;
-
- name = NULL;
- size = 0;
- parent = 0;
- parent_raw = 0;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:s:p:mh")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 's':
- size = 1;
- errno = 0;
- newsize = strtoll(optarg, NULL, 10);
- if (errno) {
- fprintf(stderr, "Invalid size '%s'\n", optarg);
- goto usage;
- }
- break;
- case 'p':
- parent = 1;
- newparent = optarg;
- break;
- case 'm':
- parent_raw = 1;
- break;
-
- case 'h':
- default:
- goto usage;
- }
- }
-
- if (!name || optind != argc)
- goto usage;
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
- if (err) {
- printf("error opening %s: %d\n", name, err);
- return err;
- }
-
- if (size) {
- err = vhd_set_phys_size(&vhd, newsize);
- if (err)
- printf("failed to set physical size to %"PRIu64":"
- " %d\n", newsize, err);
- }
-
- if (parent) {
- TEST_FAIL_AT(FAIL_REPARENT_BEGIN);
- err = vhd_change_parent(&vhd, newparent, parent_raw);
- if (err) {
- printf("failed to set parent to '%s': %d\n",
- newparent, err);
- goto done;
- }
- TEST_FAIL_AT(FAIL_REPARENT_END);
- }
-
-done:
- vhd_close(&vhd);
- return err;
-
-usage:
- printf("*** Dangerous operations, use with care ***\n");
- printf("options: <-n name> [-p NEW_PARENT set parent [-m raw]] "
- "[-s NEW_SIZE set size] [-h help]\n");
- return -EINVAL;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-query.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-query.c b/tools/vhd-tools/vhd/lib/vhd-util-query.c
deleted file mode 100644
index 44a22d0..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-query.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "libvhd.h"
-
-int
-vhd_util_query(int argc, char **argv)
-{
- char *name;
- vhd_context_t vhd;
- off_t currsize;
- int ret, err, c, size, physize, parent, fields, depth;
-
- name = NULL;
- size = 0;
- physize = 0;
- parent = 0;
- fields = 0;
- depth = 0;
-
- if (!argc || !argv) {
- err = -EINVAL;
- goto usage;
- }
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:vspfdh")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 'v':
- size = 1;
- break;
- case 's':
- physize = 1;
- break;
- case 'p':
- parent = 1;
- break;
- case 'f':
- fields = 1;
- break;
- case 'd':
- depth = 1;
- break;
- case 'h':
- err = 0;
- goto usage;
- default:
- err = -EINVAL;
- goto usage;
- }
- }
-
- if (!name || optind != argc) {
- err = -EINVAL;
- goto usage;
- }
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
- if (err) {
- printf("error opening %s: %d\n", name, err);
- return err;
- }
-
- if (size)
- printf("%"PRIu64"\n", vhd.footer.curr_size >> 20);
-
- if (physize) {
- err = vhd_get_phys_size(&vhd, &currsize);
- if (err)
- printf("failed to get physical size: %d\n", err);
- else
- printf("%"PRIu64"\n", currsize);
- }
-
- if (parent) {
- ret = 0;
-
- if (vhd.footer.type != HD_TYPE_DIFF)
- printf("%s has no parent\n", name);
- else {
- char *pname;
-
- ret = vhd_parent_locator_get(&vhd, &pname);
- if (ret)
- printf("query failed\n");
- else {
- printf("%s\n", pname);
- free(pname);
- }
- }
-
- err = (err ? : ret);
- }
-
- if (fields) {
- int hidden;
-
- ret = vhd_hidden(&vhd, &hidden);
- if (ret)
- printf("error checking 'hidden' field: %d\n", ret);
- else
- printf("hidden: %d\n", hidden);
-
- err = (err ? : ret);
- }
-
- if (depth) {
- int length;
-
- ret = vhd_chain_depth(&vhd, &length);
- if (ret)
- printf("error checking chain depth: %d\n", ret);
- else
- printf("chain depth: %d\n", length);
-
- err = (err ? : ret);
- }
-
- vhd_close(&vhd);
- return err;
-
-usage:
- printf("options: <-n name> [-v print virtual size (in MB)] "
- "[-s print physical utilization (bytes)] [-p print parent] "
- "[-f print fields] [-d print chain depth] [-h help]\n");
- return err;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-read.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-read.c b/tools/vhd-tools/vhd/lib/vhd-util-read.c
deleted file mode 100644
index 2e8dc8b..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-read.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "libvhd.h"
-#include "vhd-util.h"
-
-#define nsize 15
-static char nbuf[nsize];
-
-static inline char *
-__xconv(uint64_t num)
-{
- snprintf(nbuf, nsize, "%#" PRIx64 , num);
- return nbuf;
-}
-
-static inline char *
-__dconv(uint64_t num)
-{
- snprintf(nbuf, nsize, "%" PRIu64, num);
- return nbuf;
-}
-
-#define conv(hex, num) \
- (hex ? __xconv((uint64_t)num) : __dconv((uint64_t)num))
-
-static void
-vhd_print_header(vhd_context_t *vhd, vhd_header_t *h, int hex)
-{
- int err;
- uint32_t cksm;
- char uuid[39], time_str[26], cookie[9], out[512], *name;
-
- printf("VHD Header Summary:\n-------------------\n");
-
- snprintf(cookie, sizeof(cookie), "%s", h->cookie);
- printf("Cookie : %s\n", cookie);
-
- printf("Data offset (unusd) : %s\n", conv(hex, h->data_offset));
- printf("Table offset : %s\n", conv(hex, h->table_offset));
- printf("Header version : 0x%08x\n", h->hdr_ver);
- printf("Max BAT size : %s\n", conv(hex, h->max_bat_size));
- printf("Block size : %s ", conv(hex, h->block_size));
- printf("(%s MB)\n", conv(hex, h->block_size >> 20));
-
- err = vhd_header_decode_parent(vhd, h, &name);
- printf("Parent name : %s\n",
- (err ? "failed to read name" : name));
- free(name);
-
- blk_uuid_to_string(&h->prt_uuid, uuid, sizeof(uuid));
- printf("Parent UUID : %s\n", uuid);
-
- vhd_time_to_string(h->prt_ts, time_str);
- printf("Parent timestamp : %s\n", time_str);
-
- cksm = vhd_checksum_header(h);
- printf("Checksum : 0x%x|0x%x (%s)\n", h->checksum, cksm,
- h->checksum == cksm ? "Good!" : "Bad!");
- printf("\n");
-}
-
-static void
-vhd_print_footer(vhd_footer_t *f, int hex)
-{
- uint64_t c, h, s;
- uint32_t ff_maj, ff_min, cr_maj, cr_min, cksm, cksm_save;
- char time_str[26], creator[5], uuid[39], cookie[9];
-
- printf("VHD Footer Summary:\n-------------------\n");
-
- snprintf(cookie, sizeof(cookie), "%s", f->cookie);
- printf("Cookie : %s\n", cookie);
-
- printf("Features : (0x%08x) %s%s\n", f->features,
- (f->features & HD_TEMPORARY) ? "<TEMP>" : "",
- (f->features & HD_RESERVED) ? "<RESV>" : "");
-
- ff_maj = f->ff_version >> 16;
- ff_min = f->ff_version & 0xffff;
- printf("File format version : Major: %d, Minor: %d\n",
- ff_maj, ff_min);
-
- printf("Data offset : %s\n", conv(hex, f->data_offset));
-
- vhd_time_to_string(f->timestamp, time_str);
- printf("Timestamp : %s\n", time_str);
-
- memcpy(creator, f->crtr_app, 4);
- creator[4] = '\0';
- printf("Creator Application : '%s'\n", creator);
-
- cr_maj = f->crtr_ver >> 16;
- cr_min = f->crtr_ver & 0xffff;
- printf("Creator version : Major: %d, Minor: %d\n",
- cr_maj, cr_min);
-
- printf("Creator OS : %s\n",
- ((f->crtr_os == HD_CR_OS_WINDOWS) ? "Windows" :
- ((f->crtr_os == HD_CR_OS_MACINTOSH) ? "Macintosh" :
- "Unknown!")));
-
- printf("Original disk size : %s MB ", conv(hex, f->orig_size >> 20));
- printf("(%s Bytes)\n", conv(hex, f->orig_size));
-
- printf("Current disk size : %s MB ", conv(hex, f->curr_size >> 20));
- printf("(%s Bytes)\n", conv(hex, f->curr_size));
-
- c = f->geometry >> 16;
- h = (f->geometry & 0x0000FF00) >> 8;
- s = f->geometry & 0x000000FF;
- printf("Geometry : Cyl: %s, ", conv(hex, c));
- printf("Hds: %s, ", conv(hex, h));
- printf("Sctrs: %s\n", conv(hex, s));
- printf(" : = %s MB ", conv(hex, (c * h * s) >> 11));
- printf("(%s Bytes)\n", conv(hex, c * h * s << 9));
-
- printf("Disk type : %s\n",
- f->type <= HD_TYPE_MAX ?
- HD_TYPE_STR[f->type] : "Unknown type!\n");
-
- cksm = vhd_checksum_footer(f);
- printf("Checksum : 0x%x|0x%x (%s)\n", f->checksum, cksm,
- f->checksum == cksm ? "Good!" : "Bad!");
-
- blk_uuid_to_string(&f->uuid, uuid, sizeof(uuid));
- printf("UUID : %s\n", uuid);
-
- printf("Saved state : %s\n", f->saved == 0 ? "No" : "Yes");
- printf("Hidden : %d\n", f->hidden);
- printf("\n");
-}
-
-static inline char *
-code_name(uint32_t code)
-{
- switch(code) {
- case PLAT_CODE_NONE:
- return "PLAT_CODE_NONE";
- case PLAT_CODE_WI2R:
- return "PLAT_CODE_WI2R";
- case PLAT_CODE_WI2K:
- return "PLAT_CODE_WI2K";
- case PLAT_CODE_W2RU:
- return "PLAT_CODE_W2RU";
- case PLAT_CODE_W2KU:
- return "PLAT_CODE_W2KU";
- case PLAT_CODE_MAC:
- return "PLAT_CODE_MAC";
- case PLAT_CODE_MACX:
- return "PLAT_CODE_MACX";
- default:
- return "UNKOWN";
- }
-}
-
-static void
-vhd_print_parent(vhd_context_t *vhd, vhd_parent_locator_t *loc)
-{
- int err;
- char *buf;
-
- err = vhd_parent_locator_read(vhd, loc, &buf);
- if (err) {
- printf("failed to read parent name\n");
- return;
- }
-
- printf(" decoded name : %s\n", buf);
-}
-
-static void
-vhd_print_parent_locators(vhd_context_t *vhd, int hex)
-{
- int i, n;
- vhd_parent_locator_t *loc;
-
- printf("VHD Parent Locators:\n--------------------\n");
-
- n = sizeof(vhd->header.loc) / sizeof(struct prt_loc);
- for (i = 0; i < n; i++) {
- loc = &vhd->header.loc[i];
-
- if (loc->code == PLAT_CODE_NONE)
- continue;
-
- printf("locator: : %d\n", i);
- printf(" code : %s\n",
- code_name(loc->code));
- printf(" data_space : %s\n",
- conv(hex, loc->data_space));
- printf(" data_length : %s\n",
- conv(hex, loc->data_len));
- printf(" data_offset : %s\n",
- conv(hex, loc->data_offset));
- vhd_print_parent(vhd, loc);
- printf("\n");
- }
-}
-
-static void
-vhd_print_batmap_header(vhd_batmap_t *batmap, int hex)
-{
- uint32_t cksm;
-
- printf("VHD Batmap Summary:\n-------------------\n");
- printf("Batmap offset : %s\n",
- conv(hex, batmap->header.batmap_offset));
- printf("Batmap size (secs) : %s\n",
- conv(hex, batmap->header.batmap_size));
- printf("Batmap version : 0x%08x\n",
- batmap->header.batmap_version);
-
- cksm = vhd_checksum_batmap(batmap);
- printf("Checksum : 0x%x|0x%x (%s)\n",
- batmap->header.checksum, cksm,
- (batmap->header.checksum == cksm ? "Good!" : "Bad!"));
- printf("\n");
-}
-
-static inline int
-check_block_range(vhd_context_t *vhd, uint64_t block, int hex)
-{
- if (block > vhd->header.max_bat_size) {
- fprintf(stderr, "block %s past end of file\n",
- conv(hex, block));
- return -ERANGE;
- }
-
- return 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->batmap, hex);
- }
- }
-
- return 0;
-}
-
-static int
-vhd_dump_headers(const char *name, int hex)
-{
- vhd_context_t vhd;
-
- libvhd_set_log_level(1);
- memset(&vhd, 0, sizeof(vhd));
-
- printf("\n%s appears invalid; dumping headers\n\n", name);
-
- vhd.fd = open(name, O_DIRECT | O_LARGEFILE | O_RDONLY);
- if (vhd.fd == -1)
- return -errno;
-
- vhd.file = strdup(name);
-
- vhd_read_footer(&vhd, &vhd.footer);
- vhd_read_header(&vhd, &vhd.header);
-
- vhd_print_footer(&vhd.footer, hex);
- vhd_print_header(&vhd, &vhd.header, hex);
-
- close(vhd.fd);
- free(vhd.file);
-
- return 0;
-}
-
-static int
-vhd_print_logical_to_physical(vhd_context_t *vhd,
- uint64_t sector, int count, int hex)
-{
- int i;
- uint32_t blk, lsec;
- uint64_t cur, offset;
-
- if (vhd_sectors_to_bytes(sector + count) > vhd->footer.curr_size) {
- fprintf(stderr, "sector %s past end of file\n",
- conv(hex, sector + count));
- return -ERANGE;
- }
-
- for (i = 0; i < count; i++) {
- cur = sector + i;
- blk = cur / vhd->spb;
- lsec = cur % vhd->spb;
- offset = vhd->bat.bat[blk];
-
- if (offset != DD_BLK_UNUSED) {
- offset += lsec + 1;
- offset = vhd_sectors_to_bytes(offset);
- }
-
- printf("logical sector %s: ", conv(hex, cur));
- printf("block number: %s, ", conv(hex, blk));
- printf("sector offset: %s, ", conv(hex, lsec));
- printf("file offset: %s\n", (offset == DD_BLK_UNUSED ?
- "not allocated" : conv(hex, offset)));
- }
-
- return 0;
-}
-
-static int
-vhd_print_bat(vhd_context_t *vhd, uint64_t block, int count, int hex)
-{
- int i;
- uint64_t cur, offset;
-
- if (check_block_range(vhd, block + count, hex))
- return -ERANGE;
-
- for (i = 0; i < count; i++) {
- cur = block + i;
- offset = vhd->bat.bat[cur];
-
- printf("block: %s: ", conv(hex, cur));
- printf("offset: %s\n",
- (offset == DD_BLK_UNUSED ? "not allocated" :
- conv(hex, vhd_sectors_to_bytes(offset))));
- }
-
- return 0;
-}
-
-static inline void
-write_full(int fd, void* buf, size_t count)
-{
- ssize_t num_written = 0;
- if (!buf) return;
-
-
- while(count > 0) {
-
- num_written = write(fd, buf, count);
- if (num_written == -1) {
- if (errno == EINTR)
- continue;
- else
- return;
- }
-
- count -= num_written;
- buf += num_written;
- }
-}
-
-static int
-vhd_print_bitmap(vhd_context_t *vhd, uint64_t block, int count, int hex)
-{
- char *buf;
- int i, err;
- uint64_t cur;
-
- if (check_block_range(vhd, block + count, hex))
- return -ERANGE;
-
- for (i = 0; i < count; i++) {
- cur = block + i;
-
- if (vhd->bat.bat[cur] == DD_BLK_UNUSED) {
- printf("block %s not allocated\n", conv(hex, cur));
- continue;
- }
-
- err = vhd_read_bitmap(vhd, cur, &buf);
- if (err)
- goto out;
-
- write_full(STDOUT_FILENO, buf,
- vhd_sectors_to_bytes(vhd->bm_secs));
- free(buf);
- }
-
- err = 0;
-out:
- return err;
-}
-
-static int
-vhd_test_bitmap(vhd_context_t *vhd, uint64_t sector, int count, int hex)
-{
- char *buf;
- uint64_t cur;
- int i, err, bit;
- uint32_t blk, bm_blk, sec;
-
- if (vhd_sectors_to_bytes(sector + count) > vhd->footer.curr_size) {
- printf("sector %s past end of file\n", conv(hex, sector));
- return -ERANGE;
- }
-
- bm_blk = -1;
- buf = NULL;
-
- for (i = 0; i < count; i++) {
- cur = sector + i;
- blk = cur / vhd->spb;
- sec = cur % vhd->spb;
-
- if (blk != bm_blk) {
- bm_blk = blk;
- free(buf);
- buf = NULL;
-
- if (vhd->bat.bat[blk] != DD_BLK_UNUSED) {
- err = vhd_read_bitmap(vhd, blk, &buf);
- if (err)
- goto out;
- }
- }
-
- if (vhd->bat.bat[blk] == DD_BLK_UNUSED)
- bit = 0;
- else
- bit = vhd_bitmap_test(vhd, buf, blk);
-
- print:
- printf("block %s: ", conv(hex, blk));
- printf("sec: %s: %d\n", conv(hex, sec), bit);
- }
-
- err = 0;
- out:
- free(buf);
- return err;
-}
-
-static int
-vhd_print_batmap(vhd_context_t *vhd)
-{
- int err;
- size_t size;
-
- err = vhd_get_batmap(vhd);
- if (err) {
- printf("failed to read batmap: %d\n", err);
- return err;
- }
-
- size = vhd_sectors_to_bytes(vhd->batmap.header.batmap_size);
- write_full(STDOUT_FILENO, vhd->batmap.map, size);
-
- return 0;
-}
-
-static int
-vhd_test_batmap(vhd_context_t *vhd, uint64_t block, int count, int hex)
-{
- int i, err;
- uint64_t cur;
-
- if (check_block_range(vhd, block + count, hex))
- return -ERANGE;
-
- err = vhd_get_batmap(vhd);
- if (err) {
- fprintf(stderr, "failed to get batmap\n");
- return err;
- }
-
- for (i = 0; i < count; i++) {
- cur = block + i;
- fprintf(stderr, "batmap for block %s: %d\n", conv(hex, cur),
- vhd_batmap_test(vhd, &vhd->batmap, cur));
- }
-
- return 0;
-}
-
-static int
-vhd_print_data(vhd_context_t *vhd, uint64_t block, int count, int hex)
-{
- char *buf;
- int i, err;
- uint64_t cur;
-
- err = 0;
-
- if (check_block_range(vhd, block + count, hex))
- return -ERANGE;
-
- for (i = 0; i < count; i++) {
- cur = block + i;
-
- if (vhd->bat.bat[cur] == DD_BLK_UNUSED) {
- printf("block %s not allocated\n", conv(hex, cur));
- continue;
- }
-
- err = vhd_read_block(vhd, cur, &buf);
- if (err)
- break;
-
- write_full(STDOUT_FILENO, buf, vhd->header.block_size);
- free(buf);
- }
-
- return err;
-}
-
-static int
-vhd_read_data(vhd_context_t *vhd, uint64_t sec, int count, int hex)
-{
- char *buf;
- uint64_t cur;
- int err, max, secs;
-
- if (vhd_sectors_to_bytes(sec + count) > vhd->footer.curr_size)
- return -ERANGE;
-
- max = MIN(vhd_sectors_to_bytes(count), VHD_BLOCK_SIZE);
- err = posix_memalign((void **)&buf, VHD_SECTOR_SIZE, max);
- if (err)
- return -err;
-
- cur = sec;
- while (count) {
- secs = MIN((max >> VHD_SECTOR_SHIFT), count);
- err = vhd_io_read(vhd, buf, cur, secs);
- if (err)
- break;
-
- write_full(STDOUT_FILENO, buf, vhd_sectors_to_bytes(secs));
-
- cur += secs;
- count -= secs;
- }
-
- free(buf);
- return err;
-}
-
-int
-vhd_util_read(int argc, char **argv)
-{
- char *name;
- vhd_context_t vhd;
- int c, err, headers, hex;
- uint64_t bat, bitmap, tbitmap, batmap, tbatmap, data, lsec, count, read;
-
- err = 0;
- hex = 0;
- headers = 0;
- count = 1;
- bat = -1;
- bitmap = -1;
- tbitmap = -1;
- batmap = -1;
- tbatmap = -1;
- data = -1;
- lsec = -1;
- read = -1;
- name = NULL;
-
- if (!argc || !argv)
- goto usage;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:pt:b:m:i:aj:d:c:r:xh")) != -1) {
- switch(c) {
- case 'n':
- name = optarg;
- break;
- case 'p':
- headers = 1;
- break;
- case 't':
- lsec = strtoul(optarg, NULL, 10);
- break;
- case 'b':
- bat = strtoull(optarg, NULL, 10);
- break;
- case 'm':
- bitmap = strtoull(optarg, NULL, 10);
- break;
- case 'i':
- tbitmap = strtoul(optarg, NULL, 10);
- break;
- case 'a':
- batmap = 1;
- break;
- case 'j':
- tbatmap = strtoull(optarg, NULL, 10);
- break;
- case 'd':
- data = strtoull(optarg, NULL, 10);
- break;
- case 'r':
- read = strtoull(optarg, NULL, 10);
- break;
- case 'c':
- count = strtoul(optarg, NULL, 10);
- break;
- case 'x':
- hex = 1;
- break;
- case 'h':
- default:
- goto usage;
- }
- }
-
- if (!name || optind != argc)
- goto usage;
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
- if (err) {
- printf("Failed to open %s: %d\n", name, err);
- vhd_dump_headers(name, hex);
- return err;
- }
-
- err = vhd_get_bat(&vhd);
- if (err) {
- printf("Failed to get bat for %s: %d\n", name, err);
- goto out;
- }
-
- if (headers)
- vhd_print_headers(&vhd, hex);
-
- if (lsec != -1) {
- err = vhd_print_logical_to_physical(&vhd, lsec, count, hex);
- if (err)
- goto out;
- }
-
- if (bat != -1) {
- err = vhd_print_bat(&vhd, bat, count, hex);
- if (err)
- goto out;
- }
-
- if (bitmap != -1) {
- err = vhd_print_bitmap(&vhd, bitmap, count, hex);
- if (err)
- goto out;
- }
-
- if (tbitmap != -1) {
- err = vhd_test_bitmap(&vhd, tbitmap, count, hex);
- if (err)
- goto out;
- }
-
- if (batmap != -1) {
- err = vhd_print_batmap(&vhd);
- if (err)
- goto out;
- }
-
- if (tbatmap != -1) {
- err = vhd_test_batmap(&vhd, tbatmap, count, hex);
- if (err)
- goto out;
- }
-
- if (data != -1) {
- err = vhd_print_data(&vhd, data, count, hex);
- if (err)
- goto out;
- }
-
- if (read != -1) {
- err = vhd_read_data(&vhd, read, count, hex);
- if (err)
- goto out;
- }
-
- err = 0;
-
- out:
- vhd_close(&vhd);
- return err;
-
- usage:
- printf("options:\n"
- "-h help\n"
- "-n name\n"
- "-p print VHD headers\n"
- "-t sec translate logical sector to VHD location\n"
- "-b blk print bat entry\n"
- "-m blk print bitmap\n"
- "-i sec test bitmap for logical sector\n"
- "-a print batmap\n"
- "-j blk test batmap for block\n"
- "-d blk print data\n"
- "-c num num units\n"
- "-r sec read num sectors at sec\n"
- "-x print in hex\n");
- return EINVAL;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-repair.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-repair.c b/tools/vhd-tools/vhd/lib/vhd-util-repair.c
deleted file mode 100644
index 14ded81..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-repair.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "libvhd.h"
-
-int
-vhd_util_repair(int argc, char **argv)
-{
- char *name;
- int err, c;
- off_t eof;
- vhd_context_t vhd;
-
- name = NULL;
-
- if (!argc || !argv)
- goto usage;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:h")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 'h':
- default:
- goto usage;
- }
- }
-
- if (!name || optind != argc)
- goto usage;
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
- if (err) {
- printf("error opening %s: %d\n", name, err);
- return err;
- }
-
- err = vhd_end_of_data(&vhd, &eof);
- if (err) {
- printf("error finding end of data: %d\n", err);
- goto done;
- }
-
- err = vhd_write_footer_at(&vhd, &vhd.footer, eof);
-
- done:
- vhd_close(&vhd);
- return err;
-
-usage:
- printf("options: <-n name> [-h help]\n");
- return -EINVAL;
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e9a74959/tools/vhd-tools/vhd/lib/vhd-util-resize.c
----------------------------------------------------------------------
diff --git a/tools/vhd-tools/vhd/lib/vhd-util-resize.c b/tools/vhd-tools/vhd/lib/vhd-util-resize.c
deleted file mode 100644
index c8a9528..0000000
--- a/tools/vhd-tools/vhd/lib/vhd-util-resize.c
+++ /dev/null
@@ -1,1131 +0,0 @@
-/* Copyright (c) 2008, XenSource Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of XenSource Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <syslog.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-
-#include "libvhd-journal.h"
-
-#if 1
-#define DFPRINTF(_f, _a...) fprintf(stdout, _f, ##_a)
-#else
-#define DFPRINTF(_f, _a...) ((void)0)
-#endif
-
-#define EPRINTF(_f, _a...) \
- do { \
- syslog(LOG_INFO, "%s: " _f, __func__, ##_a); \
- DFPRINTF(_f, _a); \
- } while (0)
-
-typedef struct vhd_block {
- uint32_t block;
- uint32_t offset;
-} vhd_block_t;
-
-TEST_FAIL_EXTERN_VARS;
-
-static inline uint32_t
-secs_to_blocks_down(vhd_context_t *vhd, uint64_t secs)
-{
- return secs / vhd->spb;
-}
-
-static uint32_t
-secs_to_blocks_up(vhd_context_t *vhd, uint64_t secs)
-{
- uint32_t blocks;
-
- blocks = secs / vhd->spb;
- if (secs % vhd->spb)
- blocks++;
-
- return blocks;
-}
-
-static int
-vhd_fixed_shrink(vhd_journal_t *journal, uint64_t secs)
-{
- int err;
- uint64_t new_eof;
- vhd_context_t *vhd;
-
- vhd = &journal->vhd;
-
- new_eof = vhd->footer.curr_size - vhd_sectors_to_bytes(secs);
- if (new_eof <= sizeof(vhd_footer_t))
- return -EINVAL;
-
- err = ftruncate(vhd->fd, new_eof);
- if (err)
- return errno;
-
- vhd->footer.curr_size = new_eof;
- return vhd_write_footer(vhd, &vhd->footer);
-}
-
-static int
-vhd_write_zeros(vhd_journal_t *journal, off_t off, uint64_t size)
-{
- int err;
- char *buf;
- vhd_context_t *vhd;
- uint64_t bytes, map;
-
- vhd = &journal->vhd;
- map = MIN(size, VHD_BLOCK_SIZE);
-
- err = vhd_seek(vhd, off, SEEK_SET);
- if (err)
- return err;
-
- buf = mmap(0, map, PROT_READ, MAP_SHARED | MAP_ANON, -1, 0);
- if (buf == MAP_FAILED)
- return -errno;
-
- do {
- bytes = MIN(size, map);
-
- err = vhd_write(vhd, buf, bytes);
- if (err)
- break;
-
- size -= bytes;
- } while (size);
-
- munmap(buf, map);
-
- return err;
-}
-
-static int
-vhd_fixed_grow(vhd_journal_t *journal, uint64_t secs)
-{
- int err;
- vhd_context_t *vhd;
- uint64_t size, eof, new_eof;
-
- size = vhd_sectors_to_bytes(secs);
- vhd = &journal->vhd;
-
- err = vhd_seek(vhd, 0, SEEK_END);
- if (err)
- goto out;
-
- eof = vhd_position(vhd);
- if (eof == (off_t)-1) {
- err = -errno;
- goto out;
- }
-
- err = vhd_write_zeros(journal, eof - sizeof(vhd_footer_t), size);
- if (err)
- goto out;
-
- new_eof = eof + size;
- err = vhd_seek(vhd, new_eof, SEEK_SET);
- if (err)
- goto out;
-
- vhd->footer.curr_size += size;
- err = vhd_write_footer(vhd, &vhd->footer);
- if (err)
- goto out;
-
- err = 0;
-
-out:
- return err;
-}
-
-static int
-vhd_fixed_resize(vhd_journal_t *journal, uint64_t size)
-{
- int err;
- vhd_context_t *vhd;
- uint64_t cur_secs, new_secs;
-
- vhd = &journal->vhd;
- cur_secs = vhd->footer.curr_size >> VHD_SECTOR_SHIFT;
- new_secs = size << (20 - VHD_SECTOR_SHIFT);
-
- if (cur_secs == new_secs)
- return 0;
- else if (cur_secs > new_secs)
- err = vhd_fixed_shrink(journal, cur_secs - new_secs);
- else
- err = vhd_fixed_grow(journal, new_secs - cur_secs);
-
- return err;
-}
-
-static inline void
-swap(vhd_block_t *list, int a, int b)
-{
- vhd_block_t tmp;
-
- tmp = list[a];
- list[a] = list[b];
- list[b] = tmp;
-}
-
-static int
-partition(vhd_block_t *list, int left, int right, int pidx)
-{
- int i, sidx;
- long long pval;
-
- sidx = left;
- pval = list[pidx].offset;
- swap(list, pidx, right);
-
- for (i = left; i < right; i++)
- if (list[i].offset >= pval) {
- swap(list, sidx, i);
- ++sidx;
- }
-
- swap(list, right, sidx);
- return sidx;
-}
-
-static void
-quicksort(vhd_block_t *list, int left, int right)
-{
- int pidx, new_pidx;
-
- if (right < left)
- return;
-
- pidx = left;
- new_pidx = partition(list, left, right, pidx);
- quicksort(list, left, new_pidx - 1);
- quicksort(list, new_pidx + 1, right);
-}
-
-static int
-vhd_move_block(vhd_journal_t *journal, uint32_t src, off_t offset)
-{
- int err;
- char *buf;
- size_t size;
- vhd_context_t *vhd;
- off_t off, src_off;
-
- buf = NULL;
- vhd = &journal->vhd;
- off = offset;
- size = vhd_sectors_to_bytes(vhd->bm_secs);
- src_off = vhd->bat.bat[src];
-
- if (src_off == DD_BLK_UNUSED)
- return -EINVAL;
- src_off = vhd_sectors_to_bytes(src_off);
-
- err = vhd_journal_add_block(journal, src,
- VHD_JOURNAL_DATA | VHD_JOURNAL_METADATA);
- if (err)
- goto out;
-
- err = vhd_read_bitmap(vhd, src, &buf);
- if (err)
- goto out;
-
- err = vhd_seek(vhd, off, SEEK_SET);
- if (err)
- goto out;
-
- err = vhd_write(vhd, buf, size);
- if (err)
- goto out;
-
- free(buf);
- buf = NULL;
- off += size;
- size = vhd_sectors_to_bytes(vhd->spb);
-
- err = vhd_read_block(vhd, src, &buf);
- if (err)
- goto out;
-
- err = vhd_seek(vhd, off, SEEK_SET);
- if (err)
- goto out;
-
- err = vhd_write(vhd, buf, size);
- if (err)
- goto out;
-
- vhd->bat.bat[src] = offset >> VHD_SECTOR_SHIFT;
-
- err = vhd_write_zeros(journal, src_off,
- vhd_sectors_to_bytes(vhd->bm_secs + vhd->spb));
-
-out:
- free(buf);
- return err;
-}
-
-static int
-vhd_clobber_block(vhd_journal_t *journal, uint32_t src, uint32_t dest)
-{
- int err;
- off_t off;
- vhd_context_t *vhd;
-
- vhd = &journal->vhd;
- off = vhd_sectors_to_bytes(vhd->bat.bat[dest]);
-
- err = vhd_journal_add_block(journal, dest,
- VHD_JOURNAL_DATA | VHD_JOURNAL_METADATA);
- if (err)
- return err;
-
- err = vhd_move_block(journal, src, off);
- if (err)
- return err;
-
- vhd->bat.bat[dest] = DD_BLK_UNUSED;
-
- return 0;
-}
-
-/*
- * remove a list of blocks from the vhd file
- * if a block to be removed:
- * - resides at the end of the file: simply clear its bat entry
- * - resides elsewhere: move the last block in the file into its position
- * and update the bat to reflect this
- */
-static int
-vhd_defrag_shrink(vhd_journal_t *journal,
- vhd_block_t *original_free_list, int free_cnt)
-{
- vhd_context_t *vhd;
- int i, j, free_idx, err;
- vhd_block_t *blocks, *free_list;
-
- err = 0;
- blocks = NULL;
- free_list = NULL;
- vhd = &journal->vhd;
-
- blocks = malloc(vhd->bat.entries * sizeof(vhd_block_t));
- if (!blocks) {
- err = -ENOMEM;
- goto out;
- }
-
- free_list = malloc(free_cnt * sizeof(vhd_block_t));
- if (!free_list) {
- err = -ENOMEM;
- goto out;
- }
-
- for (i = 0; i < vhd->bat.entries; i++) {
- blocks[i].block = i;
- blocks[i].offset = vhd->bat.bat[i];
- }
-
- memcpy(free_list, original_free_list,
- free_cnt * sizeof(vhd_block_t));
-
- /* sort both the to-free list and the bat list
- * in order of descending file offset */
- quicksort(free_list, 0, free_cnt - 1);
- quicksort(blocks, 0, vhd->bat.entries - 1);
-
- for (i = 0, free_idx = 0;
- i < vhd->bat.entries && free_idx < free_cnt; i++) {
- vhd_block_t *b = blocks + i;
-
- if (b->offset == DD_BLK_UNUSED)
- continue;
-
- for (j = free_idx; j < free_cnt; j++)
- if (b->block == free_list[j].block) {
- /* the last block in the file is in the list of
- * blocks to remove; no need to shuffle the
- * data -- just clear the bat entry */
- vhd->bat.bat[free_list[j].block] = DD_BLK_UNUSED;
- free_idx++;
- continue;
- }
-
- err = vhd_clobber_block(journal, b->block,
- free_list[free_idx++].block);
- if (err)
- goto out;
- }
-
- /* clear any bat entries for blocks we did not shuffle */
- for (i = free_idx; i < free_cnt; i++)
- vhd->bat.bat[free_list[i].block] = DD_BLK_UNUSED;
-
-out:
- free(blocks);
- free(free_list);
-
- return err;
-}
-
-static int
-vhd_clear_bat_entries(vhd_journal_t *journal, uint32_t entries)
-{
- int i, err;
- vhd_context_t *vhd;
- off_t orig_map_off, new_map_off;
- uint32_t orig_entries, new_entries;
-
- vhd = &journal->vhd;
- orig_entries = vhd->header.max_bat_size;
- new_entries = orig_entries - entries;
-
- if (vhd_has_batmap(vhd)) {
- err = vhd_batmap_header_offset(vhd, &orig_map_off);
- if (err)
- return err;
- }
-
- /* update header */
- vhd->header.max_bat_size = new_entries;
- err = vhd_write_header(vhd, &vhd->header);
- if (err)
- return err;
-
- /* update footer */
- vhd->footer.curr_size = (uint64_t)new_entries * vhd->header.block_size;
- vhd->footer.geometry = vhd_chs(vhd->footer.curr_size);
- err = vhd_write_footer(vhd, &vhd->footer);
- if (err)
- return err;
-
- /* update bat -- we don't reclaim space, just clear entries */
- for (i = new_entries; i < orig_entries; i++)
- vhd->bat.bat[i] = 0;
-
- err = vhd_write_bat(vhd, &vhd->bat);
- if (err)
- return err;
-
- /* update this after write_bat so the end of the bat is zeored */
- vhd->bat.entries = new_entries;
-
- if (!vhd_has_batmap(vhd))
- return 0;
-
- /* zero out old batmap header if new header has moved */
- err = vhd_batmap_header_offset(vhd, &new_map_off);
- if (err)
- return err;
-
- if (orig_map_off != new_map_off) {
- size_t size;
-
- size = vhd_bytes_padded(sizeof(struct dd_batmap_hdr));
-
- err = vhd_write_zeros(journal, orig_map_off, size);
- if (err)
- return err;
- }
-
- /* update batmap -- clear entries for freed blocks */
- for (i = new_entries; i < orig_entries; i++)
- vhd_batmap_clear(vhd, &vhd->batmap, i);
-
- err = vhd_write_batmap(vhd, &vhd->batmap);
- if (err)
- return err;
-
- return 0;
-}
-
-static int
-vhd_dynamic_shrink(vhd_journal_t *journal, uint64_t secs)
-{
- off_t eof;
- uint32_t blocks;
- vhd_context_t *vhd;
- int i, j, err, free_cnt;
- struct vhd_block *free_list;
-
- printf("dynamic shrink not fully implemented\n");
- return -ENOSYS;
-
- eof = 0;
- free_cnt = 0;
- free_list = NULL;
- vhd = &journal->vhd;
-
- blocks = secs_to_blocks_down(vhd, secs);
- if (blocks == 0)
- return 0;
-
- if (vhd_has_batmap(vhd)) {
- err = vhd_get_batmap(vhd);
- if (err)
- return err;
- }
-
- free_list = malloc(blocks * sizeof(struct vhd_block));
- if (!free_list)
- return -ENOMEM;
-
- for (i = vhd->bat.entries - 1, j = 0; i >= 0 && j < blocks; i--, j++) {
- uint32_t blk = vhd->bat.bat[i];
-
- if (blk != DD_BLK_UNUSED) {
- free_list[free_cnt].block = i;
- free_list[free_cnt].offset = blk;
- free_cnt++;
- }
- }
-
- if (free_cnt) {
- err = vhd_defrag_shrink(journal, free_list, free_cnt);
- if (err)
- goto out;
- }
-
- err = vhd_clear_bat_entries(journal, blocks);
- if (err)
- goto out;
-
- /* remove data beyond footer */
- err = vhd_end_of_data(vhd, &eof);
- if (err)
- goto out;
-
- err = ftruncate(vhd->fd, eof + sizeof(vhd_footer_t));
- if (err) {
- err = -errno;
- goto out;
- }
-
- err = 0;
-
-out:
- free(free_list);
- return err;
-}
-
-static inline void
-vhd_first_data_block(vhd_context_t *vhd, vhd_block_t *block)
-{
- int i;
- uint32_t blk;
-
- memset(block, 0, sizeof(vhd_block_t));
-
- for (i = 0; i < vhd->bat.entries; i++) {
- blk = vhd->bat.bat[i];
-
- if (blk != DD_BLK_UNUSED) {
- if (!block->offset || blk < block->offset) {
- block->block = i;
- block->offset = blk;
- }
- }
- }
-}
-
-static inline uint32_t
-vhd_next_block_offset(vhd_context_t *vhd)
-{
- int i;
- uint32_t blk, end, spp, next;
-
- next = 0;
- spp = getpagesize() >> VHD_SECTOR_SHIFT;
-
- for (i = 0; i < vhd->bat.entries; i++) {
- blk = vhd->bat.bat[i];
-
- if (blk != DD_BLK_UNUSED) {
- end = blk + vhd->spb + vhd->bm_secs;
- next = MAX(next, end);
- }
- }
-
- return next;
-}
-
-static inline int
-in_range(off_t off, off_t start, off_t size)
-{
- return (start < off && start + size > off);
-}
-
-#define SKIP_HEADER 0x01
-#define SKIP_BAT 0x02
-#define SKIP_BATMAP 0x04
-#define SKIP_PLOC 0x08
-#define SKIP_DATA 0x10
-
-static inline int
-skip_check(int mode, int type)
-{
- return mode & type;
-}
-
-static int
-vhd_check_for_clobber(vhd_context_t *vhd, off_t off, int mode)
-{
- int i, n;
- char *msg;
- size_t size;
- vhd_block_t fb;
- vhd_parent_locator_t *loc;
-
- msg = NULL;
-
- if (!vhd_type_dynamic(vhd))
- return 0;
-
- if (off < VHD_SECTOR_SIZE) {
- msg = "backup footer";
- goto fail;
- }
-
- if (!skip_check(mode, SKIP_HEADER))
- if (in_range(off,
- vhd->footer.data_offset, sizeof(vhd_header_t))) {
- msg = "header";
- goto fail;
- }
-
- if (!skip_check(mode, SKIP_BAT))
- if (in_range(off, vhd->header.table_offset,
- vhd_bytes_padded(vhd->header.max_bat_size *
- sizeof(uint32_t)))) {
- msg = "bat";
- goto fail;
- }
-
- if (!skip_check(mode, SKIP_BATMAP))
- if (vhd_has_batmap(vhd) &&
- in_range(off, vhd->batmap.header.batmap_offset,
- vhd_bytes_padded(vhd->batmap.header.batmap_size))) {
- msg = "batmap";
- goto fail;
- }
-
- if (!skip_check(mode, SKIP_PLOC)) {
- n = sizeof(vhd->header.loc) / sizeof(vhd_parent_locator_t);
- for (i = 0; i < n; i++) {
- loc = vhd->header.loc + i;
- if (loc->code == PLAT_CODE_NONE)
- continue;
-
- size = vhd_parent_locator_size(loc);
- if (in_range(off, loc->data_offset, size)) {
- msg = "parent locator";
- goto fail;
- }
- }
- }
-
- if (!skip_check(mode, SKIP_DATA)) {
- vhd_first_data_block(vhd, &fb);
- if (fb.offset && in_range(off,
- vhd_sectors_to_bytes(fb.offset),
- VHD_BLOCK_SIZE)) {
- msg = "data block";
- goto fail;
- }
- }
-
- return 0;
-
-fail:
- EPRINTF("write to 0x%08"PRIx64" would clobber %s\n", off, msg);
- return -EINVAL;
-}
-
-/*
- * take any metadata after the bat (@eob) and shift it
- */
-static int
-vhd_shift_metadata(vhd_journal_t *journal, off_t eob,
- size_t bat_needed, size_t map_needed)
-{
- int i, n, err;
- vhd_context_t *vhd;
- size_t size_needed;
- char *buf, **locators;
- vhd_parent_locator_t *loc;
-
- vhd = &journal->vhd;
- size_needed = bat_needed + map_needed;
-
- n = sizeof(vhd->header.loc) / sizeof(vhd_parent_locator_t);
-
- locators = calloc(n, sizeof(char *));
- if (!locators)
- return -ENOMEM;
-
- for (i = 0; i < n; i++) {
- size_t size;
-
- loc = vhd->header.loc + i;
- if (loc->code == PLAT_CODE_NONE)
- continue;
-
- if (loc->data_offset < eob)
- continue;
-
- size = vhd_parent_locator_size(loc);
- err = posix_memalign((void **)&buf, VHD_SECTOR_SIZE, size);
- if (err) {
- err = -err;
- buf = NULL;
- goto out;
- }
-
- err = vhd_seek(vhd, loc->data_offset, SEEK_SET);
- if (err)
- goto out;
-
- err = vhd_read(vhd, buf, size);
- if (err)
- goto out;
-
- locators[i] = buf;
- }
-
- for (i = 0; i < n; i++) {
- off_t off;
- size_t size;
-
- if (!locators[i])
- continue;
-
- loc = vhd->header.loc + i;
- off = loc->data_offset + size_needed;
- size = vhd_parent_locator_size(loc);
-
- if (vhd_check_for_clobber(vhd, off + size, SKIP_PLOC)) {
- EPRINTF("%s: shifting locator %d would clobber data\n",
- vhd->file, i);
- return -EINVAL;
- }
-
- err = vhd_seek(vhd, off, SEEK_SET);
- if (err)
- goto out;
-
- err = vhd_write(vhd, locators[i], size);
- if (err)
- goto out;
-
- free(locators[i]);
- locators[i] = NULL;
- loc->data_offset = off;
-
- /* write the new header after writing the new bat */
- }
-
- if (vhd_has_batmap(vhd) && vhd->batmap.header.batmap_offset > eob) {
- vhd->batmap.header.batmap_offset += bat_needed;
-
- /* write the new batmap after writing the new bat */
- }
-
- err = 0;
-
-out:
- for (i = 0; i < n; i++)
- free(locators[i]);
- free(locators);
-
- return err;
-}
-
-static int
-vhd_add_bat_entries(vhd_journal_t *journal, int entries)
-{
- int i, err;
- off_t off;
- vhd_bat_t new_bat;
- vhd_context_t *vhd;
- uint32_t new_entries;
- vhd_batmap_t new_batmap;
- uint64_t bat_size, new_bat_size, map_size, new_map_size;
-
- vhd = &journal->vhd;
- new_entries = vhd->header.max_bat_size + entries;
-
- bat_size = vhd_bytes_padded(vhd->header.max_bat_size *
- sizeof(uint32_t));
- new_bat_size = vhd_bytes_padded(new_entries * sizeof(uint32_t));
-
- map_size = vhd_bytes_padded((vhd->header.max_bat_size + 7) >> 3);
- new_map_size = vhd_bytes_padded((new_entries + 7) >> 3);
-
- off = vhd->header.table_offset + new_bat_size;
- if (vhd_check_for_clobber(vhd, off, SKIP_BAT | SKIP_BATMAP)) {
- EPRINTF("%s: writing new bat of 0x%"PRIx64" bytes "
- "at 0x%08"PRIx64" would clobber data\n",
- vhd->file, new_bat_size, vhd->header.table_offset);
- return -EINVAL;
- }
-
- if (vhd_has_batmap(vhd)) {
- off = vhd->batmap.header.batmap_offset + new_map_size;
- if (vhd_check_for_clobber(vhd, off, 0)) {
- EPRINTF("%s: writing new batmap of 0x%"PRIx64" bytes"
- " at 0x%08"PRIx64" would clobber data\n", vhd->file,
- new_map_size, vhd->batmap.header.batmap_offset);
- return -EINVAL;
- }
- }
-
- /* update header */
- vhd->header.max_bat_size = new_entries;
- err = vhd_write_header(vhd, &vhd->header);
- if (err)
- return err;
-
- /* update footer */
- vhd->footer.curr_size = (uint64_t)new_entries * vhd->header.block_size;
- vhd->footer.geometry = vhd_chs(vhd->footer.curr_size);
- vhd->footer.checksum = vhd_checksum_footer(&vhd->footer);
- err = vhd_write_footer(vhd, &vhd->footer);
- if (err)
- return err;
-
- /* allocate new bat */
- err = posix_memalign((void **)&new_bat.bat, VHD_SECTOR_SIZE, new_bat_size);
- if (err)
- return -err;
-
- new_bat.spb = vhd->bat.spb;
- new_bat.entries = new_entries;
- memcpy(new_bat.bat, vhd->bat.bat, bat_size);
- for (i = vhd->bat.entries; i < new_entries; i++)
- new_bat.bat[i] = DD_BLK_UNUSED;
-
- /* write new bat */
- err = vhd_write_bat(vhd, &new_bat);
- if (err) {
- free(new_bat.bat);
- return err;
- }
-
- /* update in-memory bat */
- free(vhd->bat.bat);
- vhd->bat = new_bat;
-
- if (!vhd_has_batmap(vhd))
- return 0;
-
- /* allocate new batmap */
- err = posix_memalign((void **)&new_batmap.map,
- VHD_SECTOR_SIZE, new_map_size);
- if (err)
- return err;
-
- new_batmap.header = vhd->batmap.header;
- new_batmap.header.batmap_size = secs_round_up_no_zero(new_map_size);
- memcpy(new_batmap.map, vhd->batmap.map, map_size);
- memset(new_batmap.map + map_size, 0, new_map_size - map_size);
-
- /* write new batmap */
- err = vhd_write_batmap(vhd, &new_batmap);
- if (err) {
- free(new_batmap.map);
- return err;
- }
-
- /* update in-memory batmap */
- free(vhd->batmap.map);
- vhd->batmap = new_batmap;
-
- return 0;
-}
-
-static int
-vhd_dynamic_grow(vhd_journal_t *journal, uint64_t secs)
-{
- int i, err;
- off_t eob, eom;
- vhd_context_t *vhd;
- vhd_block_t first_block;
- uint64_t blocks, size_needed;
- uint64_t bat_needed, bat_size, bat_avail, bat_bytes, bat_secs;
- uint64_t map_needed, map_size, map_avail, map_bytes, map_secs;
-
- vhd = &journal->vhd;
-
- size_needed = 0;
- bat_needed = 0;
- map_needed = 0;
-
- /* number of vhd blocks to add */
- blocks = secs_to_blocks_up(vhd, secs);
-
- /* size in bytes needed for new bat entries */
- bat_needed = blocks * sizeof(uint32_t);
- map_needed = (blocks >> 3) + 1;
-
- /* available bytes in current bat */
- bat_bytes = vhd->header.max_bat_size * sizeof(uint32_t);
- bat_secs = secs_round_up_no_zero(bat_bytes);
- bat_size = vhd_sectors_to_bytes(bat_secs);
- bat_avail = bat_size - bat_bytes;
-
- if (vhd_has_batmap(vhd)) {
- /* avaliable bytes in current batmap */
- map_bytes = (vhd->header.max_bat_size + 7) >> 3;
- map_secs = vhd->batmap.header.batmap_size;
- map_size = vhd_sectors_to_bytes(map_secs);
- map_avail = map_size - map_bytes;
- } else {
- map_needed = 0;
- map_avail = 0;
- }
-
- /* we have enough space already; just extend the bat */
- if (bat_needed <= bat_avail && map_needed <= map_avail)
- goto add_entries;
-
- /* we need to add new sectors to the bat */
- if (bat_needed > bat_avail) {
- bat_needed -= bat_avail;
- bat_needed = vhd_bytes_padded(bat_needed);
- } else
- bat_needed = 0;
-
- /* we need to add new sectors to the batmap */
- if (map_needed > map_avail) {
- map_needed -= map_avail;
- map_needed = vhd_bytes_padded(map_needed);
- } else
- map_needed = 0;
-
- /* how many additional bytes do we need? */
- size_needed = bat_needed + map_needed;
-
- /* calculate space between end of headers and beginning of data */
- err = vhd_end_of_headers(vhd, &eom);
- if (err)
- return err;
-
- eob = vhd->header.table_offset + vhd_sectors_to_bytes(bat_secs);
- vhd_first_data_block(vhd, &first_block);
-
- /* no blocks allocated; just shift post-bat metadata */
- if (!first_block.offset)
- goto shift_metadata;
-
- /*
- * not enough space --
- * move vhd data blocks to the end of the file to make room
- */
- do {
- off_t new_off, bm_size, gap_size;
-
- new_off = vhd_sectors_to_bytes(vhd_next_block_offset(vhd));
-
- /* data region of segment should begin on page boundary */
- bm_size = vhd_sectors_to_bytes(vhd->bm_secs);
- if ((new_off + bm_size) % 4096) {
- gap_size = 4096 - ((new_off + bm_size) % 4096);
-
- err = vhd_write_zeros(journal, new_off, gap_size);
- if (err)
- return err;
-
- new_off += gap_size;
- }
-
- err = vhd_move_block(journal, first_block.block, new_off);
- if (err)
- return err;
-
- vhd_first_data_block(vhd, &first_block);
-
- } while (eom + size_needed >= vhd_sectors_to_bytes(first_block.offset));
-
- TEST_FAIL_AT(FAIL_RESIZE_DATA_MOVED);
-
-shift_metadata:
- /* shift any metadata after the bat to make room for new bat sectors */
- err = vhd_shift_metadata(journal, eob, bat_needed, map_needed);
- if (err)
- return err;
-
- TEST_FAIL_AT(FAIL_RESIZE_METADATA_MOVED);
-
-add_entries:
- return vhd_add_bat_entries(journal, blocks);
-}
-
-static int
-vhd_dynamic_resize(vhd_journal_t *journal, uint64_t size)
-{
- int err;
- vhd_context_t *vhd;
- uint64_t cur_secs, new_secs;
-
- vhd = &journal->vhd;
- cur_secs = vhd->footer.curr_size >> VHD_SECTOR_SHIFT;
- new_secs = size << (20 - VHD_SECTOR_SHIFT);
-
- if (cur_secs == new_secs)
- return 0;
-
- err = vhd_get_header(vhd);
- if (err)
- return err;
-
- err = vhd_get_bat(vhd);
- if (err)
- return err;
-
- if (vhd_has_batmap(vhd)) {
- err = vhd_get_batmap(vhd);
- if (err)
- return err;
- }
-
- if (cur_secs > new_secs)
- err = vhd_dynamic_shrink(journal, cur_secs - new_secs);
- else
- err = vhd_dynamic_grow(journal, new_secs - cur_secs);
-
- return err;
-}
-
-static int
-vhd_util_resize_check_creator(const char *name)
-{
- int err;
- vhd_context_t vhd;
-
- err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_STRICT);
- if (err) {
- printf("error opening %s: %d\n", name, err);
- return err;
- }
-
- if (!vhd_creator_tapdisk(&vhd)) {
- printf("%s not created by xen; resize not supported\n", name);
- err = -EINVAL;
- }
-
- vhd_close(&vhd);
- return err;
-}
-
-int
-vhd_util_resize(int argc, char **argv)
-{
- char *name, *jname;
- uint64_t size;
- int c, err, jerr;
- vhd_journal_t journal;
- vhd_context_t *vhd;
-
- err = -EINVAL;
- size = 0;
- name = NULL;
- jname = NULL;
-
- optind = 0;
- while ((c = getopt(argc, argv, "n:j:s:h")) != -1) {
- switch (c) {
- case 'n':
- name = optarg;
- break;
- case 'j':
- jname = optarg;
- break;
- case 's':
- err = 0;
- size = strtoull(optarg, NULL, 10);
- break;
- case 'h':
- default:
- goto usage;
- }
- }
-
- if (err || !name || !jname || argc != optind)
- goto usage;
-
- err = vhd_util_resize_check_creator(name);
- if (err)
- return err;
-
- libvhd_set_log_level(1);
- err = vhd_journal_create(&journal, name, jname);
- if (err) {
- printf("creating journal failed: %d\n", err);
- return err;
- }
-
- vhd = &journal.vhd;
-
- err = vhd_get_footer(vhd);
- if (err)
- goto out;
-
- TEST_FAIL_AT(FAIL_RESIZE_BEGIN);
-
- if (vhd_type_dynamic(vhd))
- err = vhd_dynamic_resize(&journal, size);
- else
- err = vhd_fixed_resize(&journal, size);
-
- TEST_FAIL_AT(FAIL_RESIZE_END);
-
-out:
- if (err) {
- printf("resize failed: %d\n", err);
- jerr = vhd_journal_revert(&journal);
- } else
- jerr = vhd_journal_commit(&journal);
-
- if (jerr) {
- printf("closing journal failed: %d\n", jerr);
- vhd_journal_close(&journal);
- } else
- vhd_journal_remove(&journal);
-
- return (err ? : jerr);
-
-usage:
- printf("options: <-n name> <-j journal> <-s size (in MB)> [-h help]\n");
- return -EINVAL;
-}