From: Lennart Poettering Date: Tue, 5 May 2020 13:05:59 +0000 (+0200) Subject: user-record: add new field for requesting LUKS discard on logout X-Git-Tag: v246-rc1~415^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5e86c82acd45842ec5ffbb620d77e9f2c164a7b7;p=thirdparty%2Fsystemd.git user-record: add new field for requesting LUKS discard on logout 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. --- diff --git a/src/shared/user-record-show.c b/src/shared/user-record-show.c index 7b14636ebf7..d8b46f2db29 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 7832aca8dc8..f6483112087 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 5bac3047671..83c5a71d4e7 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);