From: Lennart Poettering Date: Fri, 29 Oct 2021 12:34:24 +0000 (+0200) Subject: homectl: parse "min" and "max" as special disk size values X-Git-Tag: v250-rc1~211^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F21411%2Fhead;p=thirdparty%2Fsystemd.git homectl: parse "min" and "max" as special disk size values --- diff --git a/man/homectl.xml b/man/homectl.xml index 1b109938ce2..6ed8e90bf1e 100644 --- a/man/homectl.xml +++ b/man/homectl.xml @@ -849,7 +849,11 @@ xfs and btrfs 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 subvolume, directory, fscrypt storage - mechanisms are used, resizing will change file system quota. + 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 min and + max 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. diff --git a/src/home/homectl.c b/src/home/homectl.c index 2816f88b34c..648c275aec9 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -1763,6 +1763,32 @@ static int passwd_home(int argc, char *argv[], void *userdata) { 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; @@ -1781,9 +1807,9 @@ static int resize_home(int argc, char *argv[], void *userdata) { "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) { @@ -2907,9 +2933,9 @@ static int parse_argv(int argc, char *argv[]) { 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) diff --git a/test/units/testsuite-46.sh b/test/units/testsuite-46.sh index b5180eb8c45..16329fec362 100755 --- a/test/units/testsuite-46.sh +++ b/test/units/testsuite-46.sh @@ -87,14 +87,14 @@ if ! systemd-detect-virt -cq ; then 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