]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
homectl: add support for configuring tmpfs limits
authorLennart Poettering <lennart@poettering.net>
Fri, 10 Jan 2025 14:31:44 +0000 (15:31 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 23 Jan 2025 21:36:39 +0000 (22:36 +0100)
man/homectl.xml
src/home/homectl.c

index 6a2be700307c28cf16d32112989bf365f1bf91ac..6dc830233c6867626d5a9aaee067eb4b120ba573 100644 (file)
         <xi:include href="version-info.xml" xpointer="v245"/></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--tmp-limit=<replaceable>BYTES</replaceable></option></term>
+        <term><option>--tmp-limit=<replaceable>PERCENT</replaceable></option></term>
+        <term><option>--dev-shm-limit=<replaceable>BYTES</replaceable></option></term>
+        <term><option>--dev-shm-limit=<replaceable>PERCENT</replaceable></option></term>
+
+        <listitem><para>Controls the per-user quota on <filename>/tmp/</filename> and
+        <filename>/dev/shm/</filename> 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 <literal>tmpfs</literal> and has no effect otherwise. Note
+        that if these options are not used, a default quota might still be enforced (typically 80%.)</para>
+
+        <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--storage=<replaceable>STORAGE</replaceable></option></term>
 
index b8b6aa3a86d6bf5f1f3c8dad904c94fde16b1bc5..29786760e2d1ecc84bd94ff1214cb431cc55c371 100644 (file)
@@ -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;