Skip to content

Commit ad992e8

Browse files
committed
Expose image type detection from image_aggregator
Instances of the raw image type can only be created from the image detection logic, since a raw image is defind by not having the magic prefix of any special image format. Bug: b/435218921
1 parent 5a11f52 commit ad992e8

File tree

6 files changed

+232
-44
lines changed

6 files changed

+232
-44
lines changed

base/cvd/cuttlefish/host/libs/image_aggregator/BUILD.bazel

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ cf_cc_library(
2626
],
2727
)
2828

29+
cf_cc_library(
30+
name = "image_from_file",
31+
srcs = ["image_from_file.cc"],
32+
hdrs = ["image_from_file.h"],
33+
deps = [
34+
"//cuttlefish/common/libs/utils:files",
35+
"//cuttlefish/common/libs/utils:result",
36+
"//cuttlefish/host/libs/image_aggregator:composite_disk",
37+
"//cuttlefish/host/libs/image_aggregator:disk_image",
38+
"//cuttlefish/host/libs/image_aggregator:qcow2",
39+
"//cuttlefish/host/libs/image_aggregator:raw",
40+
"//cuttlefish/host/libs/image_aggregator:sparse_image",
41+
"//libbase",
42+
],
43+
)
44+
2945
cf_cc_library(
3046
name = "disk_image",
3147
hdrs = ["disk_image.h"],
@@ -50,7 +66,7 @@ cf_cc_library(
5066
"//cuttlefish/host/libs/config:mbr",
5167
"//cuttlefish/host/libs/image_aggregator:cdisk_spec_cc_proto",
5268
"//cuttlefish/host/libs/image_aggregator:composite_disk",
53-
"//cuttlefish/host/libs/image_aggregator:qcow2",
69+
"//cuttlefish/host/libs/image_aggregator:image_from_file",
5470
"//cuttlefish/host/libs/image_aggregator:sparse_image",
5571
"//libbase",
5672
"//libsparse",
@@ -59,6 +75,17 @@ cf_cc_library(
5975
],
6076
)
6177

78+
cf_cc_library(
79+
name = "raw",
80+
srcs = ["raw.cc"],
81+
hdrs = ["raw.h"],
82+
deps = [
83+
"//cuttlefish/common/libs/utils:files",
84+
"//cuttlefish/common/libs/utils:result",
85+
"//cuttlefish/host/libs/image_aggregator:disk_image",
86+
],
87+
)
88+
6289
cf_cc_library(
6390
name = "sparse_image",
6491
srcs = ["sparse_image.cc"],

base/cvd/cuttlefish/host/libs/image_aggregator/image_aggregator.cc

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,13 @@
4545
#include "cuttlefish/host/libs/config/mbr.h"
4646
#include "cuttlefish/host/libs/image_aggregator/cdisk_spec.pb.h"
4747
#include "cuttlefish/host/libs/image_aggregator/composite_disk.h"
48-
#include "cuttlefish/host/libs/image_aggregator/qcow2.h"
48+
#include "cuttlefish/host/libs/image_aggregator/image_from_file.h"
4949
#include "cuttlefish/host/libs/image_aggregator/sparse_image.h"
5050

5151
namespace cuttlefish {
5252
namespace {
5353

5454
constexpr int GPT_NUM_PARTITIONS = 128;
55-
static const std::string CDISK_MAGIC = "composite_disk\x1d";
56-
static const std::string QCOW2_MAGIC = "QFI\xfb";
5755

5856
/**
5957
* Creates a "Protective" MBR Partition Table header. The GUID
@@ -143,45 +141,9 @@ struct PartitionInfo {
143141
* images.
144142
*/
145143
Result<uint64_t> ExpandedStorageSize(const std::string& file_path) {
146-
android::base::unique_fd fd(open(file_path.c_str(), O_RDONLY));
147-
CF_EXPECTF(fd.get() >= 0, "Could not open '{}': {}", file_path,
148-
strerror(errno));
149-
150-
std::uint64_t file_size = FileSize(file_path);
151-
152-
// Try to read the disk in a nicely-aligned block size unless the whole file
153-
// is smaller.
154-
constexpr uint64_t MAGIC_BLOCK_SIZE = 4096;
155-
std::string magic(std::min(file_size, MAGIC_BLOCK_SIZE), '\0');
156-
157-
CF_EXPECTF(android::base::ReadFully(fd, magic.data(), magic.size()),
158-
"Failed to read '{}': {}'", file_path, strerror(errno));
159-
160-
CF_EXPECTF(lseek(fd, 0, SEEK_SET) != -1, "Failed to lseek('{}'): {}",
161-
file_path, strerror(errno));
162-
163-
// Composite disk image
164-
if (android::base::StartsWith(magic, CDISK_MAGIC)) {
165-
CompositeDiskImage image =
166-
CF_EXPECT(CompositeDiskImage::OpenExisting(file_path));
167-
return CF_EXPECT(image.VirtualSizeBytes());
168-
}
169-
170-
// Qcow2 image
171-
if (android::base::StartsWith(magic, Qcow2Image::MagicString())) {
172-
Qcow2Image image = CF_EXPECT(Qcow2Image::OpenExisting(file_path));
173-
return CF_EXPECT(image.VirtualSizeBytes());
174-
}
175-
176-
// Android-Sparse
177-
if (android::base::StartsWith(magic, AndroidSparseImage::MagicString())) {
178-
AndroidSparseImage image =
179-
CF_EXPECT(AndroidSparseImage::OpenExisting(file_path));
180-
return CF_EXPECT(image.VirtualSizeBytes());
181-
}
182-
183-
// raw image file
184-
return file_size;
144+
std::unique_ptr<DiskImage> disk = CF_EXPECT(ImageFromFile(file_path));
145+
CF_EXPECT(disk.get());
146+
return CF_EXPECT(disk->VirtualSizeBytes());
185147
}
186148

187149
/*
@@ -494,7 +456,7 @@ Result<void> CreateCompositeDisk(std::vector<ImagePartition> partitions,
494456
CF_EXPECT(builder.MakeCompositeDiskSpec(header_file, footer_file));
495457
std::ofstream composite(output_composite_path.c_str(),
496458
std::ios::binary | std::ios::trunc);
497-
composite << CDISK_MAGIC;
459+
composite << CompositeDiskImage::MagicString();
498460
composite_proto.SerializeToOstream(&composite);
499461
composite.flush();
500462

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
#include "cuttlefish/host/libs/image_aggregator/image_from_file.h"
17+
18+
#include <memory>
19+
#include <string>
20+
21+
#include <android-base/file.h>
22+
#include <android-base/strings.h>
23+
24+
#include "cuttlefish/common/libs/utils/files.h"
25+
#include "cuttlefish/common/libs/utils/result.h"
26+
#include "cuttlefish/host/libs/image_aggregator/composite_disk.h"
27+
#include "cuttlefish/host/libs/image_aggregator/disk_image.h"
28+
#include "cuttlefish/host/libs/image_aggregator/qcow2.h"
29+
#include "cuttlefish/host/libs/image_aggregator/raw.h"
30+
#include "cuttlefish/host/libs/image_aggregator/sparse_image.h"
31+
32+
namespace cuttlefish {
33+
34+
Result<std::unique_ptr<DiskImage>> ImageFromFile(const std::string& file_path) {
35+
android::base::unique_fd fd(open(file_path.c_str(), O_RDONLY));
36+
CF_EXPECTF(fd.get() >= 0, "Could not open '{}': {}", file_path,
37+
strerror(errno));
38+
39+
std::uint64_t file_size = FileSize(file_path);
40+
41+
// Try to read the disk in a nicely-aligned block size unless the whole file
42+
// is smaller.
43+
constexpr uint64_t MAGIC_BLOCK_SIZE = 4096;
44+
std::string magic(std::min(file_size, MAGIC_BLOCK_SIZE), '\0');
45+
46+
CF_EXPECTF(android::base::ReadFully(fd, magic.data(), magic.size()),
47+
"Failed to read '{}': {}'", file_path, strerror(errno));
48+
49+
CF_EXPECTF(lseek(fd, 0, SEEK_SET) != -1, "Failed to lseek('{}'): {}",
50+
file_path, strerror(errno));
51+
52+
// Composite disk image
53+
if (android::base::StartsWith(magic, CompositeDiskImage::MagicString())) {
54+
CompositeDiskImage image =
55+
CF_EXPECT(CompositeDiskImage::OpenExisting(file_path));
56+
return std::make_unique<CompositeDiskImage>(std::move(image));
57+
}
58+
59+
// Qcow2 image
60+
if (android::base::StartsWith(magic, Qcow2Image::MagicString())) {
61+
Qcow2Image image = CF_EXPECT(Qcow2Image::OpenExisting(file_path));
62+
return std::make_unique<Qcow2Image>(std::move(image));
63+
}
64+
65+
// Android-Sparse
66+
if (android::base::StartsWith(magic, AndroidSparseImage::MagicString())) {
67+
AndroidSparseImage image =
68+
CF_EXPECT(AndroidSparseImage::OpenExisting(file_path));
69+
return std::make_unique<AndroidSparseImage>(std::move(image));
70+
}
71+
72+
// raw image file
73+
RawImage raw = CF_EXPECT(RawImage::OpenExisting(file_path));
74+
return std::make_unique<RawImage>(std::move(raw));
75+
}
76+
77+
} // namespace cuttlefish
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
#pragma once
17+
18+
#include <memory>
19+
#include <string>
20+
21+
#include "cuttlefish/common/libs/utils/result.h"
22+
#include "cuttlefish/host/libs/image_aggregator/disk_image.h"
23+
24+
namespace cuttlefish {
25+
26+
Result<std::unique_ptr<DiskImage>> ImageFromFile(const std::string& path);
27+
28+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 "cuttlefish/host/libs/image_aggregator/raw.h"
18+
19+
#include <string>
20+
#include <utility>
21+
22+
#include "cuttlefish/common/libs/utils/files.h"
23+
24+
namespace cuttlefish {
25+
26+
Result<RawImage> RawImage::OpenExisting(const std::string& path) {
27+
off_t size = FileSize(path);
28+
CF_EXPECT_GE(size, 0, strerror(errno));
29+
30+
return RawImage(size);
31+
}
32+
33+
RawImage::RawImage(RawImage&& other) { size_ = std::move(other.size_); }
34+
RawImage::~RawImage() = default;
35+
RawImage& RawImage::operator=(RawImage&& other) {
36+
size_ = std::move(other.size_);
37+
return *this;
38+
}
39+
40+
Result<uint64_t> RawImage::VirtualSizeBytes() const { return size_; }
41+
42+
RawImage::RawImage(uint64_t size) : size_(size) {}
43+
44+
} // namespace cuttlefish
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
#pragma once
17+
18+
#include <stdint.h>
19+
20+
#include <memory>
21+
#include <string>
22+
23+
#include "cuttlefish/common/libs/utils/result.h"
24+
#include "cuttlefish/host/libs/image_aggregator/disk_image.h"
25+
26+
namespace cuttlefish {
27+
28+
Result<std::unique_ptr<DiskImage>> ImageFromFile(const std::string& path);
29+
30+
/** A file where the raw bytes are presented as a disk to a virtual machine. */
31+
class RawImage : public DiskImage {
32+
public:
33+
RawImage(RawImage&&);
34+
~RawImage() override;
35+
RawImage& operator=(RawImage&&);
36+
37+
Result<uint64_t> VirtualSizeBytes() const override;
38+
39+
private:
40+
static Result<RawImage> OpenExisting(const std::string& path);
41+
42+
RawImage(uint64_t size);
43+
44+
friend Result<std::unique_ptr<DiskImage>> ImageFromFile(
45+
const std::string& path);
46+
47+
uint64_t size_;
48+
};
49+
50+
} // namespace cuttlefish

0 commit comments

Comments
 (0)