]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/portable/portabled.c
Merge pull request #18007 from fw-strlen/ipv6_masq_and_dnat
[thirdparty/systemd.git] / src / portable / portabled.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <sys/stat.h>
4 #include <sys/types.h>
5
6 #include "sd-bus.h"
7 #include "sd-daemon.h"
8
9 #include "alloc-util.h"
10 #include "bus-log-control-api.h"
11 #include "bus-polkit.h"
12 #include "def.h"
13 #include "main-func.h"
14 #include "portabled-bus.h"
15 #include "portabled-image-bus.h"
16 #include "portabled.h"
17 #include "process-util.h"
18 #include "service-util.h"
19 #include "signal-util.h"
20
21 static Manager* manager_unref(Manager *m);
22 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref);
23
24 static int manager_new(Manager **ret) {
25 _cleanup_(manager_unrefp) Manager *m = NULL;
26 int r;
27
28 assert(ret);
29
30 m = new0(Manager, 1);
31 if (!m)
32 return -ENOMEM;
33
34 r = sd_event_default(&m->event);
35 if (r < 0)
36 return r;
37
38 r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
39 if (r < 0)
40 return r;
41
42 r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
43 if (r < 0)
44 return r;
45
46 (void) sd_event_set_watchdog(m->event, true);
47
48 *ret = TAKE_PTR(m);
49 return 0;
50 }
51
52 static Manager* manager_unref(Manager *m) {
53 assert(m);
54
55 hashmap_free(m->image_cache);
56
57 sd_event_source_unref(m->image_cache_defer_event);
58
59 bus_verify_polkit_async_registry_free(m->polkit_registry);
60
61 sd_bus_flush_close_unref(m->bus);
62 sd_event_unref(m->event);
63
64 return mfree(m);
65 }
66
67 static int manager_connect_bus(Manager *m) {
68 int r;
69
70 assert(m);
71 assert(!m->bus);
72
73 r = sd_bus_default_system(&m->bus);
74 if (r < 0)
75 return log_error_errno(r, "Failed to connect to system bus: %m");
76
77 r = bus_add_implementation(m->bus, &manager_object, m);
78 if (r < 0)
79 return r;
80
81 r = bus_log_control_api_register(m->bus);
82 if (r < 0)
83 return r;
84
85 r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.portable1", 0, NULL, NULL);
86 if (r < 0)
87 return log_error_errno(r, "Failed to request name: %m");
88
89 r = sd_bus_attach_event(m->bus, m->event, 0);
90 if (r < 0)
91 return log_error_errno(r, "Failed to attach bus to event loop: %m");
92
93 (void) sd_bus_set_exit_on_disconnect(m->bus, true);
94
95 return 0;
96 }
97
98 static int manager_startup(Manager *m) {
99 int r;
100
101 assert(m);
102
103 r = manager_connect_bus(m);
104 if (r < 0)
105 return r;
106
107 return 0;
108 }
109
110 static bool check_idle(void *userdata) {
111 Manager *m = userdata;
112
113 return !m->operations;
114 }
115
116 static int manager_run(Manager *m) {
117 assert(m);
118
119 return bus_event_loop_with_idle(
120 m->event,
121 m->bus,
122 "org.freedesktop.portable1",
123 DEFAULT_EXIT_USEC,
124 check_idle, m);
125 }
126
127 static int run(int argc, char *argv[]) {
128 _cleanup_(manager_unrefp) Manager *m = NULL;
129 int r;
130
131 log_setup();
132
133 r = service_parse_argv("systemd-portabled.service",
134 "Manage registrations of portable images.",
135 BUS_IMPLEMENTATIONS(&manager_object,
136 &log_control_object),
137 argc, argv);
138 if (r <= 0)
139 return r;
140
141 umask(0022);
142
143 if (argc != 1)
144 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
145
146 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, SIGTERM, SIGINT, -1) >= 0);
147
148 r = manager_new(&m);
149 if (r < 0)
150 return log_error_errno(r, "Failed to allocate manager object: %m");
151
152 r = manager_startup(m);
153 if (r < 0)
154 return log_error_errno(r, "Failed to fully start up daemon: %m");
155
156 log_debug("systemd-portabled running as pid " PID_FMT, getpid_cached());
157 sd_notify(false,
158 "READY=1\n"
159 "STATUS=Processing requests...");
160
161 r = manager_run(m);
162
163 (void) sd_notify(false,
164 "STOPPING=1\n"
165 "STATUS=Shutting down...");
166 log_debug("systemd-portabled stopped as pid " PID_FMT, getpid_cached());
167 return r;
168 }
169
170 DEFINE_MAIN_FUNCTION(run);