On Wed, Nov 17, 2010 at 01:52:42PM -0600, Adam Litke wrote:
Implement getBackingStore() for QED images. The header format is
defined in
the QED spec:
http://wiki.qemu.org/Features/QED .
+static int
+qedGetBackingStore(char **res,
+ int *format,
+ const unsigned char *buf,
+ size_t buf_size)
+{
+ unsigned long long flags;
+ unsigned long offset, size;
+
+ *res = NULL;
+ /* Check if this image has a backing file */
+ if (buf_size < QED_HDR_FEATURES_OFFSET+8)
+ return BACKING_STORE_INVALID;
+ flags = qedGetHeaderULL(buf + QED_HDR_FEATURES_OFFSET);
+ if (!(flags & QED_F_BACKING_FILE))
+ return BACKING_STORE_OK;
+
+ /* Parse the backing file */
+ if (buf_size < QED_HDR_BACKING_FILE_OFFSET+8)
+ return BACKING_STORE_INVALID;
+ offset = qedGetHeaderUL(buf + QED_HDR_BACKING_FILE_OFFSET);
+ if (offset > buf_size)
+ return BACKING_STORE_INVALID;
+ size = qedGetHeaderUL(buf + QED_HDR_BACKING_FILE_SIZE);
+ if (size == 0)
+ return BACKING_STORE_OK;
+ if (offset + size > buf_size || offset + size < offset)
+ return BACKING_STORE_INVALID;
+ if (size + 1 == 0)
+ return BACKING_STORE_INVALID;
+ if (VIR_ALLOC_N(*res, size + 1) < 0) {
+ virReportOOMError();
+ return BACKING_STORE_ERROR;
+ }
+ memcpy(*res, buf + offset, size);
+ (*res)[size] = '\0';
+
+ if (format) {
+ if (flags & QED_F_BACKING_FORMAT_NO_PROBE)
+ *format = virStorageFileFormatTypeFromString("raw");
+ else
+ *format = VIR_STORAGE_FILE_AUTO;
+ }
+
+ return BACKING_STORE_OK;
+}
Setting *format = VIR_STORAGE_FILE_AUTO is going to make non-raw backing
files unusuable in a out of the box libvirt configuration. libvirt will
refuse to recurse into any backing file marked 'auto' for security reasons,
treating them as raw.
In virDomainDiskDefForeachPath from src/conf/domain_conf.c
....
format = meta.backingStoreFormat;
if (format == VIR_STORAGE_FILE_AUTO &&
!allowProbing)
format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */
} while (nextpath);
The thing is that this QED format can do safe auto probing, so we need to
distinguish it from formats which can't do safe auto probing. We probably
need to add a separate SAFE_AUTO for this, and handle that case in
src/conf/domain_conf.c by adding
if (format == VIR_STORAGE_FILE_SAFE_AUTO)
format = VIR_STORAGE_FILE_AUTO;
in the end of that loop, which will allow it to continue the loop with
probing for that backing store.
Regards,
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://deltacloud.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|