summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-06-15 13:55:24 -0700
committerGerrit <chrome-bot@google.com>2012-06-20 14:08:24 -0700
commit6a312261fd8b18ad8cdf9c5784631311c49c79c9 (patch)
tree97fe4d2b5d174b1f8fdbcd0d491830847ba793ed
parentd7f8f3574c31dbbd506619e8f68eecf5b39ebf54 (diff)
downloadvboot-factory-2475.B.tar.gz
mount-encrypted: use minimum mkfs size on migrationfactory-2475.B
When doing a migration, try to guess at a smaller minimum size for the initial filesystem so that systems with giant drives are not needlessly penalized. Start with an even smaller initial filesystem size (16M). Move debug time counters into the main .o file to avoid compiler insanity when turning debug on and off. BUG=chromium-os:22172 TEST=link build & boot, manual testing Change-Id: I47c3ffb6e4cd88c4f0ead6fa21724704c7ed1630 Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/25638 Reviewed-by: Elly Jones <ellyjones@chromium.org>
-rw-r--r--utility/mount-encrypted.c62
-rw-r--r--utility/mount-encrypted.h4
-rw-r--r--utility/mount-helpers.c2
3 files changed, 54 insertions, 14 deletions
diff --git a/utility/mount-encrypted.c b/utility/mount-encrypted.c
index d3f71748..6fd03c24 100644
--- a/utility/mount-encrypted.c
+++ b/utility/mount-encrypted.c
@@ -48,13 +48,14 @@ static const gchar * const kCryptDevName = "encstateful";
static const gchar * const kTpmDev = "/dev/tpm0";
static const gchar * const kNullDev = "/dev/null";
static const float kSizePercent = 0.3;
+static const float kMigrationSizeMultiplier = 1.1;
static const uint32_t kLockboxIndex = 0x20000004;
static const uint32_t kLockboxSizeV1 = 0x2c;
static const uint32_t kLockboxSizeV2 = 0x45;
static const uint32_t kLockboxSaltOffset = 0x5;
static const size_t kSectorSize = 512;
static const size_t kExt4BlockSize = 4096;
-static const size_t kExt4MinBytes = 64 * 1024 * 1024;
+static const size_t kExt4MinBytes = 16 * 1024 * 1024;
enum migration_method {
MIGRATE_TEST_ONLY,
@@ -87,6 +88,11 @@ static struct bind_mount {
{ },
};
+#if DEBUG_ENABLED
+struct timeval tick = { };
+struct timeval tick_start = { };
+#endif
+
static struct bind_mount *bind_mounts = NULL;
static gchar *rootdir = NULL;
static gchar *stateful_mount = NULL;
@@ -654,6 +660,7 @@ static int setup_encrypted(void)
size_t sectors;
struct bind_mount *bind;
int sparsefd;
+ struct statvfs stateful_statbuf;
size_t blocks_min, blocks_max;
/* Use the "system key" to decrypt the "encryption key" stored in
@@ -681,27 +688,26 @@ static int setup_encrypted(void)
}
if (rebuild) {
- struct statvfs buf;
- off_t size;
+ off_t fs_bytes_max;
/* Wipe out the old files, and ignore errors. */
unlink(key_path);
unlink(block_path);
/* Calculate the desired size of the new partition. */
- if (statvfs(stateful_mount, &buf)) {
+ if (statvfs(stateful_mount, &stateful_statbuf)) {
PERROR(stateful_mount);
return 0;
}
- size = buf.f_blocks;
- size *= kSizePercent;
- size *= buf.f_frsize;
+ fs_bytes_max = stateful_statbuf.f_blocks;
+ fs_bytes_max *= kSizePercent;
+ fs_bytes_max *= stateful_statbuf.f_frsize;
INFO("Creating sparse backing file with size %llu.",
- (unsigned long long)size);
+ (unsigned long long)fs_bytes_max);
/* Create the sparse file. */
- sparsefd = sparse_create(block_path, size);
+ sparsefd = sparse_create(block_path, fs_bytes_max);
if (sparsefd < 0) {
PERROR(block_path);
return 0;
@@ -752,8 +758,42 @@ static int setup_encrypted(void)
/* Calculate filesystem min/max size. */
blocks_max = sectors / (kExt4BlockSize / kSectorSize);
- blocks_min = migrate_needed ? blocks_max :
- kExt4MinBytes / kExt4BlockSize;
+ blocks_min = kExt4MinBytes / kExt4BlockSize;
+ if (migrate_needed && migrate_allowed) {
+ off_t fs_bytes_min;
+ size_t calc_blocks_min;
+ /* When doing a migration, the new filesystem must be
+ * large enough to hold what we're going to migrate.
+ * Instead of walking the bind mount sources, which would
+ * be IO and time expensive, just read the bytes-used
+ * value from statvfs (plus 10% for overhead). It will
+ * be too large, since it includes the eCryptFS data, so
+ * we must cap at the max filesystem size just in case.
+ */
+
+ /* Bytes used in stateful partition plus 10%. */
+ fs_bytes_min = stateful_statbuf.f_blocks -
+ stateful_statbuf.f_bfree;
+ fs_bytes_min *= stateful_statbuf.f_frsize;
+ DEBUG("Stateful bytes used: %llu",
+ (unsigned long long)fs_bytes_min);
+ fs_bytes_min *= kMigrationSizeMultiplier;
+
+ /* Minimum blocks needed for that many bytes. */
+ calc_blocks_min = fs_bytes_min / kExt4BlockSize;
+ /* Do not use more than blocks_max. */
+ if (calc_blocks_min > blocks_max)
+ calc_blocks_min = blocks_max;
+ /* Do not use less than blocks_min. */
+ else if (calc_blocks_min < blocks_min)
+ calc_blocks_min = blocks_min;
+
+ DEBUG("Maximum fs blocks: %zu", blocks_max);
+ DEBUG("Minimum fs blocks: %zu", blocks_min);
+ DEBUG("Migration blocks chosen: %zu", calc_blocks_min);
+ blocks_min = calc_blocks_min;
+ }
+
if (rebuild) {
INFO("Building filesystem on %s "
"(blocksize:%zu, min:%zu, max:%zu).",
diff --git a/utility/mount-encrypted.h b/utility/mount-encrypted.h
index 3707a85a..e48617d9 100644
--- a/utility/mount-encrypted.h
+++ b/utility/mount-encrypted.h
@@ -39,8 +39,8 @@
} while (0)
#if DEBUG_ENABLED
-static struct timeval tick;
-static struct timeval tick_start;
+extern struct timeval tick;
+extern struct timeval tick_start;
# define TICK_INIT() do { \
gettimeofday(&tick, NULL); \
tick_start = tick; \
diff --git a/utility/mount-helpers.c b/utility/mount-helpers.c
index 751d3ad4..9a472bb9 100644
--- a/utility/mount-helpers.c
+++ b/utility/mount-helpers.c
@@ -658,7 +658,7 @@ int keyfile_write(const char *keyfile, uint8_t *system_key, char *string)
}
length = cipher_length + final_len;
- DEBUG("Writing %d bytes to %s", length, keyfile);
+ DEBUG("Writing %zu bytes to %s", length, keyfile);
/* TODO(keescook): replace this with a mode-400 writer. */
if (!g_file_set_contents(keyfile, (gchar *)cipher, length, &error)) {
ERROR("Unable to write %s: %s", keyfile, error->message);