From: Dietmar Maurer Date: Fri, 6 Dec 2013 05:44:05 +0000 (+0100) Subject: allow to backup into a directory X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=2bde36a46ae3a42deba243d3ab27e17c9867e707;p=pve-qemu-kvm.git allow to backup into a directory --- diff --git a/debian/patches/backup-add-dir-format.patch b/debian/patches/backup-add-dir-format.patch new file mode 100644 index 0000000..18906ab --- /dev/null +++ b/debian/patches/backup-add-dir-format.patch @@ -0,0 +1,215 @@ +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; + } + diff --git a/debian/patches/series b/debian/patches/series index c13ca90..65fd740 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -18,4 +18,5 @@ backup-vma-add-dump-config.patch backup-vma-restore-tolerate-a-size-difference-up-to-4M.patch backup-modify-job-api.patch backup-add-pve-monitor-commands.patch +backup-add-dir-format.patch internal-snapshot-async.patch