|
@@ -374,7 +374,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|
assert(bs);
|
|
assert(bs);
|
|
assert(target);
|
|
assert(target);
|
|
GLOBAL_STATE_CODE();
|
|
GLOBAL_STATE_CODE();
|
|
- GRAPH_RDLOCK_GUARD_MAINLOOP();
|
|
|
|
|
|
|
|
/* QMP interface protects us from these cases */
|
|
/* QMP interface protects us from these cases */
|
|
assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
|
|
assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
|
|
@@ -385,31 +384,33 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ bdrv_graph_rdlock_main_loop();
|
|
if (!bdrv_is_inserted(bs)) {
|
|
if (!bdrv_is_inserted(bs)) {
|
|
error_setg(errp, "Device is not inserted: %s",
|
|
error_setg(errp, "Device is not inserted: %s",
|
|
bdrv_get_device_name(bs));
|
|
bdrv_get_device_name(bs));
|
|
- return NULL;
|
|
|
|
|
|
+ goto error_rdlock;
|
|
}
|
|
}
|
|
|
|
|
|
if (!bdrv_is_inserted(target)) {
|
|
if (!bdrv_is_inserted(target)) {
|
|
error_setg(errp, "Device is not inserted: %s",
|
|
error_setg(errp, "Device is not inserted: %s",
|
|
bdrv_get_device_name(target));
|
|
bdrv_get_device_name(target));
|
|
- return NULL;
|
|
|
|
|
|
+ goto error_rdlock;
|
|
}
|
|
}
|
|
|
|
|
|
if (compress && !bdrv_supports_compressed_writes(target)) {
|
|
if (compress && !bdrv_supports_compressed_writes(target)) {
|
|
error_setg(errp, "Compression is not supported for this drive %s",
|
|
error_setg(errp, "Compression is not supported for this drive %s",
|
|
bdrv_get_device_name(target));
|
|
bdrv_get_device_name(target));
|
|
- return NULL;
|
|
|
|
|
|
+ goto error_rdlock;
|
|
}
|
|
}
|
|
|
|
|
|
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
|
|
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
|
|
- return NULL;
|
|
|
|
|
|
+ goto error_rdlock;
|
|
}
|
|
}
|
|
|
|
|
|
if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
|
|
if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
|
|
- return NULL;
|
|
|
|
|
|
+ goto error_rdlock;
|
|
}
|
|
}
|
|
|
|
+ bdrv_graph_rdunlock_main_loop();
|
|
|
|
|
|
if (perf->max_workers < 1 || perf->max_workers > INT_MAX) {
|
|
if (perf->max_workers < 1 || perf->max_workers > INT_MAX) {
|
|
error_setg(errp, "max-workers must be between 1 and %d", INT_MAX);
|
|
error_setg(errp, "max-workers must be between 1 and %d", INT_MAX);
|
|
@@ -437,6 +438,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|
|
|
|
|
len = bdrv_getlength(bs);
|
|
len = bdrv_getlength(bs);
|
|
if (len < 0) {
|
|
if (len < 0) {
|
|
|
|
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
|
|
error_setg_errno(errp, -len, "Unable to get length for '%s'",
|
|
error_setg_errno(errp, -len, "Unable to get length for '%s'",
|
|
bdrv_get_device_or_node_name(bs));
|
|
bdrv_get_device_or_node_name(bs));
|
|
goto error;
|
|
goto error;
|
|
@@ -444,6 +446,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|
|
|
|
|
target_len = bdrv_getlength(target);
|
|
target_len = bdrv_getlength(target);
|
|
if (target_len < 0) {
|
|
if (target_len < 0) {
|
|
|
|
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
|
|
error_setg_errno(errp, -target_len, "Unable to get length for '%s'",
|
|
error_setg_errno(errp, -target_len, "Unable to get length for '%s'",
|
|
bdrv_get_device_or_node_name(bs));
|
|
bdrv_get_device_or_node_name(bs));
|
|
goto error;
|
|
goto error;
|
|
@@ -493,8 +496,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|
block_copy_set_speed(bcs, speed);
|
|
block_copy_set_speed(bcs, speed);
|
|
|
|
|
|
/* Required permissions are taken by copy-before-write filter target */
|
|
/* Required permissions are taken by copy-before-write filter target */
|
|
|
|
+ bdrv_graph_wrlock(target);
|
|
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
|
|
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
|
|
&error_abort);
|
|
&error_abort);
|
|
|
|
+ bdrv_graph_wrunlock();
|
|
|
|
|
|
return &job->common;
|
|
return &job->common;
|
|
|
|
|
|
@@ -507,4 +512,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|
}
|
|
}
|
|
|
|
|
|
return NULL;
|
|
return NULL;
|
|
|
|
+
|
|
|
|
+error_rdlock:
|
|
|
|
+ bdrv_graph_rdunlock_main_loop();
|
|
|
|
+ return NULL;
|
|
}
|
|
}
|