Skip to content

Commit 7c8c319

Browse files
committed
Support extracting logical partition information from a super image
Bug: b/472421213
1 parent c11d35d commit 7c8c319

File tree

3 files changed

+170
-0
lines changed

3 files changed

+170
-0
lines changed

base/cvd/cuttlefish/host/commands/assemble_cvd/android_build/BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,19 @@ cf_cc_library(
129129
],
130130
)
131131

132+
cf_cc_library(
133+
name = "super_image",
134+
srcs = ["super_image.cc"],
135+
hdrs = ["super_image.h"],
136+
deps = [
137+
"//cuttlefish/host/commands/assemble_cvd/android_build",
138+
"//cuttlefish/result",
139+
"@abseil-cpp//absl/strings",
140+
"@android_system_core//:liblp",
141+
"@fmt",
142+
],
143+
)
144+
132145
cf_cc_library(
133146
name = "target_files",
134147
srcs = ["target_files.cc"],
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
//
2+
// Copyright (C) 2025 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+
#include "cuttlefish/host/commands/assemble_cvd/android_build/super_image.h"
17+
18+
#include <functional>
19+
#include <memory>
20+
#include <ostream>
21+
#include <set>
22+
#include <string>
23+
#include <string_view>
24+
#include <utility>
25+
#include <vector>
26+
27+
#include "absl/strings/match.h"
28+
#include "liblp/liblp.h"
29+
#include "liblp/metadata_format.h"
30+
31+
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
32+
#include "cuttlefish/result/result.h"
33+
34+
namespace cuttlefish {
35+
namespace {
36+
37+
class SuperImageAsBuildImpl : public AndroidBuild {
38+
public:
39+
SuperImageAsBuildImpl(
40+
std::unique_ptr<android::fs_mgr::LpMetadata> super_metadata)
41+
: super_metadata_(std::move(super_metadata)) {}
42+
43+
Result<std::set<std::string, std::less<void>>> LogicalPartitions() override {
44+
std::set<std::string, std::less<void>> ret;
45+
for (const LpMetadataPartition& partition : super_metadata_->partitions) {
46+
ret.emplace(android::fs_mgr::GetPartitionName(partition));
47+
}
48+
return ret;
49+
}
50+
51+
Result<std::set<std::string, std::less<void>>> PartitionsInGroup(std::string_view match) {
52+
std::set<std::string, std::less<void>> ret;
53+
for (const LpMetadataPartition& partition : super_metadata_->partitions) {
54+
CF_EXPECT_LE(partition.group_index, super_metadata_->groups.size());
55+
std::string group_name = android::fs_mgr::GetPartitionGroupName(
56+
super_metadata_->groups[partition.group_index]);
57+
58+
if (absl::StrContains(group_name, match)) {
59+
ret.emplace(android::fs_mgr::GetPartitionName(partition));
60+
}
61+
}
62+
return ret;
63+
}
64+
65+
Result<std::set<std::string, std::less<void>>> AbPartitions() override {
66+
std::set<std::string, std::less<void>> ret;
67+
for (const LpMetadataPartition& partition : super_metadata_->partitions) {
68+
if (partition.attributes & LP_PARTITION_ATTR_SLOT_SUFFIXED) {
69+
ret.emplace(android::fs_mgr::GetPartitionName(partition));
70+
}
71+
}
72+
return ret;
73+
}
74+
75+
Result<std::set<std::string, std::less<void>>> SystemPartitions() override {
76+
return CF_EXPECT(PartitionsInGroup("system"));
77+
}
78+
79+
Result<std::set<std::string, std::less<void>>> VendorPartitions() override {
80+
return CF_EXPECT(PartitionsInGroup("vendor"));
81+
}
82+
private:
83+
std::ostream& Format(std::ostream& out) const override {
84+
return out << "MetadataFromSuperImage";
85+
}
86+
87+
std::unique_ptr<android::fs_mgr::LpMetadata> super_metadata_;
88+
};
89+
90+
Result<std::unique_ptr<android::fs_mgr::LpMetadata>> SuperImageFromAndroidBuild(
91+
AndroidBuild& build, std::string_view extract_dir) {
92+
static constexpr std::string_view kSuperEmpty = "super_empty";
93+
static constexpr std::string_view kSuper = "super";
94+
// Prefer an already extracted file, then prefer extracting super_empty since
95+
// it is smaller.
96+
Result<std::string_view> path;
97+
if (path = build.ImageFile(kSuperEmpty); path.ok()) {
98+
} else if (path = build.ImageFile(kSuper); path.ok()) {
99+
} else if (path = build.ImageFile(kSuperEmpty, extract_dir); path.ok()) {
100+
} else if (path = build.ImageFile(kSuper, extract_dir); path.ok()) {
101+
} else {
102+
return CF_ERR("No super.img or super_empty.img could be found");
103+
}
104+
std::unique_ptr<android::fs_mgr::LpMetadata> metadata =
105+
android::fs_mgr::ReadFromImageFile(std::string(*path));
106+
CF_EXPECTF(metadata.get(), "Failed to parse super image '{}'", *path);
107+
return metadata;
108+
}
109+
110+
} // namespace
111+
112+
Result<std::unique_ptr<AndroidBuild>> SuperImageAsBuild(
113+
AndroidBuild& build, std::string_view extract_dir) {
114+
std::unique_ptr<android::fs_mgr::LpMetadata> lp_metadata =
115+
CF_EXPECT(SuperImageFromAndroidBuild(build, extract_dir));
116+
117+
auto super_build =
118+
std::make_unique<SuperImageAsBuildImpl>(std::move(lp_metadata));
119+
120+
CF_EXPECT(super_build->SystemPartitions());
121+
CF_EXPECT(super_build->VendorPartitions());
122+
CF_EXPECT(super_build->LogicalPartitions());
123+
CF_EXPECT(super_build->AbPartitions());
124+
125+
return super_build;
126+
}
127+
128+
} // namespace cuttlefish
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// Copyright (C) 2025 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+
#pragma once
17+
18+
#include <memory>
19+
#include <string_view>
20+
21+
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
22+
#include "cuttlefish/result/result.h"
23+
24+
namespace cuttlefish {
25+
26+
Result<std::unique_ptr<AndroidBuild>> SuperImageAsBuild(
27+
AndroidBuild& build, std::string_view extract_dir);
28+
29+
} // namespace cuttlefish

0 commit comments

Comments
 (0)