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