vm_tools: arcvm: Add support for Android fstab.
Android uses device tree to do first stage mount. Android Pie
and crosvm both support it already. We just need to enable it with
--android-fstab command line flag.
BUG=b:140846468
TEST=manual - Boot ARCVM to check /proc/device-tree/firmware/android/fstab
Change-Id: Ie62f1be94b0b1e5a2a77ebb59f33cda7c70c2fe9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/1820040
Reviewed-by: Yusuke Sato <yusukes@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Tested-by: Lepton Wu <lepton@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
diff --git a/arc/vm/launch/arcvm_launch.cc b/arc/vm/launch/arcvm_launch.cc
index 2887d56..9fbabc4 100644
--- a/arc/vm/launch/arcvm_launch.cc
+++ b/arc/vm/launch/arcvm_launch.cc
@@ -44,6 +44,7 @@
constexpr char kKernel[] = "vmlinux";
constexpr char kRootFs[] = "system.raw.img";
constexpr char kVendorImage[] = "vendor.raw.img";
+constexpr char kFstab[] = "fstab";
constexpr auto DEFAULT_TIMEOUT = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT;
@@ -305,6 +306,9 @@
disk_image->set_writable(false);
disk_image->set_do_mount(true);
+ // Add Android fstab
+ request.set_fstab(SelectDlcOrBuiltin(base::FilePath(kFstab)).value());
+
return request;
}
diff --git a/system_api/dbus/vm_concierge/service.proto b/system_api/dbus/vm_concierge/service.proto
index 7fe7d15..3fb6b58 100644
--- a/system_api/dbus/vm_concierge/service.proto
+++ b/system_api/dbus/vm_concierge/service.proto
@@ -162,6 +162,9 @@
// Parameters to pass to the ARCVM's init process.
repeated string params = 5;
+
+ // Path to Android fstab.
+ string fstab = 6;
}
enum VmStatus {
diff --git a/vm_tools/concierge/arc_vm.cc b/vm_tools/concierge/arc_vm.cc
index cadf922..4eaee36 100644
--- a/vm_tools/concierge/arc_vm.cc
+++ b/vm_tools/concierge/arc_vm.cc
@@ -86,6 +86,7 @@
std::unique_ptr<ArcVm> ArcVm::Create(
base::FilePath kernel,
base::FilePath rootfs,
+ base::FilePath fstab,
std::vector<ArcVm::Disk> disks,
arc_networkd::MacAddress mac_addr,
std::unique_ptr<arc_networkd::Subnet> subnet,
@@ -98,8 +99,8 @@
std::move(mac_addr), std::move(subnet), vsock_cid,
std::move(seneschal_server_proxy), std::move(runtime_dir), features));
- if (!vm->Start(std::move(kernel), std::move(rootfs), std::move(disks),
- std::move(params))) {
+ if (!vm->Start(std::move(kernel), std::move(rootfs), std::move(fstab),
+ std::move(disks), std::move(params))) {
vm.reset();
}
@@ -112,6 +113,7 @@
bool ArcVm::Start(base::FilePath kernel,
base::FilePath rootfs,
+ base::FilePath fstab,
std::vector<ArcVm::Disk> disks,
std::vector<string> params) {
// Set up the tap device.
@@ -138,6 +140,7 @@
"--syslog-tag", base::StringPrintf("ARCVM(%u)", vsock_cid_),
"--cras-audio",
"--cras-capture",
+ "--android-fstab", fstab.value(),
"--params", base::JoinString(params, " "),
};
// clang-format on
diff --git a/vm_tools/concierge/arc_vm.h b/vm_tools/concierge/arc_vm.h
index ea389a7..73bee61 100644
--- a/vm_tools/concierge/arc_vm.h
+++ b/vm_tools/concierge/arc_vm.h
@@ -49,6 +49,7 @@
static std::unique_ptr<ArcVm> Create(
base::FilePath kernel,
base::FilePath rootfs,
+ base::FilePath fstab,
std::vector<Disk> disks,
arc_networkd::MacAddress mac_addr,
std::unique_ptr<arc_networkd::Subnet> subnet,
@@ -126,6 +127,7 @@
// Starts the VM with the given kernel and root file system.
bool Start(base::FilePath kernel,
base::FilePath rootfs,
+ base::FilePath fstab,
std::vector<Disk> disks,
std::vector<std::string> params);
diff --git a/vm_tools/concierge/client.cc b/vm_tools/concierge/client.cc
index 08a2fbe..e3534a6 100644
--- a/vm_tools/concierge/client.cc
+++ b/vm_tools/concierge/client.cc
@@ -1009,6 +1009,7 @@
string name,
string kernel,
string rootfs,
+ string fstab,
string extra_disks,
const std::vector<string>& params) {
constexpr char arcvm_prefix[] = "/opt/google/vms/android";
@@ -1033,6 +1034,16 @@
LOG(INFO) << "using default rootfs " << rootfs;
}
+ if (fstab.empty()) {
+ fstab = base::StringPrintf("%s/fstab", arcvm_prefix);
+ if (base::PathExists(base::FilePath(fstab))) {
+ LOG(INFO) << "using default fstab " << fstab;
+ } else {
+ LOG(ERROR) << fstab << " does not exist";
+ return -1;
+ }
+ }
+
if (extra_disks.empty()) {
std::string disk_name;
base::Base64UrlEncode(name, base::Base64UrlEncodePolicy::INCLUDE_PADDING,
@@ -1063,6 +1074,7 @@
vm_tools::concierge::StartArcVmRequest request;
request.set_owner_id(std::move(cryptohome_id));
request.set_name(std::move(name));
+ request.set_fstab(std::move(fstab));
request.mutable_vm()->set_kernel(std::move(kernel));
request.mutable_vm()->set_rootfs(std::move(rootfs));
@@ -1457,6 +1469,7 @@
DEFINE_string(container_name, "", "Name of the container within the VM");
DEFINE_string(removable_media, "", "Name of the removable media to use");
DEFINE_string(image_name, "", "Name of the file on removable media to use");
+ DEFINE_string(android_fstab, "", "Path to the Android fstab");
// create_disk parameters.
DEFINE_string(cryptohome_id, "", "User cryptohome id");
@@ -1584,7 +1597,8 @@
} else if (FLAGS_start_arc_vm) {
return StartArcVm(proxy, std::move(FLAGS_cryptohome_id),
std::move(FLAGS_name), std::move(FLAGS_kernel),
- std::move(FLAGS_rootfs), std::move(FLAGS_extra_disks),
+ std::move(FLAGS_rootfs), std::move(FLAGS_android_fstab),
+ std::move(FLAGS_extra_disks),
base::CommandLine::ForCurrentProcess()->GetArgs());
} else if (FLAGS_sync_time) {
return SyncVmTimes(proxy);
diff --git a/vm_tools/concierge/service.cc b/vm_tools/concierge/service.cc
index 26976e2..3989dc3 100644
--- a/vm_tools/concierge/service.cc
+++ b/vm_tools/concierge/service.cc
@@ -1595,6 +1595,7 @@
const base::FilePath kernel(request.vm().kernel());
const base::FilePath rootfs(request.vm().rootfs());
+ const base::FilePath fstab(request.fstab());
if (!base::PathExists(kernel)) {
LOG(ERROR) << "Missing VM kernel path: " << kernel.value();
@@ -1612,6 +1613,14 @@
return dbus_response;
}
+ if (!base::PathExists(fstab)) {
+ LOG(ERROR) << "Missing VM fstab path: " << fstab.value();
+
+ response.set_failure_reason("Fstab path does not exist");
+ writer.AppendProtoAsArrayOfBytes(response);
+ return dbus_response;
+ }
+
std::vector<ArcVm::Disk> disks;
for (const auto& disk : request.disks()) {
if (!base::PathExists(base::FilePath(disk.path()))) {
@@ -1682,8 +1691,8 @@
features.gpu = base::SysInfo::OperatingSystemArchitecture() == "x86_64";
auto vm = ArcVm::Create(std::move(kernel), std::move(rootfs),
- std::move(disks), kArcVmMacAddress, std::move(subnet),
- vsock_cid, std::move(server_proxy),
+ std::move(fstab), std::move(disks), kArcVmMacAddress,
+ std::move(subnet), vsock_cid, std::move(server_proxy),
std::move(runtime_dir), features, std::move(params));
if (!vm) {
LOG(ERROR) << "Unable to start VM";