From: Lennart Poettering Date: Tue, 2 Nov 2021 22:09:31 +0000 (+0100) Subject: user-record: add rebalanceWeight field X-Git-Tag: v250-rc1~146^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9aa3e5ebdfee7a02a68198a8f2663a45c8bd4b25;p=thirdparty%2Fsystemd.git user-record: add rebalanceWeight field --- diff --git a/docs/USER_RECORD.md b/docs/USER_RECORD.md index 9634f32b70b..ea800c9928b 100644 --- a/docs/USER_RECORD.md +++ b/docs/USER_RECORD.md @@ -507,6 +507,12 @@ the size configured in `diskSize` automatically at login time. If set to `shrink-and-grown` the home area is also shrunk to the minimal size possible (as dictated by used disk space and file system constraints) on logout. +`rebalanceWeight` → An unsigned integer, `null` or a boolean. Configures the +free disk space rebalancing weight for the home area. The integer must be in +the range 1…10000 to configure an explicit weight. If unset, or set to `null` +or `true` the default weight of 100 is implied. If set to 0 or `false` +rebalancing is turned off for this home area. + `service` → A string declaring the service that defines or manages this user record. It is recommended to use reverse domain name notation for this. For example, if `systemd-homed` manages a user a string of `io.systemd.Home` is @@ -729,9 +735,10 @@ that may be used in this section are identical to the equally named ones in the `fileSystemUuid`, `luksDiscard`, `luksOfflineDiscard`, `luksCipher`, `luksCipherMode`, `luksVolumeKeySize`, `luksPbkdfHashAlgorithm`, `luksPbkdfType`, `luksPbkdfTimeCostUSec`, `luksPbkdfMemoryCost`, -`luksPbkdfParallelThreads`, `rateLimitIntervalUSec`, `rateLimitBurst`, -`enforcePasswordPolicy`, `autoLogin`, `stopDelayUSec`, `killProcesses`, -`passwordChangeMinUSec`, `passwordChangeMaxUSec`, `passwordChangeWarnUSec`, +`luksPbkdfParallelThreads`, `autoResizeMode`, `rebalanceWeight`, +`rateLimitIntervalUSec`, `rateLimitBurst`, `enforcePasswordPolicy`, +`autoLogin`, `stopDelayUSec`, `killProcesses`, `passwordChangeMinUSec`, +`passwordChangeMaxUSec`, `passwordChangeWarnUSec`, `passwordChangeInactiveUSec`, `passwordChangeNow`, `pkcs11TokenUri`, `fido2HmacCredential`. diff --git a/src/shared/user-record-show.c b/src/shared/user-record-show.c index 17502845af9..5335e640701 100644 --- a/src/shared/user-record-show.c +++ b/src/shared/user-record-show.c @@ -447,6 +447,16 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) { if (hr->auto_resize_mode >= 0) printf(" Auto Resize: %s\n", auto_resize_mode_to_string(user_record_auto_resize_mode(hr))); + if (hr->rebalance_weight != REBALANCE_WEIGHT_UNSET) { + uint64_t rb; + + rb = user_record_rebalance_weight(hr); + if (rb == REBALANCE_WEIGHT_OFF) + printf(" Rebalance: off\n"); + else + printf(" Rebalance: weight %" PRIu64 "\n", rb); + } + if (!strv_isempty(hr->ssh_authorized_keys)) printf("SSH Pub. Key: %zu\n", strv_length(hr->ssh_authorized_keys)); diff --git a/src/shared/user-record.c b/src/shared/user-record.c index fa677adb2c4..5b406d1f42c 100644 --- a/src/shared/user-record.c +++ b/src/shared/user-record.c @@ -85,6 +85,7 @@ UserRecord* user_record_new(void) { .fido2_user_verification_permitted = -1, .drop_caches = -1, .auto_resize_mode = _AUTO_RESIZE_MODE_INVALID, + .rebalance_weight = REBALANCE_WEIGHT_UNSET, }; return h; @@ -984,6 +985,36 @@ static int dispatch_auto_resize_mode(const char *name, JsonVariant *variant, Jso return 0; } +static int dispatch_rebalance_weight(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) { + uint64_t *rebalance_weight = userdata; + uintmax_t u; + + assert_se(rebalance_weight); + + if (json_variant_is_null(variant)) { + *rebalance_weight = REBALANCE_WEIGHT_UNSET; + return 0; + } + + if (json_variant_is_boolean(variant)) { + *rebalance_weight = json_variant_boolean(variant) ? REBALANCE_WEIGHT_DEFAULT : REBALANCE_WEIGHT_OFF; + return 0; + } + + if (!json_variant_is_unsigned(variant)) + return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an unsigned integer, boolean or null.", strna(name)); + + u = json_variant_unsigned(variant); + if (u >= REBALANCE_WEIGHT_MIN && u <= REBALANCE_WEIGHT_MAX) + *rebalance_weight = (uint64_t) u; + else if (u == 0) + *rebalance_weight = REBALANCE_WEIGHT_OFF; + else + return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "Rebalance weight is out of valid range %" PRIu64 "…%" PRIu64 ".", REBALANCE_WEIGHT_MIN, REBALANCE_WEIGHT_MAX); + + return 0; +} + static int dispatch_privileged(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) { static const JsonDispatch privileged_dispatch_table[] = { @@ -1177,6 +1208,7 @@ static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDisp { "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 }, + { "rebalanceWeight", _JSON_VARIANT_TYPE_INVALID, dispatch_rebalance_weight, offsetof(UserRecord, rebalance_weight), 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 }, @@ -1528,6 +1560,7 @@ int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_fla { "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 }, + { "rebalanceWeight", _JSON_VARIANT_TYPE_INVALID, dispatch_rebalance_weight, offsetof(UserRecord, rebalance_weight), 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 }, @@ -1939,6 +1972,15 @@ AutoResizeMode user_record_auto_resize_mode(UserRecord *h) { return user_record_storage(h) == USER_LUKS ? AUTO_RESIZE_SHRINK_AND_GROW : AUTO_RESIZE_OFF; } +uint64_t user_record_rebalance_weight(UserRecord *h) { + assert(h); + + if (h->rebalance_weight == REBALANCE_WEIGHT_UNSET) + return REBALANCE_WEIGHT_DEFAULT; + + return h->rebalance_weight; +} + uint64_t user_record_ratelimit_next_try(UserRecord *h) { assert(h); diff --git a/src/shared/user-record.h b/src/shared/user-record.h index c5424eef82c..276b9150678 100644 --- a/src/shared/user-record.h +++ b/src/shared/user-record.h @@ -221,6 +221,12 @@ typedef enum AutoResizeMode { _AUTO_RESIZE_MODE_INVALID = -EINVAL, } AutoResizeMode; +#define REBALANCE_WEIGHT_OFF UINT64_C(0) +#define REBALANCE_WEIGHT_DEFAULT UINT64_C(100) +#define REBALANCE_WEIGHT_MIN UINT64_C(1) +#define REBALANCE_WEIGHT_MAX UINT64_C(10000) +#define REBALANCE_WEIGHT_UNSET UINT64_MAX + typedef struct UserRecord { /* The following three fields are not part of the JSON record */ unsigned n_ref; @@ -258,6 +264,7 @@ typedef struct UserRecord { char *skeleton_directory; mode_t access_mode; AutoResizeMode auto_resize_mode; + uint64_t rebalance_weight; uint64_t tasks_max; uint64_t memory_high; @@ -397,6 +404,7 @@ 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); +uint64_t user_record_rebalance_weight(UserRecord *h); int user_record_build_image_path(UserStorage storage, const char *user_name_and_realm, char **ret);