Skip to content

Commit 551f581

Browse files
committed
Fix the size of a virtio device, backed by a block device
When a virtio device is backed by a block device, the actual size of the block device file doesn't represent the size as a virtio device. Fixes #1316 Signed-off-by: Kazuyoshi Kato <[email protected]>
1 parent 36c6857 commit 551f581

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

vmm/src/block_device.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use std::fs::File;
5+
use std::io::Error;
6+
use std::os::raw;
7+
use sys_util::ioctl_with_mut_ref;
8+
9+
const FS: raw::c_uint = 0x12;
10+
ioctl_ior_nr!(BLKGETSIZE64, FS, 114, ::std::os::raw::c_ulong);
11+
12+
pub fn get_size(path: &std::path::Path) -> std::result::Result<u64, std::io::Error> {
13+
let mut size: u64 = 0;
14+
15+
let file = File::open(path)?;
16+
let ret = unsafe {
17+
ioctl_with_mut_ref(&file, BLKGETSIZE64(), &mut size)
18+
};
19+
20+
if ret < 0 {
21+
return Err(Error::last_os_error());
22+
} else {
23+
return Ok(size)
24+
}
25+
}
26+
27+
#[cfg(test)]
28+
mod tests {
29+
use super::*;
30+
use std::path::Path;
31+
32+
#[test]
33+
fn test_invalid_file() {
34+
assert!(get_size(&Path::new("/dev/null")).is_err());
35+
}
36+
}

vmm/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern crate memory_model;
3131
extern crate net_util;
3232
extern crate rate_limiter;
3333
extern crate seccomp;
34+
#[macro_use]
3435
extern crate sys_util;
3536

3637
/// Syscalls allowed through the seccomp filter.
@@ -41,11 +42,13 @@ pub mod error;
4142
pub mod signal_handler;
4243
/// Wrappers over structures used to configure the VMM.
4344
pub mod vmm_config;
45+
mod block_device;
4446
mod vstate;
4547

4648
use std::collections::HashMap;
4749
use std::fs::{metadata, File, OpenOptions};
4850
use std::io;
51+
use std::os::unix::fs::FileTypeExt;
4952
use std::os::unix::io::{AsRawFd, RawFd};
5053
use std::path::PathBuf;
5154
use std::process;
@@ -1524,7 +1527,12 @@ impl Vmm {
15241527
if drive_config.drive_id == *drive_id {
15251528
let metadata = metadata(&drive_config.path_on_host)
15261529
.map_err(|_| DriveError::BlockDeviceUpdateFailed)?;
1527-
let new_size = metadata.len();
1530+
let new_size = if metadata.file_type().is_block_device() {
1531+
block_device::get_size(&drive_config.path_on_host)
1532+
.map_err(|_| DriveError::BlockDeviceUpdateFailed)?
1533+
} else {
1534+
metadata.len()
1535+
};
15281536
if new_size % virtio::block::SECTOR_SIZE != 0 {
15291537
warn!(
15301538
"Disk size {} is not a multiple of sector size {}; \

0 commit comments

Comments
 (0)