]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/machine/machined-dbus.c
Merge pull request #7395 from poettering/nametohandleat-loop
[thirdparty/systemd.git] / src / machine / machined-dbus.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2011 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "sd-id128.h"
26
27 #include "alloc-util.h"
28 #include "btrfs-util.h"
29 #include "bus-common-errors.h"
30 #include "bus-util.h"
31 #include "cgroup-util.h"
32 #include "fd-util.h"
33 #include "fileio.h"
34 #include "format-util.h"
35 #include "hostname-util.h"
36 #include "image-dbus.h"
37 #include "io-util.h"
38 #include "machine-dbus.h"
39 #include "machine-image.h"
40 #include "machine-pool.h"
41 #include "machined.h"
42 #include "path-util.h"
43 #include "process-util.h"
44 #include "stdio-util.h"
45 #include "strv.h"
46 #include "unit-name.h"
47 #include "user-util.h"
48
49 static int property_get_pool_path(
50 sd_bus *bus,
51 const char *path,
52 const char *interface,
53 const char *property,
54 sd_bus_message *reply,
55 void *userdata,
56 sd_bus_error *error) {
57
58 assert(bus);
59 assert(reply);
60
61 return sd_bus_message_append(reply, "s", "/var/lib/machines");
62 }
63
64 static int property_get_pool_usage(
65 sd_bus *bus,
66 const char *path,
67 const char *interface,
68 const char *property,
69 sd_bus_message *reply,
70 void *userdata,
71 sd_bus_error *error) {
72
73 _cleanup_close_ int fd = -1;
74 uint64_t usage = (uint64_t) -1;
75 struct stat st;
76
77 assert(bus);
78 assert(reply);
79
80 /* We try to read the quota info from /var/lib/machines, as
81 * well as the usage of the loopback file
82 * /var/lib/machines.raw, and pick the larger value. */
83
84 fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
85 if (fd >= 0) {
86 BtrfsQuotaInfo q;
87
88 if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
89 usage = q.referenced;
90 }
91
92 if (stat("/var/lib/machines.raw", &st) >= 0) {
93 if (usage == (uint64_t) -1 || st.st_blocks * 512ULL > usage)
94 usage = st.st_blocks * 512ULL;
95 }
96
97 return sd_bus_message_append(reply, "t", usage);
98 }
99
100 static int property_get_pool_limit(
101 sd_bus *bus,
102 const char *path,
103 const char *interface,
104 const char *property,
105 sd_bus_message *reply,
106 void *userdata,
107 sd_bus_error *error) {
108
109 _cleanup_close_ int fd = -1;
110 uint64_t size = (uint64_t) -1;
111 struct stat st;
112
113 assert(bus);
114 assert(reply);
115
116 /* We try to read the quota limit from /var/lib/machines, as
117 * well as the size of the loopback file
118 * /var/lib/machines.raw, and pick the smaller value. */
119
120 fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
121 if (fd >= 0) {
122 BtrfsQuotaInfo q;
123
124 if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
125 size = q.referenced_max;
126 }
127
128 if (stat("/var/lib/machines.raw", &st) >= 0) {
129 if (size == (uint64_t) -1 || (uint64_t) st.st_size < size)
130 size = st.st_size;
131 }
132
133 return sd_bus_message_append(reply, "t", size);
134 }
135
136 static int method_get_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
137 _cleanup_free_ char *p = NULL;
138 Manager *m = userdata;
139 Machine *machine;
140 const char *name;
141 int r;
142
143 assert(message);
144 assert(m);
145
146 r = sd_bus_message_read(message, "s", &name);
147 if (r < 0)
148 return r;
149
150 machine = hashmap_get(m->machines, name);
151 if (!machine)
152 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
153
154 p = machine_bus_path(machine);
155 if (!p)
156 return -ENOMEM;
157
158 return sd_bus_reply_method_return(message, "o", p);
159 }
160
161 static int method_get_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
162 _cleanup_free_ char *p = NULL;
163 Manager *m = userdata;
164 const char *name;
165 int r;
166
167 assert(message);
168 assert(m);
169
170 r = sd_bus_message_read(message, "s", &name);
171 if (r < 0)
172 return r;
173
174 r = image_find(name, NULL);
175 if (r == 0)
176 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
177 if (r < 0)
178 return r;
179
180 p = image_bus_path(name);
181 if (!p)
182 return -ENOMEM;
183
184 return sd_bus_reply_method_return(message, "o", p);
185 }
186
187 static int method_get_machine_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
188 _cleanup_free_ char *p = NULL;
189 Manager *m = userdata;
190 Machine *machine = NULL;
191 pid_t pid;
192 int r;
193
194 assert(message);
195 assert(m);
196
197 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
198
199 r = sd_bus_message_read(message, "u", &pid);
200 if (r < 0)
201 return r;
202
203 if (pid < 0)
204 return -EINVAL;
205
206 if (pid == 0) {
207 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
208
209 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
210 if (r < 0)
211 return r;
212
213 r = sd_bus_creds_get_pid(creds, &pid);
214 if (r < 0)
215 return r;
216 }
217
218 r = manager_get_machine_by_pid(m, pid, &machine);
219 if (r < 0)
220 return r;
221 if (!machine)
222 return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID "PID_FMT" does not belong to any known machine", pid);
223
224 p = machine_bus_path(machine);
225 if (!p)
226 return -ENOMEM;
227
228 return sd_bus_reply_method_return(message, "o", p);
229 }
230
231 static int method_list_machines(sd_bus_message *message, void *userdata, sd_bus_error *error) {
232 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
233 Manager *m = userdata;
234 Machine *machine;
235 Iterator i;
236 int r;
237
238 assert(message);
239 assert(m);
240
241 r = sd_bus_message_new_method_return(message, &reply);
242 if (r < 0)
243 return sd_bus_error_set_errno(error, r);
244
245 r = sd_bus_message_open_container(reply, 'a', "(ssso)");
246 if (r < 0)
247 return sd_bus_error_set_errno(error, r);
248
249 HASHMAP_FOREACH(machine, m->machines, i) {
250 _cleanup_free_ char *p = NULL;
251
252 p = machine_bus_path(machine);
253 if (!p)
254 return -ENOMEM;
255
256 r = sd_bus_message_append(reply, "(ssso)",
257 machine->name,
258 strempty(machine_class_to_string(machine->class)),
259 machine->service,
260 p);
261 if (r < 0)
262 return sd_bus_error_set_errno(error, r);
263 }
264
265 r = sd_bus_message_close_container(reply);
266 if (r < 0)
267 return sd_bus_error_set_errno(error, r);
268
269 return sd_bus_send(NULL, reply, NULL);
270 }
271
272 static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) {
273 const char *name, *service, *class, *root_directory;
274 const int32_t *netif = NULL;
275 MachineClass c;
276 uint32_t leader;
277 sd_id128_t id;
278 const void *v;
279 Machine *m;
280 size_t n, n_netif = 0;
281 int r;
282
283 assert(manager);
284 assert(message);
285 assert(_m);
286
287 r = sd_bus_message_read(message, "s", &name);
288 if (r < 0)
289 return r;
290 if (!machine_name_is_valid(name))
291 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine name");
292
293 r = sd_bus_message_read_array(message, 'y', &v, &n);
294 if (r < 0)
295 return r;
296 if (n == 0)
297 id = SD_ID128_NULL;
298 else if (n == 16)
299 memcpy(&id, v, n);
300 else
301 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine ID parameter");
302
303 r = sd_bus_message_read(message, "ssus", &service, &class, &leader, &root_directory);
304 if (r < 0)
305 return r;
306
307 if (read_network) {
308 size_t i;
309
310 r = sd_bus_message_read_array(message, 'i', (const void**) &netif, &n_netif);
311 if (r < 0)
312 return r;
313
314 n_netif /= sizeof(int32_t);
315
316 for (i = 0; i < n_netif; i++) {
317 if (netif[i] <= 0)
318 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid network interface index %i", netif[i]);
319 }
320 }
321
322 if (isempty(class))
323 c = _MACHINE_CLASS_INVALID;
324 else {
325 c = machine_class_from_string(class);
326 if (c < 0)
327 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine class parameter");
328 }
329
330 if (leader == 1)
331 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
332
333 if (!isempty(root_directory) && !path_is_absolute(root_directory))
334 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
335
336 if (leader == 0) {
337 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
338
339 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
340 if (r < 0)
341 return r;
342
343 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
344
345 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
346 if (r < 0)
347 return r;
348 }
349
350 if (hashmap_get(manager->machines, name))
351 return sd_bus_error_setf(error, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name);
352
353 r = manager_add_machine(manager, name, &m);
354 if (r < 0)
355 return r;
356
357 m->leader = leader;
358 m->class = c;
359 m->id = id;
360
361 if (!isempty(service)) {
362 m->service = strdup(service);
363 if (!m->service) {
364 r = -ENOMEM;
365 goto fail;
366 }
367 }
368
369 if (!isempty(root_directory)) {
370 m->root_directory = strdup(root_directory);
371 if (!m->root_directory) {
372 r = -ENOMEM;
373 goto fail;
374 }
375 }
376
377 if (n_netif > 0) {
378 assert_cc(sizeof(int32_t) == sizeof(int));
379 m->netif = memdup(netif, sizeof(int32_t) * n_netif);
380 if (!m->netif) {
381 r = -ENOMEM;
382 goto fail;
383 }
384
385 m->n_netif = n_netif;
386 }
387
388 *_m = m;
389
390 return 1;
391
392 fail:
393 machine_add_to_gc_queue(m);
394 return r;
395 }
396
397 static int method_create_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
398 Manager *manager = userdata;
399 Machine *m = NULL;
400 int r;
401
402 assert(message);
403 assert(manager);
404
405 r = method_create_or_register_machine(manager, message, read_network, &m, error);
406 if (r < 0)
407 return r;
408
409 r = sd_bus_message_enter_container(message, 'a', "(sv)");
410 if (r < 0)
411 goto fail;
412
413 r = machine_start(m, message, error);
414 if (r < 0)
415 goto fail;
416
417 m->create_message = sd_bus_message_ref(message);
418 return 1;
419
420 fail:
421 machine_add_to_gc_queue(m);
422 return r;
423 }
424
425 static int method_create_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
426 return method_create_machine_internal(message, true, userdata, error);
427 }
428
429 static int method_create_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
430 return method_create_machine_internal(message, false, userdata, error);
431 }
432
433 static int method_register_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
434 Manager *manager = userdata;
435 _cleanup_free_ char *p = NULL;
436 Machine *m = NULL;
437 int r;
438
439 assert(message);
440 assert(manager);
441
442 r = method_create_or_register_machine(manager, message, read_network, &m, error);
443 if (r < 0)
444 return r;
445
446 r = cg_pid_get_unit(m->leader, &m->unit);
447 if (r < 0) {
448 r = sd_bus_error_set_errnof(error, r,
449 "Failed to determine unit of process "PID_FMT" : %m",
450 m->leader);
451 goto fail;
452 }
453
454 r = machine_start(m, NULL, error);
455 if (r < 0)
456 goto fail;
457
458 p = machine_bus_path(m);
459 if (!p) {
460 r = -ENOMEM;
461 goto fail;
462 }
463
464 return sd_bus_reply_method_return(message, "o", p);
465
466 fail:
467 machine_add_to_gc_queue(m);
468 return r;
469 }
470
471 static int method_register_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
472 return method_register_machine_internal(message, true, userdata, error);
473 }
474
475 static int method_register_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
476 return method_register_machine_internal(message, false, userdata, error);
477 }
478
479 static int method_terminate_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
480 Manager *m = userdata;
481 Machine *machine;
482 const char *name;
483 int r;
484
485 assert(message);
486 assert(m);
487
488 r = sd_bus_message_read(message, "s", &name);
489 if (r < 0)
490 return sd_bus_error_set_errno(error, r);
491
492 machine = hashmap_get(m->machines, name);
493 if (!machine)
494 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
495
496 return bus_machine_method_terminate(message, machine, error);
497 }
498
499 static int method_kill_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
500 Manager *m = userdata;
501 Machine *machine;
502 const char *name;
503 int r;
504
505 assert(message);
506 assert(m);
507
508 r = sd_bus_message_read(message, "s", &name);
509 if (r < 0)
510 return sd_bus_error_set_errno(error, r);
511
512 machine = hashmap_get(m->machines, name);
513 if (!machine)
514 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
515
516 return bus_machine_method_kill(message, machine, error);
517 }
518
519 static int method_get_machine_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error) {
520 Manager *m = userdata;
521 Machine *machine;
522 const char *name;
523 int r;
524
525 assert(message);
526 assert(m);
527
528 r = sd_bus_message_read(message, "s", &name);
529 if (r < 0)
530 return sd_bus_error_set_errno(error, r);
531
532 machine = hashmap_get(m->machines, name);
533 if (!machine)
534 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
535
536 return bus_machine_method_get_addresses(message, machine, error);
537 }
538
539 static int method_get_machine_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
540 Manager *m = userdata;
541 Machine *machine;
542 const char *name;
543 int r;
544
545 assert(message);
546 assert(m);
547
548 r = sd_bus_message_read(message, "s", &name);
549 if (r < 0)
550 return sd_bus_error_set_errno(error, r);
551
552 machine = hashmap_get(m->machines, name);
553 if (!machine)
554 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
555
556 return bus_machine_method_get_os_release(message, machine, error);
557 }
558
559 static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_error *error) {
560 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
561 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
562 Manager *m = userdata;
563 Image *image;
564 Iterator i;
565 int r;
566
567 assert(message);
568 assert(m);
569
570 images = hashmap_new(&string_hash_ops);
571 if (!images)
572 return -ENOMEM;
573
574 r = image_discover(images);
575 if (r < 0)
576 return r;
577
578 r = sd_bus_message_new_method_return(message, &reply);
579 if (r < 0)
580 return r;
581
582 r = sd_bus_message_open_container(reply, 'a', "(ssbttto)");
583 if (r < 0)
584 return r;
585
586 HASHMAP_FOREACH(image, images, i) {
587 _cleanup_free_ char *p = NULL;
588
589 p = image_bus_path(image->name);
590 if (!p)
591 return -ENOMEM;
592
593 r = sd_bus_message_append(reply, "(ssbttto)",
594 image->name,
595 image_type_to_string(image->type),
596 image->read_only,
597 image->crtime,
598 image->mtime,
599 image->usage,
600 p);
601 if (r < 0)
602 return r;
603 }
604
605 r = sd_bus_message_close_container(reply);
606 if (r < 0)
607 return r;
608
609 return sd_bus_send(NULL, reply, NULL);
610 }
611
612 static int method_open_machine_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
613 Manager *m = userdata;
614 Machine *machine;
615 const char *name;
616 int r;
617
618 assert(message);
619 assert(m);
620
621 r = sd_bus_message_read(message, "s", &name);
622 if (r < 0)
623 return sd_bus_error_set_errno(error, r);
624
625 machine = hashmap_get(m->machines, name);
626 if (!machine)
627 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
628
629 return bus_machine_method_open_pty(message, machine, error);
630 }
631
632 static int method_open_machine_login(sd_bus_message *message, void *userdata, sd_bus_error *error) {
633 Manager *m = userdata;
634 Machine *machine;
635 const char *name;
636 int r;
637
638 assert(message);
639 assert(m);
640
641 r = sd_bus_message_read(message, "s", &name);
642 if (r < 0)
643 return r;
644
645 machine = hashmap_get(m->machines, name);
646 if (!machine)
647 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
648
649 return bus_machine_method_open_login(message, machine, error);
650 }
651
652 static int method_open_machine_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) {
653 Manager *m = userdata;
654 Machine *machine;
655 const char *name;
656
657 int r;
658
659 assert(message);
660 assert(m);
661
662 r = sd_bus_message_read(message, "s", &name);
663 if (r < 0)
664 return r;
665
666 machine = hashmap_get(m->machines, name);
667 if (!machine)
668 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
669
670 return bus_machine_method_open_shell(message, machine, error);
671 }
672
673 static int method_bind_mount_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
674 Manager *m = userdata;
675 Machine *machine;
676 const char *name;
677 int r;
678
679 assert(message);
680 assert(m);
681
682 r = sd_bus_message_read(message, "s", &name);
683 if (r < 0)
684 return r;
685
686 machine = hashmap_get(m->machines, name);
687 if (!machine)
688 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
689
690 return bus_machine_method_bind_mount(message, machine, error);
691 }
692
693 static int method_copy_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
694 Manager *m = userdata;
695 Machine *machine;
696 const char *name;
697 int r;
698
699 assert(message);
700 assert(m);
701
702 r = sd_bus_message_read(message, "s", &name);
703 if (r < 0)
704 return r;
705
706 machine = hashmap_get(m->machines, name);
707 if (!machine)
708 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
709
710 return bus_machine_method_copy(message, machine, error);
711 }
712
713 static int method_open_machine_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) {
714 Manager *m = userdata;
715 Machine *machine;
716 const char *name;
717 int r;
718
719 assert(message);
720 assert(m);
721
722 r = sd_bus_message_read(message, "s", &name);
723 if (r < 0)
724 return r;
725
726 machine = hashmap_get(m->machines, name);
727 if (!machine)
728 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
729
730 return bus_machine_method_open_root_directory(message, machine, error);
731 }
732
733 static int method_get_machine_uid_shift(sd_bus_message *message, void *userdata, sd_bus_error *error) {
734 Manager *m = userdata;
735 Machine *machine;
736 const char *name;
737 int r;
738
739 assert(message);
740 assert(m);
741
742 r = sd_bus_message_read(message, "s", &name);
743 if (r < 0)
744 return r;
745
746 machine = hashmap_get(m->machines, name);
747 if (!machine)
748 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
749
750 return bus_machine_method_get_uid_shift(message, machine, error);
751 }
752
753 static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
754 _cleanup_(image_unrefp) Image* i = NULL;
755 const char *name;
756 int r;
757
758 assert(message);
759
760 r = sd_bus_message_read(message, "s", &name);
761 if (r < 0)
762 return r;
763
764 if (!image_name_is_valid(name))
765 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
766
767 r = image_find(name, &i);
768 if (r < 0)
769 return r;
770 if (r == 0)
771 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
772
773 i->userdata = userdata;
774 return bus_image_method_remove(message, i, error);
775 }
776
777 static int method_rename_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
778 _cleanup_(image_unrefp) Image* i = NULL;
779 const char *old_name;
780 int r;
781
782 assert(message);
783
784 r = sd_bus_message_read(message, "s", &old_name);
785 if (r < 0)
786 return r;
787
788 if (!image_name_is_valid(old_name))
789 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
790
791 r = image_find(old_name, &i);
792 if (r < 0)
793 return r;
794 if (r == 0)
795 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
796
797 i->userdata = userdata;
798 return bus_image_method_rename(message, i, error);
799 }
800
801 static int method_clone_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
802 _cleanup_(image_unrefp) Image *i = NULL;
803 const char *old_name;
804 int r;
805
806 assert(message);
807
808 r = sd_bus_message_read(message, "s", &old_name);
809 if (r < 0)
810 return r;
811
812 if (!image_name_is_valid(old_name))
813 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
814
815 r = image_find(old_name, &i);
816 if (r < 0)
817 return r;
818 if (r == 0)
819 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
820
821 i->userdata = userdata;
822 return bus_image_method_clone(message, i, error);
823 }
824
825 static int method_mark_image_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error) {
826 _cleanup_(image_unrefp) Image *i = NULL;
827 const char *name;
828 int r;
829
830 assert(message);
831
832 r = sd_bus_message_read(message, "s", &name);
833 if (r < 0)
834 return r;
835
836 if (!image_name_is_valid(name))
837 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
838
839 r = image_find(name, &i);
840 if (r < 0)
841 return r;
842 if (r == 0)
843 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
844
845 i->userdata = userdata;
846 return bus_image_method_mark_read_only(message, i, error);
847 }
848
849 static int method_get_image_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
850 _cleanup_(image_unrefp) Image *i = NULL;
851 const char *name;
852 int r;
853
854 assert(message);
855
856 r = sd_bus_message_read(message, "s", &name);
857 if (r < 0)
858 return r;
859
860 if (!image_name_is_valid(name))
861 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
862
863 r = image_find(name, &i);
864 if (r < 0)
865 return r;
866 if (r == 0)
867 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
868
869 i->userdata = userdata;
870 return bus_image_method_get_hostname(message, i, error);
871 }
872
873 static int method_get_image_machine_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
874 _cleanup_(image_unrefp) Image *i = NULL;
875 const char *name;
876 int r;
877
878 assert(message);
879
880 r = sd_bus_message_read(message, "s", &name);
881 if (r < 0)
882 return r;
883
884 if (!image_name_is_valid(name))
885 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
886
887 r = image_find(name, &i);
888 if (r < 0)
889 return r;
890 if (r == 0)
891 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
892
893 i->userdata = userdata;
894 return bus_image_method_get_machine_id(message, i, error);
895 }
896
897 static int method_get_image_machine_info(sd_bus_message *message, void *userdata, sd_bus_error *error) {
898 _cleanup_(image_unrefp) Image *i = NULL;
899 const char *name;
900 int r;
901
902 assert(message);
903
904 r = sd_bus_message_read(message, "s", &name);
905 if (r < 0)
906 return r;
907
908 if (!image_name_is_valid(name))
909 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
910
911 r = image_find(name, &i);
912 if (r < 0)
913 return r;
914 if (r == 0)
915 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
916
917 i->userdata = userdata;
918 return bus_image_method_get_machine_info(message, i, error);
919 }
920
921 static int method_get_image_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
922 _cleanup_(image_unrefp) Image *i = NULL;
923 const char *name;
924 int r;
925
926 assert(message);
927
928 r = sd_bus_message_read(message, "s", &name);
929 if (r < 0)
930 return r;
931
932 if (!image_name_is_valid(name))
933 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
934
935 r = image_find(name, &i);
936 if (r < 0)
937 return r;
938 if (r == 0)
939 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
940
941 i->userdata = userdata;
942 return bus_image_method_get_os_release(message, i, error);
943 }
944
945 static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
946 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
947 _cleanup_fclose_ FILE *f = NULL;
948 bool success;
949 size_t n;
950 int r;
951
952 assert(operation);
953 assert(operation->extra_fd >= 0);
954
955 if (lseek(operation->extra_fd, 0, SEEK_SET) == (off_t) -1)
956 return -errno;
957
958 f = fdopen(operation->extra_fd, "re");
959 if (!f)
960 return -errno;
961
962 operation->extra_fd = -1;
963
964 /* The resulting temporary file starts with a boolean value that indicates success or not. */
965 errno = 0;
966 n = fread(&success, 1, sizeof(success), f);
967 if (n != sizeof(success))
968 return ret < 0 ? ret : (errno != 0 ? -errno : -EIO);
969
970 if (ret < 0) {
971 _cleanup_free_ char *name = NULL;
972
973 /* The clean-up operation failed. In this case the resulting temporary file should contain a boolean
974 * set to false followed by the name of the failed image. Let's try to read this and use it for the
975 * error message. If we can't read it, don't mind, and return the naked error. */
976
977 if (success) /* The resulting temporary file could not be updated, ignore it. */
978 return ret;
979
980 r = read_nul_string(f, &name);
981 if (r < 0 || isempty(name)) /* Same here... */
982 return ret;
983
984 return sd_bus_error_set_errnof(error, ret, "Failed to remove image %s: %m", name);
985 }
986
987 assert(success);
988
989 r = sd_bus_message_new_method_return(operation->message, &reply);
990 if (r < 0)
991 return r;
992
993 r = sd_bus_message_open_container(reply, 'a', "(st)");
994 if (r < 0)
995 return r;
996
997 /* On success the resulting temporary file will contain a list of image names that were removed followed by
998 * their size on disk. Let's read that and turn it into a bus message. */
999 for (;;) {
1000 _cleanup_free_ char *name = NULL;
1001 uint64_t size;
1002
1003 r = read_nul_string(f, &name);
1004 if (r < 0)
1005 return r;
1006 if (isempty(name)) /* reached the end */
1007 break;
1008
1009 errno = 0;
1010 n = fread(&size, 1, sizeof(size), f);
1011 if (n != sizeof(size))
1012 return errno != 0 ? -errno : -EIO;
1013
1014 r = sd_bus_message_append(reply, "(st)", name, size);
1015 if (r < 0)
1016 return r;
1017 }
1018
1019 r = sd_bus_message_close_container(reply);
1020 if (r < 0)
1021 return r;
1022
1023 return sd_bus_send(NULL, reply, NULL);
1024 }
1025
1026 static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1027 enum {
1028 REMOVE_ALL,
1029 REMOVE_HIDDEN,
1030 } mode;
1031
1032 _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
1033 _cleanup_close_ int result_fd = -1;
1034 Manager *m = userdata;
1035 Operation *operation;
1036 const char *mm;
1037 pid_t child;
1038 int r;
1039
1040 assert(message);
1041
1042 if (m->n_operations >= OPERATIONS_MAX)
1043 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
1044
1045 r = sd_bus_message_read(message, "s", &mm);
1046 if (r < 0)
1047 return r;
1048
1049 if (streq(mm, "all"))
1050 mode = REMOVE_ALL;
1051 else if (streq(mm, "hidden"))
1052 mode = REMOVE_HIDDEN;
1053 else
1054 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mode '%s'.", mm);
1055
1056 r = bus_verify_polkit_async(
1057 message,
1058 CAP_SYS_ADMIN,
1059 "org.freedesktop.machine1.manage-machines",
1060 NULL,
1061 false,
1062 UID_INVALID,
1063 &m->polkit_registry,
1064 error);
1065 if (r < 0)
1066 return r;
1067 if (r == 0)
1068 return 1; /* Will call us back */
1069
1070 if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
1071 return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
1072
1073 /* Create a temporary file we can dump information about deleted images into. We use a temporary file for this
1074 * instead of a pipe or so, since this might grow quit large in theory and we don't want to process this
1075 * continuously */
1076 result_fd = open_tmpfile_unlinkable(NULL, O_RDWR|O_CLOEXEC);
1077 if (result_fd < 0)
1078 return -errno;
1079
1080 /* This might be a slow operation, run it asynchronously in a background process */
1081 child = fork();
1082 if (child < 0)
1083 return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
1084
1085 if (child == 0) {
1086 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
1087 bool success = true;
1088 Image *image;
1089 Iterator i;
1090 ssize_t l;
1091
1092 errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
1093
1094 images = hashmap_new(&string_hash_ops);
1095 if (!images) {
1096 r = -ENOMEM;
1097 goto child_fail;
1098 }
1099
1100 r = image_discover(images);
1101 if (r < 0)
1102 goto child_fail;
1103
1104 l = write(result_fd, &success, sizeof(success));
1105 if (l < 0) {
1106 r = -errno;
1107 goto child_fail;
1108 }
1109
1110 HASHMAP_FOREACH(image, images, i) {
1111
1112 /* We can't remove vendor images (i.e. those in /usr) */
1113 if (IMAGE_IS_VENDOR(image))
1114 continue;
1115
1116 if (IMAGE_IS_HOST(image))
1117 continue;
1118
1119 if (mode == REMOVE_HIDDEN && !IMAGE_IS_HIDDEN(image))
1120 continue;
1121
1122 r = image_remove(image);
1123 if (r == -EBUSY) /* keep images that are currently being used. */
1124 continue;
1125 if (r < 0) {
1126 /* If the operation failed, let's override everything we wrote, and instead write there at which image we failed. */
1127 success = false;
1128 (void) ftruncate(result_fd, 0);
1129 (void) lseek(result_fd, 0, SEEK_SET);
1130 (void) write(result_fd, &success, sizeof(success));
1131 (void) write(result_fd, image->name, strlen(image->name)+1);
1132 goto child_fail;
1133 }
1134
1135 l = write(result_fd, image->name, strlen(image->name)+1);
1136 if (l < 0) {
1137 r = -errno;
1138 goto child_fail;
1139 }
1140
1141 l = write(result_fd, &image->usage_exclusive, sizeof(image->usage_exclusive));
1142 if (l < 0) {
1143 r = -errno;
1144 goto child_fail;
1145 }
1146 }
1147
1148 result_fd = safe_close(result_fd);
1149 _exit(EXIT_SUCCESS);
1150
1151 child_fail:
1152 (void) write(errno_pipe_fd[1], &r, sizeof(r));
1153 _exit(EXIT_FAILURE);
1154 }
1155
1156 errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
1157
1158 /* The clean-up might take a while, hence install a watch on the child and return */
1159
1160 r = operation_new(m, NULL, child, message, errno_pipe_fd[0], &operation);
1161 if (r < 0) {
1162 (void) sigkill_wait(child);
1163 return r;
1164 }
1165
1166 operation->extra_fd = result_fd;
1167 operation->done = clean_pool_done;
1168
1169 result_fd = -1;
1170 errno_pipe_fd[0] = -1;
1171
1172 return 1;
1173 }
1174
1175 static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1176 Manager *m = userdata;
1177 uint64_t limit;
1178 int r;
1179
1180 assert(message);
1181
1182 r = sd_bus_message_read(message, "t", &limit);
1183 if (r < 0)
1184 return r;
1185 if (!FILE_SIZE_VALID_OR_INFINITY(limit))
1186 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
1187
1188 r = bus_verify_polkit_async(
1189 message,
1190 CAP_SYS_ADMIN,
1191 "org.freedesktop.machine1.manage-machines",
1192 NULL,
1193 false,
1194 UID_INVALID,
1195 &m->polkit_registry,
1196 error);
1197 if (r < 0)
1198 return r;
1199 if (r == 0)
1200 return 1; /* Will call us back */
1201
1202 /* Set up the machine directory if necessary */
1203 r = setup_machine_directory(limit, error);
1204 if (r < 0)
1205 return r;
1206
1207 /* Resize the backing loopback device, if there is one, except if we asked to drop any limit */
1208 if (limit != (uint64_t) -1) {
1209 r = btrfs_resize_loopback("/var/lib/machines", limit, false);
1210 if (r == -ENOTTY)
1211 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
1212 if (r < 0 && r != -ENODEV) /* ignore ENODEV, as that's what is returned if the file system is not on loopback */
1213 return sd_bus_error_set_errnof(error, r, "Failed to adjust loopback limit: %m");
1214 }
1215
1216 (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, limit);
1217
1218 r = btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, limit);
1219 if (r == -ENOTTY)
1220 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
1221 if (r < 0)
1222 return sd_bus_error_set_errnof(error, r, "Failed to adjust quota limit: %m");
1223
1224 return sd_bus_reply_method_return(message, NULL);
1225 }
1226
1227 static int method_set_image_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1228 _cleanup_(image_unrefp) Image *i = NULL;
1229 const char *name;
1230 int r;
1231
1232 assert(message);
1233
1234 r = sd_bus_message_read(message, "s", &name);
1235 if (r < 0)
1236 return r;
1237
1238 if (!image_name_is_valid(name))
1239 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
1240
1241 r = image_find(name, &i);
1242 if (r < 0)
1243 return r;
1244 if (r == 0)
1245 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
1246
1247 i->userdata = userdata;
1248 return bus_image_method_set_limit(message, i, error);
1249 }
1250
1251 static int method_map_from_machine_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1252 _cleanup_fclose_ FILE *f = NULL;
1253 Manager *m = userdata;
1254 const char *name, *p;
1255 Machine *machine;
1256 uint32_t uid;
1257 int r;
1258
1259 r = sd_bus_message_read(message, "su", &name, &uid);
1260 if (r < 0)
1261 return r;
1262
1263 if (!uid_is_valid(uid))
1264 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1265
1266 machine = hashmap_get(m->machines, name);
1267 if (!machine)
1268 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
1269
1270 if (machine->class != MACHINE_CONTAINER)
1271 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not supported for non-container machines.");
1272
1273 p = procfs_file_alloca(machine->leader, "uid_map");
1274 f = fopen(p, "re");
1275 if (!f)
1276 return -errno;
1277
1278 for (;;) {
1279 uid_t uid_base, uid_shift, uid_range, converted;
1280 int k;
1281
1282 errno = 0;
1283 k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
1284 if (k < 0 && feof(f))
1285 break;
1286 if (k != 3) {
1287 if (ferror(f) && errno > 0)
1288 return -errno;
1289
1290 return -EIO;
1291 }
1292
1293 if (uid < uid_base || uid >= uid_base + uid_range)
1294 continue;
1295
1296 converted = uid - uid_base + uid_shift;
1297 if (!uid_is_valid(converted))
1298 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1299
1300 return sd_bus_reply_method_return(message, "u", (uint32_t) converted);
1301 }
1302
1303 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "Machine '%s' has no matching user mappings.", name);
1304 }
1305
1306 static int method_map_to_machine_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1307 Manager *m = userdata;
1308 Machine *machine;
1309 uid_t uid;
1310 Iterator i;
1311 int r;
1312
1313 r = sd_bus_message_read(message, "u", &uid);
1314 if (r < 0)
1315 return r;
1316 if (!uid_is_valid(uid))
1317 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1318 if (uid < 0x10000)
1319 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "User " UID_FMT " belongs to host UID range", uid);
1320
1321 HASHMAP_FOREACH(machine, m->machines, i) {
1322 _cleanup_fclose_ FILE *f = NULL;
1323 char p[strlen("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
1324
1325 if (machine->class != MACHINE_CONTAINER)
1326 continue;
1327
1328 xsprintf(p, "/proc/" UID_FMT "/uid_map", machine->leader);
1329 f = fopen(p, "re");
1330 if (!f) {
1331 log_warning_errno(errno, "Failed top open %s, ignoring,", p);
1332 continue;
1333 }
1334
1335 for (;;) {
1336 _cleanup_free_ char *o = NULL;
1337 uid_t uid_base, uid_shift, uid_range, converted;
1338 int k;
1339
1340 errno = 0;
1341 k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
1342 if (k < 0 && feof(f))
1343 break;
1344 if (k != 3) {
1345 if (ferror(f) && errno > 0)
1346 return -errno;
1347
1348 return -EIO;
1349 }
1350
1351 if (uid < uid_shift || uid >= uid_shift + uid_range)
1352 continue;
1353
1354 converted = (uid - uid_shift + uid_base);
1355 if (!uid_is_valid(converted))
1356 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1357
1358 o = machine_bus_path(machine);
1359 if (!o)
1360 return -ENOMEM;
1361
1362 return sd_bus_reply_method_return(message, "sou", machine->name, o, (uint32_t) converted);
1363 }
1364 }
1365
1366 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "No matching user mapping for " UID_FMT ".", uid);
1367 }
1368
1369 static int method_map_from_machine_group(sd_bus_message *message, void *groupdata, sd_bus_error *error) {
1370 _cleanup_fclose_ FILE *f = NULL;
1371 Manager *m = groupdata;
1372 const char *name, *p;
1373 Machine *machine;
1374 uint32_t gid;
1375 int r;
1376
1377 r = sd_bus_message_read(message, "su", &name, &gid);
1378 if (r < 0)
1379 return r;
1380
1381 if (!gid_is_valid(gid))
1382 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1383
1384 machine = hashmap_get(m->machines, name);
1385 if (!machine)
1386 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
1387
1388 if (machine->class != MACHINE_CONTAINER)
1389 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not supported for non-container machines.");
1390
1391 p = procfs_file_alloca(machine->leader, "gid_map");
1392 f = fopen(p, "re");
1393 if (!f)
1394 return -errno;
1395
1396 for (;;) {
1397 gid_t gid_base, gid_shift, gid_range, converted;
1398 int k;
1399
1400 errno = 0;
1401 k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT, &gid_base, &gid_shift, &gid_range);
1402 if (k < 0 && feof(f))
1403 break;
1404 if (k != 3) {
1405 if (ferror(f) && errno > 0)
1406 return -errno;
1407
1408 return -EIO;
1409 }
1410
1411 if (gid < gid_base || gid >= gid_base + gid_range)
1412 continue;
1413
1414 converted = gid - gid_base + gid_shift;
1415 if (!gid_is_valid(converted))
1416 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1417
1418 return sd_bus_reply_method_return(message, "u", (uint32_t) converted);
1419 }
1420
1421 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "Machine '%s' has no matching group mappings.", name);
1422 }
1423
1424 static int method_map_to_machine_group(sd_bus_message *message, void *groupdata, sd_bus_error *error) {
1425 Manager *m = groupdata;
1426 Machine *machine;
1427 gid_t gid;
1428 Iterator i;
1429 int r;
1430
1431 r = sd_bus_message_read(message, "u", &gid);
1432 if (r < 0)
1433 return r;
1434 if (!gid_is_valid(gid))
1435 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1436 if (gid < 0x10000)
1437 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "Group " GID_FMT " belongs to host GID range", gid);
1438
1439 HASHMAP_FOREACH(machine, m->machines, i) {
1440 _cleanup_fclose_ FILE *f = NULL;
1441 char p[strlen("/proc//gid_map") + DECIMAL_STR_MAX(pid_t) + 1];
1442
1443 if (machine->class != MACHINE_CONTAINER)
1444 continue;
1445
1446 xsprintf(p, "/proc/" GID_FMT "/gid_map", machine->leader);
1447 f = fopen(p, "re");
1448 if (!f) {
1449 log_warning_errno(errno, "Failed top open %s, ignoring,", p);
1450 continue;
1451 }
1452
1453 for (;;) {
1454 _cleanup_free_ char *o = NULL;
1455 gid_t gid_base, gid_shift, gid_range, converted;
1456 int k;
1457
1458 errno = 0;
1459 k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT, &gid_base, &gid_shift, &gid_range);
1460 if (k < 0 && feof(f))
1461 break;
1462 if (k != 3) {
1463 if (ferror(f) && errno > 0)
1464 return -errno;
1465
1466 return -EIO;
1467 }
1468
1469 if (gid < gid_shift || gid >= gid_shift + gid_range)
1470 continue;
1471
1472 converted = (gid - gid_shift + gid_base);
1473 if (!gid_is_valid(converted))
1474 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1475
1476 o = machine_bus_path(machine);
1477 if (!o)
1478 return -ENOMEM;
1479
1480 return sd_bus_reply_method_return(message, "sou", machine->name, o, (uint32_t) converted);
1481 }
1482 }
1483
1484 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "No matching group mapping for " GID_FMT ".", gid);
1485 }
1486
1487 const sd_bus_vtable manager_vtable[] = {
1488 SD_BUS_VTABLE_START(0),
1489 SD_BUS_PROPERTY("PoolPath", "s", property_get_pool_path, 0, 0),
1490 SD_BUS_PROPERTY("PoolUsage", "t", property_get_pool_usage, 0, 0),
1491 SD_BUS_PROPERTY("PoolLimit", "t", property_get_pool_limit, 0, 0),
1492 SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1493 SD_BUS_METHOD("GetImage", "s", "o", method_get_image, SD_BUS_VTABLE_UNPRIVILEGED),
1494 SD_BUS_METHOD("GetMachineByPID", "u", "o", method_get_machine_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1495 SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED),
1496 SD_BUS_METHOD("ListImages", NULL, "a(ssbttto)", method_list_images, SD_BUS_VTABLE_UNPRIVILEGED),
1497 SD_BUS_METHOD("CreateMachine", "sayssusa(sv)", "o", method_create_machine, 0),
1498 SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0),
1499 SD_BUS_METHOD("RegisterMachine", "sayssus", "o", method_register_machine, 0),
1500 SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0),
1501 SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1502 SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1503 SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
1504 SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
1505 SD_BUS_METHOD("OpenMachinePTY", "s", "hs", method_open_machine_pty, 0),
1506 SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, SD_BUS_VTABLE_UNPRIVILEGED),
1507 SD_BUS_METHOD("OpenMachineShell", "sssasas", "hs", method_open_machine_shell, SD_BUS_VTABLE_UNPRIVILEGED),
1508 SD_BUS_METHOD("BindMountMachine", "sssbb", NULL, method_bind_mount_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1509 SD_BUS_METHOD("CopyFromMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1510 SD_BUS_METHOD("CopyToMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1511 SD_BUS_METHOD("OpenMachineRootDirectory", "s", "h", method_open_machine_root_directory, SD_BUS_VTABLE_UNPRIVILEGED),
1512 SD_BUS_METHOD("GetMachineUIDShift", "s", "u", method_get_machine_uid_shift, SD_BUS_VTABLE_UNPRIVILEGED),
1513 SD_BUS_METHOD("RemoveImage", "s", NULL, method_remove_image, SD_BUS_VTABLE_UNPRIVILEGED),
1514 SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
1515 SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
1516 SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
1517 SD_BUS_METHOD("GetImageHostname", "s", "s", method_get_image_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
1518 SD_BUS_METHOD("GetImageMachineID", "s", "ay", method_get_image_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
1519 SD_BUS_METHOD("GetImageMachineInfo", "s", "a{ss}", method_get_image_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
1520 SD_BUS_METHOD("GetImageOSRelease", "s", "a{ss}", method_get_image_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
1521 SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
1522 SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),
1523 SD_BUS_METHOD("CleanPool", "s", "a(st)", method_clean_pool, SD_BUS_VTABLE_UNPRIVILEGED),
1524 SD_BUS_METHOD("MapFromMachineUser", "su", "u", method_map_from_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
1525 SD_BUS_METHOD("MapToMachineUser", "u", "sou", method_map_to_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
1526 SD_BUS_METHOD("MapFromMachineGroup", "su", "u", method_map_from_machine_group, SD_BUS_VTABLE_UNPRIVILEGED),
1527 SD_BUS_METHOD("MapToMachineGroup", "u", "sou", method_map_to_machine_group, SD_BUS_VTABLE_UNPRIVILEGED),
1528 SD_BUS_SIGNAL("MachineNew", "so", 0),
1529 SD_BUS_SIGNAL("MachineRemoved", "so", 0),
1530 SD_BUS_VTABLE_END
1531 };
1532
1533 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1534 const char *path, *result, *unit;
1535 Manager *m = userdata;
1536 Machine *machine;
1537 uint32_t id;
1538 int r;
1539
1540 assert(message);
1541 assert(m);
1542
1543 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1544 if (r < 0) {
1545 bus_log_parse_error(r);
1546 return 0;
1547 }
1548
1549 machine = hashmap_get(m->machine_units, unit);
1550 if (!machine)
1551 return 0;
1552
1553 if (streq_ptr(path, machine->scope_job)) {
1554 machine->scope_job = mfree(machine->scope_job);
1555
1556 if (machine->started) {
1557 if (streq(result, "done"))
1558 machine_send_create_reply(machine, NULL);
1559 else {
1560 _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
1561
1562 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1563
1564 machine_send_create_reply(machine, &e);
1565 }
1566 }
1567
1568 machine_save(machine);
1569 }
1570
1571 machine_add_to_gc_queue(machine);
1572 return 0;
1573 }
1574
1575 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1576 _cleanup_free_ char *unit = NULL;
1577 const char *path;
1578 Manager *m = userdata;
1579 Machine *machine;
1580 int r;
1581
1582 assert(message);
1583 assert(m);
1584
1585 path = sd_bus_message_get_path(message);
1586 if (!path)
1587 return 0;
1588
1589 r = unit_name_from_dbus_path(path, &unit);
1590 if (r == -EINVAL) /* not for a unit */
1591 return 0;
1592 if (r < 0) {
1593 log_oom();
1594 return 0;
1595 }
1596
1597 machine = hashmap_get(m->machine_units, unit);
1598 if (!machine)
1599 return 0;
1600
1601 machine_add_to_gc_queue(machine);
1602 return 0;
1603 }
1604
1605 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1606 const char *path, *unit;
1607 Manager *m = userdata;
1608 Machine *machine;
1609 int r;
1610
1611 assert(message);
1612 assert(m);
1613
1614 r = sd_bus_message_read(message, "so", &unit, &path);
1615 if (r < 0) {
1616 bus_log_parse_error(r);
1617 return 0;
1618 }
1619
1620 machine = hashmap_get(m->machine_units, unit);
1621 if (!machine)
1622 return 0;
1623
1624 machine_add_to_gc_queue(machine);
1625 return 0;
1626 }
1627
1628 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1629 Manager *m = userdata;
1630 Machine *machine;
1631 Iterator i;
1632 int b, r;
1633
1634 assert(message);
1635 assert(m);
1636
1637 r = sd_bus_message_read(message, "b", &b);
1638 if (r < 0) {
1639 bus_log_parse_error(r);
1640 return 0;
1641 }
1642 if (b)
1643 return 0;
1644
1645 /* systemd finished reloading, let's recheck all our machines */
1646 log_debug("System manager has been reloaded, rechecking machines...");
1647
1648 HASHMAP_FOREACH(machine, m->machines, i)
1649 machine_add_to_gc_queue(machine);
1650
1651 return 0;
1652 }
1653
1654 int manager_start_scope(
1655 Manager *manager,
1656 const char *scope,
1657 pid_t pid,
1658 const char *slice,
1659 const char *description,
1660 sd_bus_message *more_properties,
1661 sd_bus_error *error,
1662 char **job) {
1663
1664 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
1665 int r;
1666
1667 assert(manager);
1668 assert(scope);
1669 assert(pid > 1);
1670
1671 r = sd_bus_message_new_method_call(
1672 manager->bus,
1673 &m,
1674 "org.freedesktop.systemd1",
1675 "/org/freedesktop/systemd1",
1676 "org.freedesktop.systemd1.Manager",
1677 "StartTransientUnit");
1678 if (r < 0)
1679 return r;
1680
1681 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
1682 if (r < 0)
1683 return r;
1684
1685 r = sd_bus_message_open_container(m, 'a', "(sv)");
1686 if (r < 0)
1687 return r;
1688
1689 if (!isempty(slice)) {
1690 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
1691 if (r < 0)
1692 return r;
1693 }
1694
1695 if (!isempty(description)) {
1696 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
1697 if (r < 0)
1698 return r;
1699 }
1700
1701 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
1702 if (r < 0)
1703 return r;
1704
1705 r = sd_bus_message_append(m, "(sv)", "Delegate", "b", 1);
1706 if (r < 0)
1707 return r;
1708
1709 r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", UINT64_C(16384));
1710 if (r < 0)
1711 return bus_log_create_error(r);
1712
1713 if (more_properties) {
1714 r = sd_bus_message_copy(m, more_properties, true);
1715 if (r < 0)
1716 return r;
1717 }
1718
1719 r = sd_bus_message_close_container(m);
1720 if (r < 0)
1721 return r;
1722
1723 r = sd_bus_message_append(m, "a(sa(sv))", 0);
1724 if (r < 0)
1725 return r;
1726
1727 r = sd_bus_call(manager->bus, m, 0, error, &reply);
1728 if (r < 0)
1729 return r;
1730
1731 if (job) {
1732 const char *j;
1733 char *copy;
1734
1735 r = sd_bus_message_read(reply, "o", &j);
1736 if (r < 0)
1737 return r;
1738
1739 copy = strdup(j);
1740 if (!copy)
1741 return -ENOMEM;
1742
1743 *job = copy;
1744 }
1745
1746 return 1;
1747 }
1748
1749 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
1750 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1751 int r;
1752
1753 assert(manager);
1754 assert(unit);
1755
1756 r = sd_bus_call_method(
1757 manager->bus,
1758 "org.freedesktop.systemd1",
1759 "/org/freedesktop/systemd1",
1760 "org.freedesktop.systemd1.Manager",
1761 "StopUnit",
1762 error,
1763 &reply,
1764 "ss", unit, "fail");
1765 if (r < 0) {
1766 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
1767 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
1768
1769 if (job)
1770 *job = NULL;
1771
1772 sd_bus_error_free(error);
1773 return 0;
1774 }
1775
1776 return r;
1777 }
1778
1779 if (job) {
1780 const char *j;
1781 char *copy;
1782
1783 r = sd_bus_message_read(reply, "o", &j);
1784 if (r < 0)
1785 return r;
1786
1787 copy = strdup(j);
1788 if (!copy)
1789 return -ENOMEM;
1790
1791 *job = copy;
1792 }
1793
1794 return 1;
1795 }
1796
1797 int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error) {
1798 assert(manager);
1799 assert(unit);
1800
1801 return sd_bus_call_method(
1802 manager->bus,
1803 "org.freedesktop.systemd1",
1804 "/org/freedesktop/systemd1",
1805 "org.freedesktop.systemd1.Manager",
1806 "KillUnit",
1807 error,
1808 NULL,
1809 "ssi", unit, "all", signo);
1810 }
1811
1812 int manager_unit_is_active(Manager *manager, const char *unit) {
1813 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1814 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1815 _cleanup_free_ char *path = NULL;
1816 const char *state;
1817 int r;
1818
1819 assert(manager);
1820 assert(unit);
1821
1822 path = unit_dbus_path_from_name(unit);
1823 if (!path)
1824 return -ENOMEM;
1825
1826 r = sd_bus_get_property(
1827 manager->bus,
1828 "org.freedesktop.systemd1",
1829 path,
1830 "org.freedesktop.systemd1.Unit",
1831 "ActiveState",
1832 &error,
1833 &reply,
1834 "s");
1835 if (r < 0) {
1836 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
1837 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
1838 return true;
1839
1840 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
1841 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
1842 return false;
1843
1844 return r;
1845 }
1846
1847 r = sd_bus_message_read(reply, "s", &state);
1848 if (r < 0)
1849 return -EINVAL;
1850
1851 return !STR_IN_SET(state, "inactive", "failed");
1852 }
1853
1854 int manager_job_is_active(Manager *manager, const char *path) {
1855 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1856 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1857 int r;
1858
1859 assert(manager);
1860 assert(path);
1861
1862 r = sd_bus_get_property(
1863 manager->bus,
1864 "org.freedesktop.systemd1",
1865 path,
1866 "org.freedesktop.systemd1.Job",
1867 "State",
1868 &error,
1869 &reply,
1870 "s");
1871 if (r < 0) {
1872 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
1873 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
1874 return true;
1875
1876 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
1877 return false;
1878
1879 return r;
1880 }
1881
1882 /* We don't actually care about the state really. The fact
1883 * that we could read the job state is enough for us */
1884
1885 return true;
1886 }
1887
1888 int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) {
1889 Machine *mm;
1890 int r;
1891
1892 assert(m);
1893 assert(pid >= 1);
1894 assert(machine);
1895
1896 mm = hashmap_get(m->machine_leaders, PID_TO_PTR(pid));
1897 if (!mm) {
1898 _cleanup_free_ char *unit = NULL;
1899
1900 r = cg_pid_get_unit(pid, &unit);
1901 if (r >= 0)
1902 mm = hashmap_get(m->machine_units, unit);
1903 }
1904 if (!mm)
1905 return 0;
1906
1907 *machine = mm;
1908 return 1;
1909 }
1910
1911 int manager_add_machine(Manager *m, const char *name, Machine **_machine) {
1912 Machine *machine;
1913
1914 assert(m);
1915 assert(name);
1916
1917 machine = hashmap_get(m->machines, name);
1918 if (!machine) {
1919 machine = machine_new(m, _MACHINE_CLASS_INVALID, name);
1920 if (!machine)
1921 return -ENOMEM;
1922 }
1923
1924 if (_machine)
1925 *_machine = machine;
1926
1927 return 0;
1928 }
1929
1930 int bus_reply_pair_array(sd_bus_message *m, char **l) {
1931 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1932 char **k, **v;
1933 int r;
1934
1935 r = sd_bus_message_new_method_return(m, &reply);
1936 if (r < 0)
1937 return r;
1938
1939 r = sd_bus_message_open_container(reply, 'a', "{ss}");
1940 if (r < 0)
1941 return r;
1942
1943 STRV_FOREACH_PAIR(k, v, l) {
1944 r = sd_bus_message_append(reply, "{ss}", *k, *v);
1945 if (r < 0)
1946 return r;
1947 }
1948
1949 r = sd_bus_message_close_container(reply);
1950 if (r < 0)
1951 return r;
1952
1953 return sd_bus_send(NULL, reply, NULL);
1954
1955 }