vhost-user-blk backend: add readonly support

The current backend only support rw, and we also need
add readonly support.

The new command:
vhost_user_blk \
  --backend "image=/home/test.img, \
            sock=/home/path/vhost.socket, \
            readonly=true"

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
This commit is contained in:
Yang Zhong 2019-12-18 11:16:18 +08:00 committed by Sebastien Boeuf
parent 91549ddd71
commit cee01edb97

View File

@ -62,6 +62,8 @@ pub enum Error {
ParseImageParam,
/// Failed to parse sock parameter.
ParseSockParam,
/// Failed to parse readonly parameter.
ParseReadOnlyParam,
}
struct VhostUserBlkBackend {
@ -71,13 +73,14 @@ struct VhostUserBlkBackend {
disk_image_id: Vec<u8>,
disk_nsectors: u64,
config: virtio_blk_config,
rdonly: bool,
}
impl VhostUserBlkBackend {
pub fn new(image_path: String) -> Result<Self> {
pub fn new(image_path: String, rdonly: bool) -> Result<Self> {
let raw_img: File = OpenOptions::new()
.read(true)
.write(true)
.write(!rdonly)
.open(&image_path)
.unwrap();
@ -106,6 +109,7 @@ impl VhostUserBlkBackend {
disk_image_id: image_id,
disk_nsectors: nsectors,
config,
rdonly,
})
}
@ -162,9 +166,14 @@ impl VhostUserBackend for VhostUserBlkBackend {
}
fn features(&self) -> u64 {
1 << VIRTIO_BLK_F_MQ
let mut avail_features = 1 << VIRTIO_BLK_F_MQ
| 1 << VIRTIO_F_VERSION_1
| VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits()
| VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits();
if self.rdonly {
avail_features |= 1 << VIRTIO_BLK_F_RO;
}
avail_features
}
fn protocol_features(&self) -> VhostUserProtocolFeatures {
@ -214,6 +223,7 @@ impl VhostUserBackend for VhostUserBlkBackend {
pub struct VhostUserBlkBackendConfig<'a> {
pub image: &'a str,
pub sock: &'a str,
pub readonly: bool,
}
impl<'a> VhostUserBlkBackendConfig<'a> {
@ -222,12 +232,18 @@ impl<'a> VhostUserBlkBackendConfig<'a> {
let mut image: &str = "";
let mut sock: &str = "";
let mut readonly: bool = false;
for param in params_list.iter() {
if param.starts_with("image=") {
image = &param[6..];
} else if param.starts_with("sock=") {
sock = &param[5..];
} else if param.starts_with("readonly=") {
readonly = match param[9..].parse::<bool>() {
Ok(b) => b,
Err(_) => return Err(Error::ParseReadOnlyParam),
}
}
}
@ -238,7 +254,11 @@ impl<'a> VhostUserBlkBackendConfig<'a> {
return Err(Error::ParseSockParam);
}
Ok(VhostUserBlkBackendConfig { image, sock })
Ok(VhostUserBlkBackendConfig {
image,
sock,
readonly,
})
}
}
@ -252,7 +272,7 @@ fn main() {
.long("backend")
.help(
"Backend parameters \"image=<image_path>,\
sock=<socket_path>\"",
sock=<socket_path>,readonly=true|false\"",
)
.takes_value(true)
.min_values(1),
@ -270,7 +290,8 @@ fn main() {
};
let blk_backend = Arc::new(RwLock::new(
VhostUserBlkBackend::new(backend_config.image.to_string()).unwrap(),
VhostUserBlkBackend::new(backend_config.image.to_string(), backend_config.readonly)
.unwrap(),
));
debug!("blk_backend is created!\n");