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