This commit changes the way hmp_change() checks if an encryption key is required for the device to be inserted.
Instead of checking for QERR_DEVICE_ENCRYPTED, hmp_change() now checks if the device was successfully inserted, is encrypted and is missing an encryption key. This change is needed because QERR_DEVICE_ENCRYPTED is going to be dropped by a future commit. Signed-off-by: Luiz Capitulino <lcapitul...@redhat.com> --- hmp.c | 54 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/hmp.c b/hmp.c index 1ebeb63..ea21cf7 100644 --- a/hmp.c +++ b/hmp.c @@ -783,17 +783,29 @@ static void hmp_change_read_arg(Monitor *mon, const char *password, static void cb_hmp_change_bdrv_pwd(Monitor *mon, const char *password, void *opaque) { - Error *encryption_err = opaque; + char *device = opaque; Error *err = NULL; - const char *device; - - device = error_get_field(encryption_err, "device"); qmp_block_passwd(device, password, &err); hmp_handle_error(mon, &err); - error_free(encryption_err); monitor_read_command(mon, 1); + g_free(device); +} + +static void hmp_change_ask_user_key(Monitor *mon, const BlockInfo *binfo) +{ + monitor_printf(mon, "%s (%s) is encrypted.\n", binfo->device, + binfo->inserted->file); + + if (!monitor_get_rs(mon)) { + monitor_printf(mon, + "terminal does not support password prompting\n"); + return; + } + + readline_start(monitor_get_rs(mon), "Password: ", 1, + cb_hmp_change_bdrv_pwd, g_strdup(binfo->device)); } void hmp_change(Monitor *mon, const QDict *qdict) @@ -801,6 +813,7 @@ void hmp_change(Monitor *mon, const QDict *qdict) const char *device = qdict_get_str(qdict, "device"); const char *target = qdict_get_str(qdict, "target"); const char *arg = qdict_get_try_str(qdict, "arg"); + BlockInfoList *bdev_list = NULL, *bdev; Error *err = NULL; if (strcmp(device, "vnc") == 0 && @@ -813,21 +826,30 @@ void hmp_change(Monitor *mon, const QDict *qdict) } qmp_change(device, target, !!arg, arg, &err); - if (error_is_type(err, QERR_DEVICE_ENCRYPTED)) { - monitor_printf(mon, "%s (%s) is encrypted.\n", - error_get_field(err, "device"), - error_get_field(err, "filename")); - if (!monitor_get_rs(mon)) { - monitor_printf(mon, - "terminal does not support password prompting\n"); + if (error_is_set(&err)) { + /* qmp_change() failed. If 'device' is returned by qmp_query_block(), + * is encrypted and doesn't have a valid encryption key set, then + * either the user passed an invalid key or didn't pass one at all. + * Ask the user for the key. + */ + bdev_list = qmp_query_block(NULL); + for (bdev = bdev_list; bdev; bdev = bdev->next) { + if (!strcmp(bdev->value->device, device) && + blockinfo_is_encrypted(bdev->value) && + !blockinfo_key_is_set(bdev->value)) { + hmp_change_ask_user_key(mon, bdev->value); + break; + } + } + + if (bdev) { error_free(err); - return; + err = NULL; } - readline_start(monitor_get_rs(mon), "Password: ", 1, - cb_hmp_change_bdrv_pwd, err); - return; } + hmp_handle_error(mon, &err); + qapi_free_BlockInfoList(bdev_list); } void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict) -- 1.7.11.2.249.g31c7954.dirty