Skip to content

Commit

Permalink
homework: add auto-shrink/auto-grow
Browse files Browse the repository at this point in the history
  • Loading branch information
poettering committed Nov 23, 2021
1 parent ab3b6fc commit 2619100
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 10 deletions.
99 changes: 89 additions & 10 deletions src/home/homework-luks.c
Expand Up @@ -1402,6 +1402,42 @@ static void print_size_summary(uint64_t host_size, uint64_t encrypted_size, cons
FORMAT_BYTES((uint64_t) sfs->f_bfree * (uint64_t) sfs->f_frsize));
}

static int home_auto_grow_luks(
UserRecord *h,
HomeSetup *setup,
PasswordCache *cache) {

struct statfs sfs;

assert(h);
assert(setup);

if (!IN_SET(user_record_auto_resize_mode(h), AUTO_RESIZE_GROW, AUTO_RESIZE_SHRINK_AND_GROW))
return 0;

assert(setup->root_fd >= 0);

if (fstatfs(setup->root_fd, &sfs) < 0)
return log_error_errno(errno, "Failed to statfs home directory: %m");

if (!fs_can_online_shrink_and_grow(sfs.f_type)) {
log_debug("Not auto-grow file system, since selected file system cannot do both online shrink and grow.");
return 0;
}

log_debug("Initiating auto-grow...");

return home_resize_luks(
h,
HOME_SETUP_ALREADY_ACTIVATED|
HOME_SETUP_RESIZE_DONT_SYNC_IDENTITIES|
HOME_SETUP_RESIZE_DONT_SHRINK|
HOME_SETUP_RESIZE_DONT_UNDO,
setup,
cache,
NULL);
}

int home_activate_luks(
UserRecord *h,
HomeSetup *setup,
Expand Down Expand Up @@ -1442,6 +1478,10 @@ int home_activate_luks(
if (r < 0)
return r;

r = home_auto_grow_luks(h, setup, cache);
if (r < 0)
return r;

r = block_get_size_by_fd(setup->loop->fd, &host_size);
if (r < 0)
return log_error_errno(r, "Failed to get loopback block device size: %m");
Expand Down Expand Up @@ -1484,7 +1524,7 @@ int home_activate_luks(
setup->do_mark_clean = false;
setup->do_drop_caches = false;

log_info("Everything completed.");
log_info("Activation completed.");

print_size_summary(host_size, encrypted_size, &sfs);

Expand All @@ -1498,21 +1538,24 @@ int home_deactivate_luks(UserRecord *h, HomeSetup *setup) {

assert(h);
assert(setup);
assert(!setup->crypt_device);

/* Note that the DM device and loopback device are set to auto-detach, hence strictly speaking we
* don't have to explicitly have to detach them. However, we do that nonetheless (in case of the DM
* device), to avoid races: by explicitly detaching them we know when the detaching is complete. We
* don't bother about the loopback device because unlike the DM device it doesn't have a fixed
* name. */

r = acquire_open_luks_device(h, setup, /* graceful= */ true);
if (r < 0)
return log_error_errno(r, "Failed to initialize cryptsetup context for %s: %m", setup->dm_name);
if (r == 0) {
log_debug("LUKS device %s has already been detached.", setup->dm_name);
we_detached = false;
} else {
if (!setup->crypt_device) {
r = acquire_open_luks_device(h, setup, /* graceful= */ true);
if (r < 0)
return log_error_errno(r, "Failed to initialize cryptsetup context for %s: %m", setup->dm_name);
if (r == 0) {
log_debug("LUKS device %s has already been detached.", setup->dm_name);
we_detached = false;
}
}

if (setup->crypt_device) {
log_info("Discovered used LUKS device %s.", setup->dm_node);

cryptsetup_enable_logging(setup->crypt_device);
Expand Down Expand Up @@ -3396,7 +3439,7 @@ int home_resize_luks(
return r;
}

log_info("Everything completed.");
log_info("Resizing completed.");

print_size_summary(new_image_size, new_fs_size, &sfs);

Expand Down Expand Up @@ -3718,3 +3761,39 @@ int wait_for_block_device_gone(HomeSetup *setup, usec_t timeout_usec) {
log_debug("Successfully waited until device %s disappeared.", setup->dm_node);
return 0;
}

int home_auto_shrink_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache) {
struct statfs sfs;
int r;

assert(h);
assert(user_record_storage(h) == USER_LUKS);
assert(setup);
assert(setup->root_fd >= 0);

if (user_record_auto_resize_mode(h) != AUTO_RESIZE_SHRINK_AND_GROW)
return 0;

if (fstatfs(setup->root_fd, &sfs) < 0)
return log_error_errno(errno, "Failed to statfs home directory: %m");

if (!fs_can_online_shrink_and_grow(sfs.f_type)) {
log_debug("Not auto-shrinking file system, since selected file system cannot do both online shrink and grow.");
return 0;
}

r = home_resize_luks(
h,
HOME_SETUP_ALREADY_ACTIVATED|
HOME_SETUP_RESIZE_DONT_SYNC_IDENTITIES|
HOME_SETUP_RESIZE_MINIMIZE|
HOME_SETUP_RESIZE_DONT_GROW|
HOME_SETUP_RESIZE_DONT_UNDO,
setup,
cache,
NULL);
if (r < 0)
return r;

return 1;
}
2 changes: 2 additions & 0 deletions src/home/homework-luks.h
Expand Up @@ -24,6 +24,8 @@ int home_passwd_luks(UserRecord *h, HomeSetup *setup, const PasswordCache *cache
int home_lock_luks(UserRecord *h, HomeSetup *setup);
int home_unlock_luks(UserRecord *h, HomeSetup *setup, const PasswordCache *cache);

int home_auto_shrink_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache);

static inline uint64_t luks_volume_key_size_convert(struct crypt_device *cd) {
int k;

Expand Down
4 changes: 4 additions & 0 deletions src/home/homework.c
Expand Up @@ -908,6 +908,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {

static int home_deactivate(UserRecord *h, bool force) {
_cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
_cleanup_(password_cache_free) PasswordCache cache = {};
bool done = false;
int r;

Expand Down Expand Up @@ -952,6 +953,9 @@ static int home_deactivate(UserRecord *h, bool force) {
else
log_info("Syncing completed.");

if (user_record_storage(h) == USER_LUKS)
(void) home_auto_shrink_luks(h, &setup, &cache);

setup.root_fd = safe_close(setup.root_fd);

/* Now get rid of the bind mount, too */
Expand Down

0 comments on commit 2619100

Please sign in to comment.