--- /dev/null
+Index: new/qapi-schema.json
+===================================================================
+--- new.orig/qapi-schema.json 2013-12-06 06:05:10.000000000 +0100
++++ new/qapi-schema.json 2013-12-06 06:17:13.000000000 +0100
+@@ -586,7 +586,7 @@
+ # @vma: Proxmox vma backup format
+ ##
+ { 'enum': 'BackupFormat',
+- 'data': [ 'vma' ] }
++ 'data': [ 'vma', 'dir' ] }
+
+ ##
+ # @backup:
+Index: new/blockdev.c
+===================================================================
+--- new.orig/blockdev.c 2013-12-06 06:17:06.000000000 +0100
++++ new/blockdev.c 2013-12-06 06:17:13.000000000 +0100
+@@ -1463,6 +1463,8 @@
+ uint8_t dev_id;
+ //bool started;
+ bool completed;
++ char targetfile[PATH_MAX];
++ BlockDriverState *target;
+ } PVEBackupDevInfo;
+
+ static void pvebackup_run_next_job(void);
+@@ -1534,8 +1536,11 @@
+
+ di->completed = true;
+ di->bs = NULL;
++ di->target = NULL;
+
+- vma_writer_close_stream(backup_state.vmaw, di->dev_id);
++ if (backup_state.vmaw) {
++ vma_writer_close_stream(backup_state.vmaw, di->dev_id);
++ }
+
+ if (!backup_state.cancel) {
+ pvebackup_run_next_job();
+@@ -1610,6 +1615,7 @@
+ bool has_speed, int64_t speed, Error **errp)
+ {
+ BlockDriverState *bs;
++ const char *backup_dir = NULL;
+ Error *local_err = NULL;
+ uuid_t uuid;
+ VmaWriter *vmaw = NULL;
+@@ -1626,11 +1632,6 @@
+ /* Todo: try to auto-detect format based on file name */
+ format = has_format ? format : BACKUP_FORMAT_VMA;
+
+- if (format != BACKUP_FORMAT_VMA) {
+- error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
+- return NULL;
+- }
+-
+ if (has_devlist) {
+ devs = g_strsplit_set(devlist, ",;:", -1);
+
+@@ -1698,27 +1699,63 @@
+
+ uuid_generate(uuid);
+
+- vmaw = vma_writer_create(backup_file, uuid, &local_err);
+- if (!vmaw) {
+- if (error_is_set(&local_err)) {
+- error_propagate(errp, local_err);
++ if (format == BACKUP_FORMAT_VMA) {
++ vmaw = vma_writer_create(backup_file, uuid, &local_err);
++ if (!vmaw) {
++ if (error_is_set(&local_err)) {
++ error_propagate(errp, local_err);
++ }
++ goto err;
+ }
+- goto err;
+- }
+
+- /* register all devices for vma writer */
+- l = di_list;
+- while (l) {
+- PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+- l = g_list_next(l);
++ /* register all devices for vma writer */
++ l = di_list;
++ while (l) {
++ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
++ l = g_list_next(l);
+
+- const char *devname = bdrv_get_device_name(di->bs);
+- di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
+- if (di->dev_id <= 0) {
+- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+- "register_stream failed");
++ const char *devname = bdrv_get_device_name(di->bs);
++ di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
++ if (di->dev_id <= 0) {
++ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
++ "register_stream failed");
++ goto err;
++ }
++ }
++ } else if (format == BACKUP_FORMAT_DIR) {
++ if (mkdir(backup_file, 0640) != 0) {
++ error_setg_errno(errp, errno, "can't create directory '%s'\n",
++ backup_file);
+ goto err;
+ }
++ backup_dir = backup_file;
++
++ l = di_list;
++ while (l) {
++ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
++ l = g_list_next(l);
++
++ const char *devname = bdrv_get_device_name(di->bs);
++ snprintf(di->targetfile, PATH_MAX, "%s/%s.raw", backup_dir, devname);
++
++ int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
++ bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
++ di->size, flags, &local_err, false);
++ if (error_is_set(&local_err)) {
++ error_propagate(errp, local_err);
++ goto err;
++ }
++
++ di->target = bdrv_new("");
++ if (bdrv_open(di->target, di->targetfile, NULL, flags, NULL, &local_err) < 0) {
++ bdrv_unref(di->target);
++ error_propagate(errp, local_err);
++ goto err;
++ }
++ }
++ } else {
++ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
++ goto err;
+ }
+
+ /* add configuration file to archive */
+@@ -1731,12 +1768,27 @@
+ goto err;
+ }
+
+- const char *basename = g_path_get_basename(config_file);
+- if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
+- error_setg(errp, "unable to add config data to vma archive");
+- g_free(cdata);
+- goto err;
++ char *basename = g_path_get_basename(config_file);
++
++ if (format == BACKUP_FORMAT_VMA) {
++ if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
++ error_setg(errp, "unable to add config data to vma archive");
++ g_free(cdata);
++ g_free(basename);
++ goto err;
++ }
++ } else if (format == BACKUP_FORMAT_DIR) {
++ char config_path[PATH_MAX];
++ snprintf(config_path, PATH_MAX, "%s/%s.raw", backup_dir, basename);
++ if (!g_file_set_contents(config_path, cdata, clen, &err)) {
++ error_setg(errp, "unable to write config file '%s'", config_path);
++ g_free(cdata);
++ g_free(basename);
++ goto err;
++ }
+ }
++
++ g_free(basename);
+ g_free(cdata);
+ }
+
+@@ -1776,10 +1828,11 @@
+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+ l = g_list_next(l);
+
+- backup_start(di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL,
++ backup_start(di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL,
+ BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
+ pvebackup_dump_cb, pvebackup_complete_cb, di,
+ true, &local_err);
++
+ if (local_err != NULL) {
+ error_setg(&backup_state.error, "backup_job_create failed");
+ pvebackup_cancel(NULL);
+@@ -1796,8 +1849,17 @@
+
+ l = di_list;
+ while (l) {
+- g_free(l->data);
++ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+ l = g_list_next(l);
++
++ if (di->target) {
++ bdrv_unref(di->target);
++ }
++
++ if (di->targetfile[0]) {
++ unlink(di->targetfile);
++ }
++ g_free(di);
+ }
+ g_list_free(di_list);
+
+@@ -1811,6 +1873,10 @@
+ unlink(backup_file);
+ }
+
++ if (backup_dir) {
++ rmdir(backup_dir);
++ }
++
+ return NULL;
+ }
+