]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
user-record: add auto-resize property
authorLennart Poettering <lennart@poettering.net>
Fri, 29 Oct 2021 07:45:17 +0000 (09:45 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 23 Nov 2021 07:04:10 +0000 (08:04 +0100)
src/shared/user-record-show.c
src/shared/user-record.c
src/shared/user-record.h

index c733654b20af767c49fc5853989f2819397ef324..17502845af951a77a0dffbbb457b2a97575ecdfa 100644 (file)
@@ -444,6 +444,9 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         if (hr->drop_caches >= 0 || user_record_drop_caches(hr))
                 printf(" Drop Caches: %s\n", yes_no(user_record_drop_caches(hr)));
 
+        if (hr->auto_resize_mode >= 0)
+                printf(" Auto Resize: %s\n", auto_resize_mode_to_string(user_record_auto_resize_mode(hr)));
+
         if (!strv_isempty(hr->ssh_authorized_keys))
                 printf("SSH Pub. Key: %zu\n", strv_length(hr->ssh_authorized_keys));
 
index 268f8a3998fe9046adb24d349c6cc5ec9811cb1b..fa677adb2c413f806c43e156c239cb4c9d4865dd 100644 (file)
@@ -84,6 +84,7 @@ UserRecord* user_record_new(void) {
                 .fido2_user_presence_permitted = -1,
                 .fido2_user_verification_permitted = -1,
                 .drop_caches = -1,
+                .auto_resize_mode = _AUTO_RESIZE_MODE_INVALID,
         };
 
         return h;
@@ -957,6 +958,32 @@ static int dispatch_recovery_key(const char *name, JsonVariant *variant, JsonDis
         return 0;
 }
 
+static int dispatch_auto_resize_mode(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
+        AutoResizeMode *mode = userdata, m;
+
+        assert_se(mode);
+
+        if (json_variant_is_null(variant)) {
+                *mode = _AUTO_RESIZE_MODE_INVALID;
+                return 0;
+        }
+
+        if (json_variant_is_boolean(variant)) {
+                *mode = json_variant_boolean(variant) ? AUTO_RESIZE_SHRINK_AND_GROW : AUTO_RESIZE_OFF;
+                return 0;
+        }
+
+        if (!json_variant_is_string(variant))
+                return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string, boolean or null.", strna(name));
+
+        m = auto_resize_mode_from_string(json_variant_string(variant));
+        if (m < 0)
+                return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid automatic resize mode.", strna(name));
+
+        *mode = m;
+        return 0;
+}
+
 static int dispatch_privileged(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
 
         static const JsonDispatch privileged_dispatch_table[] = {
@@ -1149,6 +1176,7 @@ static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDisp
                 { "luksPbkdfParallelThreads",   JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_parallel_threads),   0         },
                 { "luksExtraMountOptions",      JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, luks_extra_mount_options),      0         },
                 { "dropCaches",                 JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, drop_caches),                   0         },
+                { "autoResizeMode",             _JSON_VARIANT_TYPE_INVALID, dispatch_auto_resize_mode,            offsetof(UserRecord, auto_resize_mode),              0         },
                 { "rateLimitIntervalUSec",      JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_interval_usec),       0         },
                 { "rateLimitBurst",             JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_burst),               0         },
                 { "enforcePasswordPolicy",      JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, enforce_password_policy),       0         },
@@ -1499,6 +1527,7 @@ int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_fla
                 { "luksPbkdfParallelThreads",   JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_parallel_threads),   0         },
                 { "luksExtraMountOptions",      JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, luks_extra_mount_options),      0         },
                 { "dropCaches",                 JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, drop_caches),                   0         },
+                { "autoResizeMode",             _JSON_VARIANT_TYPE_INVALID, dispatch_auto_resize_mode,            offsetof(UserRecord, auto_resize_mode),              0         },
                 { "service",                    JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, service),                       JSON_SAFE },
                 { "rateLimitIntervalUSec",      JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_interval_usec),       0         },
                 { "rateLimitBurst",             JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_burst),               0         },
@@ -1901,6 +1930,15 @@ bool user_record_drop_caches(UserRecord *h) {
         return user_record_storage(h) == USER_FSCRYPT;
 }
 
+AutoResizeMode user_record_auto_resize_mode(UserRecord *h) {
+        assert(h);
+
+        if (h->auto_resize_mode >= 0)
+                return h->auto_resize_mode;
+
+        return user_record_storage(h) == USER_LUKS ? AUTO_RESIZE_SHRINK_AND_GROW : AUTO_RESIZE_OFF;
+}
+
 uint64_t user_record_ratelimit_next_try(UserRecord *h) {
         assert(h);
 
@@ -2148,3 +2186,11 @@ static const char* const user_disposition_table[_USER_DISPOSITION_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(user_disposition, UserDisposition);
+
+static const char* const auto_resize_mode_table[_AUTO_RESIZE_MODE_MAX] = {
+        [AUTO_RESIZE_OFF]             = "off",
+        [AUTO_RESIZE_GROW]            = "grow",
+        [AUTO_RESIZE_SHRINK_AND_GROW] = "shrink-and-grow",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(auto_resize_mode, AutoResizeMode);
index 22a6bb28f420debb7679be322a7a495c7ee60c7e..c5424eef82ce5cb3ba0134d41c07ee8678c6b6dc 100644 (file)
@@ -213,6 +213,14 @@ typedef struct RecoveryKey {
         char *hashed_password;
 } RecoveryKey;
 
+typedef enum AutoResizeMode {
+        AUTO_RESIZE_OFF,               /* no automatic grow/shrink */
+        AUTO_RESIZE_GROW,              /* grow at login */
+        AUTO_RESIZE_SHRINK_AND_GROW,   /* shrink at logout + grow at login */
+        _AUTO_RESIZE_MODE_MAX,
+        _AUTO_RESIZE_MODE_INVALID = -EINVAL,
+} AutoResizeMode;
+
 typedef struct UserRecord {
         /* The following three fields are not part of the JSON record */
         unsigned n_ref;
@@ -249,6 +257,7 @@ typedef struct UserRecord {
         uint64_t disk_size_relative; /* Disk size, relative to the free bytes of the medium, normalized to UINT32_MAX = 100% */
         char *skeleton_directory;
         mode_t access_mode;
+        AutoResizeMode auto_resize_mode;
 
         uint64_t tasks_max;
         uint64_t memory_high;
@@ -387,6 +396,7 @@ usec_t user_record_ratelimit_interval_usec(UserRecord *h);
 uint64_t user_record_ratelimit_burst(UserRecord *h);
 bool user_record_can_authenticate(UserRecord *h);
 bool user_record_drop_caches(UserRecord *h);
+AutoResizeMode user_record_auto_resize_mode(UserRecord *h);
 
 int user_record_build_image_path(UserStorage storage, const char *user_name_and_realm, char **ret);
 
@@ -417,3 +427,6 @@ UserStorage user_storage_from_string(const char *s) _pure_;
 
 const char* user_disposition_to_string(UserDisposition t) _const_;
 UserDisposition user_disposition_from_string(const char *s) _pure_;
+
+const char* auto_resize_mode_to_string(AutoResizeMode m) _const_;
+AutoResizeMode auto_resize_mode_from_string(const char *s) _pure_;