]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/udev/udev-event.c
udev: fix device name shown in the log message on failure
[thirdparty/systemd.git] / src / udev / udev-event.c
CommitLineData
f13467ec 1/* SPDX-License-Identifier: GPL-2.0-or-later */
d46f37fd 2
b5efdb8a 3#include "alloc-util.h"
ff88b949 4#include "device-internal.h"
947ce772 5#include "device-private.h"
e9343893 6#include "device-util.h"
25de7aa7 7#include "fs-util.h"
068b0f77 8#include "netif-naming-scheme.h"
07630cea 9#include "netlink-util.h"
feaa6db7 10#include "path-util.h"
07630cea 11#include "string-util.h"
5ea78a39 12#include "strv.h"
25de7aa7 13#include "udev-event.h"
a2554ace 14#include "udev-node.h"
1c3edc2e 15#include "udev-trace.h"
c0af9dee 16#include "udev-util.h"
70068602 17#include "udev-watch.h"
25de7aa7 18#include "user-util.h"
8128f229 19
1a0bd015 20UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl, int log_level) {
2e088715 21 UdevEvent *event;
912541b0 22
89665d09
YW
23 assert(dev);
24
2e088715 25 event = new(UdevEvent, 1);
89665d09 26 if (!event)
912541b0 27 return NULL;
89665d09 28
2e088715 29 *event = (UdevEvent) {
cf28ad46 30 .dev = sd_device_ref(dev),
89665d09 31 .birth_usec = now(CLOCK_MONOTONIC),
6b92f429 32 .exec_delay_usec = exec_delay_usec,
e0bb2ff9 33 .rtnl = sd_netlink_ref(rtnl),
25de7aa7
YW
34 .uid = UID_INVALID,
35 .gid = GID_INVALID,
36 .mode = MODE_INVALID,
1a0bd015
YW
37 .log_level_was_debug = log_level == LOG_DEBUG,
38 .default_log_level = log_level,
89665d09
YW
39 };
40
912541b0 41 return event;
aa8734ff
KS
42}
43
2e088715 44UdevEvent *udev_event_free(UdevEvent *event) {
c1118ceb
YW
45 if (!event)
46 return NULL;
47
cf28ad46 48 sd_device_unref(event->dev);
480ecb7d 49 sd_device_unref(event->dev_db_clone);
1c4baffc 50 sd_netlink_unref(event->rtnl);
39a15c8a
YW
51 ordered_hashmap_free_free_key(event->run_list);
52 ordered_hashmap_free_free_free(event->seclabel_list);
912541b0
KS
53 free(event->program_result);
54 free(event->name);
9094ae52 55 strv_free(event->altnames);
c1118ceb
YW
56
57 return mfree(event);
aa8734ff
KS
58}
59
ff88b949
YW
60static int device_rename(sd_device *device, const char *name) {
61 _cleanup_free_ char *new_syspath = NULL;
62 const char *s;
63 int r;
64
65 assert(device);
66 assert(name);
67
68 if (!filename_is_valid(name))
69 return -EINVAL;
70
71 r = sd_device_get_syspath(device, &s);
72 if (r < 0)
73 return r;
74
75 r = path_extract_directory(s, &new_syspath);
76 if (r < 0)
77 return r;
78
79 if (!path_extend(&new_syspath, name))
80 return -ENOMEM;
81
82 if (!path_is_safe(new_syspath))
83 return -EINVAL;
84
85 /* At the time this is called, the renamed device may not exist yet. Hence, we cannot validate
86 * the new syspath. */
87 r = device_set_syspath(device, new_syspath, /* verify = */ false);
88 if (r < 0)
89 return r;
90
91 r = sd_device_get_property_value(device, "INTERFACE", &s);
92 if (r == -ENOENT)
93 return 0;
94 if (r < 0)
95 return r;
96
97 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
98 r = device_add_property_internal(device, "INTERFACE_OLD", s);
99 if (r < 0)
100 return r;
101
102 return device_add_property_internal(device, "INTERFACE", name);
103}
104
2e088715 105static int rename_netif(UdevEvent *event) {
21003384
YW
106 _cleanup_free_ char *old_syspath = NULL, *old_sysname = NULL;
107 const char *s;
60e50fb2 108 sd_device *dev;
2740750d
YW
109 int ifindex, r;
110
60e50fb2
YW
111 assert(event);
112
2740750d
YW
113 if (!event->name)
114 return 0; /* No new name is requested. */
115
60e50fb2
YW
116 dev = ASSERT_PTR(event->dev);
117
2740750d
YW
118 r = sd_device_get_ifindex(dev, &ifindex);
119 if (r == -ENOENT)
120 return 0; /* Device is not a network interface. */
121 if (r < 0)
21003384 122 return log_device_warning_errno(dev, r, "Failed to get ifindex: %m");
912541b0 123
068b0f77
YW
124 if (naming_scheme_has(NAMING_REPLACE_STRICTLY) &&
125 !ifname_valid(event->name)) {
126 log_device_warning(dev, "Invalid network interface name, ignoring: %s", event->name);
127 return 0;
128 }
129
21003384 130 r = sd_device_get_sysname(dev, &s);
a4055a60 131 if (r < 0)
21003384 132 return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
912541b0 133
21003384
YW
134 if (streq(event->name, s))
135 return 0; /* The interface name is already requested name. */
136
137 old_sysname = strdup(s);
138 if (!old_sysname)
139 return -ENOMEM;
140
141 r = sd_device_get_syspath(dev, &s);
f647962d 142 if (r < 0)
21003384
YW
143 return log_device_warning_errno(dev, r, "Failed to get syspath: %m");
144
145 old_syspath = strdup(s);
146 if (!old_syspath)
147 return -ENOMEM;
148
149 r = device_rename(dev, event->name);
150 if (r < 0) {
2b43c5cb
YW
151 /* Here and below, use dev_db_clone for logging, otherwise, logged message is prefixed with
152 * the new interface name, and e.g. 'networkctl status INTERFACE' does not show the message. */
153 log_device_warning_errno(event->dev_db_clone, r,
154 "Failed to update properties with new name '%s': %m", event->name);
21003384
YW
155 goto revert;
156 }
157
158 /* Set ID_RENAMING boolean property here. It will be dropped when the corresponding move uevent is processed. */
159 r = device_add_property(dev, "ID_RENAMING", "1");
160 if (r < 0) {
2b43c5cb 161 log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
21003384
YW
162 goto revert;
163 }
16d26d55 164
ae353ec2
YW
165 /* Also set ID_RENAMING boolean property to cloned sd_device object and save it to database
166 * before calling rtnl_set_link_name(). Otherwise, clients (e.g., systemd-networkd) may receive
167 * RTM_NEWLINK netlink message before the database is updated. */
168 r = device_add_property(event->dev_db_clone, "ID_RENAMING", "1");
21003384
YW
169 if (r < 0) {
170 log_device_warning_errno(event->dev_db_clone, r, "Failed to add 'ID_RENAMING' property: %m");
171 goto revert;
172 }
ae353ec2
YW
173
174 r = device_update_db(event->dev_db_clone);
21003384
YW
175 if (r < 0) {
176 log_device_debug_errno(event->dev_db_clone, r, "Failed to update database under /run/udev/data/: %m");
177 goto revert;
178 }
ae353ec2 179
9094ae52 180 r = rtnl_set_link_name(&event->rtnl, ifindex, event->name, event->altnames);
21003384
YW
181 if (r < 0) {
182 if (r == -EBUSY) {
2b43c5cb
YW
183 log_device_info(event->dev_db_clone,
184 "Network interface '%s' is already up, cannot rename to '%s'.",
21003384
YW
185 old_sysname, event->name);
186 r = 0;
187 } else
2b43c5cb
YW
188 log_device_error_errno(event->dev_db_clone, r,
189 "Failed to rename network interface %i from '%s' to '%s': %m",
21003384
YW
190 ifindex, old_sysname, event->name);
191 goto revert;
53584e7b 192 }
16d26d55 193
21003384 194 log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, old_sysname, event->name);
2740750d 195 return 1;
21003384
YW
196
197revert:
198 /* Restore 'dev_db_clone' */
199 (void) device_add_property(event->dev_db_clone, "ID_RENAMING", NULL);
200 (void) device_update_db(event->dev_db_clone);
201
202 /* Restore 'dev' */
203 (void) device_set_syspath(dev, old_syspath, /* verify = */ false);
204 if (sd_device_get_property_value(dev, "INTERFACE_OLD", &s) >= 0) {
205 (void) device_add_property_internal(dev, "INTERFACE", s);
206 (void) device_add_property_internal(dev, "INTERFACE_OLD", NULL);
207 }
208 (void) device_add_property(dev, "ID_RENAMING", NULL);
209
210 return r;
d46f37fd
KS
211}
212
9094ae52
YW
213static int assign_altnames(UdevEvent *event) {
214 sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
215 int ifindex, r;
216 const char *s;
217
218 if (strv_isempty(event->altnames))
219 return 0;
220
221 r = sd_device_get_ifindex(dev, &ifindex);
222 if (r == -ENOENT)
223 return 0; /* Device is not a network interface. */
224 if (r < 0)
225 return log_device_warning_errno(dev, r, "Failed to get ifindex: %m");
226
227 r = sd_device_get_sysname(dev, &s);
228 if (r < 0)
229 return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
230
231 /* Filter out the current interface name. */
232 strv_remove(event->altnames, s);
233
234 r = rtnl_append_link_alternative_names(&event->rtnl, ifindex, event->altnames);
235 if (r < 0)
236 log_device_full_errno(dev, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r,
237 "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
238
239 return 0;
240}
241
2e088715 242static int update_devnode(UdevEvent *event) {
fbd747a4 243 sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
e52eaf56
YW
244 int r;
245
7af1c780 246 r = sd_device_get_devnum(dev, NULL);
e52eaf56
YW
247 if (r == -ENOENT)
248 return 0;
249 if (r < 0)
250 return log_device_error_errno(dev, r, "Failed to get devnum: %m");
251
25de7aa7 252 if (!uid_is_valid(event->uid)) {
e52eaf56 253 r = device_get_devnode_uid(dev, &event->uid);
3708c0f4 254 if (r < 0 && r != -ENOENT)
e52eaf56
YW
255 return log_device_error_errno(dev, r, "Failed to get devnode UID: %m");
256 }
257
25de7aa7 258 if (!gid_is_valid(event->gid)) {
e52eaf56 259 r = device_get_devnode_gid(dev, &event->gid);
3708c0f4 260 if (r < 0 && r != -ENOENT)
e52eaf56
YW
261 return log_device_error_errno(dev, r, "Failed to get devnode GID: %m");
262 }
263
25de7aa7 264 if (event->mode == MODE_INVALID) {
e52eaf56
YW
265 r = device_get_devnode_mode(dev, &event->mode);
266 if (r < 0 && r != -ENOENT)
267 return log_device_error_errno(dev, r, "Failed to get devnode mode: %m");
e52eaf56 268 }
3708c0f4 269
a1130022 270 bool apply_mac = device_for_action(dev, SD_DEVICE_ADD);
e52eaf56 271
2f48561e
YW
272 r = udev_node_apply_permissions(dev, apply_mac, event->mode, event->uid, event->gid, event->seclabel_list);
273 if (r < 0)
274 return log_device_error_errno(dev, r, "Failed to apply devnode permissions: %m");
275
276 return udev_node_update(dev, event->dev_db_clone);
e52eaf56
YW
277}
278
4cac2260 279static int event_execute_rules_on_remove(
2e088715 280 UdevEvent *event,
df7ee959 281 int inotify_fd,
66f737b4 282 usec_t timeout_usec,
e2099267 283 int timeout_signal,
eb1f9e30 284 Hashmap *properties_list,
9a07157d 285 UdevRules *rules) {
912541b0 286
fbd747a4 287 sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
eb1f9e30 288 int r;
912541b0 289
ebcc52fa 290 r = device_read_db_internal(dev, true);
eb1f9e30
YW
291 if (r < 0)
292 log_device_debug_errno(dev, r, "Failed to read database under /run/udev/data/: %m");
107f2e25 293
eb1f9e30
YW
294 r = device_tag_index(dev, NULL, false);
295 if (r < 0)
296 log_device_debug_errno(dev, r, "Failed to remove corresponding tag files under /run/udev/tag/, ignoring: %m");
912541b0 297
eb1f9e30
YW
298 r = device_delete_db(dev);
299 if (r < 0)
300 log_device_debug_errno(dev, r, "Failed to delete database under /run/udev/data/, ignoring: %m");
912541b0 301
790da548
YW
302 r = udev_watch_end(inotify_fd, dev);
303 if (r < 0)
304 log_device_warning_errno(dev, r, "Failed to remove inotify watch, ignoring: %m");
eb1f9e30 305
4cac2260 306 r = udev_rules_apply_to_event(rules, event, timeout_usec, timeout_signal, properties_list);
eb1f9e30 307
d4a95a95 308 if (sd_device_get_devnum(dev, NULL) >= 0)
eb1f9e30 309 (void) udev_node_remove(dev);
4cac2260
YW
310
311 return r;
eb1f9e30
YW
312}
313
e77b146f 314static int copy_all_tags(sd_device *d, sd_device *s) {
e77b146f
LP
315 int r;
316
317 assert(d);
318
319 if (!s)
320 return 0;
321
5b90b906 322 FOREACH_DEVICE_TAG(s, tag) {
e77b146f
LP
323 r = device_add_tag(d, tag, false);
324 if (r < 0)
325 return r;
326 }
327
328 return 0;
329}
330
df7ee959
YW
331int udev_event_execute_rules(
332 UdevEvent *event,
333 int inotify_fd, /* This may be negative */
334 usec_t timeout_usec,
335 int timeout_signal,
336 Hashmap *properties_list,
337 UdevRules *rules) {
338
a1130022 339 sd_device_action_t action;
6d0fdf45 340 sd_device *dev;
eb1f9e30
YW
341 int r;
342
28235d10 343 dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
eb1f9e30
YW
344 assert(rules);
345
a1130022 346 r = sd_device_get_action(dev, &action);
eb1f9e30 347 if (r < 0)
d4d690fa 348 return log_device_error_errno(dev, r, "Failed to get ACTION: %m");
b081b27e 349
4cac2260
YW
350 if (action == SD_DEVICE_REMOVE)
351 return event_execute_rules_on_remove(event, inotify_fd, timeout_usec, timeout_signal, properties_list, rules);
912541b0 352
e7f781e4 353 /* Disable watch during event processing. */
28235d10 354 r = udev_watch_end(inotify_fd, dev);
790da548
YW
355 if (r < 0)
356 log_device_warning_errno(dev, r, "Failed to remove inotify watch, ignoring: %m");
e7f781e4 357
480ecb7d 358 r = device_clone_with_db(dev, &event->dev_db_clone);
eb1f9e30 359 if (r < 0)
99058cd6 360 return log_device_debug_errno(dev, r, "Failed to clone sd_device object: %m");
912541b0 361
e77b146f
LP
362 r = copy_all_tags(dev, event->dev_db_clone);
363 if (r < 0)
364 log_device_warning_errno(dev, r, "Failed to copy all tags from old database entry, ignoring: %m");
365
7137f2f3
YW
366 /* Drop previously added property for safety to make IMPORT{db}="ID_RENAMING" not work. This is
367 * mostly for 'move' uevent, but let's do unconditionally. Why? If a network interface is renamed in
368 * initrd, then udevd may lose the 'move' uevent during switching root. Usually, we do not set the
369 * persistent flag for network interfaces, but user may set it. Just for safety. */
370 r = device_add_property(event->dev_db_clone, "ID_RENAMING", NULL);
371 if (r < 0)
372 return log_device_debug_errno(dev, r, "Failed to remove 'ID_RENAMING' property: %m");
eb1f9e30 373
b428efa5
MS
374 DEVICE_TRACE_POINT(rules_start, dev);
375
e2099267 376 r = udev_rules_apply_to_event(rules, event, timeout_usec, timeout_signal, properties_list);
99058cd6
YW
377 if (r < 0)
378 return log_device_debug_errno(dev, r, "Failed to apply udev rules: %m");
eb1f9e30 379
b428efa5
MS
380 DEVICE_TRACE_POINT(rules_finished, dev);
381
9094ae52
YW
382 if (action == SD_DEVICE_ADD) {
383 r = rename_netif(event);
384 if (r < 0)
385 return r;
386 if (r == 0)
387 (void) assign_altnames(event);
388 }
99058cd6
YW
389
390 r = update_devnode(event);
391 if (r < 0)
392 return r;
eb1f9e30
YW
393
394 /* preserve old, or get new initialization timestamp */
480ecb7d 395 r = device_ensure_usec_initialized(dev, event->dev_db_clone);
eb1f9e30 396 if (r < 0)
99058cd6 397 return log_device_debug_errno(dev, r, "Failed to set initialization timestamp: %m");
eb1f9e30
YW
398
399 /* (re)write database file */
480ecb7d 400 r = device_tag_index(dev, event->dev_db_clone, true);
eb1f9e30 401 if (r < 0)
99058cd6 402 return log_device_debug_errno(dev, r, "Failed to update tags under /run/udev/tag/: %m");
eb1f9e30
YW
403
404 r = device_update_db(dev);
405 if (r < 0)
99058cd6 406 return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m");
eb1f9e30 407
996c8390
MS
408 device_set_is_initialized(dev);
409
7920d0a1 410 return 0;
d46f37fd 411}