1 /*
2 * Copyright (C) 2023 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/disk.h"
18
19 #include <vector>
20
21 #include <gflags/gflags.h>
22
23 #include "common/libs/utils/files.h"
24 #include "host/commands/assemble_cvd/disk_builder.h"
25 #include "host/libs/config/cuttlefish_config.h"
26 #include "host/libs/image_aggregator/image_aggregator.h"
27 #include "host/libs/vm_manager/qemu_manager.h"
28
29 DECLARE_bool(resume);
30
31 namespace cuttlefish {
32 namespace {
33
PersistentCompositeDiskConfig(const CuttlefishConfig::InstanceSpecific & instance)34 std::vector<ImagePartition> PersistentCompositeDiskConfig(
35 const CuttlefishConfig::InstanceSpecific& instance) {
36 std::vector<ImagePartition> partitions;
37
38 // Note that if the position of uboot_env changes, the environment for
39 // u-boot must be updated as well (see boot_config.cc and
40 // cuttlefish.fragment in external/u-boot).
41 partitions.push_back(ImagePartition{
42 .label = "uboot_env",
43 .image_file_path = AbsolutePath(instance.uboot_env_image_path()),
44 });
45 partitions.push_back(ImagePartition{
46 .label = "vbmeta",
47 .image_file_path = AbsolutePath(instance.vbmeta_path()),
48 });
49 if (!instance.protected_vm()) {
50 partitions.push_back(ImagePartition{
51 .label = "frp",
52 .image_file_path =
53 AbsolutePath(instance.factory_reset_protected_path()),
54 });
55 }
56 if (instance.bootconfig_supported()) {
57 partitions.push_back(ImagePartition{
58 .label = "bootconfig",
59 .image_file_path = AbsolutePath(instance.persistent_bootconfig_path()),
60 });
61 }
62 return partitions;
63 }
64
PersistentAPCompositeDiskConfig(const CuttlefishConfig::InstanceSpecific & instance)65 std::vector<ImagePartition> PersistentAPCompositeDiskConfig(
66 const CuttlefishConfig::InstanceSpecific& instance) {
67 std::vector<ImagePartition> partitions;
68
69 // Note that if the position of uboot_env changes, the environment for
70 // u-boot must be updated as well (see boot_config.cc and
71 // cuttlefish.fragment in external/u-boot).
72 partitions.push_back(ImagePartition{
73 .label = "uboot_env",
74 .image_file_path = AbsolutePath(instance.ap_uboot_env_image_path()),
75 });
76 partitions.push_back(ImagePartition{
77 .label = "vbmeta",
78 .image_file_path = AbsolutePath(instance.ap_vbmeta_path()),
79 });
80
81 return partitions;
82 }
83
84 } // namespace
85
IsVmManagerQemu(const CuttlefishConfig & config)86 bool IsVmManagerQemu(const CuttlefishConfig& config) {
87 return config.vm_manager() == VmmMode::kQemu;
88 }
InitializeInstanceCompositeDisk(const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance,AutoSetup<InitializeFactoryResetProtected>::Type &,AutoSetup<GeneratePersistentVbmeta>::Type &)89 Result<void> InitializeInstanceCompositeDisk(
90 const CuttlefishConfig& config,
91 const CuttlefishConfig::InstanceSpecific& instance,
92 AutoSetup<InitializeFactoryResetProtected>::Type& /* dependency */,
93 AutoSetup<GeneratePersistentVbmeta>::Type& /* dependency */) {
94 const auto ipath = [&instance](const std::string& path) -> std::string {
95 return instance.PerInstancePath(path.c_str());
96 };
97 auto persistent_disk_builder =
98 DiskBuilder()
99 .Partitions(PersistentCompositeDiskConfig(instance))
100 .VmManager(config.vm_manager())
101 .CrosvmPath(instance.crosvm_binary())
102 .ConfigPath(ipath("persistent_composite_disk_config.txt"))
103 .HeaderPath(ipath("persistent_composite_gpt_header.img"))
104 .FooterPath(ipath("persistent_composite_gpt_footer.img"))
105 .CompositeDiskPath(instance.persistent_composite_disk_path())
106 .ResumeIfPossible(FLAGS_resume);
107 CF_EXPECT(persistent_disk_builder.BuildCompositeDiskIfNecessary());
108 persistent_disk_builder.OverlayPath(
109 instance.PerInstancePath("persistent_composite_overlay.img"));
110 if (IsVmManagerQemu(config)) {
111 CF_EXPECT(persistent_disk_builder.BuildOverlayIfNecessary());
112 }
113
114 using APBootFlow = CuttlefishConfig::InstanceSpecific::APBootFlow;
115 if (instance.ap_boot_flow() == APBootFlow::Grub) {
116 auto persistent_ap_disk_builder =
117 DiskBuilder()
118 .Partitions(PersistentAPCompositeDiskConfig(instance))
119 .VmManager(config.vm_manager())
120 .CrosvmPath(instance.crosvm_binary())
121 .ConfigPath(ipath("ap_persistent_composite_disk_config.txt"))
122 .HeaderPath(ipath("ap_persistent_composite_gpt_header.img"))
123 .FooterPath(ipath("ap_persistent_composite_gpt_footer.img"))
124 .CompositeDiskPath(instance.persistent_ap_composite_disk_path())
125 .ResumeIfPossible(FLAGS_resume);
126 CF_EXPECT(persistent_ap_disk_builder.BuildCompositeDiskIfNecessary());
127 persistent_ap_disk_builder.OverlayPath(
128 instance.PerInstancePath("ap_persistent_composite_overlay.img"));
129 if (IsVmManagerQemu(config)) {
130 CF_EXPECT(persistent_ap_disk_builder.BuildOverlayIfNecessary());
131 }
132 }
133
134 return {};
135 }
136
137 } // namespace cuttlefish
138