<literal>xfs</literal> and <literal>btrfs</literal> the home directory may be grown while the user is
logged in, and on the latter also shrunk while the user is logged in. If the
<literal>subvolume</literal>, <literal>directory</literal>, <literal>fscrypt</literal> storage
- mechanisms are used, resizing will change file system quota.</para></listitem>
+ mechanisms are used, resizing will change file system quota. The size parameter may make use of the
+ usual suffixes B, K, M, G, T (to the base of 1024). The special strings <literal>min</literal> and
+ <literal>max</literal> may be specified in place of a numeric size value, for minimizing or
+ maximizing disk space assigned to the home area, taking constraints of the file system, disk usage inside
+ the home area and on the backing storage into account.</para></listitem>
</varlistentry>
<varlistentry>
return 0;
}
+static int parse_disk_size(const char *t, uint64_t *ret) {
+ int r;
+
+ assert(t);
+ assert(ret);
+
+ if (streq(t, "min"))
+ *ret = 0;
+ else if (streq(t, "max"))
+ *ret = UINT64_MAX-1; /* Largest size that isn't UINT64_MAX special marker */
+ else {
+ uint64_t ds;
+
+ r = parse_size(t, 1024, &ds);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse disk size parameter: %s", t);
+
+ if (ds >= UINT64_MAX) /* UINT64_MAX has special meaning for us ("dont change"), refuse */
+ return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Disk size out of range: %s", t);
+
+ *ret = ds;
+ }
+
+ return 0;
+}
+
static int resize_home(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(user_record_unrefp) UserRecord *secret = NULL;
"Relative disk size specification currently not supported when resizing.");
if (argc > 2) {
- r = parse_size(argv[2], 1024, &ds);
+ r = parse_disk_size(argv[2], &ds);
if (r < 0)
- return log_error_errno(r, "Failed to parse disk size parameter: %s", argv[2]);
+ return r;
}
if (arg_disk_size != UINT64_MAX) {
r = parse_permyriad(optarg);
if (r < 0) {
- r = parse_size(optarg, 1024, &arg_disk_size);
+ r = parse_disk_size(optarg, &arg_disk_size);
if (r < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Disk size '%s' not valid.", optarg);
+ return r;
r = drop_from_identity("diskSizeRelative");
if (r < 0)
inspect test-user
# minimize while inactive
- PASSWORD=xEhErW0ndafV4s homectl resize test-user 0
+ PASSWORD=xEhErW0ndafV4s homectl resize test-user min
inspect test-user
PASSWORD=xEhErW0ndafV4s homectl activate test-user
inspect test-user
# grow while active
- PASSWORD=xEhErW0ndafV4s homectl resize test-user 1T
+ PASSWORD=xEhErW0ndafV4s homectl resize test-user max
inspect test-user
# minimize while active