Skip to content
Snippets Groups Projects
  • Vladimir Sementsov-Ogievskiy's avatar
    af5bcd77
    block: copy-before-write: realize snapshot-access API · af5bcd77
    Vladimir Sementsov-Ogievskiy authored
    
    Current scheme of image fleecing looks like this:
    
    [guest]                    [NBD export]
      |                              |
      |root                          | root
      v                              v
    [copy-before-write] -----> [temp.qcow2]
      |                 target  |
      |file                     |backing
      v                         |
    [active disk] <-------------+
    
     - On guest writes copy-before-write filter copies old data from active
       disk to temp.qcow2. So fleecing client (NBD export) when reads
       changed regions from temp.qcow2 image and unchanged from active disk
       through backing link.
    
    This patch makes possible new image fleecing scheme:
    
    [guest]                   [NBD export]
       |                            |
       | root                       | root
       v                 file       v
    [copy-before-write]<------[snapshot-access]
       |           |
       | file      | target
       v           v
    [active-disk] [temp.img]
    
     - copy-before-write does CBW operations and also provides
       snapshot-access API. The API may be accessed through
       snapshot-access driver.
    
    Benefits of new scheme:
    
    1. Access control: if remote client try to read data that not covered
       by original dirty bitmap used on copy-before-write open, client gets
       -EACCES.
    
    2. Discard support: if remote client do DISCARD, this additionally to
       discarding data in temp.img informs block-copy process to not copy
       these clusters. Next read from discarded area will return -EACCES.
       This is significant thing: when fleecing user reads data that was
       not yet copied to temp.img, we can avoid copying it on further guest
       write.
    
    3. Synchronisation between client reads and block-copy write is more
       efficient. In old scheme we just rely on BDRV_REQ_SERIALISING flag
       used for writes to temp.qcow2. New scheme is less blocking:
         - fleecing reads are never blocked: if data region is untouched or
           in-flight, we just read from active-disk, otherwise we read from
           temp.img
         - writes to temp.img are not blocked by fleecing reads
         - still, guest writes of-course are blocked by in-flight fleecing
           reads, that currently read from active-disk - it's the minimum
           necessary blocking
    
    4. Temporary image may be of any format, as we don't rely on backing
       feature.
    
    5. Permission relation are simplified. With old scheme we have to share
       write permission on target child of copy-before-write, otherwise
       backing link conflicts with copy-before-write file child write
       permissions. With new scheme we don't have backing link, and
       copy-before-write node may have unshared access to temporary node.
       (Not realized in this commit, will be in future).
    
    6. Having control on fleecing reads we'll be able to implement
       alternative behavior on failed copy-before-write operations.
       Currently we just break guest request (that's a historical behavior
       of backup). But in some scenarios it's a bad behavior: better
       is to drop the backup as failed but don't break guest request.
       With new scheme we can simply unset some bits in a bitmap on CBW
       failure and further fleecing reads will -EACCES, or something like
       this. (Not implemented in this commit, will be in future)
       Additional application for this is implementing timeout for CBW
       operations.
    
    Iotest 257 output is updated, as two more bitmaps now live in
    copy-before-write filter.
    
    Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
    Message-Id: <20220303194349.2304213-13-vsementsov@virtuozzo.com>
    Signed-off-by: default avatarHanna Reitz <hreitz@redhat.com>
    af5bcd77
    History
    block: copy-before-write: realize snapshot-access API
    Vladimir Sementsov-Ogievskiy authored
    
    Current scheme of image fleecing looks like this:
    
    [guest]                    [NBD export]
      |                              |
      |root                          | root
      v                              v
    [copy-before-write] -----> [temp.qcow2]
      |                 target  |
      |file                     |backing
      v                         |
    [active disk] <-------------+
    
     - On guest writes copy-before-write filter copies old data from active
       disk to temp.qcow2. So fleecing client (NBD export) when reads
       changed regions from temp.qcow2 image and unchanged from active disk
       through backing link.
    
    This patch makes possible new image fleecing scheme:
    
    [guest]                   [NBD export]
       |                            |
       | root                       | root
       v                 file       v
    [copy-before-write]<------[snapshot-access]
       |           |
       | file      | target
       v           v
    [active-disk] [temp.img]
    
     - copy-before-write does CBW operations and also provides
       snapshot-access API. The API may be accessed through
       snapshot-access driver.
    
    Benefits of new scheme:
    
    1. Access control: if remote client try to read data that not covered
       by original dirty bitmap used on copy-before-write open, client gets
       -EACCES.
    
    2. Discard support: if remote client do DISCARD, this additionally to
       discarding data in temp.img informs block-copy process to not copy
       these clusters. Next read from discarded area will return -EACCES.
       This is significant thing: when fleecing user reads data that was
       not yet copied to temp.img, we can avoid copying it on further guest
       write.
    
    3. Synchronisation between client reads and block-copy write is more
       efficient. In old scheme we just rely on BDRV_REQ_SERIALISING flag
       used for writes to temp.qcow2. New scheme is less blocking:
         - fleecing reads are never blocked: if data region is untouched or
           in-flight, we just read from active-disk, otherwise we read from
           temp.img
         - writes to temp.img are not blocked by fleecing reads
         - still, guest writes of-course are blocked by in-flight fleecing
           reads, that currently read from active-disk - it's the minimum
           necessary blocking
    
    4. Temporary image may be of any format, as we don't rely on backing
       feature.
    
    5. Permission relation are simplified. With old scheme we have to share
       write permission on target child of copy-before-write, otherwise
       backing link conflicts with copy-before-write file child write
       permissions. With new scheme we don't have backing link, and
       copy-before-write node may have unshared access to temporary node.
       (Not realized in this commit, will be in future).
    
    6. Having control on fleecing reads we'll be able to implement
       alternative behavior on failed copy-before-write operations.
       Currently we just break guest request (that's a historical behavior
       of backup). But in some scenarios it's a bad behavior: better
       is to drop the backup as failed but don't break guest request.
       With new scheme we can simply unset some bits in a bitmap on CBW
       failure and further fleecing reads will -EACCES, or something like
       this. (Not implemented in this commit, will be in future)
       Additional application for this is implementing timeout for CBW
       operations.
    
    Iotest 257 output is updated, as two more bitmaps now live in
    copy-before-write filter.
    
    Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
    Message-Id: <20220303194349.2304213-13-vsementsov@virtuozzo.com>
    Signed-off-by: default avatarHanna Reitz <hreitz@redhat.com>