---
block/meson.build | 2 +
meson.build | 5 +
- vma-reader.c | 867 +++++++++++++++++++++++++++++++++++++++++++++
- vma-writer.c | 793 +++++++++++++++++++++++++++++++++++++++++
- vma.c | 878 ++++++++++++++++++++++++++++++++++++++++++++++
+ vma-reader.c | 867 ++++++++++++++++++++++++++++++++++++++++++++
+ vma-writer.c | 793 ++++++++++++++++++++++++++++++++++++++++
+ vma.c | 900 ++++++++++++++++++++++++++++++++++++++++++++++
vma.h | 150 ++++++++
- 6 files changed, 2695 insertions(+)
+ 6 files changed, 2717 insertions(+)
create mode 100644 vma-reader.c
create mode 100644 vma-writer.c
create mode 100644 vma.c
softmmu_ss.add(files('block-ram-registrar.c'))
diff --git a/meson.build b/meson.build
-index d964e741e7..603cdb97bb 100644
+index 30447cfaef..38a4e2bcef 100644
--- a/meson.build
+++ b/meson.build
@@ -1527,6 +1527,8 @@ keyutils = dependency('libkeyutils', required: false,
# libselinux
selinux = dependency('libselinux',
required: get_option('selinux'),
-@@ -3646,6 +3648,9 @@ if have_tools
+@@ -3650,6 +3652,9 @@ if have_tools
dependencies: [blockdev, qemuutil, gnutls, selinux],
install: true)
+}
diff --git a/vma.c b/vma.c
new file mode 100644
-index 0000000000..304f02bc84
+index 0000000000..347f6283ca
--- /dev/null
+++ b/vma.c
-@@ -0,0 +1,878 @@
+@@ -0,0 +1,900 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ "vma list <filename>\n"
+ "vma config <filename> [-c config]\n"
+ "vma create <filename> [-c config] pathname ...\n"
-+ "vma extract <filename> [-r <fifo>] <targetdir>\n"
++ "vma extract <filename> [-d <drive-list>] [-r <fifo>] <targetdir>\n"
+ "vma verify <filename> [-v]\n"
+ ;
+
+ const char *filename;
+ const char *dirname;
+ const char *readmap = NULL;
++ gchar **drive_list = NULL;
+
+ for (;;) {
-+ c = getopt(argc, argv, "hvr:");
++ c = getopt(argc, argv, "hvd:r:");
+ if (c == -1) {
+ break;
+ }
+ case 'h':
+ help();
+ break;
++ case 'd':
++ drive_list = g_strsplit(optarg, ",", 254);
++ break;
+ case 'r':
+ readmap = optarg;
+ break;
+
+ int i;
+ int vmstate_fd = -1;
-+ guint8 vmstate_stream = 0;
++ bool drive_rename_bitmap[255];
++ memset(drive_rename_bitmap, 0, sizeof(drive_rename_bitmap));
+
+ for (i = 1; i < 255; i++) {
+ VmaDeviceInfo *di = vma_reader_get_device_info(vmar, i);
+ if (di && (strcmp(di->devname, "vmstate") == 0)) {
-+ vmstate_stream = i;
+ char *statefn = g_strdup_printf("%s/vmstate.bin", dirname);
+ vmstate_fd = open(statefn, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if (vmstate_fd < 0) {
+
+ BlockBackend *blk = NULL;
+
-+ if (readmap) {
++ if (drive_list) {
++ skip = true;
++ int j;
++ for (j = 0; drive_list[j]; j++) {
++ if (strcmp(drive_list[j], di->devname) == 0) {
++ skip = false;
++ drive_rename_bitmap[i] = true;
++ break;
++ }
++ }
++ } else {
++ drive_rename_bitmap[i] = true;
++ }
++
++ if (!skip && readmap) {
+ RestoreMap *map;
+ map = (RestoreMap *)g_hash_table_lookup(devmap, di->devname);
+ if (map == NULL) {
+ cache = map->cache;
+ write_zero = map->write_zero;
+ skip = map->skip;
-+ } else {
++ } else if (!skip) {
+ devfn = g_strdup_printf("%s/tmp-disk-%s.raw",
+ dirname, di->devname);
+ printf("DEVINFO %s %zd\n", devfn, di->size);
+ }
+ }
+
++ if (drive_list) {
++ g_strfreev(drive_list);
++ }
++
+ if (vma_reader_restore(vmar, vmstate_fd, verbose, &errp) < 0) {
+ g_error("restore failed - %s", error_get_pretty(errp));
+ }
+ if (!readmap) {
+ for (i = 1; i < 255; i++) {
+ VmaDeviceInfo *di = vma_reader_get_device_info(vmar, i);
-+ if (di && (i != vmstate_stream)) {
++ if (di && drive_rename_bitmap[i]) {
+ char *tmpfn = g_strdup_printf("%s/tmp-disk-%s.raw",
+ dirname, di->devname);
+ char *fn = g_strdup_printf("%s/disk-%s.raw",
+ ret = blk_co_preadv(job->target, start * VMA_CLUSTER_SIZE,
+ readlen, &qiov, 0);
+ if (ret < 0) {
-+ vma_writer_set_error(job->vmaw, "read error", -1);
++ vma_writer_set_error(job->vmaw, "read error");
+ goto out;
+ }
+
+ size_t zb = 0;
+ if (vma_writer_write(job->vmaw, job->dev_id, start, buf, &zb) < 0) {
-+ vma_writer_set_error(job->vmaw, "backup_dump_cb vma_writer_write failed", -1);
++ vma_writer_set_error(job->vmaw, "backup_dump_cb vma_writer_write failed");
+ goto out;
+ }
+ }
+}
diff --git a/vma.h b/vma.h
new file mode 100644
-index 0000000000..1b62859165
+index 0000000000..86d2873aa5
--- /dev/null
+++ b/vma.h
@@ -0,0 +1,150 @@
+int coroutine_fn vma_writer_flush_output(VmaWriter *vmaw);
+
+int vma_writer_get_status(VmaWriter *vmaw, VmaStatus *status);
-+void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...);
++void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
+
+
+VmaReader *vma_reader_create(const char *filename, Error **errp);