main: autodetect disk image type

Make --disk and --rwdisk automatically distinguish between qcow2 and raw
disk images.  --qcow and --rwqcow are kept as aliases for compatibility.

BUG=chromium:893380
TEST=Boot crosvm with both raw and qcow2 disk images.

Change-Id: I5b572626ca5ab894c78454f59355f27d552cbf7d
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1275185
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This commit is contained in:
Daniel Verkamp 2018-10-10 17:25:14 -07:00 committed by chrome-bot
parent de198cc9be
commit f02fdd1f66
3 changed files with 12 additions and 19 deletions

View file

@ -1239,7 +1239,7 @@ pub fn convert(src_file: File, dst_file: File, dst_type: ImageType) -> Result<()
}
/// Detect the type of an image file by checking for a valid qcow2 header.
fn detect_image_type(file: &File) -> Result<ImageType> {
pub fn detect_image_type(file: &File) -> Result<ImageType> {
let mut f = file;
let orig_seek = f.seek(SeekFrom::Current(0)).map_err(Error::SeekingFile)?;
f.seek(SeekFrom::Start(0)).map_err(Error::SeekingFile)?;

View file

@ -29,14 +29,13 @@ use devices::{self, PciDevice, VirtioPciDevice};
use io_jail::{self, Minijail};
use kvm::*;
use net_util::Tap;
use qcow::{self, QcowFile};
use qcow::{self, ImageType, QcowFile};
use sys_util;
use sys_util::*;
use vhost;
use vm_control::VmRequest;
use Config;
use DiskType;
use VirtIoDeviceInfo;
use arch::{self, LinuxArch, RunnableLinuxVm, VirtioDeviceStub, VmComponents};
@ -58,6 +57,7 @@ pub enum Error {
CreateSignalFd(sys_util::SignalFdError),
CreateSocket(io::Error),
CreateTimerFd(sys_util::Error),
DetectImageType(qcow::Error),
DeviceJail(io_jail::Error),
DevicePivotRoot(io_jail::Error),
Disk(io::Error),
@ -112,6 +112,9 @@ impl fmt::Display for Error {
&Error::CreateSignalFd(ref e) => write!(f, "failed to create signalfd: {:?}", e),
&Error::CreateSocket(ref e) => write!(f, "failed to create socket: {}", e),
&Error::CreateTimerFd(ref e) => write!(f, "failed to create timerfd: {}", e),
&Error::DetectImageType(ref e) => {
write!(f, "failed to detect disk image type: {:?}", e)
}
&Error::DeviceJail(ref e) => write!(f, "failed to jail device: {}", e),
&Error::DevicePivotRoot(ref e) => write!(f, "failed to pivot root device: {}", e),
&Error::Disk(ref e) => write!(f, "failed to load disk image: {}", e),
@ -286,15 +289,16 @@ fn create_virtio_devs(
};
flock(&raw_image, lock_op, true).map_err(Error::DiskImageLock)?;
let block_box: Box<devices::virtio::VirtioDevice> = match disk.disk_type {
DiskType::FlatFile => {
let image_type = qcow::detect_image_type(&raw_image).map_err(Error::DetectImageType)?;
let block_box: Box<devices::virtio::VirtioDevice> = match image_type {
ImageType::Raw => {
// Access as a raw block device.
Box::new(
devices::virtio::Block::new(raw_image, disk.read_only)
.map_err(|e| Error::BlockDeviceNew(e))?,
)
}
DiskType::Qcow => {
ImageType::Qcow2 => {
// Valid qcow header present
let qcow_image =
QcowFile::from(raw_image).map_err(|e| Error::QcowDeviceCreate(e))?;

View file

@ -55,15 +55,9 @@ use vm_control::VmRequest;
static SECCOMP_POLICY_DIR: &'static str = "/usr/share/policy/crosvm";
enum DiskType {
FlatFile,
Qcow,
}
struct DiskOption {
path: PathBuf,
read_only: bool,
disk_type: DiskType,
}
/// Contains all the info needed to create the system's virtio devices.
@ -233,11 +227,6 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
cfg.virtio_dev_info.disks.push(DiskOption {
path: disk_path,
read_only: !name.starts_with("rw"),
disk_type: if name.ends_with("qcow") {
DiskType::Qcow
} else {
DiskType::FlatFile
},
});
}
"host_ip" => {
@ -448,9 +437,9 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> {
"PATH",
"Path to a root disk image. Like `--disk` but adds appropriate kernel command line option."),
Argument::short_value('d', "disk", "PATH", "Path to a disk image."),
Argument::value("qcow", "PATH", "Path to a qcow2 disk image."),
Argument::value("qcow", "PATH", "Path to a qcow2 disk image. (Deprecated; use --disk instead.)"),
Argument::value("rwdisk", "PATH", "Path to a writable disk image."),
Argument::value("rwqcow", "PATH", "Path to a writable qcow2 disk image."),
Argument::value("rwqcow", "PATH", "Path to a writable qcow2 disk image. (Deprecated; use --rwdisk instead.)"),
Argument::value("host_ip",
"IP",
"IP address to assign to host tap interface."),