1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "bus-error.h"
4 #include "bus-locator.h"
5 #include "dissect-image.h"
6 #include "systemctl-mount.h"
7 #include "systemctl-util.h"
8 #include "systemctl.h"
9
verb_bind(int argc,char * argv[],void * userdata)10 int verb_bind(int argc, char *argv[], void *userdata) {
11 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
12 _cleanup_free_ char *n = NULL;
13 sd_bus *bus;
14 int r;
15
16 r = acquire_bus(BUS_MANAGER, &bus);
17 if (r < 0)
18 return r;
19
20 polkit_agent_open_maybe();
21
22 r = unit_name_mangle(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, &n);
23 if (r < 0)
24 return log_error_errno(r, "Failed to mangle unit name: %m");
25
26 r = bus_call_method(
27 bus,
28 bus_systemd_mgr,
29 "BindMountUnit",
30 &error,
31 NULL,
32 "sssbb",
33 n,
34 argv[2],
35 argv[3],
36 arg_read_only,
37 arg_mkdir);
38 if (r < 0)
39 return log_error_errno(r, "Failed to bind mount: %s", bus_error_message(&error, r));
40
41 return 0;
42 }
43
verb_mount_image(int argc,char * argv[],void * userdata)44 int verb_mount_image(int argc, char *argv[], void *userdata) {
45 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
46 const char *unit = argv[1], *src = argv[2], *dest = argv[3];
47 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
48 _cleanup_free_ char *n = NULL;
49 sd_bus *bus;
50 int r;
51
52 r = acquire_bus(BUS_MANAGER, &bus);
53 if (r < 0)
54 return r;
55
56 polkit_agent_open_maybe();
57
58 r = unit_name_mangle(unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, &n);
59 if (r < 0)
60 return log_error_errno(r, "Failed to mangle unit name: %m");
61
62 r = bus_message_new_method_call(
63 bus,
64 &m,
65 bus_systemd_mgr,
66 "MountImageUnit");
67 if (r < 0)
68 return bus_log_create_error(r);
69
70 r = sd_bus_message_append(
71 m,
72 "sssbb",
73 n,
74 src,
75 dest,
76 arg_read_only,
77 arg_mkdir);
78 if (r < 0)
79 return bus_log_create_error(r);
80
81 r = sd_bus_message_open_container(m, 'a', "(ss)");
82 if (r < 0)
83 return bus_log_create_error(r);
84
85 if (argc > 4) {
86 _cleanup_free_ char *partition = NULL, *mount_options = NULL;
87 const char *options = argv[4];
88
89 r = extract_many_words(&options, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL);
90 if (r < 0)
91 return r;
92 /* Single set of options, applying to the root partition/single filesystem */
93 if (r == 1) {
94 r = sd_bus_message_append(m, "(ss)", "root", partition);
95 if (r < 0)
96 return bus_log_create_error(r);
97 } else if (r > 1) {
98 if (partition_designator_from_string(partition) < 0)
99 return bus_log_create_error(-EINVAL);
100
101 r = sd_bus_message_append(m, "(ss)", partition, mount_options);
102 if (r < 0)
103 return bus_log_create_error(r);
104 }
105 }
106
107 r = sd_bus_message_close_container(m);
108 if (r < 0)
109 return bus_log_create_error(r);
110
111 r = sd_bus_call(bus, m, -1, &error, NULL);
112 if (r < 0)
113 return log_error_errno(r, "Failed to mount image: %s", bus_error_message(&error, r));
114
115 return 0;
116 }
117