homectl: parse "min" and "max" as special disk size values

This commit is contained in:
Lennart Poettering 2021-10-29 14:34:24 +02:00
parent 41caad6fcc
commit 9f5827e01c
3 changed files with 37 additions and 7 deletions

View file

@ -849,7 +849,11 @@
<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>

View file

@ -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)

View file

@ -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