From 5e86c82acd45842ec5ffbb620d77e9f2c164a7b7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 May 2020 15:05:59 +0200 Subject: [PATCH] user-record: add new field for requesting LUKS discard on logout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We make this entirely independent of the regular discard field, i.e. the one that controls discard behaviour when the home directory is online. Not all combinations make a ridiculous amount of sense, but most do. Specifically: online-discard = yes, offline-discard = yes → Discard when activating explicitly, and during runtime using the "discard" mount option, and discard explicitly when logging out again. online-discard = no, offline-discard = yes → The new default: when logging in allocate the full backing store, and use no discard while active. When loging out discard everything. This provides nice behaviour: we take minimal storage when offline but provide allocation guarantees while online. online-discard = no, offline-discard = no → Never, ever discard, always operate with fully allocated backing store. The extra safe mode. --- src/shared/user-record-show.c | 2 +- src/shared/user-record.c | 24 ++++++++++++++++++++++++ src/shared/user-record.h | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/shared/user-record-show.c b/src/shared/user-record-show.c index 7b14636ebf..d8b46f2db2 100644 --- a/src/shared/user-record-show.c +++ b/src/shared/user-record-show.c @@ -279,7 +279,7 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) { printf(" Access Mode: 0%03oo\n", user_record_access_mode(hr)); if (storage == USER_LUKS) { - printf("LUKS Discard: %s\n", yes_no(user_record_luks_discard(hr))); + printf("LUKS Discard: online=%s offline=%s\n", yes_no(user_record_luks_discard(hr)), yes_no(user_record_luks_offline_discard(hr))); if (!sd_id128_is_null(hr->luks_uuid)) printf(" LUKS UUID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(hr->luks_uuid)); diff --git a/src/shared/user-record.c b/src/shared/user-record.c index 7832aca8dc..f648311208 100644 --- a/src/shared/user-record.c +++ b/src/shared/user-record.c @@ -52,6 +52,7 @@ UserRecord* user_record_new(void) { .nodev = true, .nosuid = true, .luks_discard = -1, + .luks_offline_discard = -1, .luks_volume_key_size = UINT64_MAX, .luks_pbkdf_time_cost_usec = UINT64_MAX, .luks_pbkdf_memory_cost = UINT64_MAX, @@ -944,6 +945,7 @@ static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDisp { "luksUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, luks_uuid), 0 }, { "fileSystemUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, file_system_uuid), 0 }, { "luksDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_discard), 0, }, + { "luksOfflineDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_offline_discard), 0, }, { "luksCipher", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher), JSON_SAFE }, { "luksCipherMode", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher_mode), JSON_SAFE }, { "luksVolumeKeySize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_volume_key_size), 0 }, @@ -1276,6 +1278,7 @@ int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_fla { "luksUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, luks_uuid), 0 }, { "fileSystemUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, file_system_uuid), 0 }, { "luksDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_discard), 0 }, + { "luksOfflineDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_offline_discard), 0 }, { "luksCipher", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher), JSON_SAFE }, { "luksCipherMode", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher_mode), JSON_SAFE }, { "luksVolumeKeySize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_volume_key_size), 0 }, @@ -1500,6 +1503,27 @@ bool user_record_luks_discard(UserRecord *h) { return path_startswith(ip, "/dev/"); } +bool user_record_luks_offline_discard(UserRecord *h) { + const char *ip; + + assert(h); + + if (h->luks_offline_discard >= 0) + return h->luks_offline_discard; + + /* Discard while we are logged out should generally be a good idea, except when operating directly on + * physical media, where we should just bind it to the online discard mode. */ + + ip = user_record_image_path(h); + if (!ip) + return false; + + if (path_startswith(ip, "/dev/")) + return user_record_luks_discard(h); + + return true; +} + const char *user_record_luks_cipher(UserRecord *h) { assert(h); diff --git a/src/shared/user-record.h b/src/shared/user-record.h index 5bac304767..83c5a71d4e 100644 --- a/src/shared/user-record.h +++ b/src/shared/user-record.h @@ -261,6 +261,7 @@ typedef struct UserRecord { sd_id128_t file_system_uuid; int luks_discard; + int luks_offline_discard; char *luks_cipher; char *luks_cipher_mode; uint64_t luks_volume_key_size; @@ -332,6 +333,7 @@ const char *user_record_cifs_user_name(UserRecord *h); const char *user_record_shell(UserRecord *h); const char *user_record_real_name(UserRecord *h); bool user_record_luks_discard(UserRecord *h); +bool user_record_luks_offline_discard(UserRecord *h); const char *user_record_luks_cipher(UserRecord *h); const char *user_record_luks_cipher_mode(UserRecord *h); uint64_t user_record_luks_volume_key_size(UserRecord *h);