]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-device/device-private.c
tree-wide: use TAKE_PTR() and TAKE_FD() macros
[thirdparty/systemd.git] / src / libsystemd / sd-device / device-private.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <ctype.h>
23 #include <net/if.h>
24 #include <sys/types.h>
25
26 #include "sd-device.h"
27
28 #include "alloc-util.h"
29 #include "device-internal.h"
30 #include "device-private.h"
31 #include "device-util.h"
32 #include "fd-util.h"
33 #include "fileio.h"
34 #include "fs-util.h"
35 #include "hashmap.h"
36 #include "macro.h"
37 #include "mkdir.h"
38 #include "parse-util.h"
39 #include "path-util.h"
40 #include "refcnt.h"
41 #include "set.h"
42 #include "string-table.h"
43 #include "string-util.h"
44 #include "strv.h"
45 #include "strxcpyx.h"
46 #include "user-util.h"
47 #include "util.h"
48
49 int device_add_property(sd_device *device, const char *key, const char *value) {
50 int r;
51
52 assert(device);
53 assert(key);
54
55 r = device_add_property_aux(device, key, value, false);
56 if (r < 0)
57 return r;
58
59 if (key[0] != '.') {
60 r = device_add_property_aux(device, key, value, true);
61 if (r < 0)
62 return r;
63 }
64
65 return 0;
66 }
67
68 static int device_add_property_internal_from_string(sd_device *device, const char *str) {
69 _cleanup_free_ char *key = NULL;
70 char *value;
71
72 assert(device);
73 assert(str);
74
75 key = strdup(str);
76 if (!key)
77 return -ENOMEM;
78
79 value = strchr(key, '=');
80 if (!value)
81 return -EINVAL;
82
83 *value = '\0';
84
85 if (isempty(++value))
86 value = NULL;
87
88 return device_add_property_internal(device, key, value);
89 }
90
91 static int handle_db_line(sd_device *device, char key, const char *value) {
92 char *path;
93 int r;
94
95 assert(device);
96 assert(value);
97
98 switch (key) {
99 case 'S':
100 path = strjoina("/dev/", value);
101 r = device_add_devlink(device, path);
102 if (r < 0)
103 return r;
104
105 break;
106 case 'L':
107 r = safe_atoi(value, &device->devlink_priority);
108 if (r < 0)
109 return r;
110
111 break;
112 case 'E':
113 r = device_add_property_internal_from_string(device, value);
114 if (r < 0)
115 return r;
116
117 break;
118 case 'G':
119 r = device_add_tag(device, value);
120 if (r < 0)
121 return r;
122
123 break;
124 case 'W':
125 r = safe_atoi(value, &device->watch_handle);
126 if (r < 0)
127 return r;
128
129 break;
130 case 'I':
131 r = device_set_usec_initialized(device, value);
132 if (r < 0)
133 return r;
134
135 break;
136 default:
137 log_debug("device db: unknown key '%c'", key);
138 }
139
140 return 0;
141 }
142
143 void device_set_devlink_priority(sd_device *device, int priority) {
144 assert(device);
145
146 device->devlink_priority = priority;
147 }
148
149 void device_set_is_initialized(sd_device *device) {
150 assert(device);
151
152 device->is_initialized = true;
153 }
154
155 int device_ensure_usec_initialized(sd_device *device, sd_device *device_old) {
156 char num[DECIMAL_STR_MAX(usec_t)];
157 usec_t usec_initialized;
158 int r;
159
160 assert(device);
161
162 if (device_old && device_old->usec_initialized > 0)
163 usec_initialized = device_old->usec_initialized;
164 else
165 usec_initialized = now(CLOCK_MONOTONIC);
166
167 r = snprintf(num, sizeof(num), USEC_FMT, usec_initialized);
168 if (r < 0)
169 return -errno;
170
171 r = device_set_usec_initialized(device, num);
172 if (r < 0)
173 return r;
174
175 return 0;
176 }
177
178 static int device_read_db(sd_device *device) {
179 _cleanup_free_ char *db = NULL;
180 char *path;
181 const char *id, *value;
182 char key;
183 size_t db_len;
184 unsigned i;
185 int r;
186
187 enum {
188 PRE_KEY,
189 KEY,
190 PRE_VALUE,
191 VALUE,
192 INVALID_LINE,
193 } state = PRE_KEY;
194
195 assert(device);
196
197 if (device->db_loaded || device->sealed)
198 return 0;
199
200 r = device_get_id_filename(device, &id);
201 if (r < 0)
202 return r;
203
204 path = strjoina("/run/udev/data/", id);
205
206 r = read_full_file(path, &db, &db_len);
207 if (r < 0) {
208 if (r == -ENOENT)
209 return 0;
210 else
211 return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path);
212 }
213
214 /* devices with a database entry are initialized */
215 device_set_is_initialized(device);
216
217 for (i = 0; i < db_len; i++) {
218 switch (state) {
219 case PRE_KEY:
220 if (!strchr(NEWLINE, db[i])) {
221 key = db[i];
222
223 state = KEY;
224 }
225
226 break;
227 case KEY:
228 if (db[i] != ':') {
229 log_debug("sd-device: ignoring invalid db entry with key '%c'", key);
230
231 state = INVALID_LINE;
232 } else {
233 db[i] = '\0';
234
235 state = PRE_VALUE;
236 }
237
238 break;
239 case PRE_VALUE:
240 value = &db[i];
241
242 state = VALUE;
243
244 break;
245 case INVALID_LINE:
246 if (strchr(NEWLINE, db[i]))
247 state = PRE_KEY;
248
249 break;
250 case VALUE:
251 if (strchr(NEWLINE, db[i])) {
252 db[i] = '\0';
253 r = handle_db_line(device, key, value);
254 if (r < 0)
255 log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value);
256
257 state = PRE_KEY;
258 }
259
260 break;
261 default:
262 assert_not_reached("invalid state when parsing db");
263 }
264 }
265
266 device->db_loaded = true;
267
268 return 0;
269 }
270
271 uint64_t device_get_properties_generation(sd_device *device) {
272 assert(device);
273
274 return device->properties_generation;
275 }
276
277 uint64_t device_get_tags_generation(sd_device *device) {
278 assert(device);
279
280 return device->tags_generation;
281 }
282
283 uint64_t device_get_devlinks_generation(sd_device *device) {
284 assert(device);
285
286 return device->devlinks_generation;
287 }
288
289 int device_get_devnode_mode(sd_device *device, mode_t *mode) {
290 int r;
291
292 assert(device);
293 assert(mode);
294
295 r = device_read_db(device);
296 if (r < 0)
297 return r;
298
299 *mode = device->devmode;
300
301 return 0;
302 }
303
304 int device_get_devnode_uid(sd_device *device, uid_t *uid) {
305 int r;
306
307 assert(device);
308 assert(uid);
309
310 r = device_read_db(device);
311 if (r < 0)
312 return r;
313
314 *uid = device->devuid;
315
316 return 0;
317 }
318
319 static int device_set_devuid(sd_device *device, const char *uid) {
320 unsigned u;
321 int r;
322
323 assert(device);
324 assert(uid);
325
326 r = safe_atou(uid, &u);
327 if (r < 0)
328 return r;
329
330 r = device_add_property_internal(device, "DEVUID", uid);
331 if (r < 0)
332 return r;
333
334 device->devuid = u;
335
336 return 0;
337 }
338
339 int device_get_devnode_gid(sd_device *device, gid_t *gid) {
340 int r;
341
342 assert(device);
343 assert(gid);
344
345 r = device_read_db(device);
346 if (r < 0)
347 return r;
348
349 *gid = device->devgid;
350
351 return 0;
352 }
353
354 static int device_set_devgid(sd_device *device, const char *gid) {
355 unsigned g;
356 int r;
357
358 assert(device);
359 assert(gid);
360
361 r = safe_atou(gid, &g);
362 if (r < 0)
363 return r;
364
365 r = device_add_property_internal(device, "DEVGID", gid);
366 if (r < 0)
367 return r;
368
369 device->devgid = g;
370
371 return 0;
372 }
373
374 static int device_amend(sd_device *device, const char *key, const char *value) {
375 int r;
376
377 assert(device);
378 assert(key);
379 assert(value);
380
381 if (streq(key, "DEVPATH")) {
382 char *path;
383
384 path = strjoina("/sys", value);
385
386 /* the caller must verify or trust this data (e.g., if it comes from the kernel) */
387 r = device_set_syspath(device, path, false);
388 if (r < 0)
389 return log_debug_errno(r, "sd-device: could not set syspath to '%s': %m", path);
390 } else if (streq(key, "SUBSYSTEM")) {
391 r = device_set_subsystem(device, value);
392 if (r < 0)
393 return log_debug_errno(r, "sd-device: could not set subsystem to '%s': %m", value);
394 } else if (streq(key, "DEVTYPE")) {
395 r = device_set_devtype(device, value);
396 if (r < 0)
397 return log_debug_errno(r, "sd-device: could not set devtype to '%s': %m", value);
398 } else if (streq(key, "DEVNAME")) {
399 r = device_set_devname(device, value);
400 if (r < 0)
401 return log_debug_errno(r, "sd-device: could not set devname to '%s': %m", value);
402 } else if (streq(key, "USEC_INITIALIZED")) {
403 r = device_set_usec_initialized(device, value);
404 if (r < 0)
405 return log_debug_errno(r, "sd-device: could not set usec-initialized to '%s': %m", value);
406 } else if (streq(key, "DRIVER")) {
407 r = device_set_driver(device, value);
408 if (r < 0)
409 return log_debug_errno(r, "sd-device: could not set driver to '%s': %m", value);
410 } else if (streq(key, "IFINDEX")) {
411 r = device_set_ifindex(device, value);
412 if (r < 0)
413 return log_debug_errno(r, "sd-device: could not set ifindex to '%s': %m", value);
414 } else if (streq(key, "DEVMODE")) {
415 r = device_set_devmode(device, value);
416 if (r < 0)
417 return log_debug_errno(r, "sd-device: could not set devmode to '%s': %m", value);
418 } else if (streq(key, "DEVUID")) {
419 r = device_set_devuid(device, value);
420 if (r < 0)
421 return log_debug_errno(r, "sd-device: could not set devuid to '%s': %m", value);
422 } else if (streq(key, "DEVGID")) {
423 r = device_set_devgid(device, value);
424 if (r < 0)
425 return log_debug_errno(r, "sd-device: could not set devgid to '%s': %m", value);
426 } else if (streq(key, "DEVLINKS")) {
427 const char *word, *state;
428 size_t l;
429
430 FOREACH_WORD(word, l, value, state) {
431 char devlink[l + 1];
432
433 strncpy(devlink, word, l);
434 devlink[l] = '\0';
435
436 r = device_add_devlink(device, devlink);
437 if (r < 0)
438 return log_debug_errno(r, "sd-device: could not add devlink '%s': %m", devlink);
439 }
440 } else if (streq(key, "TAGS")) {
441 const char *word, *state;
442 size_t l;
443
444 FOREACH_WORD_SEPARATOR(word, l, value, ":", state) {
445 char tag[l + 1];
446
447 (void)strncpy(tag, word, l);
448 tag[l] = '\0';
449
450 r = device_add_tag(device, tag);
451 if (r < 0)
452 return log_debug_errno(r, "sd-device: could not add tag '%s': %m", tag);
453 }
454 } else {
455 r = device_add_property_internal(device, key, value);
456 if (r < 0)
457 return log_debug_errno(r, "sd-device: could not add property '%s=%s': %m", key, value);
458 }
459
460 return 0;
461 }
462
463 static const char* const device_action_table[_DEVICE_ACTION_MAX] = {
464 [DEVICE_ACTION_ADD] = "add",
465 [DEVICE_ACTION_REMOVE] = "remove",
466 [DEVICE_ACTION_CHANGE] = "change",
467 [DEVICE_ACTION_MOVE] = "move",
468 [DEVICE_ACTION_ONLINE] = "online",
469 [DEVICE_ACTION_OFFLINE] = "offline",
470 [DEVICE_ACTION_BIND] = "bind",
471 [DEVICE_ACTION_UNBIND] = "unbind",
472 };
473
474 DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction);
475
476 static int device_append(sd_device *device, char *key, const char **_major, const char **_minor, uint64_t *_seqnum,
477 DeviceAction *_action) {
478 DeviceAction action = _DEVICE_ACTION_INVALID;
479 uint64_t seqnum = 0;
480 const char *major = NULL, *minor = NULL;
481 char *value;
482 int r;
483
484 assert(device);
485 assert(key);
486 assert(_major);
487 assert(_minor);
488 assert(_seqnum);
489 assert(_action);
490
491 value = strchr(key, '=');
492 if (!value) {
493 log_debug("sd-device: not a key-value pair: '%s'", key);
494 return -EINVAL;
495 }
496
497 *value = '\0';
498
499 value++;
500
501 if (streq(key, "MAJOR"))
502 major = value;
503 else if (streq(key, "MINOR"))
504 minor = value;
505 else {
506 if (streq(key, "ACTION")) {
507 action = device_action_from_string(value);
508 if (action == _DEVICE_ACTION_INVALID)
509 return -EINVAL;
510 } else if (streq(key, "SEQNUM")) {
511 r = safe_atou64(value, &seqnum);
512 if (r < 0)
513 return r;
514 else if (seqnum == 0)
515 /* kernel only sends seqnum > 0 */
516 return -EINVAL;
517 }
518
519 r = device_amend(device, key, value);
520 if (r < 0)
521 return r;
522 }
523
524 if (major != 0)
525 *_major = major;
526
527 if (minor != 0)
528 *_minor = minor;
529
530 if (action != _DEVICE_ACTION_INVALID)
531 *_action = action;
532
533 if (seqnum > 0)
534 *_seqnum = seqnum;
535
536 return 0;
537 }
538
539 void device_seal(sd_device *device) {
540 assert(device);
541
542 device->sealed = true;
543 }
544
545 static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum) {
546 assert(device);
547
548 if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) {
549 log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum");
550 return -EINVAL;
551 }
552
553 device->sealed = true;
554
555 return 0;
556 }
557
558 int device_new_from_strv(sd_device **ret, char **strv) {
559 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
560 char **key;
561 const char *major = NULL, *minor = NULL;
562 DeviceAction action = _DEVICE_ACTION_INVALID;
563 uint64_t seqnum;
564 int r;
565
566 assert(ret);
567 assert(strv);
568
569 r = device_new_aux(&device);
570 if (r < 0)
571 return r;
572
573 STRV_FOREACH(key, strv) {
574 r = device_append(device, *key, &major, &minor, &seqnum, &action);
575 if (r < 0)
576 return r;
577 }
578
579 if (major) {
580 r = device_set_devnum(device, major, minor);
581 if (r < 0)
582 return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
583 }
584
585 r = device_verify(device, action, seqnum);
586 if (r < 0)
587 return r;
588
589 *ret = TAKE_PTR(device);
590
591 return 0;
592 }
593
594 int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
595 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
596 const char *major = NULL, *minor = NULL;
597 DeviceAction action = _DEVICE_ACTION_INVALID;
598 uint64_t seqnum;
599 unsigned i = 0;
600 int r;
601
602 assert(ret);
603 assert(nulstr);
604 assert(len);
605
606 r = device_new_aux(&device);
607 if (r < 0)
608 return r;
609
610 while (i < len) {
611 char *key;
612 const char *end;
613
614 key = (char*)&nulstr[i];
615 end = memchr(key, '\0', len - i);
616 if (!end) {
617 log_debug("sd-device: failed to parse nulstr");
618 return -EINVAL;
619 }
620 i += end - key + 1;
621
622 r = device_append(device, key, &major, &minor, &seqnum, &action);
623 if (r < 0)
624 return r;
625 }
626
627 if (major) {
628 r = device_set_devnum(device, major, minor);
629 if (r < 0)
630 return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
631 }
632
633 r = device_verify(device, action, seqnum);
634 if (r < 0)
635 return r;
636
637 *ret = TAKE_PTR(device);
638
639 return 0;
640 }
641
642 static int device_update_properties_bufs(sd_device *device) {
643 const char *val, *prop;
644 _cleanup_free_ char **buf_strv = NULL;
645 _cleanup_free_ uint8_t *buf_nulstr = NULL;
646 size_t allocated_nulstr = 0;
647 size_t nulstr_len = 0, num = 0, i = 0;
648
649 assert(device);
650
651 if (!device->properties_buf_outdated)
652 return 0;
653
654 FOREACH_DEVICE_PROPERTY(device, prop, val) {
655 size_t len = 0;
656
657 len = strlen(prop) + 1 + strlen(val);
658
659 buf_nulstr = GREEDY_REALLOC0(buf_nulstr, allocated_nulstr, nulstr_len + len + 2);
660 if (!buf_nulstr)
661 return -ENOMEM;
662
663 strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
664 nulstr_len += len + 1;
665 ++num;
666 }
667
668 /* build buf_strv from buf_nulstr */
669 buf_strv = new0(char *, num + 1);
670 if (!buf_strv)
671 return -ENOMEM;
672
673 NULSTR_FOREACH(val, (char*) buf_nulstr) {
674 buf_strv[i] = (char *) val;
675 assert(i < num);
676 i++;
677 }
678
679 free_and_replace(device->properties_nulstr, buf_nulstr);
680 device->properties_nulstr_len = nulstr_len;
681 free_and_replace(device->properties_strv, buf_strv);
682
683 device->properties_buf_outdated = false;
684
685 return 0;
686 }
687
688 int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
689 int r;
690
691 assert(device);
692 assert(nulstr);
693 assert(len);
694
695 r = device_update_properties_bufs(device);
696 if (r < 0)
697 return r;
698
699 *nulstr = device->properties_nulstr;
700 *len = device->properties_nulstr_len;
701
702 return 0;
703 }
704
705 int device_get_properties_strv(sd_device *device, char ***strv) {
706 int r;
707
708 assert(device);
709 assert(strv);
710
711 r = device_update_properties_bufs(device);
712 if (r < 0)
713 return r;
714
715 *strv = device->properties_strv;
716
717 return 0;
718 }
719
720 int device_get_devlink_priority(sd_device *device, int *priority) {
721 int r;
722
723 assert(device);
724 assert(priority);
725
726 r = device_read_db(device);
727 if (r < 0)
728 return r;
729
730 *priority = device->devlink_priority;
731
732 return 0;
733 }
734
735 int device_get_watch_handle(sd_device *device, int *handle) {
736 int r;
737
738 assert(device);
739 assert(handle);
740
741 r = device_read_db(device);
742 if (r < 0)
743 return r;
744
745 *handle = device->watch_handle;
746
747 return 0;
748 }
749
750 void device_set_watch_handle(sd_device *device, int handle) {
751 assert(device);
752
753 device->watch_handle = handle;
754 }
755
756 int device_rename(sd_device *device, const char *name) {
757 _cleanup_free_ char *dirname = NULL;
758 char *new_syspath;
759 const char *interface;
760 int r;
761
762 assert(device);
763 assert(name);
764
765 dirname = dirname_malloc(device->syspath);
766 if (!dirname)
767 return -ENOMEM;
768
769 new_syspath = strjoina(dirname, "/", name);
770
771 /* the user must trust that the new name is correct */
772 r = device_set_syspath(device, new_syspath, false);
773 if (r < 0)
774 return r;
775
776 r = sd_device_get_property_value(device, "INTERFACE", &interface);
777 if (r >= 0) {
778 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
779 r = device_add_property_internal(device, "INTERFACE_OLD", interface);
780 if (r < 0)
781 return r;
782
783 r = device_add_property_internal(device, "INTERFACE", name);
784 if (r < 0)
785 return r;
786 } else if (r != -ENOENT)
787 return r;
788
789 return 0;
790 }
791
792 int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
793 _cleanup_(sd_device_unrefp) sd_device *ret = NULL;
794 int r;
795
796 assert(old_device);
797 assert(new_device);
798
799 r = device_new_aux(&ret);
800 if (r < 0)
801 return r;
802
803 r = device_set_syspath(ret, old_device->syspath, false);
804 if (r < 0)
805 return r;
806
807 r = device_set_subsystem(ret, old_device->subsystem);
808 if (r < 0)
809 return r;
810
811 ret->devnum = old_device->devnum;
812
813 *new_device = TAKE_PTR(ret);
814
815 return 0;
816 }
817
818 int device_clone_with_db(sd_device *old_device, sd_device **new_device) {
819 _cleanup_(sd_device_unrefp) sd_device *ret = NULL;
820 int r;
821
822 assert(old_device);
823 assert(new_device);
824
825 r = device_shallow_clone(old_device, &ret);
826 if (r < 0)
827 return r;
828
829 r = device_read_db(ret);
830 if (r < 0)
831 return r;
832
833 ret->sealed = true;
834
835 *new_device = TAKE_PTR(ret);
836
837 return 0;
838 }
839
840 int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) {
841 _cleanup_(sd_device_unrefp) sd_device *ret = NULL;
842 int r;
843
844 assert(new_device);
845 assert(syspath);
846 assert(action);
847
848 r = sd_device_new_from_syspath(&ret, syspath);
849 if (r < 0)
850 return r;
851
852 r = device_read_uevent_file(ret);
853 if (r < 0)
854 return r;
855
856 r = device_add_property_internal(ret, "ACTION", action);
857 if (r < 0)
858 return r;
859
860 *new_device = TAKE_PTR(ret);
861
862 return 0;
863 }
864
865 int device_copy_properties(sd_device *device_dst, sd_device *device_src) {
866 const char *property, *value;
867 int r;
868
869 assert(device_dst);
870 assert(device_src);
871
872 FOREACH_DEVICE_PROPERTY(device_src, property, value) {
873 r = device_add_property(device_dst, property, value);
874 if (r < 0)
875 return r;
876 }
877
878 return 0;
879 }
880
881 void device_cleanup_tags(sd_device *device) {
882 assert(device);
883
884 set_free_free(device->tags);
885 device->tags = NULL;
886 device->property_tags_outdated = true;
887 device->tags_generation++;
888 }
889
890 void device_cleanup_devlinks(sd_device *device) {
891 assert(device);
892
893 set_free_free(device->devlinks);
894 device->devlinks = NULL;
895 device->property_devlinks_outdated = true;
896 device->devlinks_generation++;
897 }
898
899 void device_remove_tag(sd_device *device, const char *tag) {
900 assert(device);
901 assert(tag);
902
903 free(set_remove(device->tags, tag));
904 device->property_tags_outdated = true;
905 device->tags_generation++;
906 }
907
908 static int device_tag(sd_device *device, const char *tag, bool add) {
909 const char *id;
910 char *path;
911 int r;
912
913 assert(device);
914 assert(tag);
915
916 r = device_get_id_filename(device, &id);
917 if (r < 0)
918 return r;
919
920 path = strjoina("/run/udev/tags/", tag, "/", id);
921
922 if (add) {
923 r = touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
924 if (r < 0)
925 return r;
926 } else {
927 r = unlink(path);
928 if (r < 0 && errno != ENOENT)
929 return -errno;
930 }
931
932 return 0;
933 }
934
935 int device_tag_index(sd_device *device, sd_device *device_old, bool add) {
936 const char *tag;
937 int r = 0, k;
938
939 if (add && device_old) {
940 /* delete possible left-over tags */
941 FOREACH_DEVICE_TAG(device_old, tag) {
942 if (!sd_device_has_tag(device, tag)) {
943 k = device_tag(device_old, tag, false);
944 if (r >= 0 && k < 0)
945 r = k;
946 }
947 }
948 }
949
950 FOREACH_DEVICE_TAG(device, tag) {
951 k = device_tag(device, tag, add);
952 if (r >= 0 && k < 0)
953 r = k;
954 }
955
956 return r;
957 }
958
959 static bool device_has_info(sd_device *device) {
960 assert(device);
961
962 if (!set_isempty(device->devlinks))
963 return true;
964
965 if (device->devlink_priority != 0)
966 return true;
967
968 if (!ordered_hashmap_isempty(device->properties_db))
969 return true;
970
971 if (!set_isempty(device->tags))
972 return true;
973
974 if (device->watch_handle >= 0)
975 return true;
976
977 return false;
978 }
979
980 void device_set_db_persist(sd_device *device) {
981 assert(device);
982
983 device->db_persist = true;
984 }
985
986 int device_update_db(sd_device *device) {
987 const char *id;
988 char *path;
989 _cleanup_fclose_ FILE *f = NULL;
990 _cleanup_free_ char *path_tmp = NULL;
991 bool has_info;
992 int r;
993
994 assert(device);
995
996 has_info = device_has_info(device);
997
998 r = device_get_id_filename(device, &id);
999 if (r < 0)
1000 return r;
1001
1002 path = strjoina("/run/udev/data/", id);
1003
1004 /* do not store anything for otherwise empty devices */
1005 if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
1006 r = unlink(path);
1007 if (r < 0 && errno != ENOENT)
1008 return -errno;
1009
1010 return 0;
1011 }
1012
1013 /* write a database file */
1014 r = mkdir_parents(path, 0755);
1015 if (r < 0)
1016 return r;
1017
1018 r = fopen_temporary(path, &f, &path_tmp);
1019 if (r < 0)
1020 return r;
1021
1022 /*
1023 * set 'sticky' bit to indicate that we should not clean the
1024 * database when we transition from initramfs to the real root
1025 */
1026 if (device->db_persist) {
1027 r = fchmod(fileno(f), 01644);
1028 if (r < 0) {
1029 r = -errno;
1030 goto fail;
1031 }
1032 } else {
1033 r = fchmod(fileno(f), 0644);
1034 if (r < 0) {
1035 r = -errno;
1036 goto fail;
1037 }
1038 }
1039
1040 if (has_info) {
1041 const char *property, *value, *tag;
1042 Iterator i;
1043
1044 if (major(device->devnum) > 0) {
1045 const char *devlink;
1046
1047 FOREACH_DEVICE_DEVLINK(device, devlink)
1048 fprintf(f, "S:%s\n", devlink + STRLEN("/dev/"));
1049
1050 if (device->devlink_priority != 0)
1051 fprintf(f, "L:%i\n", device->devlink_priority);
1052
1053 if (device->watch_handle >= 0)
1054 fprintf(f, "W:%i\n", device->watch_handle);
1055 }
1056
1057 if (device->usec_initialized > 0)
1058 fprintf(f, "I:"USEC_FMT"\n", device->usec_initialized);
1059
1060 ORDERED_HASHMAP_FOREACH_KEY(value, property, device->properties_db, i)
1061 fprintf(f, "E:%s=%s\n", property, value);
1062
1063 FOREACH_DEVICE_TAG(device, tag)
1064 fprintf(f, "G:%s\n", tag);
1065 }
1066
1067 r = fflush_and_check(f);
1068 if (r < 0)
1069 goto fail;
1070
1071 r = rename(path_tmp, path);
1072 if (r < 0) {
1073 r = -errno;
1074 goto fail;
1075 }
1076
1077 log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty",
1078 path, device->devpath);
1079
1080 return 0;
1081
1082 fail:
1083 (void) unlink(path);
1084 (void) unlink(path_tmp);
1085
1086 return log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath);
1087 }
1088
1089 int device_delete_db(sd_device *device) {
1090 const char *id;
1091 char *path;
1092 int r;
1093
1094 assert(device);
1095
1096 r = device_get_id_filename(device, &id);
1097 if (r < 0)
1098 return r;
1099
1100 path = strjoina("/run/udev/data/", id);
1101
1102 r = unlink(path);
1103 if (r < 0 && errno != ENOENT)
1104 return -errno;
1105
1106 return 0;
1107 }
1108
1109 int device_read_db_force(sd_device *device) {
1110 assert(device);
1111
1112 return device_read_db_aux(device, true);
1113 }