All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org, mreitz@redhat.com
Subject: Re: [Qemu-devel] [PATCH 06/10] qemu-img: Prepare for locked images
Date: Tue, 12 Jan 2016 16:20:31 +0100	[thread overview]
Message-ID: <87si22su2o.fsf@blackfin.pond.sub.org> (raw)
In-Reply-To: <20160111160533.GF9454@noname.redhat.com> (Kevin Wolf's message of "Mon, 11 Jan 2016 17:05:33 +0100")

Kevin Wolf <kwolf@redhat.com> writes:

> Am 11.01.2016 um 16:49 hat Markus Armbruster geschrieben:
>> Eric Blake <eblake@redhat.com> writes:
>> 
>> > On 12/22/2015 09:46 AM, Kevin Wolf wrote:
>> >> This patch extends qemu-img for working with locked images. It prints a
>> >> helpful error message when trying to access a locked image read-write,
>> >> and adds a 'qemu-img force-unlock' command as well as a 'qemu-img check
>> >> -r all --force' option in order to override a lock left behind after a
>> >> qemu crash.
>> >> 
>> >> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
>> >> ---
>> >>  include/block/block.h |  1 +
>> >>  include/qapi/error.h  |  1 +
>> >>  qapi/common.json      |  3 +-
>> >>  qemu-img-cmds.hx      | 10 ++++--
>> >>  qemu-img.c | 96
>> >> +++++++++++++++++++++++++++++++++++++++++++--------
>> >>  qemu-img.texi         | 20 ++++++++++-
>> >>  6 files changed, 113 insertions(+), 18 deletions(-)
>> >> 
>> >
>> >> +++ b/include/qapi/error.h
>> >> @@ -102,6 +102,7 @@ typedef enum ErrorClass {
>> >>      ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE,
>> >>      ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND,
>> >>      ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP,
>> >> +    ERROR_CLASS_IMAGE_FILE_LOCKED = QAPI_ERROR_CLASS_IMAGEFILELOCKED,
>> >>  } ErrorClass;
>> >
>> > Wow - a new ErrorClass.  It's been a while since we could justify one of
>> > these, but I think you might have found a case.
>> 
>> Spell out the rationale for the new ErrorClass, please.
>
> Action to be taken for this error class: Decide whether the lock is a
> leftover from a previous qemu run that ended in an unclean shutdown. If
> so, retry with overriding the lock.
>
> Currently used by qemu-img when ordered to override a lock. libvirt
> will need to do the same.

Let's see whether I understand the intended use:

    open image
    if open fails with ImageFileLocked:
        guess whether the lock is stale
        if guessing not stale:
            error out
        open image with lock override

Correct?

Obvious troublespots:

1. If you guess wrong, you destroy the image.  No worse than before, so
   okay, declare documentation problem.

2. TOCTTOU open to open with lock override

   I understand this lock cannot be foolproof, but I dislike the "if
   lock stale then steal lock" TOCTTOU trap all the same.

        Process A                       Process B
        open image, ImageFileLocked
        guess not stale (correct)
                                        open image, ImageFileLocked
                                        guess not stale (correct)
                                        open image with lock override
        open image with lock override

   To avoid, you need to add a suitable unique identifier to the lock,
   then change the override to "override the lock with this unique ID".

   A smartly chosen identifier might even help with guessing whether the
   lock is stale, at least in some cases.

3. TOCTTOU within open (hypothetical, haven't read your code)

   Obviously, "open image" needs to acquire the lock.  Is open+lock
   atomic with respect to concurrent open+lock?

> Alternative design without a new error class: Accept the
> override-lock=on option on the block.c level (QAPI BlockdevOptionsBase)
> and ignore it silently for image formats that don't support locking
> (i.e. anything but qcow2), so that qemu-img and libvirt can set this
> option unconditionally even if they don't know that the image is locked
> (but libvirt would have to check first if qemu supports the option at
> all in order to maintain compatibility with old qemu versions).
>
> In my opinion, this would be worse design than adding an error class. It
> would also prevent libvirt from logging when it forcefully unlocks an
> image.

Well, QEMU could (and probably should) say something when overriding a
lock, and libvirt should certainly log whatever QEMU says.

Let me try a different tack.  It may well be unworkable.

An image may support a lock.  If it does, it carries an ID uniquely
identifying a particular lock - unlock period.

When you open an image supporting locking, you atomically acquire its
lock and set its lock ID.  If the user specifies the ID, we use that,
else we make one up.

To open with lock override, you need to specify something like
override=ID.

Intended use by management application, ignoring the need for lock
override:

    generate lock ID for this image and save it in persistent management
      storage
    open and lock image, setting the lock ID
    ...
    unlock and close image
    delete lock ID in persistent management storage

Now extend to override the lock when necessary:

    if persistent management storage has lock ID for this image
        open with lock override=ID
    else
        generate lock ID for this image and save...
        open and lock...

This lets the management application override its own stale locks after
a crash, but it won't override anybody else's locks, and it doesn't
engage in any guesswork.

Obviously, the management application will also need to be able to
override stale locks from opens by someone else, say a human user
bypassing the management application.  Perhaps like this:

    examine the image
    if it's locked:
        get the lock ID
        let next higher level in the stack decide whether it's stale
            (this level might be a human user)
        if it's stale:
            open with lock override=ID

No open-to-open-with-override TOCTTOU.

Thoughts?

  reply	other threads:[~2016-01-12 15:20 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-22 16:46 [Qemu-devel] [PATCH 00/10] qcow2: Implement image locking Kevin Wolf
2015-12-22 16:46 ` [Qemu-devel] [PATCH 01/10] qcow2: Write feature table only for v3 images Kevin Wolf
2015-12-22 20:20   ` Eric Blake
2016-01-11 15:20     ` Kevin Wolf
2015-12-22 16:46 ` [Qemu-devel] [PATCH 02/10] qcow2: Write full header on image creation Kevin Wolf
2015-12-22 20:25   ` Eric Blake
2015-12-22 16:46 ` [Qemu-devel] [PATCH 03/10] block: Assert no write requests under BDRV_O_INCOMING Kevin Wolf
2015-12-22 20:27   ` Eric Blake
2015-12-22 16:46 ` [Qemu-devel] [PATCH 04/10] block: Fix error path in bdrv_invalidate_cache() Kevin Wolf
2015-12-22 20:31   ` Eric Blake
2015-12-22 16:46 ` [Qemu-devel] [PATCH 05/10] block: Inactivate BDS when migration completes Kevin Wolf
2015-12-22 20:43   ` Eric Blake
2016-01-05 20:21     ` [Qemu-devel] [Qemu-block] " John Snow
2016-01-13 14:25       ` Kevin Wolf
2016-01-13 16:35         ` Eric Blake
2015-12-22 16:46 ` [Qemu-devel] [PATCH 06/10] qemu-img: Prepare for locked images Kevin Wolf
2015-12-22 16:57   ` Daniel P. Berrange
2015-12-22 17:00     ` Kevin Wolf
2015-12-22 21:06   ` Eric Blake
2016-01-11 15:49     ` Markus Armbruster
2016-01-11 16:05       ` Kevin Wolf
2016-01-12 15:20         ` Markus Armbruster [this message]
2016-01-12 17:36           ` Kevin Wolf
2016-01-13  8:44             ` Markus Armbruster
2016-01-13 14:19               ` Kevin Wolf
2016-01-14 13:07                 ` Markus Armbruster
2016-01-14 14:19                   ` Kevin Wolf
2016-01-11 16:22     ` Kevin Wolf
2015-12-22 21:41   ` Eric Blake
2015-12-22 16:46 ` [Qemu-devel] [PATCH 07/10] qcow2: Implement .bdrv_inactivate Kevin Wolf
2015-12-22 21:17   ` Eric Blake
2016-01-11 15:34     ` Kevin Wolf
2015-12-22 16:46 ` [Qemu-devel] [PATCH 08/10] qcow2: Fix BDRV_O_INCOMING handling in qcow2_invalidate_cache() Kevin Wolf
2015-12-22 21:22   ` Eric Blake
2015-12-22 16:46 ` [Qemu-devel] [PATCH 09/10] qcow2: Make image inaccessible after failed qcow2_invalidate_cache() Kevin Wolf
2015-12-22 21:24   ` Eric Blake
2015-12-22 16:46 ` [Qemu-devel] [PATCH 10/10] qcow2: Add image locking Kevin Wolf
2015-12-22 22:04   ` Eric Blake
2015-12-23  3:14 ` [Qemu-devel] [PATCH 00/10] qcow2: Implement " Fam Zheng
2015-12-23  7:35   ` [Qemu-devel] [Qemu-block] " Denis V. Lunev
2015-12-23  7:46     ` [Qemu-devel] [PATCH RFC 0/5] generic image locking and crash recovery Denis V. Lunev
2015-12-23  7:46       ` [Qemu-devel] [PATCH 1/5] block: added lock image option and callback Denis V. Lunev
2015-12-23 23:48         ` Eric Blake
2016-01-11 17:31         ` Kevin Wolf
2016-01-11 17:58           ` Daniel P. Berrange
2016-01-11 18:35             ` Kevin Wolf
2016-01-13  8:52               ` Markus Armbruster
2016-01-13  9:12                 ` Denis V. Lunev
2016-01-13  9:50                   ` Daniel P. Berrange
2016-01-13  9:51               ` Daniel P. Berrange
2016-01-12  5:38           ` Denis V. Lunev
2016-01-12 10:10             ` Kevin Wolf
2016-01-12 11:33               ` Fam Zheng
2016-01-12 12:24                 ` Denis V. Lunev
2016-01-12 12:28                 ` Kevin Wolf
2016-01-12 13:17                   ` Fam Zheng
2016-01-12 13:24                     ` Daniel P. Berrange
2016-01-13  0:08                       ` Fam Zheng
2016-01-12 15:59                 ` Denis V. Lunev
2016-01-13  0:10                   ` Fam Zheng
2016-01-13 16:44                     ` Eric Blake
2016-01-14  7:23                       ` Denis V. Lunev
2015-12-23  7:46       ` [Qemu-devel] [PATCH 2/5] block: implemented bdrv_lock_image for raw file Denis V. Lunev
2015-12-23 12:40         ` Daniel P. Berrange
2015-12-23  7:46       ` [Qemu-devel] [PATCH 3/5] block: added check image option and callback bdrv_is_opened_unclean Denis V. Lunev
2015-12-23  9:09         ` Fam Zheng
2015-12-23  9:14           ` Denis V. Lunev
2015-12-23  7:46       ` [Qemu-devel] [PATCH 4/5] qcow2: implemented bdrv_is_opened_unclean Denis V. Lunev
2016-01-11 17:37         ` Kevin Wolf
2015-12-23  7:46       ` [Qemu-devel] [PATCH 5/5] block/paralels: added paralles implementation for bdrv_is_opened_unclean Denis V. Lunev
2015-12-23  8:09       ` [Qemu-devel] [PATCH RFC 0/5] generic image locking and crash recovery Fam Zheng
2015-12-23  8:36         ` Denis V. Lunev
2015-12-23 10:47   ` [Qemu-devel] [PATCH 00/10] qcow2: Implement image locking Daniel P. Berrange
2015-12-23 12:15     ` [Qemu-devel] [Qemu-block] " Roman Kagan
2015-12-23 12:29       ` Daniel P. Berrange
2015-12-23 12:41         ` Denis V. Lunev
2015-12-23 12:46           ` Daniel P. Berrange
2015-12-23 12:34       ` Daniel P. Berrange
2015-12-23 12:47         ` Denis V. Lunev
2015-12-23 12:56           ` Daniel P. Berrange
2016-01-11 17:14     ` [Qemu-devel] " Kevin Wolf
2016-01-11 17:54       ` Daniel P. Berrange
2016-01-13  8:56       ` Markus Armbruster
2016-01-13  9:11         ` [Qemu-devel] [Qemu-block] " Denis V. Lunev
2015-12-23 23:19   ` [Qemu-devel] " Max Reitz
2015-12-24  5:41     ` [Qemu-devel] [Qemu-block] " Denis V. Lunev
2015-12-24  5:42       ` Denis V. Lunev
2016-01-04 17:02       ` Max Reitz
2016-01-11 16:47       ` Kevin Wolf
2016-01-11 17:56         ` Daniel P. Berrange
2015-12-23 14:57 ` [Qemu-devel] " Vasiliy Tolstov
2015-12-23 15:08   ` [Qemu-devel] [Qemu-block] " Denis V. Lunev
2015-12-23 15:11     ` Vasiliy Tolstov
2016-01-11 16:25       ` Kevin Wolf
2015-12-23 15:09   ` Denis V. Lunev
2015-12-24  5:43 ` Denis V. Lunev
2016-01-11 16:33   ` Kevin Wolf
2016-01-11 16:38     ` Denis V. Lunev
2016-01-14 14:01 ` Max Reitz

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=87si22su2o.fsf@blackfin.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.