diff options
author | A. Cody Schuffelen <schuffelen@google.com> | 2019-12-23 18:27:11 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-21 21:52:53 +0000 |
commit | 9ca6039b030a5c83062cfec9a5ff52f42814fa13 (patch) | |
tree | da4efa052a2f0afe1b736a26ad83eb216c90b7e0 /src | |
parent | 4f48eab6027a3ab3e4b87893f7ec275f67f62922 (diff) | |
download | crosvm-9ca6039b030a5c83062cfec9a5ff52f42814fa13.tar crosvm-9ca6039b030a5c83062cfec9a5ff52f42814fa13.tar.gz crosvm-9ca6039b030a5c83062cfec9a5ff52f42814fa13.tar.bz2 crosvm-9ca6039b030a5c83062cfec9a5ff52f42814fa13.tar.lz crosvm-9ca6039b030a5c83062cfec9a5ff52f42814fa13.tar.xz crosvm-9ca6039b030a5c83062cfec9a5ff52f42814fa13.tar.zst crosvm-9ca6039b030a5c83062cfec9a5ff52f42814fa13.zip |
Support generating and opening backing files
The new functionality can be invoked through "crosvm create_qcow2 --backing_file=backing new_file". The old behavior of creating a qcow image with a particular size is still available with its original syntax. This is relevant to implement as by default something like qemu-img will create a new image that assumes the backing file is raw or qcow, while crosvm can use its knowledge of other formats (such as composite disk, and later android sparse) to determine the true size of the backing file. TEST=unit tests BUG=b:140069322 Change-Id: I22de6a79c6d8566a9fcb0bc8124e2d74fea9ca55 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1982833 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 80 |
1 files changed, 64 insertions, 16 deletions
diff --git a/src/main.rs b/src/main.rs index 569935c..ce3e660 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1385,34 +1385,82 @@ fn balloon_vms(mut args: std::env::Args) -> std::result::Result<(), ()> { vms_request(&VmRequest::BalloonCommand(command), args) } -fn create_qcow2(mut args: std::env::Args) -> std::result::Result<(), ()> { - if args.len() != 2 { - print_help("crosvm create_qcow2", "PATH SIZE", &[]); - println!("Create a new QCOW2 image at `PATH` of the specified `SIZE` in bytes."); +fn create_qcow2(args: std::env::Args) -> std::result::Result<(), ()> { + let arguments = [ + Argument::positional("PATH", "where to create the qcow2 image"), + Argument::positional("[SIZE]", "the expanded size of the image"), + Argument::value( + "backing_file", + "path/to/file", + " the file to back the image", + ), + ]; + let mut positional_index = 0; + let mut file_path = String::from(""); + let mut size: Option<u64> = None; + let mut backing_file: Option<String> = None; + set_arguments(args, &arguments[..], |name, value| { + match (name, positional_index) { + ("", 0) => { + // NAME + positional_index += 1; + file_path = value.unwrap().to_owned(); + } + ("", 1) => { + // [SIZE] + positional_index += 1; + size = Some(value.unwrap().parse::<u64>().map_err(|_| { + argument::Error::InvalidValue { + value: value.unwrap().to_owned(), + expected: "SIZE should be a nonnegative integer", + } + })?); + } + ("", _) => { + return Err(argument::Error::TooManyArguments( + "Expected at most 2 positional arguments".to_owned(), + )); + } + ("backing_file", _) => { + backing_file = value.map(|x| x.to_owned()); + } + _ => unreachable!(), + }; + Ok(()) + }) + .map_err(|e| { + error!("Unable to parse command line arguments: {}", e); + })?; + if file_path.len() == 0 || !(size.is_some() ^ backing_file.is_some()) { + print_help("crosvm create_qcow2", "PATH [SIZE]", &arguments); + println!( + "Create a new QCOW2 image at `PATH` of either the specified `SIZE` in bytes or +with a '--backing_file'." + ); return Err(()); } - let file_path = args.nth(0).unwrap(); - let size: u64 = match args.nth(0).unwrap().parse::<u64>() { - Ok(n) => n, - Err(_) => { - error!("Failed to parse size of the disk."); - return Err(()); - } - }; let file = OpenOptions::new() .create(true) .read(true) .write(true) + .truncate(true) .open(&file_path) .map_err(|e| { error!("Failed opening qcow file at '{}': {}", file_path, e); })?; - QcowFile::new(file, size).map_err(|e| { - error!("Failed to create qcow file at '{}': {}", file_path, e); - })?; - + match (size, backing_file) { + (Some(size), None) => QcowFile::new(file, size).map_err(|e| { + error!("Failed to create qcow file at '{}': {}", file_path, e); + })?, + (None, Some(backing_file)) => { + QcowFile::new_from_backing(file, &backing_file).map_err(|e| { + error!("Failed to create qcow file at '{}': {}", file_path, e); + })? + } + _ => unreachable!(), + }; Ok(()) } |