From: Lennart Poettering Date: Fri, 10 Jan 2025 14:31:44 +0000 (+0100) Subject: homectl: add support for configuring tmpfs limits X-Git-Tag: v258-rc1~1499^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b2aebf4dd695d52cf8b6cbd38ba57affdc5a6bb;p=thirdparty%2Fsystemd.git homectl: add support for configuring tmpfs limits --- diff --git a/man/homectl.xml b/man/homectl.xml index 6a2be700307..6dc830233c6 100644 --- a/man/homectl.xml +++ b/man/homectl.xml @@ -758,6 +758,22 @@ + + + + + + + Controls the per-user quota on /tmp/ and + /dev/shm/ that is applied when the user logs in. Takes either an absolute value + in bytes (with the usual K, M, G, T suffixes to the base of 1024), or a percentage. In the latter + case the limit is applied relative to the size of the respective file system. This limit is only + applied if the relevant file system is tmpfs and has no effect otherwise. Note + that if these options are not used, a default quota might still be enforced (typically 80%.) + + + + diff --git a/src/home/homectl.c b/src/home/homectl.c index b8b6aa3a86d..29786760e2d 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -2830,6 +2830,9 @@ static int help(int argc, char *argv[], void *userdata) { " --memory-max=BYTES Set maximum memory limit\n" " --cpu-weight=WEIGHT Set CPU weight\n" " --io-weight=WEIGHT Set IO weight\n" + " --tmp-limit=BYTES|PERCENT Set limit on /tmp/\n" + " --dev-shm-limit=BYTES|PERCENT\n" + " Set limit on /dev/shm/\n" "\n%4$sStorage User Record Properties:%5$s\n" " --storage=STORAGE Storage type to use (luks, fscrypt, directory,\n" " subvolume, cifs)\n" @@ -2978,6 +2981,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_PROMPT_NEW_USER, ARG_AVATAR, ARG_LOGIN_BACKGROUND, + ARG_TMP_LIMIT, + ARG_DEV_SHM_LIMIT, }; static const struct option options[] = { @@ -3078,6 +3083,8 @@ static int parse_argv(int argc, char *argv[]) { { "blob", required_argument, NULL, 'b' }, { "avatar", required_argument, NULL, ARG_AVATAR }, { "login-background", required_argument, NULL, ARG_LOGIN_BACKGROUND }, + { "tmp-limit", required_argument, NULL, ARG_TMP_LIMIT }, + { "dev-shm-limit", required_argument, NULL, ARG_DEV_SHM_LIMIT }, {} }; @@ -4511,6 +4518,56 @@ static int parse_argv(int argc, char *argv[]) { break; } + case ARG_TMP_LIMIT: + case ARG_DEV_SHM_LIMIT: { + const char *field = + c == ARG_TMP_LIMIT ? "tmpLimit" : + c == ARG_DEV_SHM_LIMIT ? "devShmLimit" : NULL; + const char *field_scale = + c == ARG_TMP_LIMIT ? "tmpLimitScale" : + c == ARG_DEV_SHM_LIMIT ? "devShmLimitScale" : NULL; + + assert(field); + assert(field_scale); + + if (isempty(optarg)) { + r = drop_from_identity(field); + if (r < 0) + return r; + r = drop_from_identity(field_scale); + if (r < 0) + return r; + break; + } + + r = parse_permyriad(optarg); + if (r < 0) { + uint64_t u; + + r = parse_size(optarg, 1024, &u); + if (r < 0) + return log_error_errno(r, "Failed to parse %s/%s parameter: %s", field, field_scale, optarg); + + r = sd_json_variant_set_field_unsigned(&arg_identity_extra, field, u); + if (r < 0) + return log_error_errno(r, "Failed to set %s field: %m", field); + + r = drop_from_identity(field_scale); + if (r < 0) + return r; + } else { + r = sd_json_variant_set_field_unsigned(&arg_identity_extra, field_scale, UINT32_SCALE_FROM_PERMYRIAD(r)); + if (r < 0) + return log_error_errno(r, "Failed to set %s field: %m", field_scale); + + r = drop_from_identity(field); + if (r < 0) + return r; + } + + break; + } + case '?': return -EINVAL;