qmp_drive_backup(backup->device, backup->target,
backup->has_format, backup->format,
+ backup->sync,
backup->has_mode, backup->mode,
backup->has_speed, backup->speed,
backup->has_on_source_error, backup->on_source_error,
void qmp_drive_backup(const char *device, const char *target,
bool has_format, const char *format,
+ enum MirrorSyncMode sync,
bool has_mode, enum NewImageMode mode,
bool has_speed, int64_t speed,
bool has_on_source_error, BlockdevOnError on_source_error,
int64_t size;
int ret;
+ if (sync != MIRROR_SYNC_MODE_FULL) {
+ error_setg(errp, "only sync mode 'full' is currently supported");
+ return;
+ }
if (!has_speed) {
speed = 0;
}
{
.name = "drive-backup",
- .args_type = "device:B,target:s,speed:i?,mode:s?,format:s?,"
+ .args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
"on-source-error:s?,on-target-error:s?",
.mhandler.cmd_new = qmp_marshal_input_drive_backup,
},
- "format": the format of the new destination, default is to probe if 'mode' is
'existing', else the format of the source
(json-string, optional)
+- "sync": what parts of the disk image should be copied to the destination;
+ possibilities include "full" for all the disk, "top" for only the sectors
+ allocated in the topmost image, or "none" to only replicate new I/O
+ (MirrorSyncMode).
- "mode": whether and how QEMU should create a new image
(NewImageMode, optional, default 'absolute-paths')
- "speed": the maximum speed, in bytes per second (json-int, optional)
self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-backup', device='drive0',
- target=target_img)
+ target=target_img, sync='full')
self.assert_qmp(result, 'return', {})
event = self.cancel_and_wait()
self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-backup', device='drive0',
- target=target_img)
+ target=target_img, sync='full')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-pause', device='drive0')
def test_medium_not_found(self):
result = self.vm.qmp('drive-backup', device='ide1-cd0',
- target=target_img)
+ target=target_img, sync='full')
self.assert_qmp(result, 'error/class', 'GenericError')
def test_image_not_found(self):
result = self.vm.qmp('drive-backup', device='drive0',
- mode='existing', target=target_img)
+ target=target_img, sync='full', mode='existing')
self.assert_qmp(result, 'error/class', 'GenericError')
def test_device_not_found(self):
result = self.vm.qmp('drive-backup', device='nonexistent',
- target=target_img)
+ target=target_img, sync='full')
self.assert_qmp(result, 'error/class', 'DeviceNotFound')
class TestSetSpeed(iotests.QMPTestCase):
self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-backup', device='drive0',
- target=target_img)
+ target=target_img, sync='full')
self.assert_qmp(result, 'return', {})
# Default speed is 0
# Check setting speed in drive-backup works
result = self.vm.qmp('drive-backup', device='drive0',
- target=target_img, speed=4*1024*1024)
+ target=target_img, sync='full', speed=4*1024*1024)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block-jobs')
self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-backup', device='drive0',
- target=target_img, speed=-1)
+ target=target_img, sync='full', speed=-1)
self.assert_qmp(result, 'error/class', 'GenericError')
self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-backup', device='drive0',
- target=target_img)
+ target=target_img, sync='full')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
result = self.vm.qmp('transaction', actions=[{
'type': 'drive-backup',
'data': { 'device': 'drive0',
- 'target': target_img },
+ 'target': target_img,
+ 'sync': 'full' },
}
])
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('transaction', actions=[{
'type': 'drive-backup',
'data': { 'device': 'drive0',
- 'target': target_img },
+ 'target': target_img,
+ 'sync': 'full' },
}
])
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('transaction', actions=[{
'type': 'drive-backup',
'data': { 'device': 'ide1-cd0',
- 'target': target_img },
+ 'target': target_img,
+ 'sync': 'full' },
}
])
self.assert_qmp(result, 'error/class', 'GenericError')
'type': 'drive-backup',
'data': { 'device': 'drive0',
'mode': 'existing',
- 'target': target_img },
+ 'target': target_img,
+ 'sync': 'full' },
}
])
self.assert_qmp(result, 'error/class', 'GenericError')
'type': 'drive-backup',
'data': { 'device': 'nonexistent',
'mode': 'existing',
- 'target': target_img },
+ 'target': target_img,
+ 'sync': 'full' },
}
])
self.assert_qmp(result, 'error/class', 'DeviceNotFound')
'type': 'drive-backup',
'data': { 'device': 'nonexistent',
'mode': 'existing',
- 'target': target_img },
+ 'target': target_img,
+ 'sync': 'full' },
}, {
'type': 'Abort',
'data': {},