| Index: utils.cc
|
| diff --git a/utils.cc b/utils.cc
|
| index 6006eb85e736f63933380e613f26ebad509b75a6..c8a4da64e29cf1d23037a4b9c7c329ccc593ef72 100644
|
| --- a/utils.cc
|
| +++ b/utils.cc
|
| @@ -18,6 +18,7 @@
|
|
|
| #include <algorithm>
|
|
|
| +#include <base/eintr_wrapper.h>
|
| #include <base/file_path.h>
|
| #include <base/file_util.h>
|
| #include <base/rand_util.h>
|
| @@ -421,6 +422,61 @@ bool UnmountFilesystem(const string& mountpoint) {
|
| return true;
|
| }
|
|
|
| +bool GetFilesystemSize(const std::string& device,
|
| + int* out_block_count,
|
| + int* out_block_size) {
|
| + int fd = HANDLE_EINTR(open(device.c_str(), O_RDONLY));
|
| + TEST_AND_RETURN_FALSE(fd >= 0);
|
| + ScopedFdCloser fd_closer(&fd);
|
| + return GetFilesystemSizeFromFD(fd, out_block_count, out_block_size);
|
| +}
|
| +
|
| +bool GetFilesystemSizeFromFD(int fd,
|
| + int* out_block_count,
|
| + int* out_block_size) {
|
| + TEST_AND_RETURN_FALSE(fd >= 0);
|
| +
|
| + // Determine the ext3 filesystem size by directly reading the block count and
|
| + // block size information from the superblock. See include/linux/ext3_fs.h for
|
| + // more details on the structure.
|
| + ssize_t kBufferSize = 16 * sizeof(uint32_t);
|
| + char buffer[kBufferSize];
|
| + const int kSuperblockOffset = 1024;
|
| + if (HANDLE_EINTR(pread(fd, buffer, kBufferSize, kSuperblockOffset)) !=
|
| + kBufferSize) {
|
| + PLOG(ERROR) << "Unable to determine file system size:";
|
| + return false;
|
| + }
|
| + uint32_t block_count; // ext3_fs.h: ext3_super_block.s_blocks_count
|
| + uint32_t log_block_size; // ext3_fs.h: ext3_super_block.s_log_block_size
|
| + uint16_t magic; // ext3_fs.h: ext3_super_block.s_magic
|
| + memcpy(&block_count, &buffer[1 * sizeof(int32_t)], sizeof(block_count));
|
| + memcpy(&log_block_size, &buffer[6 * sizeof(int32_t)], sizeof(log_block_size));
|
| + memcpy(&magic, &buffer[14 * sizeof(int32_t)], sizeof(magic));
|
| + block_count = le32toh(block_count);
|
| + const int kExt3MinBlockLogSize = 10; // ext3_fs.h: EXT3_MIN_BLOCK_LOG_SIZE
|
| + log_block_size = le32toh(log_block_size) + kExt3MinBlockLogSize;
|
| + magic = le16toh(magic);
|
| +
|
| + // Sanity check the parameters.
|
| + const uint16_t kExt3SuperMagic = 0xef53; // ext3_fs.h: EXT3_SUPER_MAGIC
|
| + TEST_AND_RETURN_FALSE(magic == kExt3SuperMagic);
|
| + const int kExt3MinBlockSize = 1024; // ext3_fs.h: EXT3_MIN_BLOCK_SIZE
|
| + const int kExt3MaxBlockSize = 4096; // ext3_fs.h: EXT3_MAX_BLOCK_SIZE
|
| + int block_size = 1 << log_block_size;
|
| + TEST_AND_RETURN_FALSE(block_size >= kExt3MinBlockSize &&
|
| + block_size <= kExt3MaxBlockSize);
|
| + TEST_AND_RETURN_FALSE(block_count > 0);
|
| +
|
| + if (out_block_count) {
|
| + *out_block_count = block_count;
|
| + }
|
| + if (out_block_size) {
|
| + *out_block_size = block_size;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| bool GetBootloader(BootLoader* out_bootloader) {
|
| // For now, hardcode to syslinux.
|
| *out_bootloader = BootLoader_SYSLINUX;
|
|
|