From: Luiz Capitulino <lcapitulino@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: kwolf@redhat.com, aliguori@us.ibm.com, qemu-devel@nongnu.org,
mdroth@linux.vnet.ibm.com, pbonzini@redhat.com,
eblake@redhat.com
Subject: Re: [Qemu-devel] [PATCH 12/34] hmp: hmp_cont(): don't rely on QERR_DEVICE_ENCRYPTED
Date: Thu, 2 Aug 2012 11:22:35 -0300 [thread overview]
Message-ID: <20120802112235.4b18c09c@doriath.home> (raw)
In-Reply-To: <87k3xhqzmj.fsf@blackfin.pond.sub.org>
On Thu, 02 Aug 2012 13:53:08 +0200
Markus Armbruster <armbru@redhat.com> wrote:
> Luiz Capitulino <lcapitulino@redhat.com> writes:
>
> > This commit changes hmp_cont() to loop through all block devices
> > and proactively set an encryption key for any encrypted device
> > without a valid one.
> >
> > This change is needed because QERR_DEVICE_ENCRYPTED is going to be
> > dropped by a future commit.
> >
> > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
> > ---
> > hmp.c | 43 +++++++++++++++++++++++++------------------
> > 1 file changed, 25 insertions(+), 18 deletions(-)
> >
> > diff --git a/hmp.c b/hmp.c
> > index 6b72a64..1ebeb63 100644
> > --- a/hmp.c
> > +++ b/hmp.c
> > @@ -610,34 +610,41 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict)
> >
> > static void hmp_cont_cb(void *opaque, int err)
> > {
> > - Monitor *mon = opaque;
> > -
> > if (!err) {
> > - hmp_cont(mon, NULL);
> > + qmp_cont(NULL);
> > }
> > }
> >
> > -void hmp_cont(Monitor *mon, const QDict *qdict)
> > +static bool blockinfo_is_encrypted(const BlockInfo *bdev)
> > {
> > - Error *errp = NULL;
> > -
> > - qmp_cont(&errp);
> > - if (error_is_set(&errp)) {
> > - if (error_is_type(errp, QERR_DEVICE_ENCRYPTED)) {
> > - const char *device;
> > + return (bdev->inserted && bdev->inserted->encrypted);
> > +}
> >
> > - /* The device is encrypted. Ask the user for the password
> > - and retry */
> > +static bool blockinfo_key_is_set(const BlockInfo *bdev)
> > +{
> > + return (bdev->inserted && bdev->inserted->valid_encryption_key);
> > +}
> >
> > - device = error_get_field(errp, "device");
> > - assert(device != NULL);
> > +void hmp_cont(Monitor *mon, const QDict *qdict)
> > +{
> > + BlockInfoList *bdev_list, *bdev;
> > + Error *errp = NULL;
> >
> > - monitor_read_block_device_key(mon, device, hmp_cont_cb, mon);
> > - error_free(errp);
> > - return;
> > + bdev_list = qmp_query_block(NULL);
> > + for (bdev = bdev_list; bdev; bdev = bdev->next) {
> > + if (blockinfo_is_encrypted(bdev->value) &&
> > + !blockinfo_key_is_set(bdev->value)) {
> > + monitor_read_block_device_key(mon, bdev->value->device,
> > + hmp_cont_cb, NULL);
> > + goto out;
> > }
> > - hmp_handle_error(mon, &errp);
> > }
> > +
> > + qmp_cont(&errp);
> > + hmp_handle_error(mon, &errp);
> > +
> > +out:
> > + qapi_free_BlockInfoList(bdev_list);
> > }
> >
> > void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
>
> Quote my previous analysis:
>
> Diff makes this change look worse than it is. Odd: M-x ediff gets it
> right. Anyway, here's how I think it works:
>
> Unchanged qmp_cont(): search the bdrv_states for the first encrypted one
> without a key. If found, set err argument to QERR_DEVICE_ENCRYPTED.
> Other errors unrelated to encrypted devices are also possible.
>
> hmp_cont() before: try qmp_cont(). If we get QERR_DEVICE_ENCRYPTED,
> extract the device from the error object, and prompt for its key, with a
> callback that retries hmp_cont() if the key was provided.
>
> After: search the bdrv_states for an encrypted one without a key. If
> there is none, qmp_cont(), no special error handling. If there is one,
> prompt for its key, with a callback that runs qmp_cont() if the key was
> provided.
>
> End quote.
>
> Two observations:
>
> 1. I don't understand how this works for multiple encrypted BDSs without
> keys. If there are any, hmp_cont() starts reading the first one's key,
> then returns. But the callback doesn't start reading the next one's
> key. Please explain.
The callback calls qmp_cont(), which will fail. Then the user will enter
cont again, and the loop on BlockInfos will run again and the user will
be asked for the password of the next image.
IOW, each time cont is issued by the user it will ask for the password
of a different device.
That's the current behavior, and I believe it was also the behavior before
I converted cont to the qapi.
> 2. qmp_cont() uses bdrv_key_required() to test whether a BDS lacks a
> key. Your new hmp_cont() uses blockinfo_is_encrypted() &&
> !blockinfo_key_is_set(). Not obvious that the two are equivalent.
>
> I'm afraid they are not. bdrv_key_required() checks the backing image
> first:
>
> int bdrv_key_required(BlockDriverState *bs)
> {
> BlockDriverState *backing_hd = bs->backing_hd;
>
> if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
> return 1;
> return (bs->encrypted && !bs->valid_key);
> }
>
> Your code doesn't:
>
> static bool blockinfo_is_encrypted(const BlockInfo *bdev)
> {
> return (bdev->inserted && bdev->inserted->encrypted);
> }
>
> static bool blockinfo_key_is_set(const BlockInfo *bdev)
> {
> return (bdev->inserted && bdev->inserted->valid_encryption_key);
> }
>
> BlockInfoList *qmp_query_block(Error **errp)
> {
> BlockInfoList *head = NULL, *cur_item = NULL;
> BlockDriverState *bs;
>
> QTAILQ_FOREACH(bs, &bdrv_states, list) {
> BlockInfoList *info = g_malloc0(sizeof(*info));
> [...]
> if (bs->drv) {
> info->value->has_inserted = true;
> info->value->inserted = g_malloc0(sizeof(*info->value->inserted));
> [...]
> info->value->inserted->encrypted = bs->encrypted;
> info->value->inserted->valid_encryption_key = bs->valid_key;
> [...]
>
> Are you sure this is correct?
Is it actually possible for backing_hd to be false and valid_key to be true?
> I understand we require HMP code to go via QMP for everything, to keep
> HMP honest. This case shows a drawback: duplicated code, leading to
> inconsistencies.
Keeping DeviceEncrypted would solve this.
next prev parent reply other threads:[~2012-08-02 14:22 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-02 1:02 [Qemu-devel] [PATCH v1 00/34]: add new error format Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 01/34] monitor: drop unused monitor debug code Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 02/34] qerror: QERR_AMBIGUOUS_PATH: drop %(object) from human msg Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 03/34] qerror: QERR_DEVICE_ENCRYPTED: add filename info to " Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 04/34] qerror: reduce public exposure Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 05/34] qerror: drop qerror_abort() Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 06/34] qerror: avoid passing qerr pointer Luiz Capitulino
2012-08-02 11:23 ` Markus Armbruster
2012-08-02 13:44 ` Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 07/34] qerror: QError: drop file, linenr, func Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 08/34] qerror: qerror_format(): return an allocated string Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 09/34] qerror: don't delay error message construction Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 10/34] error: " Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 11/34] qmp: query-block: add 'valid_encryption_key' field Luiz Capitulino
2012-08-02 11:35 ` Markus Armbruster
2012-08-02 13:54 ` Luiz Capitulino
2012-08-10 7:56 ` Markus Armbruster
2012-08-10 13:33 ` Luiz Capitulino
2012-08-10 16:35 ` Markus Armbruster
2012-08-10 17:00 ` Luiz Capitulino
2012-08-10 17:17 ` Markus Armbruster
2012-08-10 17:50 ` Luiz Capitulino
2012-08-11 7:45 ` Markus Armbruster
2012-08-13 13:35 ` Luiz Capitulino
2012-08-13 13:50 ` Markus Armbruster
2012-08-13 14:02 ` Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 12/34] hmp: hmp_cont(): don't rely on QERR_DEVICE_ENCRYPTED Luiz Capitulino
2012-08-02 11:53 ` Markus Armbruster
2012-08-02 14:22 ` Luiz Capitulino [this message]
2012-08-10 8:42 ` Markus Armbruster
2012-08-10 14:22 ` Luiz Capitulino
2012-08-10 16:37 ` Markus Armbruster
2012-08-02 1:02 ` [Qemu-devel] [PATCH 13/34] hmp: hmp_change(): " Luiz Capitulino
2012-08-02 13:27 ` Markus Armbruster
2012-08-02 13:46 ` Paolo Bonzini
2012-08-02 13:53 ` Markus Armbruster
2012-08-02 13:57 ` Paolo Bonzini
2012-08-02 14:53 ` Luiz Capitulino
2012-08-02 14:51 ` Luiz Capitulino
2012-08-02 14:42 ` Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 14/34] net: inet_connect(), inet_connect_opts(): add in_progress argument Luiz Capitulino
2012-08-02 15:12 ` Markus Armbruster
2012-08-02 1:02 ` [Qemu-devel] [PATCH 15/34] net: inet_connect(), inet_connect_opts(): return -errno Luiz Capitulino
2012-08-02 13:41 ` Luiz Capitulino
2012-08-02 15:50 ` Markus Armbruster
2012-08-02 16:49 ` Luiz Capitulino
2012-08-06 6:52 ` Amos Kong
2012-08-06 19:59 ` Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 16/34] migration: don't rely on QERR_SOCKET_* Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 17/34] qerror: drop QERR_SOCKET_CONNECT_IN_PROGRESS Luiz Capitulino
2012-08-02 15:58 ` Markus Armbruster
2012-08-06 7:04 ` Amos Kong
2012-08-02 16:54 ` Michael Roth
2012-08-02 17:08 ` Luiz Capitulino
2012-08-03 18:26 ` Michael Roth
2012-08-03 20:31 ` Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 18/34] error: drop unused functions Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 19/34] block: block_int: include qerror.h Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 20/34] hmp: hmp.h: include qdict.h Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 21/34] qapi: qapi-types.h: don't include qapi/qapi-types-core.h Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 22/34] qapi: generate correct enum names for camel case enums Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 23/34] qapi: don't convert enum strings to lowercase Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 24/34] qapi-schema: add ErrorClass enum Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 25/34] qerror: qerror_table: don't use C99 struct initializers Luiz Capitulino
2012-08-02 16:48 ` Markus Armbruster
2012-08-02 1:02 ` [Qemu-devel] [PATCH 26/34] error, qerror: add ErrorClass argument to error functions Luiz Capitulino
2012-08-02 16:57 ` Markus Armbruster
2012-08-02 1:02 ` [Qemu-devel] [PATCH 27/34] qerror: add proper ErrorClass value for QERR_ macros Luiz Capitulino
2012-08-02 17:01 ` Markus Armbruster
2012-08-02 1:02 ` [Qemu-devel] [PATCH 28/34] error: add error_get_class() Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 29/34] qmp: switch to the new error format on the wire Luiz Capitulino
2012-08-02 17:12 ` Markus Armbruster
2012-08-02 17:19 ` Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 30/34] qemu-ga: " Luiz Capitulino
2012-08-03 17:44 ` Michael Roth
2012-08-03 17:56 ` Eric Blake
2012-08-03 18:02 ` Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 31/34] error, qerror: pass desc string to error calls Luiz Capitulino
2012-08-02 17:19 ` Markus Armbruster
2012-08-02 1:02 ` [Qemu-devel] [PATCH 32/34] qerror: drop qerror_table and qerror_format() Luiz Capitulino
2012-08-02 1:02 ` [Qemu-devel] [PATCH 33/34] error: drop error_get_qobject()/error_set_qobject() Luiz Capitulino
2012-08-02 17:20 ` Markus Armbruster
2012-08-02 1:02 ` [Qemu-devel] [PATCH 34/34] error, qerror: drop QDict member Luiz Capitulino
2012-08-02 13:41 ` [Qemu-devel] [PATCH v1 00/34]: add new error format Luiz Capitulino
2012-08-02 17:22 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120802112235.4b18c09c@doriath.home \
--to=lcapitulino@redhat.com \
--cc=aliguori@us.ibm.com \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).