1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "host/commands/assemble_cvd/disk_flags.h"
18
19 #include <sys/statvfs.h>
20
21 #include <fstream>
22 #include <string>
23 #include <vector>
24
25 #include <android-base/logging.h>
26 #include <android-base/parsebool.h>
27 #include <android-base/parseint.h>
28 #include <android-base/strings.h>
29 #include <fruit/fruit.h>
30 #include <gflags/gflags.h>
31
32 #include "common/libs/fs/shared_buf.h"
33 #include "common/libs/utils/files.h"
34 #include "common/libs/utils/flag_parser.h"
35 #include "common/libs/utils/result.h"
36 #include "common/libs/utils/size_utils.h"
37 #include "common/libs/utils/subprocess.h"
38 #include "host/commands/assemble_cvd/boot_config.h"
39 #include "host/commands/assemble_cvd/boot_image_utils.h"
40 #include "host/commands/assemble_cvd/bootconfig_args.h"
41 #include "host/commands/assemble_cvd/disk/disk.h"
42 #include "host/commands/assemble_cvd/disk_builder.h"
43 #include "host/commands/assemble_cvd/flags_defaults.h"
44 #include "host/commands/assemble_cvd/super_image_mixer.h"
45 #include "host/commands/assemble_cvd/vendor_dlkm_utils.h"
46 #include "host/libs/avb/avb.h"
47 #include "host/libs/config/cuttlefish_config.h"
48 #include "host/libs/config/data_image.h"
49 #include "host/libs/config/inject.h"
50 #include "host/libs/config/instance_nums.h"
51 #include "host/libs/vm_manager/gem5_manager.h"
52
53 DECLARE_string(system_image_dir);
54
55 DEFINE_string(boot_image, CF_DEFAULTS_BOOT_IMAGE,
56 "Location of cuttlefish boot image. If empty it is assumed to be "
57 "boot.img in the directory specified by -system_image_dir.");
58 DEFINE_string(
59 init_boot_image, CF_DEFAULTS_INIT_BOOT_IMAGE,
60 "Location of cuttlefish init boot image. If empty it is assumed to "
61 "be init_boot.img in the directory specified by -system_image_dir.");
62 DEFINE_string(data_image, CF_DEFAULTS_DATA_IMAGE,
63 "Location of the data partition image.");
64 DEFINE_string(super_image, CF_DEFAULTS_SUPER_IMAGE,
65 "Location of the super partition image.");
66 DEFINE_string(misc_info_txt, "", "Location of the misc_info.txt file.");
67 DEFINE_string(
68 vendor_boot_image, CF_DEFAULTS_VENDOR_BOOT_IMAGE,
69 "Location of cuttlefish vendor boot image. If empty it is assumed to "
70 "be vendor_boot.img in the directory specified by -system_image_dir.");
71 DEFINE_string(vbmeta_image, CF_DEFAULTS_VBMETA_IMAGE,
72 "Location of cuttlefish vbmeta image. If empty it is assumed to "
73 "be vbmeta.img in the directory specified by -system_image_dir.");
74 DEFINE_string(
75 vbmeta_system_image, CF_DEFAULTS_VBMETA_SYSTEM_IMAGE,
76 "Location of cuttlefish vbmeta_system image. If empty it is assumed to "
77 "be vbmeta_system.img in the directory specified by -system_image_dir.");
78 DEFINE_string(
79 vbmeta_vendor_dlkm_image, CF_DEFAULTS_VBMETA_VENDOR_DLKM_IMAGE,
80 "Location of cuttlefish vbmeta_vendor_dlkm image. If empty it is assumed "
81 "to "
82 "be vbmeta_vendor_dlkm.img in the directory specified by "
83 "-system_image_dir.");
84 DEFINE_string(
85 vbmeta_system_dlkm_image, CF_DEFAULTS_VBMETA_SYSTEM_DLKM_IMAGE,
86 "Location of cuttlefish vbmeta_system_dlkm image. If empty it is assumed "
87 "to "
88 "be vbmeta_system_dlkm.img in the directory specified by "
89 "-system_image_dir.");
90 DEFINE_string(vvmtruststore_path, CF_DEFAULTS_VVMTRUSTSTORE_PATH,
91 "Location of the vvmtruststore image");
92
93 DEFINE_string(
94 default_target_zip, CF_DEFAULTS_DEFAULT_TARGET_ZIP,
95 "Location of default target zip file.");
96 DEFINE_string(
97 system_target_zip, CF_DEFAULTS_SYSTEM_TARGET_ZIP,
98 "Location of system target zip file.");
99
100 DEFINE_string(android_efi_loader, CF_DEFAULTS_ANDROID_EFI_LOADER,
101 "Location of android EFI loader for android efi load flow.");
102
103 DEFINE_string(linux_kernel_path, CF_DEFAULTS_LINUX_KERNEL_PATH,
104 "Location of linux kernel for cuttlefish otheros flow.");
105 DEFINE_string(linux_initramfs_path, CF_DEFAULTS_LINUX_INITRAMFS_PATH,
106 "Location of linux initramfs.img for cuttlefish otheros flow.");
107 DEFINE_string(linux_root_image, CF_DEFAULTS_LINUX_ROOT_IMAGE,
108 "Location of linux root filesystem image for cuttlefish otheros flow.");
109
110 DEFINE_string(chromeos_disk, CF_DEFAULTS_CHROMEOS_DISK,
111 "Location of a complete ChromeOS GPT disk");
112 DEFINE_string(chromeos_kernel_path, CF_DEFAULTS_CHROMEOS_KERNEL_PATH,
113 "Location of the chromeos kernel for the chromeos flow.");
114 DEFINE_string(chromeos_root_image, CF_DEFAULTS_CHROMEOS_ROOT_IMAGE,
115 "Location of chromeos root filesystem image for chromeos flow.");
116
117 DEFINE_string(fuchsia_zedboot_path, CF_DEFAULTS_FUCHSIA_ZEDBOOT_PATH,
118 "Location of fuchsia zedboot path for cuttlefish otheros flow.");
119 DEFINE_string(fuchsia_multiboot_bin_path, CF_DEFAULTS_FUCHSIA_MULTIBOOT_BIN_PATH,
120 "Location of fuchsia multiboot bin path for cuttlefish otheros flow.");
121 DEFINE_string(fuchsia_root_image, CF_DEFAULTS_FUCHSIA_ROOT_IMAGE,
122 "Location of fuchsia root filesystem image for cuttlefish otheros flow.");
123
124 DEFINE_string(
125 custom_partition_path, CF_DEFAULTS_CUSTOM_PARTITION_PATH,
126 "Location of custom image that will be passed as a \"custom\" partition"
127 "to rootfs and can be used by /dev/block/by-name/custom. Multiple images "
128 "can be passed, separated by semicolons and can be used as "
129 "/dev/block/by-name/custom_1, /dev/block/by-name/custom_2, etc. Example: "
130 "--custom_partition_path=\"/path/to/custom.img;/path/to/other.img\"");
131
132 DEFINE_string(
133 hibernation_image, CF_DEFAULTS_HIBERNATION_IMAGE,
134 "Location of the hibernation path that will be used when hibernating.");
135
136 DEFINE_string(blank_metadata_image_mb, CF_DEFAULTS_BLANK_METADATA_IMAGE_MB,
137 "The size of the blank metadata image to generate, MB.");
138 DEFINE_string(
139 blank_sdcard_image_mb, CF_DEFAULTS_BLANK_SDCARD_IMAGE_MB,
140 "If enabled, the size of the blank sdcard image to generate, MB.");
141
142 DECLARE_string(ap_rootfs_image);
143 DECLARE_string(bootloader);
144 DECLARE_string(initramfs_path);
145 DECLARE_string(kernel_path);
146 DECLARE_bool(resume);
147 DECLARE_bool(use_overlay);
148 DECLARE_bool(use_16k);
149
150 namespace cuttlefish {
151
152 using APBootFlow = CuttlefishConfig::InstanceSpecific::APBootFlow;
153 using vm_manager::Gem5Manager;
154
ResolveInstanceFiles()155 Result<void> ResolveInstanceFiles() {
156 CF_EXPECT(!FLAGS_system_image_dir.empty(),
157 "--system_image_dir must be specified.");
158 if (FLAGS_use_16k) {
159 CF_EXPECT(FLAGS_kernel_path.empty(),
160 "--use_16k is not compatible with --kernel_path");
161 CF_EXPECT(FLAGS_initramfs_path.empty(),
162 "--use_16k is not compatible with --initramfs_path");
163 }
164
165 // It is conflict (invalid) to pass both kernel_path/initramfs_path
166 // and image file paths.
167 bool flags_kernel_initramfs_has_input = (FLAGS_kernel_path != "")
168 || (FLAGS_initramfs_path != "");
169 bool flags_image_has_input =
170 (FLAGS_super_image != "") || (FLAGS_vendor_boot_image != "") ||
171 (FLAGS_vbmeta_vendor_dlkm_image != "") ||
172 (FLAGS_vbmeta_system_dlkm_image != "") || (FLAGS_boot_image != "");
173 CF_EXPECT(!(flags_kernel_initramfs_has_input && flags_image_has_input),
174 "Cannot pass both kernel_path/initramfs_path and image file paths");
175
176 std::vector<std::string> system_image_dir =
177 android::base::Split(FLAGS_system_image_dir, ",");
178 std::string default_boot_image = "";
179 std::string default_init_boot_image = "";
180 std::string default_data_image = "";
181 std::string default_super_image = "";
182 std::string default_misc_info_txt = "";
183 std::string default_vendor_boot_image = "";
184 std::string default_vbmeta_image = "";
185 std::string default_vbmeta_system_image = "";
186 std::string default_vbmeta_vendor_dlkm_image = "";
187 std::string default_vbmeta_system_dlkm_image = "";
188 std::string default_16k_kernel_image = "";
189 std::string default_16k_ramdisk_image = "";
190 std::string default_hibernation_image = "";
191
192 std::string cur_system_image_dir;
193 std::string comma_str = "";
194 auto instance_nums =
195 CF_EXPECT(InstanceNumsCalculator().FromGlobalGflags().Calculate());
196 for (int instance_index = 0; instance_index < instance_nums.size(); instance_index++) {
197 if (instance_index < system_image_dir.size()) {
198 cur_system_image_dir = system_image_dir[instance_index];
199 } else {
200 // legacy variable or out of boundary. Vectorize by copy [0] to all instances
201 cur_system_image_dir = system_image_dir[0];
202 }
203 if (instance_index > 0) {
204 comma_str = ",";
205 }
206
207 // If user did not specify location of either of these files, expect them to
208 // be placed in --system_image_dir location.
209 default_boot_image += comma_str + cur_system_image_dir + "/boot.img";
210 default_init_boot_image += comma_str + cur_system_image_dir + "/init_boot.img";
211 default_data_image += comma_str + cur_system_image_dir + "/userdata.img";
212 default_super_image += comma_str + cur_system_image_dir + "/super.img";
213 default_misc_info_txt +=
214 comma_str + cur_system_image_dir + "/misc_info.txt";
215 default_vendor_boot_image += comma_str + cur_system_image_dir + "/vendor_boot.img";
216 default_vbmeta_image += comma_str + cur_system_image_dir + "/vbmeta.img";
217 default_vbmeta_system_image += comma_str + cur_system_image_dir + "/vbmeta_system.img";
218 default_vbmeta_vendor_dlkm_image +=
219 comma_str + cur_system_image_dir + "/vbmeta_vendor_dlkm.img";
220 default_vbmeta_system_dlkm_image +=
221 comma_str + cur_system_image_dir + "/vbmeta_system_dlkm.img";
222 default_hibernation_image +=
223 comma_str + cur_system_image_dir + "/hibernation_swap.img";
224 if (FLAGS_use_16k) {
225 const auto kernel_16k = cur_system_image_dir + "/kernel_16k";
226 const auto ramdisk_16k = cur_system_image_dir + "/ramdisk_16k.img";
227 default_16k_kernel_image += comma_str + kernel_16k;
228 default_16k_ramdisk_image += comma_str + ramdisk_16k;
229 CF_EXPECT(FileExists(kernel_16k),
230 kernel_16k + " missing for launching 16k cuttlefish");
231 CF_EXPECT(FileExists(ramdisk_16k),
232 ramdisk_16k + " missing for launching 16k cuttlefish");
233 }
234 }
235 if (FLAGS_use_16k) {
236 LOG(INFO) << "Using 16k kernel: " << default_16k_kernel_image;
237 LOG(INFO) << "Using 16k ramdisk: " << default_16k_ramdisk_image;
238
239 SetCommandLineOptionWithMode("kernel_path",
240 default_16k_kernel_image.c_str(),
241 google::FlagSettingMode::SET_FLAGS_DEFAULT);
242 SetCommandLineOptionWithMode("initramfs_path",
243 default_16k_ramdisk_image.c_str(),
244 google::FlagSettingMode::SET_FLAGS_DEFAULT);
245 }
246 SetCommandLineOptionWithMode("boot_image", default_boot_image.c_str(),
247 google::FlagSettingMode::SET_FLAGS_DEFAULT);
248 SetCommandLineOptionWithMode("init_boot_image",
249 default_init_boot_image.c_str(),
250 google::FlagSettingMode::SET_FLAGS_DEFAULT);
251 SetCommandLineOptionWithMode("data_image", default_data_image.c_str(),
252 google::FlagSettingMode::SET_FLAGS_DEFAULT);
253 SetCommandLineOptionWithMode("super_image", default_super_image.c_str(),
254 google::FlagSettingMode::SET_FLAGS_DEFAULT);
255 SetCommandLineOptionWithMode("misc_info_txt", default_misc_info_txt.c_str(),
256 google::FlagSettingMode::SET_FLAGS_DEFAULT);
257 SetCommandLineOptionWithMode("vendor_boot_image",
258 default_vendor_boot_image.c_str(),
259 google::FlagSettingMode::SET_FLAGS_DEFAULT);
260 SetCommandLineOptionWithMode("vbmeta_image", default_vbmeta_image.c_str(),
261 google::FlagSettingMode::SET_FLAGS_DEFAULT);
262 SetCommandLineOptionWithMode("vbmeta_system_image",
263 default_vbmeta_system_image.c_str(),
264 google::FlagSettingMode::SET_FLAGS_DEFAULT);
265 SetCommandLineOptionWithMode("vbmeta_vendor_dlkm_image",
266 default_vbmeta_vendor_dlkm_image.c_str(),
267 google::FlagSettingMode::SET_FLAGS_DEFAULT);
268 SetCommandLineOptionWithMode("vbmeta_system_dlkm_image",
269 default_vbmeta_system_dlkm_image.c_str(),
270 google::FlagSettingMode::SET_FLAGS_DEFAULT);
271 SetCommandLineOptionWithMode("hibernation_image",
272 default_hibernation_image.c_str(),
273 google::FlagSettingMode::SET_FLAGS_DEFAULT);
274
275 return {};
276 }
277
chromeos_composite_disk_config(const CuttlefishConfig::InstanceSpecific & instance)278 std::vector<ImagePartition> chromeos_composite_disk_config(
279 const CuttlefishConfig::InstanceSpecific& instance) {
280 std::vector<ImagePartition> partitions;
281
282 partitions.emplace_back(ImagePartition{
283 .label = "STATE",
284 .image_file_path = AbsolutePath(instance.chromeos_state_image()),
285 .type = kLinuxFilesystem,
286 .read_only = FLAGS_use_overlay,
287 });
288 partitions.emplace_back(ImagePartition{
289 .label = "linux_esp",
290 .image_file_path = AbsolutePath(instance.esp_image_path()),
291 .type = kEfiSystemPartition,
292 .read_only = FLAGS_use_overlay,
293 });
294 partitions.emplace_back(ImagePartition{
295 .label = "linux_root",
296 .image_file_path = AbsolutePath(instance.chromeos_root_image()),
297 .type = kLinuxFilesystem,
298 .read_only = FLAGS_use_overlay,
299 });
300
301 return partitions;
302 }
303
linux_composite_disk_config(const CuttlefishConfig::InstanceSpecific & instance)304 std::vector<ImagePartition> linux_composite_disk_config(
305 const CuttlefishConfig::InstanceSpecific& instance) {
306 std::vector<ImagePartition> partitions;
307
308 partitions.push_back(ImagePartition{
309 .label = "linux_esp",
310 .image_file_path = AbsolutePath(instance.esp_image_path()),
311 .type = kEfiSystemPartition,
312 .read_only = FLAGS_use_overlay,
313 });
314 partitions.push_back(ImagePartition{
315 .label = "linux_root",
316 .image_file_path = AbsolutePath(instance.linux_root_image()),
317 .read_only = FLAGS_use_overlay,
318 });
319
320 return partitions;
321 }
322
fuchsia_composite_disk_config(const CuttlefishConfig::InstanceSpecific & instance)323 std::vector<ImagePartition> fuchsia_composite_disk_config(
324 const CuttlefishConfig::InstanceSpecific& instance) {
325 std::vector<ImagePartition> partitions;
326
327 partitions.push_back(ImagePartition{
328 .label = "fuchsia_esp",
329 .image_file_path = AbsolutePath(instance.esp_image_path()),
330 .type = kEfiSystemPartition,
331 .read_only = FLAGS_use_overlay,
332 });
333
334 return partitions;
335 }
336
android_composite_disk_config(const CuttlefishConfig::InstanceSpecific & instance)337 std::vector<ImagePartition> android_composite_disk_config(
338 const CuttlefishConfig::InstanceSpecific& instance) {
339 std::vector<ImagePartition> partitions;
340
341 partitions.push_back(ImagePartition{
342 .label = "misc",
343 .image_file_path = AbsolutePath(instance.misc_image()),
344 .read_only = FLAGS_use_overlay,
345 });
346 partitions.push_back(ImagePartition{
347 .label = "boot_a",
348 .image_file_path = AbsolutePath(instance.new_boot_image()),
349 .read_only = FLAGS_use_overlay,
350 });
351 partitions.push_back(ImagePartition{
352 .label = "boot_b",
353 .image_file_path = AbsolutePath(instance.new_boot_image()),
354 .read_only = FLAGS_use_overlay,
355 });
356 const auto init_boot_path = instance.init_boot_image();
357 if (FileExists(init_boot_path)) {
358 partitions.push_back(ImagePartition{
359 .label = "init_boot_a",
360 .image_file_path = AbsolutePath(init_boot_path),
361 .read_only = FLAGS_use_overlay,
362 });
363 partitions.push_back(ImagePartition{
364 .label = "init_boot_b",
365 .image_file_path = AbsolutePath(init_boot_path),
366 .read_only = FLAGS_use_overlay,
367 });
368 }
369 partitions.push_back(ImagePartition{
370 .label = "vendor_boot_a",
371 .image_file_path = AbsolutePath(instance.new_vendor_boot_image()),
372 .read_only = FLAGS_use_overlay,
373 });
374 partitions.push_back(ImagePartition{
375 .label = "vendor_boot_b",
376 .image_file_path = AbsolutePath(instance.new_vendor_boot_image()),
377 .read_only = FLAGS_use_overlay,
378 });
379 auto vbmeta_image = instance.new_vbmeta_image();
380 if (!FileExists(vbmeta_image)) {
381 vbmeta_image = instance.vbmeta_image();
382 }
383 partitions.push_back(ImagePartition{
384 .label = "vbmeta_a",
385 .image_file_path = AbsolutePath(vbmeta_image),
386 .read_only = FLAGS_use_overlay,
387 });
388 partitions.push_back(ImagePartition{
389 .label = "vbmeta_b",
390 .image_file_path = AbsolutePath(vbmeta_image),
391 .read_only = FLAGS_use_overlay,
392 });
393 partitions.push_back(ImagePartition{
394 .label = "vbmeta_system_a",
395 .image_file_path = AbsolutePath(instance.vbmeta_system_image()),
396 .read_only = FLAGS_use_overlay,
397 });
398 partitions.push_back(ImagePartition{
399 .label = "vbmeta_system_b",
400 .image_file_path = AbsolutePath(instance.vbmeta_system_image()),
401 .read_only = FLAGS_use_overlay,
402 });
403 auto vbmeta_vendor_dlkm_img = instance.new_vbmeta_vendor_dlkm_image();
404 if (!FileExists(vbmeta_vendor_dlkm_img)) {
405 vbmeta_vendor_dlkm_img = instance.vbmeta_vendor_dlkm_image();
406 }
407 if (FileExists(vbmeta_vendor_dlkm_img)) {
408 partitions.push_back(ImagePartition{
409 .label = "vbmeta_vendor_dlkm_a",
410 .image_file_path = AbsolutePath(vbmeta_vendor_dlkm_img),
411 .read_only = FLAGS_use_overlay,
412 });
413 partitions.push_back(ImagePartition{
414 .label = "vbmeta_vendor_dlkm_b",
415 .image_file_path = AbsolutePath(vbmeta_vendor_dlkm_img),
416 .read_only = FLAGS_use_overlay,
417 });
418 }
419 auto vbmeta_system_dlkm_img = instance.new_vbmeta_system_dlkm_image();
420 if (!FileExists(vbmeta_system_dlkm_img)) {
421 vbmeta_system_dlkm_img = instance.vbmeta_system_dlkm_image();
422 }
423 if (FileExists(vbmeta_system_dlkm_img)) {
424 partitions.push_back(ImagePartition{
425 .label = "vbmeta_system_dlkm_a",
426 .image_file_path = AbsolutePath(vbmeta_system_dlkm_img),
427 .read_only = FLAGS_use_overlay,
428 });
429 partitions.push_back(ImagePartition{
430 .label = "vbmeta_system_dlkm_b",
431 .image_file_path = AbsolutePath(vbmeta_system_dlkm_img),
432 .read_only = FLAGS_use_overlay,
433 });
434 }
435 auto super_image = instance.new_super_image();
436 if (!FileExists(super_image)) {
437 super_image = instance.super_image();
438 }
439 partitions.push_back(ImagePartition{
440 .label = "super",
441 .image_file_path = AbsolutePath(super_image),
442 .read_only = FLAGS_use_overlay,
443 });
444 auto data_image = instance.new_data_image();
445 if (!FileExists(data_image)) {
446 data_image = instance.data_image();
447 }
448 partitions.push_back(ImagePartition{
449 .label = "userdata",
450 .image_file_path = AbsolutePath(data_image),
451 .read_only = FLAGS_use_overlay,
452 });
453 partitions.push_back(ImagePartition{
454 .label = "metadata",
455 .image_file_path = AbsolutePath(instance.metadata_image()),
456 .read_only = FLAGS_use_overlay,
457 });
458 const auto hibernation_partition_image =
459 instance.hibernation_partition_image();
460 if (FileExists(hibernation_partition_image)) {
461 partitions.push_back(ImagePartition{
462 .label = "hibernation",
463 .image_file_path = AbsolutePath(hibernation_partition_image),
464 .read_only = FLAGS_use_overlay,
465 });
466 }
467
468 const auto vvmtruststore_path = instance.vvmtruststore_path();
469 if (!vvmtruststore_path.empty()) {
470 partitions.push_back(ImagePartition{
471 .label = "vvmtruststore",
472 .image_file_path = AbsolutePath(vvmtruststore_path),
473 .read_only = FLAGS_use_overlay,
474 });
475 }
476
477 const auto custom_partition_path = instance.custom_partition_path();
478 if (!custom_partition_path.empty()) {
479 auto custom_partition_paths =
480 android::base::Split(custom_partition_path, ";");
481 for (int i = 0; i < custom_partition_paths.size(); i++) {
482 partitions.push_back(ImagePartition{
483 .label = i > 0 ? "custom_" + std::to_string(i) : "custom",
484 .image_file_path = AbsolutePath(custom_partition_paths[i]),
485 .read_only = FLAGS_use_overlay,
486 });
487 }
488 }
489
490 return partitions;
491 }
492
AndroidEfiLoaderCompositeDiskConfig(const CuttlefishConfig::InstanceSpecific & instance)493 std::vector<ImagePartition> AndroidEfiLoaderCompositeDiskConfig(
494 const CuttlefishConfig::InstanceSpecific& instance) {
495 std::vector<ImagePartition> partitions =
496 android_composite_disk_config(instance);
497 // Cuttlefish uboot EFI bootflow by default looks at the first partition
498 // for EFI application. Thus we put "android_esp" at the beginning.
499 partitions.insert(
500 partitions.begin(),
501 ImagePartition{
502 .label = "android_esp",
503 .image_file_path = AbsolutePath(instance.esp_image_path()),
504 .type = kEfiSystemPartition,
505 .read_only = FLAGS_use_overlay,
506 });
507
508 return partitions;
509 }
510
GetApCompositeDiskConfig(const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance)511 std::vector<ImagePartition> GetApCompositeDiskConfig(const CuttlefishConfig& config,
512 const CuttlefishConfig::InstanceSpecific& instance) {
513 std::vector<ImagePartition> partitions;
514
515 if (instance.ap_boot_flow() == APBootFlow::Grub) {
516 partitions.push_back(ImagePartition{
517 .label = "ap_esp",
518 .image_file_path = AbsolutePath(instance.ap_esp_image_path()),
519 .read_only = FLAGS_use_overlay,
520 });
521 }
522
523 partitions.push_back(ImagePartition{
524 .label = "ap_rootfs",
525 .image_file_path = AbsolutePath(config.ap_rootfs_image()),
526 .read_only = FLAGS_use_overlay,
527 });
528
529 return partitions;
530 }
531
GetOsCompositeDiskConfig(const CuttlefishConfig::InstanceSpecific & instance)532 std::vector<ImagePartition> GetOsCompositeDiskConfig(
533 const CuttlefishConfig::InstanceSpecific& instance) {
534 switch (instance.boot_flow()) {
535 case CuttlefishConfig::InstanceSpecific::BootFlow::Android:
536 return android_composite_disk_config(instance);
537 case CuttlefishConfig::InstanceSpecific::BootFlow::AndroidEfiLoader:
538 return AndroidEfiLoaderCompositeDiskConfig(instance);
539 case CuttlefishConfig::InstanceSpecific::BootFlow::ChromeOs:
540 return chromeos_composite_disk_config(instance);
541 case CuttlefishConfig::InstanceSpecific::BootFlow::ChromeOsDisk:
542 return {};
543 case CuttlefishConfig::InstanceSpecific::BootFlow::Linux:
544 return linux_composite_disk_config(instance);
545 case CuttlefishConfig::InstanceSpecific::BootFlow::Fuchsia:
546 return fuchsia_composite_disk_config(instance);
547 }
548 }
549
OsCompositeDiskBuilder(const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance)550 DiskBuilder OsCompositeDiskBuilder(const CuttlefishConfig& config,
551 const CuttlefishConfig::InstanceSpecific& instance) {
552 auto builder =
553 DiskBuilder()
554 .VmManager(config.vm_manager())
555 .CrosvmPath(instance.crosvm_binary())
556 .ConfigPath(instance.PerInstancePath("os_composite_disk_config.txt"))
557 .ResumeIfPossible(FLAGS_resume);
558 if (instance.boot_flow() ==
559 CuttlefishConfig::InstanceSpecific::BootFlow::ChromeOsDisk) {
560 return builder.EntireDisk(instance.chromeos_disk())
561 .CompositeDiskPath(instance.chromeos_disk());
562 }
563 return builder.Partitions(GetOsCompositeDiskConfig(instance))
564 .HeaderPath(instance.PerInstancePath("os_composite_gpt_header.img"))
565 .FooterPath(instance.PerInstancePath("os_composite_gpt_footer.img"))
566 .CompositeDiskPath(instance.os_composite_disk_path());
567 }
568
ApCompositeDiskBuilder(const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance)569 DiskBuilder ApCompositeDiskBuilder(const CuttlefishConfig& config,
570 const CuttlefishConfig::InstanceSpecific& instance) {
571 return DiskBuilder()
572 .Partitions(GetApCompositeDiskConfig(config, instance))
573 .VmManager(config.vm_manager())
574 .CrosvmPath(instance.crosvm_binary())
575 .ConfigPath(instance.PerInstancePath("ap_composite_disk_config.txt"))
576 .HeaderPath(instance.PerInstancePath("ap_composite_gpt_header.img"))
577 .FooterPath(instance.PerInstancePath("ap_composite_gpt_footer.img"))
578 .CompositeDiskPath(instance.ap_composite_disk_path())
579 .ResumeIfPossible(FLAGS_resume);
580 }
581
AvailableSpaceAtPath(const std::string & path)582 static uint64_t AvailableSpaceAtPath(const std::string& path) {
583 struct statvfs vfs {};
584 if (statvfs(path.c_str(), &vfs) != 0) {
585 int error_num = errno;
586 LOG(ERROR) << "Could not find space available at " << path << ", error was "
587 << strerror(error_num);
588 return 0;
589 }
590 // f_frsize (block size) * f_bavail (free blocks) for unprivileged users.
591 return static_cast<uint64_t>(vfs.f_frsize) * vfs.f_bavail;
592 }
593
InitializeChromeOsState(const CuttlefishConfig::InstanceSpecific & instance)594 Result<void> InitializeChromeOsState(
595 const CuttlefishConfig::InstanceSpecific& instance) {
596 using BootFlow = CuttlefishConfig::InstanceSpecific::BootFlow;
597 if (instance.boot_flow() != BootFlow::ChromeOs) {
598 return {};
599 } else if (FileExists(instance.chromeos_state_image())) {
600 return {};
601 }
602 CF_EXPECT(CreateBlankImage(instance.chromeos_state_image(), 8096, "ext4"));
603 return {};
604 }
605
InitializeMetadataImage(const CuttlefishConfig::InstanceSpecific & instance)606 Result<void> InitializeMetadataImage(
607 const CuttlefishConfig::InstanceSpecific& instance) {
608 if (FileExists(instance.metadata_image()) &&
609 FileSize(instance.metadata_image()) == instance.blank_metadata_image_mb()
610 << 20) {
611 return {};
612 }
613
614 CF_EXPECT(CreateBlankImage(instance.metadata_image(),
615 instance.blank_metadata_image_mb(), "none"),
616 "Failed to create \"" << instance.metadata_image()
617 << "\" with size "
618 << instance.blank_metadata_image_mb());
619 return {};
620 }
621
InitializeAccessKregistryImage(const CuttlefishConfig::InstanceSpecific & instance)622 Result<void> InitializeAccessKregistryImage(
623 const CuttlefishConfig::InstanceSpecific& instance) {
624 auto access_kregistry = instance.access_kregistry_path();
625 if (FileExists(access_kregistry)) {
626 return {};
627 }
628 CF_EXPECT(CreateBlankImage(access_kregistry, 2 /* mb */, "none"),
629 "Failed to create \"" << access_kregistry << "\"");
630 return {};
631 }
632
InitializeHwcomposerPmemImage(const CuttlefishConfig::InstanceSpecific & instance)633 Result<void> InitializeHwcomposerPmemImage(
634 const CuttlefishConfig::InstanceSpecific& instance) {
635 if (FileExists(instance.hwcomposer_pmem_path())) {
636 return {};
637 }
638 CF_EXPECT(
639 CreateBlankImage(instance.hwcomposer_pmem_path(), 2 /* mb */, "none"),
640 "Failed creating \"" << instance.hwcomposer_pmem_path() << "\"");
641 return {};
642 }
643
InitializePstore(const CuttlefishConfig::InstanceSpecific & instance)644 Result<void> InitializePstore(
645 const CuttlefishConfig::InstanceSpecific& instance) {
646 if (FileExists(instance.pstore_path())) {
647 return {};
648 }
649
650 CF_EXPECT(CreateBlankImage(instance.pstore_path(), 2 /* mb */, "none"),
651 "Failed to create \"" << instance.pstore_path() << "\"");
652 return {};
653 }
654
InitializePflash(const CuttlefishConfig::InstanceSpecific & instance)655 Result<void> InitializePflash(
656 const CuttlefishConfig::InstanceSpecific& instance) {
657 if (FileExists(instance.pflash_path())) {
658 return {};
659 }
660
661 auto boot_size_mb = FileSize(instance.bootloader()) / (1 << 20);
662
663 // Pad out bootloader space to 4MB
664 CF_EXPECTF(CreateBlankImage(instance.pflash_path(), 4 - boot_size_mb, "none"),
665 "Failed to create '{}'", instance.pflash_path());
666 return {};
667 }
668
InitializeSdCard(const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance)669 Result<void> InitializeSdCard(
670 const CuttlefishConfig& config,
671 const CuttlefishConfig::InstanceSpecific& instance) {
672 if (!(instance.use_sdcard() && !instance.protected_vm())) {
673 return {};
674 }
675 if (FileExists(instance.sdcard_path())) {
676 return {};
677 }
678 CF_EXPECT(CreateBlankImage(instance.sdcard_path(),
679 instance.blank_sdcard_image_mb(), "sdcard"),
680 "Failed to create \"" << instance.sdcard_path() << "\"");
681 if (config.vm_manager() == VmmMode::kQemu) {
682 const std::string crosvm_path = instance.crosvm_binary();
683 CreateQcowOverlay(crosvm_path, instance.sdcard_path(),
684 instance.sdcard_overlay_path());
685 }
686 return {};
687 }
688
VbmetaEnforceMinimumSize(const CuttlefishConfig::InstanceSpecific & instance)689 Result<void> VbmetaEnforceMinimumSize(
690 const CuttlefishConfig::InstanceSpecific& instance) {
691 // libavb expects to be able to read the maximum vbmeta size, so we must
692 // provide a partition which matches this or the read will fail
693 for (const auto& vbmeta_image :
694 {instance.vbmeta_image(), instance.new_vbmeta_image(),
695 instance.vbmeta_system_image(), instance.vbmeta_vendor_dlkm_image(),
696 instance.vbmeta_system_dlkm_image()}) {
697 // In some configurations of cuttlefish, the vendor dlkm vbmeta image does
698 // not exist
699 if (FileExists(vbmeta_image)) {
700 CF_EXPECT(EnforceVbMetaSize(vbmeta_image));
701 }
702 }
703 return {};
704 }
705
BootloaderPresentCheck(const CuttlefishConfig::InstanceSpecific & instance)706 Result<void> BootloaderPresentCheck(
707 const CuttlefishConfig::InstanceSpecific& instance) {
708 CF_EXPECT(FileHasContent(instance.bootloader()),
709 "File not found: " << instance.bootloader());
710 return {};
711 }
712
DiskChangesComponent(const FetcherConfig * fetcher,const CuttlefishConfig * config,const CuttlefishConfig::InstanceSpecific * instance)713 static fruit::Component<> DiskChangesComponent(
714 const FetcherConfig* fetcher, const CuttlefishConfig* config,
715 const CuttlefishConfig::InstanceSpecific* instance) {
716 return fruit::createComponent()
717 .bindInstance(*fetcher)
718 .bindInstance(*config)
719 .bindInstance(*instance)
720 .install(CuttlefishKeyAvbComponent)
721 .install(AutoSetup<InitializeMetadataImage>::Component)
722 .install(AutoSetup<InitializeChromeOsState>::Component)
723 .install(AutoSetup<RepackKernelRamdisk>::Component)
724 .install(AutoSetup<VbmetaEnforceMinimumSize>::Component)
725 .install(AutoSetup<BootloaderPresentCheck>::Component)
726 .install(AutoSetup<Gem5ImageUnpacker>::Component)
727 .install(AutoSetup<InitializeMiscImage>::Component)
728 // Create esp if necessary
729 .install(AutoSetup<InitializeEspImage>::Component)
730 .install(SuperImageRebuilderComponent);
731 }
732
DiskChangesPerInstanceComponent(const FetcherConfig * fetcher,const CuttlefishConfig * config,const CuttlefishConfig::InstanceSpecific * instance)733 static fruit::Component<> DiskChangesPerInstanceComponent(
734 const FetcherConfig* fetcher, const CuttlefishConfig* config,
735 const CuttlefishConfig::InstanceSpecific* instance) {
736 return fruit::createComponent()
737 .bindInstance(*fetcher)
738 .bindInstance(*config)
739 .bindInstance(*instance)
740 .install(AutoSetup<InitializeAccessKregistryImage>::Component)
741 .install(AutoSetup<InitBootloaderEnvPartition>::Component)
742 .install(AutoSetup<InitializeFactoryResetProtected>::Component)
743 .install(AutoSetup<InitializeHwcomposerPmemImage>::Component)
744 .install(AutoSetup<InitializePstore>::Component)
745 .install(AutoSetup<InitializeSdCard>::Component)
746 .install(AutoSetup<GeneratePersistentBootconfig>::Component)
747 .install(AutoSetup<GeneratePersistentVbmeta>::Component)
748 .install(AutoSetup<InitializeInstanceCompositeDisk>::Component)
749 .install(AutoSetup<InitializeDataImage>::Component)
750 .install(AutoSetup<InitializePflash>::Component);
751 }
752
DiskImageFlagsVectorization(CuttlefishConfig & config,const FetcherConfig & fetcher_config)753 Result<void> DiskImageFlagsVectorization(CuttlefishConfig& config, const FetcherConfig& fetcher_config) {
754 std::vector<std::string> boot_image =
755 android::base::Split(FLAGS_boot_image, ",");
756 std::vector<std::string> init_boot_image =
757 android::base::Split(FLAGS_init_boot_image, ",");
758 std::vector<std::string> data_image =
759 android::base::Split(FLAGS_data_image, ",");
760 std::vector<std::string> super_image =
761 android::base::Split(FLAGS_super_image, ",");
762 std::vector<std::string> misc_info =
763 android::base::Split(FLAGS_misc_info_txt, ",");
764 std::vector<std::string> vendor_boot_image =
765 android::base::Split(FLAGS_vendor_boot_image, ",");
766 std::vector<std::string> vbmeta_image =
767 android::base::Split(FLAGS_vbmeta_image, ",");
768 std::vector<std::string> vbmeta_system_image =
769 android::base::Split(FLAGS_vbmeta_system_image, ",");
770 auto vbmeta_vendor_dlkm_image =
771 android::base::Split(FLAGS_vbmeta_vendor_dlkm_image, ",");
772 auto vbmeta_system_dlkm_image =
773 android::base::Split(FLAGS_vbmeta_system_dlkm_image, ",");
774 auto vvmtruststore_path = android::base::Split(FLAGS_vvmtruststore_path, ",");
775
776 std::vector<std::string> default_target_zip_vec =
777 android::base::Split(FLAGS_default_target_zip, ",");
778 std::vector<std::string> system_target_zip_vec =
779 android::base::Split(FLAGS_system_target_zip, ",");
780
781 std::vector<std::string> android_efi_loader =
782 android::base::Split(FLAGS_android_efi_loader, ",");
783
784 std::vector<std::string> chromeos_disk =
785 android::base::Split(FLAGS_chromeos_disk, ",");
786 std::vector<std::string> chromeos_kernel_path =
787 android::base::Split(FLAGS_chromeos_kernel_path, ",");
788 std::vector<std::string> chromeos_root_image =
789 android::base::Split(FLAGS_chromeos_root_image, ",");
790
791 std::vector<std::string> linux_kernel_path =
792 android::base::Split(FLAGS_linux_kernel_path, ",");
793 std::vector<std::string> linux_initramfs_path =
794 android::base::Split(FLAGS_linux_initramfs_path, ",");
795 std::vector<std::string> linux_root_image =
796 android::base::Split(FLAGS_linux_root_image, ",");
797
798 std::vector<std::string> fuchsia_zedboot_path =
799 android::base::Split(FLAGS_fuchsia_zedboot_path, ",");
800 std::vector<std::string> fuchsia_multiboot_bin_path =
801 android::base::Split(FLAGS_fuchsia_multiboot_bin_path, ",");
802 std::vector<std::string> fuchsia_root_image =
803 android::base::Split(FLAGS_fuchsia_root_image, ",");
804
805 std::vector<std::string> custom_partition_path =
806 android::base::Split(FLAGS_custom_partition_path, ",");
807 std::vector<std::string> hibernation_image =
808 android::base::Split(FLAGS_hibernation_image, ",");
809
810 std::vector<std::string> bootloader =
811 android::base::Split(FLAGS_bootloader, ",");
812 std::vector<std::string> initramfs_path =
813 android::base::Split(FLAGS_initramfs_path, ",");
814 std::vector<std::string> kernel_path =
815 android::base::Split(FLAGS_kernel_path, ",");
816
817 std::vector<std::string> blank_metadata_image_mb =
818 android::base::Split(FLAGS_blank_metadata_image_mb, ",");
819 std::vector<std::string> blank_sdcard_image_mb =
820 android::base::Split(FLAGS_blank_sdcard_image_mb, ",");
821
822 std::string cur_kernel_path;
823 std::string cur_initramfs_path;
824 std::string cur_boot_image;
825 std::string cur_vendor_boot_image;
826 std::string cur_super_image;
827 int value{};
828 int instance_index = 0;
829 auto instance_nums =
830 CF_EXPECT(InstanceNumsCalculator().FromGlobalGflags().Calculate());
831 for (const auto& num : instance_nums) {
832 auto instance = config.ForInstance(num);
833 if (instance_index >= misc_info.size()) {
834 instance.set_misc_info_txt(misc_info[0]);
835 } else {
836 instance.set_misc_info_txt(misc_info[instance_index]);
837 }
838 if (instance_index >= boot_image.size()) {
839 cur_boot_image = boot_image[0];
840 } else {
841 cur_boot_image = boot_image[instance_index];
842 }
843 instance.set_boot_image(cur_boot_image);
844 instance.set_new_boot_image(cur_boot_image);
845
846 if (instance_index >= init_boot_image.size()) {
847 instance.set_init_boot_image(init_boot_image[0]);
848 } else {
849 instance.set_init_boot_image(init_boot_image[instance_index]);
850 }
851 if (instance_index >= vendor_boot_image.size()) {
852 cur_vendor_boot_image = vendor_boot_image[0];
853 } else {
854 cur_vendor_boot_image = vendor_boot_image[instance_index];
855 }
856 instance.set_vendor_boot_image(cur_vendor_boot_image);
857 instance.set_new_vendor_boot_image(cur_vendor_boot_image);
858
859 if (instance_index >= vbmeta_image.size()) {
860 instance.set_vbmeta_image(vbmeta_image[0]);
861 } else {
862 instance.set_vbmeta_image(vbmeta_image[instance_index]);
863 }
864 if (instance_index >= vbmeta_system_image.size()) {
865 instance.set_vbmeta_system_image(vbmeta_system_image[0]);
866 } else {
867 instance.set_vbmeta_system_image(vbmeta_system_image[instance_index]);
868 }
869 if (instance_index >= vbmeta_vendor_dlkm_image.size()) {
870 instance.set_vbmeta_vendor_dlkm_image(vbmeta_vendor_dlkm_image[0]);
871 } else {
872 instance.set_vbmeta_vendor_dlkm_image(
873 vbmeta_vendor_dlkm_image[instance_index]);
874 }
875 if (instance_index >= vbmeta_system_dlkm_image.size()) {
876 instance.set_vbmeta_system_dlkm_image(vbmeta_system_dlkm_image[0]);
877 } else {
878 instance.set_vbmeta_system_dlkm_image(
879 vbmeta_system_dlkm_image[instance_index]);
880 }
881 if (instance_index >= vvmtruststore_path.size()) {
882 instance.set_vvmtruststore_path(vvmtruststore_path[0]);
883 } else {
884 instance.set_vvmtruststore_path(vvmtruststore_path[instance_index]);
885 }
886 if (instance_index >= super_image.size()) {
887 cur_super_image = super_image[0];
888 } else {
889 cur_super_image = super_image[instance_index];
890 }
891 instance.set_super_image(cur_super_image);
892 if (instance_index >= data_image.size()) {
893 instance.set_data_image(data_image[0]);
894 } else {
895 instance.set_data_image(data_image[instance_index]);
896 }
897 if (instance_index >= android_efi_loader.size()) {
898 instance.set_android_efi_loader(android_efi_loader[0]);
899 } else {
900 instance.set_android_efi_loader(android_efi_loader[instance_index]);
901 }
902 if (instance_index >= chromeos_disk.size()) {
903 instance.set_chromeos_disk(chromeos_disk[0]);
904 } else {
905 instance.set_chromeos_disk(chromeos_disk[instance_index]);
906 }
907 if (instance_index >= chromeos_kernel_path.size()) {
908 instance.set_chromeos_kernel_path(chromeos_kernel_path[0]);
909 } else {
910 instance.set_chromeos_kernel_path(chromeos_kernel_path[instance_index]);
911 }
912 if (instance_index >= chromeos_root_image.size()) {
913 instance.set_chromeos_root_image(chromeos_root_image[0]);
914 } else {
915 instance.set_chromeos_root_image(chromeos_root_image[instance_index]);
916 }
917 if (instance_index >= linux_kernel_path.size()) {
918 instance.set_linux_kernel_path(linux_kernel_path[0]);
919 } else {
920 instance.set_linux_kernel_path(linux_kernel_path[instance_index]);
921 }
922 if (instance_index >= linux_initramfs_path.size()) {
923 instance.set_linux_initramfs_path(linux_initramfs_path[0]);
924 } else {
925 instance.set_linux_initramfs_path(linux_initramfs_path[instance_index]);
926 }
927 if (instance_index >= linux_root_image.size()) {
928 instance.set_linux_root_image(linux_root_image[0]);
929 } else {
930 instance.set_linux_root_image(linux_root_image[instance_index]);
931 }
932 if (instance_index >= fuchsia_zedboot_path.size()) {
933 instance.set_fuchsia_zedboot_path(fuchsia_zedboot_path[0]);
934 } else {
935 instance.set_fuchsia_zedboot_path(fuchsia_zedboot_path[instance_index]);
936 }
937 if (instance_index >= fuchsia_multiboot_bin_path.size()) {
938 instance.set_fuchsia_multiboot_bin_path(fuchsia_multiboot_bin_path[0]);
939 } else {
940 instance.set_fuchsia_multiboot_bin_path(fuchsia_multiboot_bin_path[instance_index]);
941 }
942 if (instance_index >= fuchsia_root_image.size()) {
943 instance.set_fuchsia_root_image(fuchsia_root_image[0]);
944 } else {
945 instance.set_fuchsia_root_image(fuchsia_root_image[instance_index]);
946 }
947 if (instance_index >= custom_partition_path.size()) {
948 instance.set_custom_partition_path(custom_partition_path[0]);
949 } else {
950 instance.set_custom_partition_path(custom_partition_path[instance_index]);
951 }
952 if (instance_index >= hibernation_image.size()) {
953 instance.set_hibernation_partition_image(hibernation_image[0]);
954 } else {
955 instance.set_hibernation_partition_image(
956 hibernation_image[instance_index]);
957 }
958 if (instance_index >= bootloader.size()) {
959 instance.set_bootloader(bootloader[0]);
960 } else {
961 instance.set_bootloader(bootloader[instance_index]);
962 }
963 if (instance_index >= kernel_path.size()) {
964 cur_kernel_path = kernel_path[0];
965 } else {
966 cur_kernel_path = kernel_path[instance_index];
967 }
968 instance.set_kernel_path(cur_kernel_path);
969 if (instance_index >= initramfs_path.size()) {
970 cur_initramfs_path = initramfs_path[0];
971 } else {
972 cur_initramfs_path = initramfs_path[instance_index];
973 }
974 instance.set_initramfs_path(cur_initramfs_path);
975
976 using android::base::ParseInt;
977 if (instance_index >= blank_metadata_image_mb.size()) {
978 CF_EXPECTF(ParseInt(blank_metadata_image_mb[0], &value), "'{}'",
979 blank_metadata_image_mb[0]);
980 } else {
981 CF_EXPECTF(ParseInt(blank_metadata_image_mb[instance_index], &value),
982 "'{}'", blank_metadata_image_mb[value]);
983 }
984 instance.set_blank_metadata_image_mb(value);
985
986 if (instance_index >= blank_sdcard_image_mb.size()) {
987 CF_EXPECTF(ParseInt(blank_sdcard_image_mb[0], &value), "'{}'",
988 blank_sdcard_image_mb[0]);
989 } else {
990 CF_EXPECTF(ParseInt(blank_sdcard_image_mb[instance_index], &value),
991 "'{}'", blank_sdcard_image_mb[instance_index]);
992 }
993 instance.set_blank_sdcard_image_mb(value);
994
995 // Repacking a boot.img changes boot_image and vendor_boot_image paths
996 const CuttlefishConfig& const_config = const_cast<const CuttlefishConfig&>(config);
997 const CuttlefishConfig::InstanceSpecific const_instance = const_config.ForInstance(num);
998 if (cur_kernel_path.size() && config.vm_manager() != VmmMode::kGem5) {
999 const std::string new_boot_image_path =
1000 const_instance.PerInstancePath("boot_repacked.img");
1001 // change the new flag value to corresponding instance
1002 instance.set_new_boot_image(new_boot_image_path.c_str());
1003 }
1004
1005 instance.set_new_data_image(const_instance.PerInstancePath("userdata.img"));
1006 if (instance_index >= data_image.size()) {
1007 instance.set_data_image(data_image[0]);
1008 } else {
1009 instance.set_data_image(data_image[instance_index]);
1010 }
1011
1012 if (cur_kernel_path.size() || cur_initramfs_path.size()) {
1013 const std::string new_vendor_boot_image_path =
1014 const_instance.PerInstancePath("vendor_boot_repacked.img");
1015 // Repack the vendor boot images if kernels and/or ramdisks are passed in.
1016 if (cur_initramfs_path.size()) {
1017 // change the new flag value to corresponding instance
1018 instance.set_new_vendor_boot_image(new_vendor_boot_image_path.c_str());
1019 }
1020 }
1021
1022 if (instance_index >= default_target_zip_vec.size()) {
1023 instance.set_default_target_zip(default_target_zip_vec[0]);
1024 } else {
1025 instance.set_default_target_zip(default_target_zip_vec[instance_index]);
1026 }
1027 if (instance_index >= system_target_zip_vec.size()) {
1028 instance.set_system_target_zip(system_target_zip_vec[0]);
1029 } else {
1030 instance.set_system_target_zip(system_target_zip_vec[instance_index]);
1031 }
1032
1033 // We will need to rebuild vendor_dlkm if custom ramdisk is specified, as a
1034 // result super image would need to be rebuilt as well.
1035 if (CF_EXPECT(SuperImageNeedsRebuilding(fetcher_config,
1036 const_instance.default_target_zip(),
1037 const_instance.system_target_zip())) ||
1038 cur_initramfs_path.size()) {
1039 const std::string new_super_image_path =
1040 const_instance.PerInstancePath("super.img");
1041 instance.set_new_super_image(new_super_image_path);
1042 const std::string new_vbmeta_image_path =
1043 const_instance.PerInstancePath("os_vbmeta.img");
1044 instance.set_new_vbmeta_image(new_vbmeta_image_path);
1045 }
1046
1047 instance.set_new_vbmeta_vendor_dlkm_image(
1048 const_instance.PerInstancePath("vbmeta_vendor_dlkm_repacked.img"));
1049 instance.set_new_vbmeta_system_dlkm_image(
1050 const_instance.PerInstancePath("vbmeta_system_dlkm_repacked.img"));
1051
1052 instance_index++;
1053 }
1054 return {};
1055 }
1056
CreateDynamicDiskFiles(const FetcherConfig & fetcher_config,const CuttlefishConfig & config)1057 Result<void> CreateDynamicDiskFiles(const FetcherConfig& fetcher_config,
1058 const CuttlefishConfig& config) {
1059 for (const auto& instance : config.Instances()) {
1060 // TODO(schuffelen): Unify this with the other injector created in
1061 // assemble_cvd.cpp
1062 fruit::Injector<> injector(DiskChangesComponent, &fetcher_config, &config,
1063 &instance);
1064 for (auto& late_injected : injector.getMultibindings<LateInjected>()) {
1065 CF_EXPECT(late_injected->LateInject(injector));
1066 }
1067
1068 const auto& features = injector.getMultibindings<SetupFeature>();
1069 CF_EXPECT(SetupFeature::RunSetup(features));
1070 fruit::Injector<> instance_injector(DiskChangesPerInstanceComponent,
1071 &fetcher_config, &config, &instance);
1072 for (auto& late_injected :
1073 instance_injector.getMultibindings<LateInjected>()) {
1074 CF_EXPECT(late_injected->LateInject(instance_injector));
1075 }
1076
1077 const auto& instance_features =
1078 instance_injector.getMultibindings<SetupFeature>();
1079 CF_EXPECT(SetupFeature::RunSetup(instance_features),
1080 "instance = \"" << instance.instance_name() << "\"");
1081
1082 // Check if filling in the sparse image would run out of disk space.
1083 auto existing_sizes = SparseFileSizes(instance.data_image());
1084 CF_EXPECT(existing_sizes.sparse_size > 0 || existing_sizes.disk_size > 0,
1085 "Unable to determine size of \"" << instance.data_image()
1086 << "\". Does this file exist?");
1087 auto available_space = AvailableSpaceAtPath(instance.data_image());
1088 if (available_space <
1089 existing_sizes.sparse_size - existing_sizes.disk_size) {
1090 // TODO(schuffelen): Duplicate this check in run_cvd when it can run on a
1091 // separate machine
1092 return CF_ERR("Not enough space remaining in fs containing \""
1093 << instance.data_image() << "\", wanted "
1094 << (existing_sizes.sparse_size - existing_sizes.disk_size)
1095 << ", got " << available_space);
1096 } else {
1097 LOG(DEBUG) << "Available space: " << available_space;
1098 LOG(DEBUG) << "Sparse size of \"" << instance.data_image()
1099 << "\": " << existing_sizes.sparse_size;
1100 LOG(DEBUG) << "Disk size of \"" << instance.data_image()
1101 << "\": " << existing_sizes.disk_size;
1102 }
1103
1104 auto os_disk_builder = OsCompositeDiskBuilder(config, instance);
1105 const auto os_built_composite = CF_EXPECT(os_disk_builder.BuildCompositeDiskIfNecessary());
1106
1107 auto ap_disk_builder = ApCompositeDiskBuilder(config, instance);
1108 if (instance.ap_boot_flow() != APBootFlow::None) {
1109 CF_EXPECT(ap_disk_builder.BuildCompositeDiskIfNecessary());
1110 }
1111
1112 if (os_built_composite) {
1113 if (FileExists(instance.access_kregistry_path())) {
1114 CF_EXPECT(CreateBlankImage(instance.access_kregistry_path(), 2 /* mb */,
1115 "none"),
1116 "Failed for \"" << instance.access_kregistry_path() << "\"");
1117 }
1118 if (FileExists(instance.hwcomposer_pmem_path())) {
1119 CF_EXPECT(CreateBlankImage(instance.hwcomposer_pmem_path(), 2 /* mb */,
1120 "none"),
1121 "Failed for \"" << instance.hwcomposer_pmem_path() << "\"");
1122 }
1123 if (FileExists(instance.pstore_path())) {
1124 CF_EXPECT(CreateBlankImage(instance.pstore_path(), 2 /* mb */, "none"),
1125 "Failed for\"" << instance.pstore_path() << "\"");
1126 }
1127 }
1128
1129 if (!instance.protected_vm()) {
1130 os_disk_builder.OverlayPath(instance.PerInstancePath("overlay.img"));
1131 CF_EXPECT(os_disk_builder.BuildOverlayIfNecessary());
1132 if (instance.ap_boot_flow() != APBootFlow::None) {
1133 ap_disk_builder.OverlayPath(instance.PerInstancePath("ap_overlay.img"));
1134 CF_EXPECT(ap_disk_builder.BuildOverlayIfNecessary());
1135 }
1136 }
1137 }
1138
1139 for (auto instance : config.Instances()) {
1140 // Check that the files exist
1141 for (const auto& file : instance.virtual_disk_paths()) {
1142 if (!file.empty()) {
1143 CF_EXPECT(FileHasContent(file), "File not found: \"" << file << "\"");
1144 }
1145 }
1146 // Gem5 Simulate per-instance what the bootloader would usually do
1147 // Since on other devices this runs every time, just do it here every time
1148 if (config.vm_manager() == VmmMode::kGem5) {
1149 RepackGem5BootImage(instance.PerInstancePath("initrd.img"),
1150 instance.persistent_bootconfig_path(),
1151 config.assembly_dir(), instance.initramfs_path());
1152 }
1153 }
1154
1155 return {};
1156 }
1157
1158 } // namespace cuttlefish
1159