]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/home/homed-manager.c
Merge pull request #22259 from bluca/exec_cond_restart
[thirdparty/systemd.git] / src / home / homed-manager.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <grp.h>
4 #include <linux/fs.h>
5 #include <linux/magic.h>
6 #include <math.h>
7 #include <openssl/pem.h>
8 #include <pwd.h>
9 #include <sys/ioctl.h>
10 #include <sys/quota.h>
11 #include <sys/stat.h>
12
13 #include "btrfs-util.h"
14 #include "bus-common-errors.h"
15 #include "bus-error.h"
16 #include "bus-log-control-api.h"
17 #include "bus-polkit.h"
18 #include "clean-ipc.h"
19 #include "conf-files.h"
20 #include "device-util.h"
21 #include "dirent-util.h"
22 #include "fd-util.h"
23 #include "fileio.h"
24 #include "format-util.h"
25 #include "fs-util.h"
26 #include "gpt.h"
27 #include "home-util.h"
28 #include "homed-conf.h"
29 #include "homed-home-bus.h"
30 #include "homed-home.h"
31 #include "homed-manager-bus.h"
32 #include "homed-manager.h"
33 #include "homed-varlink.h"
34 #include "io-util.h"
35 #include "mkdir.h"
36 #include "process-util.h"
37 #include "quota-util.h"
38 #include "random-util.h"
39 #include "resize-fs.h"
40 #include "socket-util.h"
41 #include "sort-util.h"
42 #include "stat-util.h"
43 #include "strv.h"
44 #include "sync-util.h"
45 #include "tmpfile-util.h"
46 #include "udev-util.h"
47 #include "user-record-sign.h"
48 #include "user-record-util.h"
49 #include "user-record.h"
50 #include "user-util.h"
51
52 /* Where to look for private/public keys that are used to sign the user records. We are not using
53 * CONF_PATHS_NULSTR() here since we want to insert /var/lib/systemd/home/ in the middle. And we insert that
54 * since we want to auto-generate a persistent private/public key pair if we need to. */
55 #define KEY_PATHS_NULSTR \
56 "/etc/systemd/home/\0" \
57 "/run/systemd/home/\0" \
58 "/var/lib/systemd/home/\0" \
59 "/usr/local/lib/systemd/home/\0" \
60 "/usr/lib/systemd/home/\0"
61
62 static bool uid_is_home(uid_t uid) {
63 return uid >= HOME_UID_MIN && uid <= HOME_UID_MAX;
64 }
65 /* Takes a value generated randomly or by hashing and turns it into a UID in the right range */
66
67 #define UID_CLAMP_INTO_HOME_RANGE(rnd) (((uid_t) (rnd) % (HOME_UID_MAX - HOME_UID_MIN + 1)) + HOME_UID_MIN)
68
69 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_uid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
70 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_name_hash_ops, char, string_hash_func, string_compare_func, Home, home_free);
71 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_worker_pid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
72 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops, char, path_hash_func, path_compare, Home, home_free);
73
74 static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata);
75 static int manager_gc_images(Manager *m);
76 static int manager_enumerate_images(Manager *m);
77 static int manager_assess_image(Manager *m, int dir_fd, const char *dir_path, const char *dentry_name);
78 static void manager_revalidate_image(Manager *m, Home *h);
79
80 static void manager_watch_home(Manager *m) {
81 struct statfs sfs;
82 int r;
83
84 assert(m);
85
86 m->inotify_event_source = sd_event_source_disable_unref(m->inotify_event_source);
87 m->scan_slash_home = false;
88
89 if (statfs(get_home_root(), &sfs) < 0) {
90 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
91 "Failed to statfs() %s directory, disabling automatic scanning.", get_home_root());
92 return;
93 }
94
95 if (is_network_fs(&sfs)) {
96 log_info("%s is a network file system, disabling automatic scanning.", get_home_root());
97 return;
98 }
99
100 if (is_fs_type(&sfs, AUTOFS_SUPER_MAGIC)) {
101 log_info("%s is on autofs, disabling automatic scanning.", get_home_root());
102 return;
103 }
104
105 m->scan_slash_home = true;
106
107 r = sd_event_add_inotify(m->event, &m->inotify_event_source, get_home_root(),
108 IN_CREATE|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF|IN_ONLYDIR|IN_MOVED_TO|IN_MOVED_FROM|IN_DELETE,
109 on_home_inotify, m);
110 if (r < 0)
111 log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
112 "Failed to create inotify watch on %s, ignoring.", get_home_root());
113
114 (void) sd_event_source_set_description(m->inotify_event_source, "home-inotify");
115
116 log_info("Watching %s.", get_home_root());
117 }
118
119 static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata) {
120 _cleanup_free_ char *j = NULL;
121 Manager *m = userdata;
122 const char *e, *n;
123
124 assert(m);
125 assert(event);
126
127 if ((event->mask & (IN_Q_OVERFLOW|IN_MOVE_SELF|IN_DELETE_SELF|IN_IGNORED|IN_UNMOUNT)) != 0) {
128
129 if (FLAGS_SET(event->mask, IN_Q_OVERFLOW))
130 log_debug("%s inotify queue overflow, rescanning.", get_home_root());
131 else if (FLAGS_SET(event->mask, IN_MOVE_SELF))
132 log_info("%s moved or renamed, recreating watch and rescanning.", get_home_root());
133 else if (FLAGS_SET(event->mask, IN_DELETE_SELF))
134 log_info("%s deleted, recreating watch and rescanning.", get_home_root());
135 else if (FLAGS_SET(event->mask, IN_UNMOUNT))
136 log_info("%s unmounted, recreating watch and rescanning.", get_home_root());
137 else if (FLAGS_SET(event->mask, IN_IGNORED))
138 log_info("%s watch invalidated, recreating watch and rescanning.", get_home_root());
139
140 manager_watch_home(m);
141 (void) manager_gc_images(m);
142 (void) manager_enumerate_images(m);
143 (void) bus_manager_emit_auto_login_changed(m);
144 return 0;
145 }
146
147 /* For the other inotify events, let's ignore all events for file names that don't match our
148 * expectations */
149 if (isempty(event->name))
150 return 0;
151 e = endswith(event->name, FLAGS_SET(event->mask, IN_ISDIR) ? ".homedir" : ".home");
152 if (!e)
153 return 0;
154
155 n = strndupa_safe(event->name, e - event->name);
156 if (!suitable_user_name(n))
157 return 0;
158
159 j = path_join(get_home_root(), event->name);
160 if (!j)
161 return log_oom();
162
163 if ((event->mask & (IN_CREATE|IN_CLOSE_WRITE|IN_MOVED_TO)) != 0) {
164 if (FLAGS_SET(event->mask, IN_CREATE))
165 log_debug("%s has been created, having a look.", j);
166 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
167 log_debug("%s has been modified, having a look.", j);
168 else if (FLAGS_SET(event->mask, IN_MOVED_TO))
169 log_debug("%s has been moved in, having a look.", j);
170
171 (void) manager_assess_image(m, -1, get_home_root(), event->name);
172 (void) bus_manager_emit_auto_login_changed(m);
173 }
174
175 if ((event->mask & (IN_DELETE | IN_CLOSE_WRITE | IN_MOVED_FROM)) != 0) {
176 Home *h;
177
178 if (FLAGS_SET(event->mask, IN_DELETE))
179 log_debug("%s has been deleted, revalidating.", j);
180 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
181 log_debug("%s has been closed after writing, revalidating.", j);
182 else if (FLAGS_SET(event->mask, IN_MOVED_FROM))
183 log_debug("%s has been moved away, revalidating.", j);
184
185 h = hashmap_get(m->homes_by_name, n);
186 if (h) {
187 manager_revalidate_image(m, h);
188 (void) bus_manager_emit_auto_login_changed(m);
189 }
190 }
191
192 return 0;
193 }
194
195 int manager_new(Manager **ret) {
196 _cleanup_(manager_freep) Manager *m = NULL;
197 int r;
198
199 assert(ret);
200
201 m = new(Manager, 1);
202 if (!m)
203 return -ENOMEM;
204
205 *m = (Manager) {
206 .default_storage = _USER_STORAGE_INVALID,
207 .rebalance_interval_usec = 2 * USEC_PER_MINUTE, /* initially, rebalance every 2min */
208 };
209
210 r = manager_parse_config_file(m);
211 if (r < 0)
212 return r;
213
214 r = sd_event_default(&m->event);
215 if (r < 0)
216 return r;
217
218 r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
219 if (r < 0)
220 return r;
221
222 r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
223 if (r < 0)
224 return r;
225
226 (void) sd_event_set_watchdog(m->event, true);
227
228 m->homes_by_uid = hashmap_new(&homes_by_uid_hash_ops);
229 if (!m->homes_by_uid)
230 return -ENOMEM;
231
232 m->homes_by_name = hashmap_new(&homes_by_name_hash_ops);
233 if (!m->homes_by_name)
234 return -ENOMEM;
235
236 m->homes_by_worker_pid = hashmap_new(&homes_by_worker_pid_hash_ops);
237 if (!m->homes_by_worker_pid)
238 return -ENOMEM;
239
240 m->homes_by_sysfs = hashmap_new(&homes_by_sysfs_hash_ops);
241 if (!m->homes_by_sysfs)
242 return -ENOMEM;
243
244 *ret = TAKE_PTR(m);
245 return 0;
246 }
247
248 Manager* manager_free(Manager *m) {
249 Home *h;
250
251 assert(m);
252
253 HASHMAP_FOREACH(h, m->homes_by_worker_pid)
254 (void) home_wait_for_worker(h);
255
256 m->bus = sd_bus_flush_close_unref(m->bus);
257 m->polkit_registry = bus_verify_polkit_async_registry_free(m->polkit_registry);
258
259 m->device_monitor = sd_device_monitor_unref(m->device_monitor);
260
261 m->inotify_event_source = sd_event_source_unref(m->inotify_event_source);
262 m->notify_socket_event_source = sd_event_source_unref(m->notify_socket_event_source);
263 m->deferred_rescan_event_source = sd_event_source_unref(m->deferred_rescan_event_source);
264 m->deferred_gc_event_source = sd_event_source_unref(m->deferred_gc_event_source);
265 m->deferred_auto_login_event_source = sd_event_source_unref(m->deferred_auto_login_event_source);
266 m->rebalance_event_source = sd_event_source_unref(m->rebalance_event_source);
267
268 m->event = sd_event_unref(m->event);
269
270 m->homes_by_uid = hashmap_free(m->homes_by_uid);
271 m->homes_by_name = hashmap_free(m->homes_by_name);
272 m->homes_by_worker_pid = hashmap_free(m->homes_by_worker_pid);
273 m->homes_by_sysfs = hashmap_free(m->homes_by_sysfs);
274
275 if (m->private_key)
276 EVP_PKEY_free(m->private_key);
277
278 hashmap_free(m->public_keys);
279
280 varlink_server_unref(m->varlink_server);
281 free(m->userdb_service);
282
283 free(m->default_file_system_type);
284
285 return mfree(m);
286 }
287
288 int manager_verify_user_record(Manager *m, UserRecord *hr) {
289 EVP_PKEY *pkey;
290 int r;
291
292 assert(m);
293 assert(hr);
294
295 if (!m->private_key && hashmap_isempty(m->public_keys)) {
296 r = user_record_has_signature(hr);
297 if (r < 0)
298 return r;
299
300 return r ? -ENOKEY : USER_RECORD_UNSIGNED;
301 }
302
303 /* Is it our own? */
304 if (m->private_key) {
305 r = user_record_verify(hr, m->private_key);
306 switch (r) {
307
308 case USER_RECORD_FOREIGN:
309 /* This record is not signed by this key, but let's see below */
310 break;
311
312 case USER_RECORD_SIGNED: /* Signed by us, but also by others, let's propagate that */
313 case USER_RECORD_SIGNED_EXCLUSIVE: /* Signed by us, and nothing else, ditto */
314 case USER_RECORD_UNSIGNED: /* Not signed at all, ditto */
315 default:
316 return r;
317 }
318 }
319
320 HASHMAP_FOREACH(pkey, m->public_keys) {
321 r = user_record_verify(hr, pkey);
322 switch (r) {
323
324 case USER_RECORD_FOREIGN:
325 /* This record is not signed by this key, but let's see our other keys */
326 break;
327
328 case USER_RECORD_SIGNED: /* It's signed by this key we are happy with, but which is not our own. */
329 case USER_RECORD_SIGNED_EXCLUSIVE:
330 return USER_RECORD_FOREIGN;
331
332 case USER_RECORD_UNSIGNED: /* It's not signed at all */
333 default:
334 return r;
335 }
336 }
337
338 return -ENOKEY;
339 }
340
341 static int manager_add_home_by_record(
342 Manager *m,
343 const char *name,
344 int dir_fd,
345 const char *fname) {
346
347 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
348 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
349 unsigned line, column;
350 int r, is_signed;
351 struct stat st;
352 Home *h;
353
354 assert(m);
355 assert(name);
356 assert(fname);
357
358 if (fstatat(dir_fd, fname, &st, 0) < 0)
359 return log_error_errno(errno, "Failed to stat identity record %s: %m", fname);
360
361 if (!S_ISREG(st.st_mode)) {
362 log_debug("Identity record file %s is not a regular file, ignoring.", fname);
363 return 0;
364 }
365
366 if (st.st_size == 0)
367 goto unlink_this_file;
368
369 r = json_parse_file_at(NULL, dir_fd, fname, JSON_PARSE_SENSITIVE, &v, &line, &column);
370 if (r < 0)
371 return log_error_errno(r, "Failed to parse identity record at %s:%u%u: %m", fname, line, column);
372
373 if (json_variant_is_blank_object(v))
374 goto unlink_this_file;
375
376 hr = user_record_new();
377 if (!hr)
378 return log_oom();
379
380 r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
381 if (r < 0)
382 return r;
383
384 if (!streq_ptr(hr->user_name, name))
385 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
386 "Identity's user name %s does not match file name %s, refusing.",
387 hr->user_name, name);
388
389 is_signed = manager_verify_user_record(m, hr);
390 switch (is_signed) {
391
392 case -ENOKEY:
393 return log_warning_errno(is_signed, "User record %s is not signed by any accepted key, ignoring.", fname);
394 case USER_RECORD_UNSIGNED:
395 return log_warning_errno(SYNTHETIC_ERRNO(EPERM), "User record %s is not signed at all, ignoring.", fname);
396 case USER_RECORD_SIGNED:
397 log_info("User record %s is signed by us (and others), accepting.", fname);
398 break;
399 case USER_RECORD_SIGNED_EXCLUSIVE:
400 log_info("User record %s is signed only by us, accepting.", fname);
401 break;
402 case USER_RECORD_FOREIGN:
403 log_info("User record %s is signed by registered key from others, accepting.", fname);
404 break;
405 default:
406 assert(is_signed < 0);
407 return log_error_errno(is_signed, "Failed to verify signature of user record in %s: %m", fname);
408 }
409
410 h = hashmap_get(m->homes_by_name, name);
411 if (h) {
412 r = home_set_record(h, hr);
413 if (r < 0)
414 return log_error_errno(r, "Failed to update home record for %s: %m", name);
415
416 /* If we acquired a record now for a previously unallocated entry, then reset the state. This
417 * makes sure home_get_state() will check for the availability of the image file dynamically
418 * in order to detect to distinguish HOME_INACTIVE and HOME_ABSENT. */
419 if (h->state == HOME_UNFIXATED)
420 h->state = _HOME_STATE_INVALID;
421 } else {
422 r = home_new(m, hr, NULL, &h);
423 if (r < 0)
424 return log_error_errno(r, "Failed to allocate new home object: %m");
425
426 log_info("Added registered home for user %s.", hr->user_name);
427 }
428
429 /* Only entries we exclusively signed are writable to us, hence remember the result */
430 h->signed_locally = is_signed == USER_RECORD_SIGNED_EXCLUSIVE;
431
432 return 1;
433
434 unlink_this_file:
435 /* If this is an empty file, then let's just remove it. An empty file is not useful in any case, and
436 * apparently xfs likes to leave empty files around when not unmounted cleanly (see
437 * https://github.com/systemd/systemd/issues/15178 for example). Note that we don't delete non-empty
438 * files even if they are invalid, because that's just too risky, we might delete data the user still
439 * needs. But empty files are never useful, hence let's just remove them. */
440
441 if (unlinkat(dir_fd, fname, 0) < 0)
442 return log_error_errno(errno, "Failed to remove empty user record file %s: %m", fname);
443
444 log_notice("Discovered empty user record file %s/%s, removed automatically.", home_record_dir(), fname);
445 return 0;
446 }
447
448 static int manager_enumerate_records(Manager *m) {
449 _cleanup_closedir_ DIR *d = NULL;
450
451 assert(m);
452
453 d = opendir(home_record_dir());
454 if (!d)
455 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
456 "Failed to open %s: %m", home_record_dir());
457
458 FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read record directory: %m")) {
459 _cleanup_free_ char *n = NULL;
460 const char *e;
461
462 if (!dirent_is_file(de))
463 continue;
464
465 e = endswith(de->d_name, ".identity");
466 if (!e)
467 continue;
468
469 n = strndup(de->d_name, e - de->d_name);
470 if (!n)
471 return log_oom();
472
473 if (!suitable_user_name(n))
474 continue;
475
476 (void) manager_add_home_by_record(m, n, dirfd(d), de->d_name);
477 }
478
479 return 0;
480 }
481
482 static int search_quota(uid_t uid, const char *exclude_quota_path) {
483 struct stat exclude_st = {};
484 dev_t previous_devno = 0;
485 const char *where;
486 int r;
487
488 /* Checks whether the specified UID owns any files on the files system, but ignore any file system
489 * backing the specified file. The file is used when operating on home directories, where it's OK if
490 * the UID of them already owns files. */
491
492 if (exclude_quota_path && stat(exclude_quota_path, &exclude_st) < 0) {
493 if (errno != ENOENT)
494 return log_warning_errno(errno, "Failed to stat %s, ignoring: %m", exclude_quota_path);
495 }
496
497 /* Check a few usual suspects where regular users might own files. Note that this is by no means
498 * comprehensive, but should cover most cases. Note that in an ideal world every user would be
499 * registered in NSS and avoid our own UID range, but for all other cases, it's a good idea to be
500 * paranoid and check quota if we can. */
501 FOREACH_STRING(where, get_home_root(), "/tmp/", "/var/", "/var/mail/", "/var/tmp/", "/var/spool/") {
502 struct dqblk req;
503 struct stat st;
504
505 if (stat(where, &st) < 0) {
506 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
507 "Failed to stat %s, ignoring: %m", where);
508 continue;
509 }
510
511 if (major(st.st_dev) == 0) {
512 log_debug("Directory %s is not on a real block device, not checking quota for UID use.", where);
513 continue;
514 }
515
516 if (st.st_dev == exclude_st.st_dev) { /* If an exclude path is specified, then ignore quota
517 * reported on the same block device as that path. */
518 log_debug("Directory %s is where the home directory is located, not checking quota for UID use.", where);
519 continue;
520 }
521
522 if (st.st_dev == previous_devno) { /* Does this directory have the same devno as the previous
523 * one we tested? If so, there's no point in testing this
524 * again. */
525 log_debug("Directory %s is on same device as previous tested directory, not checking quota for UID use a second time.", where);
526 continue;
527 }
528
529 previous_devno = st.st_dev;
530
531 r = quotactl_devno(QCMD_FIXED(Q_GETQUOTA, USRQUOTA), st.st_dev, uid, &req);
532 if (r < 0) {
533 if (ERRNO_IS_NOT_SUPPORTED(r))
534 log_debug_errno(r, "No UID quota support on %s, ignoring.", where);
535 else if (ERRNO_IS_PRIVILEGE(r))
536 log_debug_errno(r, "UID quota support for %s prohibited, ignoring.", where);
537 else
538 log_warning_errno(r, "Failed to query quota on %s, ignoring: %m", where);
539
540 continue;
541 }
542
543 if ((FLAGS_SET(req.dqb_valid, QIF_SPACE) && req.dqb_curspace > 0) ||
544 (FLAGS_SET(req.dqb_valid, QIF_INODES) && req.dqb_curinodes > 0)) {
545 log_debug_errno(errno, "Quota reports UID " UID_FMT " occupies disk space on %s.", uid, where);
546 return 1;
547 }
548 }
549
550 return 0;
551 }
552
553 static int manager_acquire_uid(
554 Manager *m,
555 uid_t start_uid,
556 const char *user_name,
557 const char *exclude_quota_path,
558 uid_t *ret) {
559
560 static const uint8_t hash_key[] = {
561 0xa3, 0xb8, 0x82, 0x69, 0x9a, 0x71, 0xf7, 0xa9,
562 0xe0, 0x7c, 0xf6, 0xf1, 0x21, 0x69, 0xd2, 0x1e
563 };
564
565 enum {
566 PHASE_SUGGESTED,
567 PHASE_HASHED,
568 PHASE_RANDOM
569 } phase = PHASE_SUGGESTED;
570
571 unsigned n_tries = 100;
572 int r;
573
574 assert(m);
575 assert(ret);
576
577 for (;;) {
578 struct passwd *pw;
579 struct group *gr;
580 uid_t candidate;
581 Home *other;
582
583 if (--n_tries <= 0)
584 return -EBUSY;
585
586 switch (phase) {
587
588 case PHASE_SUGGESTED:
589 phase = PHASE_HASHED;
590
591 if (!uid_is_home(start_uid))
592 continue;
593
594 candidate = start_uid;
595 break;
596
597 case PHASE_HASHED:
598 phase = PHASE_RANDOM;
599
600 if (!user_name)
601 continue;
602
603 candidate = UID_CLAMP_INTO_HOME_RANGE(siphash24(user_name, strlen(user_name), hash_key));
604 break;
605
606 case PHASE_RANDOM:
607 random_bytes(&candidate, sizeof(candidate));
608 candidate = UID_CLAMP_INTO_HOME_RANGE(candidate);
609 break;
610
611 default:
612 assert_not_reached();
613 }
614
615 other = hashmap_get(m->homes_by_uid, UID_TO_PTR(candidate));
616 if (other) {
617 log_debug("Candidate UID " UID_FMT " already used by another home directory (%s), let's try another.",
618 candidate, other->user_name);
619 continue;
620 }
621
622 pw = getpwuid(candidate);
623 if (pw) {
624 log_debug("Candidate UID " UID_FMT " already registered by another user in NSS (%s), let's try another.",
625 candidate, pw->pw_name);
626 continue;
627 }
628
629 gr = getgrgid((gid_t) candidate);
630 if (gr) {
631 log_debug("Candidate UID " UID_FMT " already registered by another group in NSS (%s), let's try another.",
632 candidate, gr->gr_name);
633 continue;
634 }
635
636 r = search_ipc(candidate, (gid_t) candidate);
637 if (r < 0)
638 continue;
639 if (r > 0) {
640 log_debug_errno(r, "Candidate UID " UID_FMT " already owns IPC objects, let's try another: %m",
641 candidate);
642 continue;
643 }
644
645 r = search_quota(candidate, exclude_quota_path);
646 if (r != 0)
647 continue;
648
649 *ret = candidate;
650 return 0;
651 }
652 }
653
654 static int manager_add_home_by_image(
655 Manager *m,
656 const char *user_name,
657 const char *realm,
658 const char *image_path,
659 const char *sysfs,
660 UserStorage storage,
661 uid_t start_uid) {
662
663 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
664 uid_t uid;
665 Home *h;
666 int r;
667
668 assert(m);
669
670 assert(m);
671 assert(user_name);
672 assert(image_path);
673 assert(storage >= 0);
674 assert(storage < _USER_STORAGE_MAX);
675
676 h = hashmap_get(m->homes_by_name, user_name);
677 if (h) {
678 bool same;
679
680 if (h->state != HOME_UNFIXATED) {
681 log_debug("Found an image for user %s which already has a record, skipping.", user_name);
682 return 0; /* ignore images that synthesize a user we already have a record for */
683 }
684
685 same = user_record_storage(h->record) == storage;
686 if (same) {
687 if (h->sysfs && sysfs)
688 same = path_equal(h->sysfs, sysfs);
689 else if (!!h->sysfs != !!sysfs)
690 same = false;
691 else {
692 const char *p;
693
694 p = user_record_image_path(h->record);
695 same = p && path_equal(p, image_path);
696 }
697 }
698
699 if (!same) {
700 log_debug("Found multiple images for user '%s', ignoring image '%s'.", user_name, image_path);
701 return 0;
702 }
703 } else {
704 /* Check NSS, in case there's another user or group by this name */
705 if (getpwnam(user_name) || getgrnam(user_name)) {
706 log_debug("Found an existing user or group by name '%s', ignoring image '%s'.", user_name, image_path);
707 return 0;
708 }
709 }
710
711 if (h && uid_is_valid(h->uid))
712 uid = h->uid;
713 else {
714 r = manager_acquire_uid(m, start_uid, user_name,
715 IN_SET(storage, USER_SUBVOLUME, USER_DIRECTORY, USER_FSCRYPT) ? image_path : NULL,
716 &uid);
717 if (r < 0)
718 return log_warning_errno(r, "Failed to acquire unused UID for %s: %m", user_name);
719 }
720
721 hr = user_record_new();
722 if (!hr)
723 return log_oom();
724
725 r = user_record_synthesize(hr, user_name, realm, image_path, storage, uid, (gid_t) uid);
726 if (r < 0)
727 return log_error_errno(r, "Failed to synthesize home record for %s (image %s): %m", user_name, image_path);
728
729 if (h) {
730 r = home_set_record(h, hr);
731 if (r < 0)
732 return log_error_errno(r, "Failed to update home record for %s: %m", user_name);
733 } else {
734 r = home_new(m, hr, sysfs, &h);
735 if (r < 0)
736 return log_error_errno(r, "Failed to allocate new home object: %m");
737
738 h->state = HOME_UNFIXATED;
739
740 log_info("Discovered new home for user %s through image %s.", user_name, image_path);
741 }
742
743 return 1;
744 }
745
746 int manager_augment_record_with_uid(
747 Manager *m,
748 UserRecord *hr) {
749
750 const char *exclude_quota_path = NULL;
751 uid_t start_uid = UID_INVALID, uid;
752 int r;
753
754 assert(m);
755 assert(hr);
756
757 if (uid_is_valid(hr->uid))
758 return 0;
759
760 if (IN_SET(hr->storage, USER_CLASSIC, USER_SUBVOLUME, USER_DIRECTORY, USER_FSCRYPT)) {
761 const char * ip;
762
763 ip = user_record_image_path(hr);
764 if (ip) {
765 struct stat st;
766
767 if (stat(ip, &st) < 0) {
768 if (errno != ENOENT)
769 log_warning_errno(errno, "Failed to stat(%s): %m", ip);
770 } else if (uid_is_home(st.st_uid)) {
771 start_uid = st.st_uid;
772 exclude_quota_path = ip;
773 }
774 }
775 }
776
777 r = manager_acquire_uid(m, start_uid, hr->user_name, exclude_quota_path, &uid);
778 if (r < 0)
779 return r;
780
781 log_debug("Acquired new UID " UID_FMT " for %s.", uid, hr->user_name);
782
783 r = user_record_add_binding(
784 hr,
785 _USER_STORAGE_INVALID,
786 NULL,
787 SD_ID128_NULL,
788 SD_ID128_NULL,
789 SD_ID128_NULL,
790 NULL,
791 NULL,
792 UINT64_MAX,
793 NULL,
794 NULL,
795 uid,
796 (gid_t) uid);
797 if (r < 0)
798 return r;
799
800 return 1;
801 }
802
803 static int manager_assess_image(
804 Manager *m,
805 int dir_fd,
806 const char *dir_path,
807 const char *dentry_name) {
808
809 char *luks_suffix, *directory_suffix;
810 _cleanup_free_ char *path = NULL;
811 struct stat st;
812 int r;
813
814 assert(m);
815 assert(dir_path);
816 assert(dentry_name);
817
818 luks_suffix = endswith(dentry_name, ".home");
819 if (luks_suffix)
820 directory_suffix = NULL;
821 else
822 directory_suffix = endswith(dentry_name, ".homedir");
823
824 /* Early filter out: by name */
825 if (!luks_suffix && !directory_suffix)
826 return 0;
827
828 path = path_join(dir_path, dentry_name);
829 if (!path)
830 return log_oom();
831
832 /* Follow symlinks here, to allow people to link in stuff to make them available locally. */
833 if (dir_fd >= 0)
834 r = fstatat(dir_fd, dentry_name, &st, 0);
835 else
836 r = stat(path, &st);
837 if (r < 0)
838 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
839 "Failed to stat() directory entry '%s', ignoring: %m", dentry_name);
840
841 if (S_ISREG(st.st_mode)) {
842 _cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL;
843
844 if (!luks_suffix)
845 return 0;
846
847 n = strndup(dentry_name, luks_suffix - dentry_name);
848 if (!n)
849 return log_oom();
850
851 r = split_user_name_realm(n, &user_name, &realm);
852 if (r == -EINVAL) /* Not the right format: ignore */
853 return 0;
854 if (r < 0)
855 return log_error_errno(r, "Failed to split image name into user name/realm: %m");
856
857 return manager_add_home_by_image(m, user_name, realm, path, NULL, USER_LUKS, UID_INVALID);
858 }
859
860 if (S_ISDIR(st.st_mode)) {
861 _cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL;
862 _cleanup_close_ int fd = -1;
863 UserStorage storage;
864
865 if (!directory_suffix)
866 return 0;
867
868 n = strndup(dentry_name, directory_suffix - dentry_name);
869 if (!n)
870 return log_oom();
871
872 r = split_user_name_realm(n, &user_name, &realm);
873 if (r == -EINVAL) /* Not the right format: ignore */
874 return 0;
875 if (r < 0)
876 return log_error_errno(r, "Failed to split image name into user name/realm: %m");
877
878 if (dir_fd >= 0)
879 fd = openat(dir_fd, dentry_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
880 else
881 fd = open(path, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
882 if (fd < 0)
883 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
884 "Failed to open directory '%s', ignoring: %m", path);
885
886 if (fstat(fd, &st) < 0)
887 return log_warning_errno(errno, "Failed to fstat() %s, ignoring: %m", path);
888
889 assert(S_ISDIR(st.st_mode)); /* Must hold, we used O_DIRECTORY above */
890
891 r = btrfs_is_subvol_fd(fd);
892 if (r < 0)
893 return log_warning_errno(errno, "Failed to determine whether %s is a btrfs subvolume: %m", path);
894 if (r > 0)
895 storage = USER_SUBVOLUME;
896 else {
897 struct fscrypt_policy policy;
898
899 if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) {
900
901 if (errno == ENODATA)
902 log_debug_errno(errno, "Determined %s is not fscrypt encrypted.", path);
903 else if (ERRNO_IS_NOT_SUPPORTED(errno))
904 log_debug_errno(errno, "Determined %s is not fscrypt encrypted because kernel or file system doesn't support it.", path);
905 else
906 log_debug_errno(errno, "FS_IOC_GET_ENCRYPTION_POLICY failed with unexpected error code on %s, ignoring: %m", path);
907
908 storage = USER_DIRECTORY;
909 } else
910 storage = USER_FSCRYPT;
911 }
912
913 return manager_add_home_by_image(m, user_name, realm, path, NULL, storage, st.st_uid);
914 }
915
916 return 0;
917 }
918
919 int manager_enumerate_images(Manager *m) {
920 _cleanup_closedir_ DIR *d = NULL;
921
922 assert(m);
923
924 if (!m->scan_slash_home)
925 return 0;
926
927 d = opendir(get_home_root());
928 if (!d)
929 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
930 "Failed to open %s: %m", get_home_root());
931
932 FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read %s directory: %m", get_home_root()))
933 (void) manager_assess_image(m, dirfd(d), get_home_root(), de->d_name);
934
935 return 0;
936 }
937
938 static int manager_connect_bus(Manager *m) {
939 _cleanup_free_ char *b = NULL;
940 const char *suffix, *busname;
941 int r;
942
943 assert(m);
944 assert(!m->bus);
945
946 r = sd_bus_default_system(&m->bus);
947 if (r < 0)
948 return log_error_errno(r, "Failed to connect to system bus: %m");
949
950 r = bus_add_implementation(m->bus, &manager_object, m);
951 if (r < 0)
952 return r;
953
954 r = bus_log_control_api_register(m->bus);
955 if (r < 0)
956 return r;
957
958 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
959 if (suffix) {
960 b = strjoin("org.freedesktop.home1.", suffix);
961 if (!b)
962 return log_oom();
963 busname = b;
964 } else
965 busname = "org.freedesktop.home1";
966
967 r = sd_bus_request_name_async(m->bus, NULL, busname, 0, NULL, NULL);
968 if (r < 0)
969 return log_error_errno(r, "Failed to request name: %m");
970
971 r = sd_bus_attach_event(m->bus, m->event, 0);
972 if (r < 0)
973 return log_error_errno(r, "Failed to attach bus to event loop: %m");
974
975 (void) sd_bus_set_exit_on_disconnect(m->bus, true);
976
977 return 0;
978 }
979
980 static int manager_bind_varlink(Manager *m) {
981 _cleanup_free_ char *p = NULL;
982 const char *suffix, *socket_path;
983 int r;
984
985 assert(m);
986 assert(!m->varlink_server);
987
988 r = varlink_server_new(&m->varlink_server, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA);
989 if (r < 0)
990 return log_error_errno(r, "Failed to allocate varlink server object: %m");
991
992 varlink_server_set_userdata(m->varlink_server, m);
993
994 r = varlink_server_bind_method_many(
995 m->varlink_server,
996 "io.systemd.UserDatabase.GetUserRecord", vl_method_get_user_record,
997 "io.systemd.UserDatabase.GetGroupRecord", vl_method_get_group_record,
998 "io.systemd.UserDatabase.GetMemberships", vl_method_get_memberships);
999 if (r < 0)
1000 return log_error_errno(r, "Failed to register varlink methods: %m");
1001
1002 (void) mkdir_p("/run/systemd/userdb", 0755);
1003
1004 /* To make things easier to debug, when working from a homed managed home directory, let's optionally
1005 * use a different varlink socket name */
1006 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
1007 if (suffix) {
1008 p = strjoin("/run/systemd/userdb/io.systemd.Home.", suffix);
1009 if (!p)
1010 return log_oom();
1011 socket_path = p;
1012 } else
1013 socket_path = "/run/systemd/userdb/io.systemd.Home";
1014
1015 r = varlink_server_listen_address(m->varlink_server, socket_path, 0666);
1016 if (r < 0)
1017 return log_error_errno(r, "Failed to bind to varlink socket: %m");
1018
1019 r = varlink_server_attach_event(m->varlink_server, m->event, SD_EVENT_PRIORITY_NORMAL);
1020 if (r < 0)
1021 return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
1022
1023 assert(!m->userdb_service);
1024 m->userdb_service = strdup(basename(socket_path));
1025 if (!m->userdb_service)
1026 return log_oom();
1027
1028 /* Avoid recursion */
1029 if (setenv("SYSTEMD_BYPASS_USERDB", m->userdb_service, 1) < 0)
1030 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m");
1031
1032 return 0;
1033 }
1034
1035 static ssize_t read_datagram(
1036 int fd,
1037 struct ucred *ret_sender,
1038 void **ret,
1039 int *ret_passed_fd) {
1040
1041 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int))) control;
1042 _cleanup_free_ void *buffer = NULL;
1043 _cleanup_close_ int passed_fd = -1;
1044 struct ucred *sender = NULL;
1045 struct cmsghdr *cmsg;
1046 struct msghdr mh;
1047 struct iovec iov;
1048 ssize_t n, m;
1049
1050 assert(fd >= 0);
1051 assert(ret_sender);
1052 assert(ret);
1053 assert(ret_passed_fd);
1054
1055 n = next_datagram_size_fd(fd);
1056 if (n < 0)
1057 return n;
1058
1059 buffer = malloc(n + 2);
1060 if (!buffer)
1061 return -ENOMEM;
1062
1063 /* Pass one extra byte, as a size check */
1064 iov = IOVEC_MAKE(buffer, n + 1);
1065
1066 mh = (struct msghdr) {
1067 .msg_iov = &iov,
1068 .msg_iovlen = 1,
1069 .msg_control = &control,
1070 .msg_controllen = sizeof(control),
1071 };
1072
1073 m = recvmsg_safe(fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
1074 if (m < 0)
1075 return m;
1076
1077 /* Ensure the size matches what we determined before */
1078 if (m != n) {
1079 cmsg_close_all(&mh);
1080 return -EMSGSIZE;
1081 }
1082
1083 CMSG_FOREACH(cmsg, &mh) {
1084 if (cmsg->cmsg_level == SOL_SOCKET &&
1085 cmsg->cmsg_type == SCM_CREDENTIALS &&
1086 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1087 assert(!sender);
1088 sender = (struct ucred*) CMSG_DATA(cmsg);
1089 }
1090
1091 if (cmsg->cmsg_level == SOL_SOCKET &&
1092 cmsg->cmsg_type == SCM_RIGHTS) {
1093
1094 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
1095 cmsg_close_all(&mh);
1096 return -EMSGSIZE;
1097 }
1098
1099 assert(passed_fd < 0);
1100 passed_fd = *(int*) CMSG_DATA(cmsg);
1101 }
1102 }
1103
1104 if (sender)
1105 *ret_sender = *sender;
1106 else
1107 *ret_sender = (struct ucred) UCRED_INVALID;
1108
1109 *ret_passed_fd = TAKE_FD(passed_fd);
1110
1111 /* For safety reasons: let's always NUL terminate. */
1112 ((char*) buffer)[n] = 0;
1113 *ret = TAKE_PTR(buffer);
1114
1115 return 0;
1116 }
1117
1118 static int on_notify_socket(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1119 _cleanup_strv_free_ char **l = NULL;
1120 _cleanup_free_ void *datagram = NULL;
1121 _cleanup_close_ int passed_fd = -1;
1122 struct ucred sender = UCRED_INVALID;
1123 Manager *m = userdata;
1124 ssize_t n;
1125 Home *h;
1126
1127 assert(s);
1128 assert(m);
1129
1130 n = read_datagram(fd, &sender, &datagram, &passed_fd);
1131 if (n < 0) {
1132 if (ERRNO_IS_TRANSIENT(n))
1133 return 0;
1134 return log_error_errno(n, "Failed to read notify datagram: %m");
1135 }
1136
1137 if (sender.pid <= 0) {
1138 log_warning("Received notify datagram without valid sender PID, ignoring.");
1139 return 0;
1140 }
1141
1142 h = hashmap_get(m->homes_by_worker_pid, PID_TO_PTR(sender.pid));
1143 if (!h) {
1144 log_warning("Received notify datagram of unknown process, ignoring.");
1145 return 0;
1146 }
1147
1148 l = strv_split(datagram, "\n");
1149 if (!l)
1150 return log_oom();
1151
1152 home_process_notify(h, l, TAKE_FD(passed_fd));
1153 return 0;
1154 }
1155
1156 static int manager_listen_notify(Manager *m) {
1157 _cleanup_close_ int fd = -1;
1158 union sockaddr_union sa = {
1159 .un.sun_family = AF_UNIX,
1160 .un.sun_path = "/run/systemd/home/notify",
1161 };
1162 const char *suffix;
1163 int r;
1164
1165 assert(m);
1166 assert(!m->notify_socket_event_source);
1167
1168 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
1169 if (suffix) {
1170 _cleanup_free_ char *unix_path = NULL;
1171
1172 unix_path = strjoin("/run/systemd/home/notify.", suffix);
1173 if (!unix_path)
1174 return log_oom();
1175 r = sockaddr_un_set_path(&sa.un, unix_path);
1176 if (r < 0)
1177 return log_error_errno(r, "Socket path %s does not fit in sockaddr_un: %m", unix_path);
1178 }
1179
1180 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1181 if (fd < 0)
1182 return log_error_errno(errno, "Failed to create listening socket: %m");
1183
1184 (void) mkdir_parents(sa.un.sun_path, 0755);
1185 (void) sockaddr_un_unlink(&sa.un);
1186
1187 if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
1188 return log_error_errno(errno, "Failed to bind to socket: %m");
1189
1190 r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
1191 if (r < 0)
1192 return r;
1193
1194 r = sd_event_add_io(m->event, &m->notify_socket_event_source, fd, EPOLLIN, on_notify_socket, m);
1195 if (r < 0)
1196 return log_error_errno(r, "Failed to allocate event source for notify socket: %m");
1197
1198 (void) sd_event_source_set_description(m->notify_socket_event_source, "notify-socket");
1199
1200 /* Make sure we process sd_notify() before SIGCHLD for any worker, so that we always know the error
1201 * number of a client before it exits. */
1202 r = sd_event_source_set_priority(m->notify_socket_event_source, SD_EVENT_PRIORITY_NORMAL - 5);
1203 if (r < 0)
1204 return log_error_errno(r, "Failed to alter priority of NOTIFY_SOCKET event source: %m");
1205
1206 r = sd_event_source_set_io_fd_own(m->notify_socket_event_source, true);
1207 if (r < 0)
1208 return log_error_errno(r, "Failed to pass ownership of notify socket: %m");
1209
1210 return TAKE_FD(fd);
1211 }
1212
1213 static int manager_add_device(Manager *m, sd_device *d) {
1214 _cleanup_free_ char *user_name = NULL, *realm = NULL, *node = NULL;
1215 const char *tabletype, *parttype, *partname, *partuuid, *sysfs;
1216 sd_id128_t id;
1217 int r;
1218
1219 assert(m);
1220 assert(d);
1221
1222 r = sd_device_get_syspath(d, &sysfs);
1223 if (r < 0)
1224 return log_error_errno(r, "Failed to acquire sysfs path of device: %m");
1225
1226 r = sd_device_get_property_value(d, "ID_PART_TABLE_TYPE", &tabletype);
1227 if (r == -ENOENT)
1228 return 0;
1229 if (r < 0)
1230 return log_error_errno(r, "Failed to acquire ID_PART_TABLE_TYPE device property, ignoring: %m");
1231
1232 if (!streq(tabletype, "gpt")) {
1233 log_debug("Found partition (%s) on non-GPT table, ignoring.", sysfs);
1234 return 0;
1235 }
1236
1237 r = sd_device_get_property_value(d, "ID_PART_ENTRY_TYPE", &parttype);
1238 if (r == -ENOENT)
1239 return 0;
1240 if (r < 0)
1241 return log_error_errno(r, "Failed to acquire ID_PART_ENTRY_TYPE device property, ignoring: %m");
1242 r = sd_id128_from_string(parttype, &id);
1243 if (r < 0)
1244 return log_debug_errno(r, "Failed to parse ID_PART_ENTRY_TYPE field '%s', ignoring: %m", parttype);
1245 if (!sd_id128_equal(id, GPT_USER_HOME)) {
1246 log_debug("Found partition (%s) we don't care about, ignoring.", sysfs);
1247 return 0;
1248 }
1249
1250 r = sd_device_get_property_value(d, "ID_PART_ENTRY_NAME", &partname);
1251 if (r < 0)
1252 return log_warning_errno(r, "Failed to acquire ID_PART_ENTRY_NAME device property, ignoring: %m");
1253
1254 r = split_user_name_realm(partname, &user_name, &realm);
1255 if (r == -EINVAL)
1256 return log_warning_errno(r, "Found partition with correct partition type but a non-parsable partition name '%s', ignoring.", partname);
1257 if (r < 0)
1258 return log_error_errno(r, "Failed to validate partition name '%s': %m", partname);
1259
1260 r = sd_device_get_property_value(d, "ID_FS_UUID", &partuuid);
1261 if (r < 0)
1262 return log_warning_errno(r, "Failed to acquire ID_FS_UUID device property, ignoring: %m");
1263
1264 r = sd_id128_from_string(partuuid, &id);
1265 if (r < 0)
1266 return log_warning_errno(r, "Failed to parse ID_FS_UUID field '%s', ignoring: %m", partuuid);
1267
1268 if (asprintf(&node, "/dev/disk/by-uuid/" SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(id)) < 0)
1269 return log_oom();
1270
1271 return manager_add_home_by_image(m, user_name, realm, node, sysfs, USER_LUKS, UID_INVALID);
1272 }
1273
1274 static int manager_on_device(sd_device_monitor *monitor, sd_device *d, void *userdata) {
1275 Manager *m = userdata;
1276 int r;
1277
1278 assert(m);
1279 assert(d);
1280
1281 if (device_for_action(d, SD_DEVICE_REMOVE)) {
1282 const char *sysfs;
1283 Home *h;
1284
1285 r = sd_device_get_syspath(d, &sysfs);
1286 if (r < 0) {
1287 log_warning_errno(r, "Failed to acquire sysfs path from device: %m");
1288 return 0;
1289 }
1290
1291 log_info("block device %s has been removed.", sysfs);
1292
1293 /* Let's see if we previously synthesized a home record from this device, if so, let's just
1294 * revalidate that. Otherwise let's revalidate them all, but asynchronously. */
1295 h = hashmap_get(m->homes_by_sysfs, sysfs);
1296 if (h)
1297 manager_revalidate_image(m, h);
1298 else
1299 manager_enqueue_gc(m, NULL);
1300 } else
1301 (void) manager_add_device(m, d);
1302
1303 (void) bus_manager_emit_auto_login_changed(m);
1304 return 0;
1305 }
1306
1307 static int manager_watch_devices(Manager *m) {
1308 int r;
1309
1310 assert(m);
1311 assert(!m->device_monitor);
1312
1313 r = sd_device_monitor_new(&m->device_monitor);
1314 if (r < 0)
1315 return log_error_errno(r, "Failed to allocate device monitor: %m");
1316
1317 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "block", NULL);
1318 if (r < 0)
1319 return log_error_errno(r, "Failed to configure device monitor match: %m");
1320
1321 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
1322 if (r < 0)
1323 return log_error_errno(r, "Failed to attach device monitor to event loop: %m");
1324
1325 r = sd_device_monitor_start(m->device_monitor, manager_on_device, m);
1326 if (r < 0)
1327 return log_error_errno(r, "Failed to start device monitor: %m");
1328
1329 return 0;
1330 }
1331
1332 static int manager_enumerate_devices(Manager *m) {
1333 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
1334 sd_device *d;
1335 int r;
1336
1337 assert(m);
1338
1339 r = sd_device_enumerator_new(&e);
1340 if (r < 0)
1341 return r;
1342
1343 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
1344 if (r < 0)
1345 return r;
1346
1347 FOREACH_DEVICE(e, d)
1348 (void) manager_add_device(m, d);
1349
1350 return 0;
1351 }
1352
1353 static int manager_load_key_pair(Manager *m) {
1354 _cleanup_(fclosep) FILE *f = NULL;
1355 struct stat st;
1356 int r;
1357
1358 assert(m);
1359
1360 if (m->private_key) {
1361 EVP_PKEY_free(m->private_key);
1362 m->private_key = NULL;
1363 }
1364
1365 r = search_and_fopen_nulstr("local.private", "re", NULL, KEY_PATHS_NULSTR, &f, NULL);
1366 if (r == -ENOENT)
1367 return 0;
1368 if (r < 0)
1369 return log_error_errno(r, "Failed to read private key file: %m");
1370
1371 if (fstat(fileno(f), &st) < 0)
1372 return log_error_errno(errno, "Failed to stat private key file: %m");
1373
1374 r = stat_verify_regular(&st);
1375 if (r < 0)
1376 return log_error_errno(r, "Private key file is not regular: %m");
1377
1378 if (st.st_uid != 0 || (st.st_mode & 0077) != 0)
1379 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Private key file is readable by more than the root user");
1380
1381 m->private_key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
1382 if (!m->private_key)
1383 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to load private key pair");
1384
1385 log_info("Successfully loaded private key pair.");
1386
1387 return 1;
1388 }
1389
1390 DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY_CTX*, EVP_PKEY_CTX_free, NULL);
1391
1392 static int manager_generate_key_pair(Manager *m) {
1393 _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
1394 _cleanup_(unlink_and_freep) char *temp_public = NULL, *temp_private = NULL;
1395 _cleanup_fclose_ FILE *fpublic = NULL, *fprivate = NULL;
1396 int r;
1397
1398 if (m->private_key) {
1399 EVP_PKEY_free(m->private_key);
1400 m->private_key = NULL;
1401 }
1402
1403 ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
1404 if (!ctx)
1405 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate Ed25519 key generation context.");
1406
1407 if (EVP_PKEY_keygen_init(ctx) <= 0)
1408 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize Ed25519 key generation context.");
1409
1410 log_info("Generating key pair for signing local user identity records.");
1411
1412 if (EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
1413 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate Ed25519 key pair");
1414
1415 log_info("Successfully created Ed25519 key pair.");
1416
1417 (void) mkdir_p("/var/lib/systemd/home", 0755);
1418
1419 /* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */
1420 r = fopen_temporary("/var/lib/systemd/home/local.public", &fpublic, &temp_public);
1421 if (r < 0)
1422 return log_error_errno(errno, "Failed to open key file for writing: %m");
1423
1424 if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
1425 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
1426
1427 r = fflush_sync_and_check(fpublic);
1428 if (r < 0)
1429 return log_error_errno(r, "Failed to write private key: %m");
1430
1431 fpublic = safe_fclose(fpublic);
1432
1433 /* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */
1434 r = fopen_temporary("/var/lib/systemd/home/local.private", &fprivate, &temp_private);
1435 if (r < 0)
1436 return log_error_errno(errno, "Failed to open key file for writing: %m");
1437
1438 if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, 0) <= 0)
1439 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
1440
1441 r = fflush_sync_and_check(fprivate);
1442 if (r < 0)
1443 return log_error_errno(r, "Failed to write private key: %m");
1444
1445 fprivate = safe_fclose(fprivate);
1446
1447 /* Both are written now, move them into place */
1448
1449 if (rename(temp_public, "/var/lib/systemd/home/local.public") < 0)
1450 return log_error_errno(errno, "Failed to move public key file into place: %m");
1451 temp_public = mfree(temp_public);
1452
1453 if (rename(temp_private, "/var/lib/systemd/home/local.private") < 0) {
1454 (void) unlink_noerrno("/var/lib/systemd/home/local.public"); /* try to remove the file we already created */
1455 return log_error_errno(errno, "Failed to move private key file into place: %m");
1456 }
1457 temp_private = mfree(temp_private);
1458
1459 r = fsync_path_at(AT_FDCWD, "/var/lib/systemd/home/");
1460 if (r < 0)
1461 log_warning_errno(r, "Failed to sync /var/lib/systemd/home/, ignoring: %m");
1462
1463 return 1;
1464 }
1465
1466 int manager_acquire_key_pair(Manager *m) {
1467 int r;
1468
1469 assert(m);
1470
1471 /* Already there? */
1472 if (m->private_key)
1473 return 1;
1474
1475 /* First try to load key off disk */
1476 r = manager_load_key_pair(m);
1477 if (r != 0)
1478 return r;
1479
1480 /* Didn't work, generate a new one */
1481 return manager_generate_key_pair(m);
1482 }
1483
1484 int manager_sign_user_record(Manager *m, UserRecord *u, UserRecord **ret, sd_bus_error *error) {
1485 int r;
1486
1487 assert(m);
1488 assert(u);
1489 assert(ret);
1490
1491 r = manager_acquire_key_pair(m);
1492 if (r < 0)
1493 return r;
1494 if (r == 0)
1495 return sd_bus_error_set(error, BUS_ERROR_NO_PRIVATE_KEY, "Can't sign without local key.");
1496
1497 return user_record_sign(u, m->private_key, ret);
1498 }
1499
1500 DEFINE_PRIVATE_HASH_OPS_FULL(public_key_hash_ops, char, string_hash_func, string_compare_func, free, EVP_PKEY, EVP_PKEY_free);
1501 DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY*, EVP_PKEY_free, NULL);
1502
1503 static int manager_load_public_key_one(Manager *m, const char *path) {
1504 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
1505 _cleanup_fclose_ FILE *f = NULL;
1506 _cleanup_free_ char *fn = NULL;
1507 struct stat st;
1508 int r;
1509
1510 assert(m);
1511
1512 if (streq(basename(path), "local.public")) /* we already loaded the private key, which includes the public one */
1513 return 0;
1514
1515 f = fopen(path, "re");
1516 if (!f) {
1517 if (errno == ENOENT)
1518 return 0;
1519
1520 return log_error_errno(errno, "Failed to open public key %s: %m", path);
1521 }
1522
1523 if (fstat(fileno(f), &st) < 0)
1524 return log_error_errno(errno, "Failed to stat public key %s: %m", path);
1525
1526 r = stat_verify_regular(&st);
1527 if (r < 0)
1528 return log_error_errno(r, "Public key file %s is not a regular file: %m", path);
1529
1530 if (st.st_uid != 0 || (st.st_mode & 0022) != 0)
1531 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Public key file %s is writable by more than the root user, refusing.", path);
1532
1533 r = hashmap_ensure_allocated(&m->public_keys, &public_key_hash_ops);
1534 if (r < 0)
1535 return log_oom();
1536
1537 pkey = PEM_read_PUBKEY(f, &pkey, NULL, NULL);
1538 if (!pkey)
1539 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key file %s.", path);
1540
1541 fn = strdup(basename(path));
1542 if (!fn)
1543 return log_oom();
1544
1545 r = hashmap_put(m->public_keys, fn, pkey);
1546 if (r < 0)
1547 return log_error_errno(r, "Failed to add public key to set: %m");
1548
1549 TAKE_PTR(fn);
1550 TAKE_PTR(pkey);
1551
1552 return 0;
1553 }
1554
1555 static int manager_load_public_keys(Manager *m) {
1556 _cleanup_strv_free_ char **files = NULL;
1557 char **i;
1558 int r;
1559
1560 assert(m);
1561
1562 m->public_keys = hashmap_free(m->public_keys);
1563
1564 r = conf_files_list_nulstr(
1565 &files,
1566 ".public",
1567 NULL,
1568 CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
1569 KEY_PATHS_NULSTR);
1570 if (r < 0)
1571 return log_error_errno(r, "Failed to assemble list of public key directories: %m");
1572
1573 STRV_FOREACH(i, files)
1574 (void) manager_load_public_key_one(m, *i);
1575
1576 return 0;
1577 }
1578
1579 int manager_startup(Manager *m) {
1580 int r;
1581
1582 assert(m);
1583
1584 r = manager_listen_notify(m);
1585 if (r < 0)
1586 return r;
1587
1588 r = manager_connect_bus(m);
1589 if (r < 0)
1590 return r;
1591
1592 r = manager_bind_varlink(m);
1593 if (r < 0)
1594 return r;
1595
1596 r = manager_load_key_pair(m); /* only try to load it, don't generate any */
1597 if (r < 0)
1598 return r;
1599
1600 r = manager_load_public_keys(m);
1601 if (r < 0)
1602 return r;
1603
1604 manager_watch_home(m);
1605 (void) manager_watch_devices(m);
1606
1607 (void) manager_enumerate_records(m);
1608 (void) manager_enumerate_images(m);
1609 (void) manager_enumerate_devices(m);
1610
1611 /* Let's clean up home directories whose devices got removed while we were not running */
1612 (void) manager_enqueue_gc(m, NULL);
1613
1614 return 0;
1615 }
1616
1617 void manager_revalidate_image(Manager *m, Home *h) {
1618 int r;
1619
1620 assert(m);
1621 assert(h);
1622
1623 /* Frees an automatically discovered image, if it's synthetic and its image disappeared. Unmounts any
1624 * image if it's mounted but it's image vanished. */
1625
1626 if (h->current_operation || !ordered_set_isempty(h->pending_operations))
1627 return;
1628
1629 if (h->state == HOME_UNFIXATED) {
1630 r = user_record_test_image_path(h->record);
1631 if (r < 0)
1632 log_warning_errno(r, "Can't determine if image of %s exists, freeing unfixated user: %m", h->user_name);
1633 else if (r == USER_TEST_ABSENT)
1634 log_info("Image for %s disappeared, freeing unfixated user.", h->user_name);
1635 else
1636 return;
1637
1638 home_free(h);
1639
1640 } else if (h->state < 0) {
1641
1642 r = user_record_test_home_directory(h->record);
1643 if (r < 0) {
1644 log_warning_errno(r, "Unable to determine state of home directory, ignoring: %m");
1645 return;
1646 }
1647
1648 if (r == USER_TEST_MOUNTED) {
1649 r = user_record_test_image_path(h->record);
1650 if (r < 0) {
1651 log_warning_errno(r, "Unable to determine state of image path, ignoring: %m");
1652 return;
1653 }
1654
1655 if (r == USER_TEST_ABSENT) {
1656 _cleanup_(operation_unrefp) Operation *o = NULL;
1657
1658 log_notice("Backing image disappeared while home directory %s was mounted, unmounting it forcibly.", h->user_name);
1659 /* Wowza, the thing is mounted, but the device is gone? Act on it. */
1660
1661 r = home_killall(h);
1662 if (r < 0)
1663 log_warning_errno(r, "Failed to kill processes of user %s, ignoring: %m", h->user_name);
1664
1665 /* We enqueue the operation here, after all the home directory might
1666 * currently already run some operation, and we can deactivate it only after
1667 * that's complete. */
1668 o = operation_new(OPERATION_DEACTIVATE_FORCE, NULL);
1669 if (!o) {
1670 log_oom();
1671 return;
1672 }
1673
1674 r = home_schedule_operation(h, o, NULL);
1675 if (r < 0)
1676 log_warning_errno(r, "Failed to enqueue forced home directory %s deactivation, ignoring: %m", h->user_name);
1677 }
1678 }
1679 }
1680 }
1681
1682 int manager_gc_images(Manager *m) {
1683 Home *h;
1684
1685 assert_se(m);
1686
1687 if (m->gc_focus) {
1688 /* Focus on a specific home */
1689
1690 h = TAKE_PTR(m->gc_focus);
1691 manager_revalidate_image(m, h);
1692 } else {
1693 /* Gc all */
1694
1695 HASHMAP_FOREACH(h, m->homes_by_name)
1696 manager_revalidate_image(m, h);
1697 }
1698
1699 return 0;
1700 }
1701
1702 static int on_deferred_rescan(sd_event_source *s, void *userdata) {
1703 Manager *m = userdata;
1704
1705 assert(m);
1706
1707 m->deferred_rescan_event_source = sd_event_source_disable_unref(m->deferred_rescan_event_source);
1708
1709 manager_enumerate_devices(m);
1710 manager_enumerate_images(m);
1711 return 0;
1712 }
1713
1714 int manager_enqueue_rescan(Manager *m) {
1715 int r;
1716
1717 assert(m);
1718
1719 if (m->deferred_rescan_event_source)
1720 return 0;
1721
1722 if (!m->event)
1723 return 0;
1724
1725 if (IN_SET(sd_event_get_state(m->event), SD_EVENT_FINISHED, SD_EVENT_EXITING))
1726 return 0;
1727
1728 r = sd_event_add_defer(m->event, &m->deferred_rescan_event_source, on_deferred_rescan, m);
1729 if (r < 0)
1730 return log_error_errno(r, "Failed to allocate rescan event source: %m");
1731
1732 r = sd_event_source_set_priority(m->deferred_rescan_event_source, SD_EVENT_PRIORITY_IDLE+1);
1733 if (r < 0)
1734 log_warning_errno(r, "Failed to tweak priority of event source, ignoring: %m");
1735
1736 (void) sd_event_source_set_description(m->deferred_rescan_event_source, "deferred-rescan");
1737 return 1;
1738 }
1739
1740 static int on_deferred_gc(sd_event_source *s, void *userdata) {
1741 Manager *m = userdata;
1742
1743 assert(m);
1744
1745 m->deferred_gc_event_source = sd_event_source_disable_unref(m->deferred_gc_event_source);
1746
1747 manager_gc_images(m);
1748 return 0;
1749 }
1750
1751 int manager_enqueue_gc(Manager *m, Home *focus) {
1752 int r;
1753
1754 assert(m);
1755
1756 /* This enqueues a request to GC dead homes. It may be called with focus=NULL in which case all homes
1757 * will be scanned, or with the parameter set, in which case only that home is checked. */
1758
1759 if (!m->event)
1760 return 0;
1761
1762 if (IN_SET(sd_event_get_state(m->event), SD_EVENT_FINISHED, SD_EVENT_EXITING))
1763 return 0;
1764
1765 /* If a focus home is specified, then remember to focus just on this home. Otherwise invalidate any
1766 * focus that might be set to look at all homes. */
1767
1768 if (m->deferred_gc_event_source) {
1769 if (m->gc_focus != focus) /* not the same focus, then look at everything */
1770 m->gc_focus = NULL;
1771
1772 return 0;
1773 } else
1774 m->gc_focus = focus; /* start focused */
1775
1776 r = sd_event_add_defer(m->event, &m->deferred_gc_event_source, on_deferred_gc, m);
1777 if (r < 0)
1778 return log_error_errno(r, "Failed to allocate GC event source: %m");
1779
1780 r = sd_event_source_set_priority(m->deferred_gc_event_source, SD_EVENT_PRIORITY_IDLE);
1781 if (r < 0)
1782 log_warning_errno(r, "Failed to tweak priority of event source, ignoring: %m");
1783
1784 (void) sd_event_source_set_description(m->deferred_gc_event_source, "deferred-gc");
1785 return 1;
1786 }
1787
1788 static bool manager_shall_rebalance(Manager *m) {
1789 Home *h;
1790
1791 assert(m);
1792
1793 if (IN_SET(m->rebalance_state, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING))
1794 return true;
1795
1796 HASHMAP_FOREACH(h, m->homes_by_name)
1797 if (home_shall_rebalance(h))
1798 return true;
1799
1800 return false;
1801 }
1802
1803 static int home_cmp(Home *const*a, Home *const*b) {
1804 int r;
1805
1806 assert(a);
1807 assert(*a);
1808 assert(b);
1809 assert(*b);
1810
1811 /* Order user records by their weight (and by their name, to make things stable). We put the records
1812 * with the highest weight last, since we distribute space from the beginning and round down, hence
1813 * later entries tend to get slightly more than earlier entries. */
1814
1815 r = CMP(user_record_rebalance_weight((*a)->record), user_record_rebalance_weight((*b)->record));
1816 if (r != 0)
1817 return r;
1818
1819 return strcmp((*a)->user_name, (*b)->user_name);
1820 }
1821
1822 static int manager_rebalance_calculate(Manager *m) {
1823 uint64_t weight_sum, free_sum, usage_sum = 0, min_free = UINT64_MAX;
1824 _cleanup_free_ Home **array = NULL;
1825 bool relevant = false;
1826 struct statfs sfs;
1827 int c = 0, r;
1828 Home *h;
1829
1830 assert(m);
1831
1832 if (statfs(get_home_root(), &sfs) < 0)
1833 return log_error_errno(errno, "Failed to statfs() /home: %m");
1834
1835 free_sum = (uint64_t) sfs.f_bsize * sfs.f_bavail; /* This much free space is available on the
1836 * underlying pool directory */
1837
1838 weight_sum = REBALANCE_WEIGHT_BACKING; /* Grant the underlying pool directory a fixed weight of 20
1839 * (home dirs get 100 by default, i.e. 5x more). This weight
1840 * is not configurable, the per-home weights are. */
1841
1842 HASHMAP_FOREACH(h, m->homes_by_name) {
1843 statfs_f_type_t fstype;
1844 h->rebalance_pending = false; /* First, reset the flag, we only want it to be true for the
1845 * homes that qualify for rebalancing */
1846
1847 if (!home_shall_rebalance(h)) /* Only look at actual candidates */
1848 continue;
1849
1850 if (home_is_busy(h))
1851 return -EBUSY; /* Let's not rebalance if there's a busy home directory. */
1852
1853 r = home_get_disk_status(
1854 h,
1855 &h->rebalance_size,
1856 &h->rebalance_usage,
1857 &h->rebalance_free,
1858 NULL,
1859 NULL,
1860 &fstype,
1861 NULL);
1862 if (r < 0) {
1863 log_warning_errno(r, "Failed to get free space of home '%s', ignoring.", h->user_name);
1864 continue;
1865 }
1866
1867 if (h->rebalance_free > UINT64_MAX - free_sum)
1868 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Rebalance free overflow");
1869 free_sum += h->rebalance_free;
1870
1871 if (h->rebalance_usage > UINT64_MAX - usage_sum)
1872 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Rebalance usage overflow");
1873 usage_sum += h->rebalance_usage;
1874
1875 h->rebalance_weight = user_record_rebalance_weight(h->record);
1876 if (h->rebalance_weight > UINT64_MAX - weight_sum)
1877 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Rebalance weight overflow");
1878 weight_sum += h->rebalance_weight;
1879
1880 h->rebalance_min = minimal_size_by_fs_magic(fstype);
1881
1882 if (!GREEDY_REALLOC(array, c+1))
1883 return log_oom();
1884
1885 array[c++] = h;
1886 }
1887
1888 if (c == 0) {
1889 log_debug("No homes to rebalance.");
1890 return 0;
1891 }
1892
1893 assert(weight_sum > 0);
1894
1895 log_debug("Disk space usage by all home directories to rebalance: %s — available disk space: %s",
1896 FORMAT_BYTES(usage_sum), FORMAT_BYTES(free_sum));
1897
1898 /* Bring the home directories in a well-defined order, so that we distribute space in a reproducible
1899 * way for the same parameters. */
1900 typesafe_qsort(array, c, home_cmp);
1901
1902 for (int i = 0; i < c; i++) {
1903 uint64_t new_free;
1904 double d;
1905
1906 h = array[i];
1907
1908 assert(h->rebalance_free <= free_sum);
1909 assert(h->rebalance_usage <= usage_sum);
1910 assert(h->rebalance_weight <= weight_sum);
1911
1912 d = ((double) (free_sum / 4096) * (double) h->rebalance_weight) / (double) weight_sum; /* Calculate new space for this home in units of 4K */
1913
1914 /* Convert from units of 4K back to bytes */
1915 if (d >= (double) (UINT64_MAX/4096))
1916 new_free = UINT64_MAX;
1917 else
1918 new_free = (uint64_t) d * 4096;
1919
1920 /* Subtract the weight and assigned space from the sums now, to distribute the rounding noise
1921 * to the remaining home dirs */
1922 free_sum = LESS_BY(free_sum, new_free);
1923 weight_sum = LESS_BY(weight_sum, h->rebalance_weight);
1924
1925 /* Keep track of home directory with the least amount of space left: we want to schedule the
1926 * next rebalance more quickly if this is low */
1927 if (new_free < min_free)
1928 min_free = h->rebalance_size;
1929
1930 if (new_free > UINT64_MAX - h->rebalance_usage)
1931 h->rebalance_goal = UINT64_MAX-1; /* maximum size */
1932 else {
1933 h->rebalance_goal = h->rebalance_usage + new_free;
1934
1935 if (h->rebalance_min != UINT64_MAX && h->rebalance_goal < h->rebalance_min)
1936 h->rebalance_goal = h->rebalance_min;
1937 }
1938
1939 /* Skip over this home if the state doesn't match the operation */
1940 if ((m->rebalance_state == REBALANCE_SHRINKING && h->rebalance_goal > h->rebalance_size) ||
1941 (m->rebalance_state == REBALANCE_GROWING && h->rebalance_goal < h->rebalance_size))
1942 h->rebalance_pending = false;
1943 else {
1944 log_debug("Rebalancing home directory '%s' %s → %s.", h->user_name,
1945 FORMAT_BYTES(h->rebalance_size), FORMAT_BYTES(h->rebalance_goal));
1946 h->rebalance_pending = true;
1947 }
1948
1949 if ((fabs((double) h->rebalance_size - (double) h->rebalance_goal) * 100 / (double) h->rebalance_size) >= 5.0)
1950 relevant = true;
1951 }
1952
1953 /* Scale next rebalancing interval based on the least amount of space of any of the home
1954 * directories. We pick a time in the range 1min … 15min, scaled by log2(min_free), so that:
1955 * 10M → ~0.7min, 100M → ~2.7min, 1G → ~4.6min, 10G → ~6.5min, 100G ~8.4 */
1956 m->rebalance_interval_usec = (usec_t) CLAMP((LESS_BY(log2(min_free), 22)*15*USEC_PER_MINUTE)/26,
1957 1 * USEC_PER_MINUTE,
1958 15 * USEC_PER_MINUTE);
1959
1960
1961 log_debug("Rebalancing interval set to %s.", FORMAT_TIMESPAN(m->rebalance_interval_usec, USEC_PER_MSEC));
1962
1963 /* Let's suppress small resizes, growing/shrinking file systems isn't free after all */
1964 if (!relevant) {
1965 log_debug("Skipping rebalancing, since all calculated size changes are below ±5%%.");
1966 return 0;
1967 }
1968
1969 return c;
1970 }
1971
1972 static int manager_rebalance_apply(Manager *m) {
1973 int c = 0, r;
1974 Home *h;
1975
1976 assert(m);
1977
1978 HASHMAP_FOREACH(h, m->homes_by_name) {
1979 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1980
1981 if (!h->rebalance_pending)
1982 continue;
1983
1984 h->rebalance_pending = false;
1985
1986 r = home_resize(h, h->rebalance_goal, /* secret= */ NULL, /* automatic= */ true, &error);
1987 if (r < 0)
1988 log_warning_errno(r, "Failed to resize home '%s' for rebalancing, ignoring: %s",
1989 h->user_name, bus_error_message(&error, r));
1990 else
1991 c++;
1992 }
1993
1994 return c;
1995 }
1996
1997 static void manager_rebalance_reply_messages(Manager *m) {
1998 int r;
1999
2000 assert(m);
2001
2002 for (;;) {
2003 _cleanup_(sd_bus_message_unrefp) sd_bus_message *msg =
2004 set_steal_first(m->rebalance_pending_method_calls);
2005
2006 if (!msg)
2007 break;
2008
2009 r = sd_bus_reply_method_return(msg, NULL);
2010 if (r < 0)
2011 log_debug_errno(r, "Failed to reply to rebalance method call, ignoring: %m");
2012 }
2013 }
2014
2015 static int manager_rebalance_now(Manager *m) {
2016 RebalanceState busy_state; /* the state to revert to when operation fails if busy */
2017 int r;
2018
2019 assert(m);
2020
2021 log_debug("Rebalancing now...");
2022
2023 /* We maintain a simple state engine here to keep track of what we are doing. We'll first shrink all
2024 * homes that shall be shrunk and then grow all homes that shall be grown, so that they can take up
2025 * the space now freed. */
2026
2027 for (;;) {
2028 switch (m->rebalance_state) {
2029
2030 case REBALANCE_IDLE:
2031 case REBALANCE_PENDING:
2032 case REBALANCE_WAITING:
2033 /* First shrink large home dirs */
2034 m->rebalance_state = REBALANCE_SHRINKING;
2035 busy_state = REBALANCE_PENDING;
2036
2037 /* We are initiating the next rebalancing cycle now, let's make the queued methods
2038 * calls the pending ones, and flush out any pending ones (which shouldn't exist at
2039 * this time anyway) */
2040 set_clear(m->rebalance_pending_method_calls);
2041 SWAP_TWO(m->rebalance_pending_method_calls, m->rebalance_queued_method_calls);
2042
2043 log_debug("Shrinking phase..");
2044 break;
2045
2046 case REBALANCE_SHRINKING:
2047 /* Then grow small home dirs */
2048 m->rebalance_state = REBALANCE_GROWING;
2049 busy_state = REBALANCE_SHRINKING;
2050 log_debug("Growing phase..");
2051 break;
2052
2053 case REBALANCE_GROWING:
2054 /* Finally, we are done */
2055 log_info("Rebalancing complete.");
2056 m->rebalance_state = REBALANCE_IDLE;
2057 r = 0;
2058 goto finish;
2059
2060 case REBALANCE_OFF:
2061 default:
2062 assert_not_reached();
2063 }
2064
2065 r = manager_rebalance_calculate(m);
2066 if (r == -EBUSY) {
2067 /* Calculations failed because one home directory is currently busy. Revert to a state that
2068 * tells us what to do next. */
2069 log_debug("Can't enter phase, busy.");
2070 m->rebalance_state = busy_state;
2071 return r;
2072 }
2073 if (r < 0)
2074 goto finish;
2075 if (r == 0)
2076 continue; /* got to next step immediately, if there's nothing to do */
2077
2078 r = manager_rebalance_apply(m);
2079 if (r < 0)
2080 goto finish;
2081 if (r > 0)
2082 break; /* At least one resize operation is now pending, we are done for now */
2083
2084 /* If there was nothing to apply, go for next state right-away */
2085 }
2086
2087 return 0;
2088
2089 finish:
2090 /* Reset state and schedule next rebalance */
2091 m->rebalance_state = REBALANCE_IDLE;
2092 manager_rebalance_reply_messages(m);
2093 (void) manager_schedule_rebalance(m, /* immediately= */ false);
2094 return r;
2095 }
2096
2097 static int on_rebalance_timer(sd_event_source *s, usec_t t, void *userdata) {
2098 Manager *m = userdata;
2099
2100 assert(s);
2101 assert(m);
2102 assert(IN_SET(m->rebalance_state, REBALANCE_WAITING, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING));
2103
2104 (void) manager_rebalance_now(m);
2105 return 0;
2106 }
2107
2108 int manager_schedule_rebalance(Manager *m, bool immediately) {
2109 int r;
2110
2111 assert(m);
2112
2113 /* Check if there are any records where rebalancing is requested */
2114 if (!manager_shall_rebalance(m)) {
2115 log_debug("Not scheduling rebalancing, not needed.");
2116 r = 0; /* report that we didn't schedule anything because nothing needed it */
2117 goto turn_off;
2118 }
2119
2120 if (immediately) {
2121 /* If we are told to rebalance immediately, then mark a rebalance as pending (even if we area
2122 * already running one) */
2123
2124 if (m->rebalance_event_source) {
2125 r = sd_event_source_set_time(m->rebalance_event_source, 0);
2126 if (r < 0) {
2127 log_error_errno(r, "Failed to schedule immediate rebalancing: %m");
2128 goto turn_off;
2129 }
2130
2131 r = sd_event_source_set_enabled(m->rebalance_event_source, SD_EVENT_ONESHOT);
2132 if (r < 0) {
2133 log_error_errno(r, "Failed to enable rebalancing event source: %m");
2134 goto turn_off;
2135 }
2136 } else {
2137 r = sd_event_add_time(m->event, &m->rebalance_event_source, CLOCK_MONOTONIC, 0, USEC_PER_SEC, on_rebalance_timer, m);
2138 if (r < 0) {
2139 log_error_errno(r, "Failed to allocate rebalance event source: %m");
2140 goto turn_off;
2141 }
2142
2143 r = sd_event_source_set_priority(m->rebalance_event_source, SD_EVENT_PRIORITY_IDLE + 10);
2144 if (r < 0) {
2145 log_error_errno(r, "Failed to set rebalance event source priority: %m");
2146 goto turn_off;
2147 }
2148
2149 (void) sd_event_source_set_description(m->rebalance_event_source, "rebalance");
2150
2151 }
2152
2153 if (!IN_SET(m->rebalance_state, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING))
2154 m->rebalance_state = REBALANCE_PENDING;
2155
2156 log_debug("Scheduled immediate rebalancing...");
2157 return 1; /* report that we scheduled something */
2158 }
2159
2160 /* If we are told to schedule a rebalancing eventually, then do so only if we are not executing
2161 * anything yet. Also if we have something scheduled already, leave it in place */
2162 if (!IN_SET(m->rebalance_state, REBALANCE_OFF, REBALANCE_IDLE))
2163 return 1; /* report that there's already something scheduled */
2164
2165 if (m->rebalance_event_source) {
2166 r = sd_event_source_set_time_relative(m->rebalance_event_source, m->rebalance_interval_usec);
2167 if (r < 0) {
2168 log_error_errno(r, "Failed to schedule immediate rebalancing: %m");
2169 goto turn_off;
2170 }
2171
2172 r = sd_event_source_set_enabled(m->rebalance_event_source, SD_EVENT_ONESHOT);
2173 if (r < 0) {
2174 log_error_errno(r, "Failed to enable rebalancing event source: %m");
2175 goto turn_off;
2176 }
2177 } else {
2178 r = sd_event_add_time_relative(m->event, &m->rebalance_event_source, CLOCK_MONOTONIC, m->rebalance_interval_usec, USEC_PER_SEC, on_rebalance_timer, m);
2179 if (r < 0) {
2180 log_error_errno(r, "Failed to allocate rebalance event source: %m");
2181 goto turn_off;
2182 }
2183
2184 r = sd_event_source_set_priority(m->rebalance_event_source, SD_EVENT_PRIORITY_IDLE + 10);
2185 if (r < 0) {
2186 log_error_errno(r, "Failed to set rebalance event source priority: %m");
2187 goto turn_off;
2188 }
2189
2190 (void) sd_event_source_set_description(m->rebalance_event_source, "rebalance");
2191 }
2192
2193 m->rebalance_state = REBALANCE_WAITING; /* We managed to enqueue a timer event, we now wait until it fires */
2194 log_debug("Scheduled rebalancing in %s...", FORMAT_TIMESPAN(m->rebalance_interval_usec, 0));
2195 return 1; /* report that we scheduled something */
2196
2197 turn_off:
2198 m->rebalance_event_source = sd_event_source_disable_unref(m->rebalance_event_source);
2199 m->rebalance_state = REBALANCE_OFF;
2200 manager_rebalance_reply_messages(m);
2201 return r;
2202 }
2203
2204 int manager_reschedule_rebalance(Manager *m) {
2205 int r;
2206
2207 assert(m);
2208
2209 /* If a rebalance is pending reschedules it so it gets executed immediately */
2210
2211 if (!IN_SET(m->rebalance_state, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING))
2212 return 0;
2213
2214 r = manager_schedule_rebalance(m, /* immediately= */ true);
2215 if (r < 0)
2216 return r;
2217
2218 return 1;
2219 }