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.
This commit is contained in:
Lennart Poettering 2020-05-05 15:05:59 +02:00
parent c06bcd4d68
commit 5e86c82acd
3 changed files with 27 additions and 1 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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);