From 6ecbbfd72312a07c1b9cd686aa2594f072448d40 Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Thu, 18 Jan 2018 13:39:51 -0800 Subject: [PATCH] Add qcow_utils for exposing qcow functions as a C library This C library will be use by the VM launcher to create the qcow2 files used for persistent VM data. CQ-DEPEND=CL:884263 BUG=none TEST=cargo test --all -- --test-threads=1 Change-Id: Ibd7f71d2e3f1f72f781978f014865d2161f033f5 Signed-off-by: Dylan Reid Reviewed-on: https://chromium-review.googlesource.com/875116 --- Cargo.lock | 33 ++++++++++++++++--------- Cargo.toml | 1 + qcow_utils/Cargo.toml | 12 +++++++++ qcow_utils/src/qcow_utils.h | 10 ++++++++ qcow_utils/src/qcow_utils.rs | 47 ++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 qcow_utils/Cargo.toml create mode 100644 qcow_utils/src/qcow_utils.h create mode 100644 qcow_utils/src/qcow_utils.rs diff --git a/Cargo.lock b/Cargo.lock index f4052a258a..5c0d367a8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,15 +1,3 @@ -[root] -name = "x86_64" -version = "0.1.0" -dependencies = [ - "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "data_model 0.1.0", - "kvm 0.1.0", - "kvm_sys 0.1.0", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "sys_util 0.1.0", -] - [[package]] name = "bitflags" version = "1.0.1" @@ -38,6 +26,7 @@ dependencies = [ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "plugin_proto 0.5.0", "qcow 0.1.0", + "qcow_utils 0.1.0", "sys_util 0.1.0", "vm_control 0.1.0", "x86_64 0.1.0", @@ -184,6 +173,14 @@ dependencies = [ "sys_util 0.1.0", ] +[[package]] +name = "qcow_utils" +version = "0.1.0" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "qcow 0.1.0", +] + [[package]] name = "rand" version = "0.3.20" @@ -243,6 +240,18 @@ dependencies = [ "sys_util 0.1.0", ] +[[package]] +name = "x86_64" +version = "0.1.0" +dependencies = [ + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "data_model 0.1.0", + "kvm 0.1.0", + "kvm_sys 0.1.0", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "sys_util 0.1.0", +] + [metadata] "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" diff --git a/Cargo.toml b/Cargo.toml index cdbe542ca5..80a7c5ff0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ vm_control = { path = "vm_control" } data_model = { path = "data_model" } qcow = { path = "qcow" } plugin_proto = { path = "plugin_proto", optional = true } +qcow_utils = { path = "qcow_utils" } [target.'cfg(target_arch = "x86_64")'.dependencies] x86_64 = { path = "x86_64" } diff --git a/qcow_utils/Cargo.toml b/qcow_utils/Cargo.toml new file mode 100644 index 0000000000..5ec33435fb --- /dev/null +++ b/qcow_utils/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "qcow_utils" +version = "0.1.0" +authors = ["The Chromium OS Authors"] + +[lib] +path = "src/qcow_utils.rs" +crate-type = ["cdylib"] + +[dependencies] +libc = "*" +qcow = { path = "../qcow" } diff --git a/qcow_utils/src/qcow_utils.h b/qcow_utils/src/qcow_utils.h new file mode 100644 index 0000000000..1bddeec1d4 --- /dev/null +++ b/qcow_utils/src/qcow_utils.h @@ -0,0 +1,10 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +// Exported interface to basic qcow functionality to be used from C. + +// Create a basic, empty qcow2 file that can grow to `virtual_size` at `path`. +int create_qcow_with_size(const char *path, uint64_t virtual_size); diff --git a/qcow_utils/src/qcow_utils.rs b/qcow_utils/src/qcow_utils.rs new file mode 100644 index 0000000000..083db0b3c8 --- /dev/null +++ b/qcow_utils/src/qcow_utils.rs @@ -0,0 +1,47 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Exported interface to basic qcow functionality to be used from C. + +extern crate libc; +extern crate qcow; + +use std::ffi::CStr; +use std::fs::OpenOptions; +use std::os::raw::{c_char, c_int}; +use libc::EINVAL; + +use qcow::QcowHeader; + +#[no_mangle] +pub extern "C" fn create_qcow_with_size(path: *const c_char, + virtual_size: u64) -> c_int { + let c_str = unsafe { + // NULL pointers are checked, but this will access any other invalid pointer passed from C + // code. It's the caller's responsibility to pass a valid pointer. + if path.is_null() { + return -EINVAL; + } + CStr::from_ptr(path) + }; + let file_path = match c_str.to_str() { + Ok(s) => s, + Err(_) => return -EINVAL, + }; + + let h = QcowHeader::create_for_size(virtual_size); + let mut file = match OpenOptions::new() + .create(true) + .read(true) + .write(true) + .open(file_path) { + Ok(f) => f, + Err(_) => return -1, + }; + + match h.write_to(&mut file) { + Ok(()) => 0, + Err(_) => -1, + } +}