Giter VIP home page Giter VIP logo

bdev_ubi's Introduction

bdev_ubi

Introduction

bdev_ubi provides an SPDK virtual bdev layered over another bdev, enabling copy-on-access for a base image.

This can be utilized to set up a block device initialized with an image file, without the delay of an initial copy. With bdev_ubi, copying occurs lazily upon block access, rather than at the provisioning time.

For instance, let's say you already have a bdev named "aio0" and you wish to populate it with data from /opt/images/large-image.raw. A conventional approach would be to copy large-image.raw to aio0 using tools like spdk_dd, which can be time-consuming. However, with bdev_ubi, you can proceed by invoking the following json-rpc method:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "bdev_ubi_create",
  "params": {
    "name": "ubi0",
    "base_bdev": "aio0",
    "image_path": "/opt/images/large-image.raw",
    "stripe_size_mb": 1
  }
}

and rather than directly using aio0, use ubi0 as the block device. This action completes almost instantly, eliminating the need for initial data copying. The actual data copying will occur lazily during I/O requests.

Building

Install some requirements:

sudo apt update
sudo apt install pkg-config build-essential liburing-dev

Clone and build SPDK:

git clone https://github.com/spdk/spdk
cd spdk
git submodule update --init
sudo scripts/pkgdep.sh
./configure --with-crypto --with-vhost
make -j16

Build bdev_ubi:

SPDK_PATH=/path/to/spdk/build/ make

Usage

The steps in the previous section generates an SPDK app in build/bin/vhost_ubi. The application can be managed through JSON-RPC or by providing block device (bdev) configuration via command-line arguments, analogous to the functionality offered by the SPDK's standard vhost application.

For instance, begin by downloading and preparing the Ubuntu Jammy image, which will be used as the base read-only image:

wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
qemu-img convert -p -f qcow2 -O raw jammy-server-cloudimg-amd64.img jammy.raw

Next, generate the file that will function as the writable layer for the block device:

touch write-space
truncate -s 5G write-space

Next, reserve 1G of hugepages:

echo 512 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

Finally, start the app with the configuration provided in examples/spdk_conf.json:

sudo build/bin/vhost_ubi --json examples/spdk_conf.json -S /var/tmp

What will happen is:

  • An aio bdev called aio0 will be created pointing to write-space.
  • A ubi bdev called ubi0 will be created, with base image jammy.raw and base bdev aio0.
  • A vhost-user-blk controller called vhost.0 will be created, which will be bound to the UNIX domain socket /var/tmp/vhost.0.

Now you can start a VM using the vhost disk:

sudo cloud-hypervisor \
    ...
    --disk vhost_user=true,socket=/var/tmp/vhost.0,num_queues=4,queue_size=256 \
    ...

JSON-RPC API

bdev_ubi_create

Parameters:

  • name (text, required): Name of the bdev to be created.
  • image_path (text, required): Path to the image file.
  • base_bdev (text, required): Name of base bdev.
  • stripe_size_kb (integer, required): Stripe size in kibibytes.
  • no_sync (boolean, optional): Ignore sync requests. Defaults to false.
  • copy_on_read (boolean, optional): Fetch stripes for reads. Defaults to true.
  • directio (boolean, optional): Use O_DIRECT when opening the image file. Defaults to true;

Note. When creating the bdev for the first time, magic bits in the metadata section of base image should be zeroed. For unencrypted base bdev, truncate command in the previous section will take care of this. For encrypted base bdev, spdk_dd can be used with parameters --bs 512 --count 1 --if /dev/zero --ob [ubi_bdev_name].

bdev_ubi_delete

Parameters:

  • name (text, required): Name of the bdev to be deleted.

Internals

Data Layout

First 8MB of base bdev is reserved for metadata. Metadata consists of:

  • Magic bytes (9 bytes): BDEV_UBI\0
  • Metadata version major (2 bytes)
  • Metadata version minor (2 bytes)
  • stripe_size_kb (1 byte)
  • Stripe headers: 2 byte per stripes. Currently it specifies whether a stripe has been fetched from image or not. 15-bits are reserved for future extension.
  • Padding to make the total size 8MB.

Then at the 8MB offset the actual disk data starts.

Read/Write I/O operations

If the stripe containing the requested block range hasn't been fetched yet, then a stripe fetch is enqueued. Once stripe has been fetched, the actual I/O operation is served.

Flush (aka sync)

  • Data for the requested range is flushed to base bdev.
  • Once data flush is finished, and if metadata has been modified in memory, then metadata is first written and then flushed to base bdev.

bdev_ubi's People

Contributors

pykello avatar

Stargazers

Ozgun Erdogan avatar Enes Çakır avatar  avatar Abolfazl avatar  avatar

Watchers

 avatar Ozgun Erdogan avatar  avatar  avatar

Forkers

pykello

bdev_ubi's Issues

Missing LICENSE file

Congrats on the exciting things being launched!

I found this repo via @fdr's comment on HN but realized there is no license attached.

Would be good if you could clarify if this is also licensed under the same Elastic-style license as the main ubicloud repo, or a different license. FWIW, I personally would welcome a more liberal license, so this can be used without restrictions for learning purposes.

Segfault when out of memory

#0  spdk_put_io_channel (ch=0x0) at thread.c:2422
Backtrace stopped: Cannot access memory at address 0xffffbac2d168

Errors when exiting without deleting controllers & bdevs first.

If I hit Ctrl-C before deleting controllers & bdevs first, I get the following errors:

[2023-11-15 12:58:28.498117] vhost_blk.c:1218:vhost_user_bdev_remove_cb: *WARNING*: vhost.0: hot-removing bdev - all further requests will fail.
[2023-11-15 12:58:28.550627] reactor.c: 983:reactor_run: *ERROR*: spdk_thread_exit() was not called on thread 'vhost.0'
[2023-11-15 12:58:28.550674] reactor.c: 985:reactor_run: *ERROR*: This will result in a non-zero exit code in a future release.

This isn't high priority, as this won't happen if bdevs and controllers are deleted before stopping. But we need to understand why this doesn't happen in SPDK's vhost app, but happens here, and fix it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.