liblp: Add a helper to differentiate empty from non-empty images.
Also, finally explain the difference between these somewhere. Bug: 140204341 Test: lpdump Change-Id: I128780b01a28e893afac65f3aa4f4a8d36032d63
This commit is contained in:
parent
50e408db2d
commit
922cfefbb9
4 changed files with 49 additions and 5 deletions
|
@ -17,6 +17,7 @@
|
|||
#include "images.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
|
||||
|
@ -27,12 +28,45 @@
|
|||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
using android::base::borrowed_fd;
|
||||
using android::base::unique_fd;
|
||||
|
||||
#if defined(_WIN32)
|
||||
static const int O_NOFOLLOW = 0;
|
||||
#endif
|
||||
|
||||
static bool IsEmptySuperImage(borrowed_fd fd) {
|
||||
struct stat s;
|
||||
if (fstat(fd.get(), &s) < 0) {
|
||||
PERROR << __PRETTY_FUNCTION__ << " fstat failed";
|
||||
return false;
|
||||
}
|
||||
if (s.st_size < LP_METADATA_GEOMETRY_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rewind back to the start, read the geometry struct.
|
||||
LpMetadataGeometry geometry = {};
|
||||
if (SeekFile64(fd.get(), 0, SEEK_SET) < 0) {
|
||||
PERROR << __PRETTY_FUNCTION__ << " lseek failed";
|
||||
return false;
|
||||
}
|
||||
if (!android::base::ReadFully(fd, &geometry, sizeof(geometry))) {
|
||||
PERROR << __PRETTY_FUNCTION__ << " read failed";
|
||||
return false;
|
||||
}
|
||||
return geometry.magic == LP_METADATA_GEOMETRY_MAGIC;
|
||||
}
|
||||
|
||||
bool IsEmptySuperImage(const std::string& file) {
|
||||
unique_fd fd = GetControlFileOrOpen(file, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
PERROR << __PRETTY_FUNCTION__ << " open failed";
|
||||
return false;
|
||||
}
|
||||
return IsEmptySuperImage(fd);
|
||||
}
|
||||
|
||||
std::unique_ptr<LpMetadata> ReadFromImageFile(int fd) {
|
||||
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(LP_METADATA_GEOMETRY_SIZE);
|
||||
if (SeekFile64(fd, 0, SEEK_SET) < 0) {
|
||||
|
|
|
@ -70,8 +70,15 @@ bool UpdatePartitionTable(const std::string& super_partition, const LpMetadata&
|
|||
uint32_t slot_number);
|
||||
std::unique_ptr<LpMetadata> ReadMetadata(const std::string& super_partition, uint32_t slot_number);
|
||||
|
||||
// Returns whether an image is an "empty" image or not. An empty image contains
|
||||
// only metadata. Unlike a flashed block device, there are no reserved bytes or
|
||||
// backup sections, and only one slot is stored (even if multiple slots are
|
||||
// supported). It is a format specifically for storing only metadata.
|
||||
bool IsEmptySuperImage(const std::string& file);
|
||||
|
||||
// Read/Write logical partition metadata to an image file, for diagnostics or
|
||||
// flashing.
|
||||
// flashing. If no partition images are specified, the file will be in the
|
||||
// empty format.
|
||||
bool WriteToImageFile(const std::string& file, const LpMetadata& metadata, uint32_t block_size,
|
||||
const std::map<std::string, std::string>& images, bool sparsify);
|
||||
bool WriteToImageFile(const std::string& file, const LpMetadata& metadata);
|
||||
|
|
|
@ -205,9 +205,9 @@ bool SetBlockReadonly(int fd, bool readonly) {
|
|||
#endif
|
||||
}
|
||||
|
||||
base::unique_fd GetControlFileOrOpen(const char* path, int flags) {
|
||||
base::unique_fd GetControlFileOrOpen(std::string_view path, int flags) {
|
||||
#if defined(__ANDROID__)
|
||||
int fd = android_get_control_file(path);
|
||||
int fd = android_get_control_file(path.data());
|
||||
if (fd >= 0) {
|
||||
int newfd = TEMP_FAILURE_RETRY(dup(fd));
|
||||
if (newfd >= 0) {
|
||||
|
@ -216,7 +216,7 @@ base::unique_fd GetControlFileOrOpen(const char* path, int flags) {
|
|||
PERROR << "Cannot dup fd for already controlled file: " << path << ", reopening...";
|
||||
}
|
||||
#endif
|
||||
return base::unique_fd(open(path, flags));
|
||||
return base::unique_fd(open(path.data(), flags));
|
||||
}
|
||||
|
||||
bool UpdateMetadataForInPlaceSnapshot(LpMetadata* metadata, uint32_t source_slot_number,
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
|
||||
|
@ -94,7 +97,7 @@ bool UpdatePartitionName(LpMetadataPartition* partition, const std::string& name
|
|||
// Call BLKROSET ioctl on fd so that fd is readonly / read-writable.
|
||||
bool SetBlockReadonly(int fd, bool readonly);
|
||||
|
||||
::android::base::unique_fd GetControlFileOrOpen(const char* path, int flags);
|
||||
::android::base::unique_fd GetControlFileOrOpen(std::string_view path, int flags);
|
||||
|
||||
// For Virtual A/B updates, modify |metadata| so that it can be written to |target_slot_number|.
|
||||
bool UpdateMetadataForInPlaceSnapshot(LpMetadata* metadata, uint32_t source_slot_number,
|
||||
|
|
Loading…
Reference in a new issue