chiark / gitweb /
86d760cddf0f788e4c6ac44ea1778c46f3feb15f
[elogind.git] / src / libelogind / 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;
427
428                         devlink = strndupa(word, l);
429
430                         r = device_add_devlink(device, devlink);
431                         if (r < 0)
432                                 return log_debug_errno(r, "sd-device: could not add devlink '%s': %m", devlink);
433                 }
434         } else if (streq(key, "TAGS")) {
435                 const char *word, *state;
436                 size_t l;
437
438                 FOREACH_WORD_SEPARATOR(word, l, value, ":", state) {
439                         char *tag;
440
441                         tag = strndupa(word, l);
442
443                         r = device_add_tag(device, tag);
444                         if (r < 0)
445                                 return log_debug_errno(r, "sd-device: could not add tag '%s': %m", tag);
446                 }
447         } else {
448                 r = device_add_property_internal(device, key, value);
449                 if (r < 0)
450                         return log_debug_errno(r, "sd-device: could not add property '%s=%s': %m", key, value);
451         }
452
453         return 0;
454 }
455
456 static const char* const device_action_table[_DEVICE_ACTION_MAX] = {
457         [DEVICE_ACTION_ADD] = "add",
458         [DEVICE_ACTION_REMOVE] = "remove",
459         [DEVICE_ACTION_CHANGE] = "change",
460         [DEVICE_ACTION_MOVE] = "move",
461         [DEVICE_ACTION_ONLINE] = "online",
462         [DEVICE_ACTION_OFFLINE] = "offline",
463 };
464
465 DEFINE_STRING_TABLE_LOOKUP(device_action, DeviceAction);
466
467 static int device_append(sd_device *device, char *key, const char **_major, const char **_minor, uint64_t *_seqnum,
468                          DeviceAction *_action) {
469         DeviceAction action = _DEVICE_ACTION_INVALID;
470         uint64_t seqnum = 0;
471         const char *major = NULL, *minor = NULL;
472         char *value;
473         int r;
474
475         assert(device);
476         assert(key);
477         assert(_major);
478         assert(_minor);
479         assert(_seqnum);
480         assert(_action);
481
482         value = strchr(key, '=');
483         if (!value) {
484                 log_debug("sd-device: not a key-value pair: '%s'", key);
485                 return -EINVAL;
486         }
487
488         *value = '\0';
489
490         value++;
491
492         if (streq(key, "MAJOR"))
493                 major = value;
494         else if (streq(key, "MINOR"))
495                 minor = value;
496         else {
497                 if (streq(key, "ACTION")) {
498                         action = device_action_from_string(value);
499                         if (action == _DEVICE_ACTION_INVALID)
500                                 return -EINVAL;
501                 } else if (streq(key, "SEQNUM")) {
502                         r = safe_atou64(value, &seqnum);
503                         if (r < 0)
504                                 return r;
505                         else if (seqnum == 0)
506                                  /* kernel only sends seqnum > 0 */
507                                 return -EINVAL;
508                 }
509
510                 r = device_amend(device, key, value);
511                 if (r < 0)
512                         return r;
513         }
514
515         if (major != 0)
516                 *_major = major;
517
518         if (minor != 0)
519                 *_minor = minor;
520
521         if (action != _DEVICE_ACTION_INVALID)
522                 *_action = action;
523
524         if (seqnum > 0)
525                 *_seqnum = seqnum;
526
527         return 0;
528 }
529
530 void device_seal(sd_device *device) {
531         assert(device);
532
533         device->sealed = true;
534 }
535
536 static int device_verify(sd_device *device, DeviceAction action, uint64_t seqnum) {
537         assert(device);
538
539         if (!device->devpath || !device->subsystem || action == _DEVICE_ACTION_INVALID || seqnum == 0) {
540                 log_debug("sd-device: device created from strv lacks devpath, subsystem, action or seqnum");
541                 return -EINVAL;
542         }
543
544         device->sealed = true;
545
546         return 0;
547 }
548
549 int device_new_from_strv(sd_device **ret, char **strv) {
550         _cleanup_device_unref_ sd_device *device = NULL;
551         char **key;
552         const char *major = NULL, *minor = NULL;
553         DeviceAction action = _DEVICE_ACTION_INVALID;
554         uint64_t seqnum;
555         int r;
556
557         assert(ret);
558         assert(strv);
559
560         r = device_new_aux(&device);
561         if (r < 0)
562                 return r;
563
564         STRV_FOREACH(key, strv) {
565                 r = device_append(device, *key, &major, &minor, &seqnum, &action);
566                 if (r < 0)
567                         return r;
568         }
569
570         if (major) {
571                 r = device_set_devnum(device, major, minor);
572                 if (r < 0)
573                         return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
574         }
575
576         r = device_verify(device, action, seqnum);
577         if (r < 0)
578                 return r;
579
580         *ret = device;
581         device = NULL;
582
583         return 0;
584 }
585
586 int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
587         _cleanup_device_unref_ sd_device *device = NULL;
588         const char *major = NULL, *minor = NULL;
589         DeviceAction action = _DEVICE_ACTION_INVALID;
590         uint64_t seqnum;
591         unsigned i = 0;
592         int r;
593
594         assert(ret);
595         assert(nulstr);
596         assert(len);
597
598         r = device_new_aux(&device);
599         if (r < 0)
600                 return r;
601
602         while (i < len) {
603                 char *key;
604                 const char *end;
605
606                 key = (char*)&nulstr[i];
607                 end = memchr(key, '\0', len - i);
608                 if (!end) {
609                         log_debug("sd-device: failed to parse nulstr");
610                         return -EINVAL;
611                 }
612                 i += end - key + 1;
613
614                 r = device_append(device, key, &major, &minor, &seqnum, &action);
615                 if (r < 0)
616                         return r;
617         }
618
619         if (major) {
620                 r = device_set_devnum(device, major, minor);
621                 if (r < 0)
622                         return log_debug_errno(r, "sd-device: could not set devnum %s:%s: %m", major, minor);
623         }
624
625         r = device_verify(device, action, seqnum);
626         if (r < 0)
627                 return r;
628
629         *ret = device;
630         device = NULL;
631
632         return 0;
633 }
634
635 static int device_update_properties_bufs(sd_device *device) {
636         const char *val, *prop;
637         char **buf_strv = NULL;
638         uint8_t *buf_nulstr = NULL;
639         size_t allocated_nulstr = 0, allocated_strv = 0;
640         size_t nulstr_len = 0, strv_size = 0;
641
642         assert(device);
643
644         if (!device->properties_buf_outdated)
645                 return 0;
646
647         FOREACH_DEVICE_PROPERTY(device, prop, val) {
648                 size_t len = 0;
649
650                 len = strlen(prop) + 1 + strlen(val);
651
652                 buf_nulstr = GREEDY_REALLOC0(buf_nulstr, allocated_nulstr, nulstr_len + len + 2);
653                 if (!buf_nulstr)
654                         return -ENOMEM;
655
656                 buf_strv = GREEDY_REALLOC0(buf_strv, allocated_strv, strv_size + 2);
657                 if (!buf_strv)
658                         return -ENOMEM;
659
660                 buf_strv[++ strv_size] = (char *)&buf_nulstr[nulstr_len];
661                 strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
662                 nulstr_len += len + 1;
663         }
664
665         free(device->properties_nulstr);
666         free(device->properties_strv);
667         device->properties_nulstr = buf_nulstr;
668         device->properties_nulstr_len = nulstr_len;
669         device->properties_strv = buf_strv;
670
671         device->properties_buf_outdated = false;
672
673         return 0;
674 }
675
676 int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
677         int r;
678
679         assert(device);
680         assert(nulstr);
681         assert(len);
682
683         r = device_update_properties_bufs(device);
684         if (r < 0)
685                 return r;
686
687         *nulstr = device->properties_nulstr;
688         *len = device->properties_nulstr_len;
689
690         return 0;
691 }
692
693 int device_get_properties_strv(sd_device *device, char ***strv) {
694         int r;
695
696         assert(device);
697         assert(strv);
698
699         r = device_update_properties_bufs(device);
700         if (r < 0)
701                 return r;
702
703         *strv = device->properties_strv;
704
705         return 0;
706 }
707
708 int device_get_devlink_priority(sd_device *device, int *priority) {
709         int r;
710
711         assert(device);
712         assert(priority);
713
714         r = device_read_db(device);
715         if (r < 0)
716                 return r;
717
718         *priority = device->devlink_priority;
719
720         return 0;
721 }
722
723 int device_get_watch_handle(sd_device *device, int *handle) {
724         int r;
725
726         assert(device);
727         assert(handle);
728
729         r = device_read_db(device);
730         if (r < 0)
731                 return r;
732
733         *handle = device->watch_handle;
734
735         return 0;
736 }
737
738 void device_set_watch_handle(sd_device *device, int handle) {
739         assert(device);
740
741         device->watch_handle = handle;
742 }
743
744 int device_rename(sd_device *device, const char *name) {
745         _cleanup_free_ char *dirname = NULL;
746         char *new_syspath;
747         const char *interface;
748         int r;
749
750         assert(device);
751         assert(name);
752
753         dirname = dirname_malloc(device->syspath);
754         if (!dirname)
755                 return -ENOMEM;
756
757         new_syspath = strjoina(dirname, "/", name);
758
759         /* the user must trust that the new name is correct */
760         r = device_set_syspath(device, new_syspath, false);
761         if (r < 0)
762                 return r;
763
764         r = sd_device_get_property_value(device, "INTERFACE", &interface);
765         if (r >= 0) {
766                 r = device_add_property_internal(device, "INTERFACE", name);
767                 if (r < 0)
768                         return r;
769
770                 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
771                 r = device_add_property_internal(device, "INTERFACE_OLD", interface);
772                 if (r < 0)
773                         return r;
774         } else if (r != -ENOENT)
775                 return r;
776
777         return 0;
778 }
779
780 int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
781         _cleanup_device_unref_ sd_device *ret = NULL;
782         int r;
783
784         assert(old_device);
785         assert(new_device);
786
787         r = device_new_aux(&ret);
788         if (r < 0)
789                 return r;
790
791         r = device_set_syspath(ret, old_device->syspath, false);
792         if (r < 0)
793                 return r;
794
795         r = device_set_subsystem(ret, old_device->subsystem);
796         if (r < 0)
797                 return r;
798
799         ret->devnum = old_device->devnum;
800
801         *new_device = ret;
802         ret = NULL;
803
804         return 0;
805 }
806
807 int device_clone_with_db(sd_device *old_device, sd_device **new_device) {
808         _cleanup_device_unref_ sd_device *ret = NULL;
809         int r;
810
811         assert(old_device);
812         assert(new_device);
813
814         r = device_shallow_clone(old_device, &ret);
815         if (r < 0)
816                 return r;
817
818         r = device_read_db(ret);
819         if (r < 0)
820                 return r;
821
822         ret->sealed = true;
823
824         *new_device = ret;
825         ret = NULL;
826
827         return 0;
828 }
829
830 int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) {
831         _cleanup_device_unref_ sd_device *ret = NULL;
832         int r;
833
834         assert(new_device);
835         assert(syspath);
836         assert(action);
837
838         r = sd_device_new_from_syspath(&ret, syspath);
839         if (r < 0)
840                 return r;
841
842         r = device_read_uevent_file(ret);
843         if (r < 0)
844                 return r;
845
846         r = device_add_property_internal(ret, "ACTION", action);
847         if (r < 0)
848                 return r;
849
850         *new_device = ret;
851         ret = NULL;
852
853         return 0;
854 }
855
856 int device_copy_properties(sd_device *device_dst, sd_device *device_src) {
857         const char *property, *value;
858         int r;
859
860         assert(device_dst);
861         assert(device_src);
862
863         FOREACH_DEVICE_PROPERTY(device_src, property, value) {
864                 r = device_add_property(device_dst, property, value);
865                 if (r < 0)
866                         return r;
867         }
868
869         return 0;
870 }
871
872 void device_cleanup_tags(sd_device *device) {
873         assert(device);
874
875         set_free_free(device->tags);
876         device->tags = NULL;
877         device->property_tags_outdated = true;
878         device->tags_generation ++;
879 }
880
881 void device_cleanup_devlinks(sd_device *device) {
882         assert(device);
883
884         set_free_free(device->devlinks);
885         device->devlinks = NULL;
886         device->property_devlinks_outdated = true;
887         device->devlinks_generation ++;
888 }
889
890 void device_remove_tag(sd_device *device, const char *tag) {
891         assert(device);
892         assert(tag);
893
894         free(set_remove(device->tags, tag));
895         device->property_tags_outdated = true;
896         device->tags_generation ++;
897 }
898
899 static int device_tag(sd_device *device, const char *tag, bool add) {
900         const char *id;
901         char *path;
902         int r;
903
904         assert(device);
905         assert(tag);
906
907         r = device_get_id_filename(device, &id);
908         if (r < 0)
909                 return r;
910
911         path = strjoina("/run/udev/tags/", tag, "/", id);
912
913         if (add) {
914                 r = touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
915                 if (r < 0)
916                         return r;
917         } else {
918                 r = unlink(path);
919                 if (r < 0 && errno != ENOENT)
920                         return -errno;
921         }
922
923         return 0;
924 }
925
926 int device_tag_index(sd_device *device, sd_device *device_old, bool add) {
927         const char *tag;
928         int r = 0, k;
929
930         if (add && device_old) {
931                 /* delete possible left-over tags */
932                 FOREACH_DEVICE_TAG(device_old, tag) {
933                         if (!sd_device_has_tag(device, tag)) {
934                                 k = device_tag(device_old, tag, false);
935                                 if (r >= 0 && k < 0)
936                                         r = k;
937                         }
938                 }
939         }
940
941         FOREACH_DEVICE_TAG(device, tag) {
942                 k = device_tag(device, tag, add);
943                 if (r >= 0 && k < 0)
944                         r = k;
945         }
946
947         return r;
948 }
949
950 static bool device_has_info(sd_device *device) {
951         assert(device);
952
953         if (!set_isempty(device->devlinks))
954                 return true;
955
956         if (device->devlink_priority != 0)
957                 return true;
958
959         if (!ordered_hashmap_isempty(device->properties_db))
960                 return true;
961
962         if (!set_isempty(device->tags))
963                 return true;
964
965         if (device->watch_handle >= 0)
966                 return true;
967
968         return false;
969 }
970
971 void device_set_db_persist(sd_device *device) {
972         assert(device);
973
974         device->db_persist = true;
975 }
976
977 int device_update_db(sd_device *device) {
978         const char *id;
979         char *path;
980         _cleanup_fclose_ FILE *f = NULL;
981         _cleanup_free_ char *path_tmp = NULL;
982         bool has_info;
983         int r;
984
985         assert(device);
986
987         has_info = device_has_info(device);
988
989         r = device_get_id_filename(device, &id);
990         if (r < 0)
991                 return r;
992
993         path = strjoina("/run/udev/data/", id);
994
995         /* do not store anything for otherwise empty devices */
996         if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
997                 r = unlink(path);
998                 if (r < 0 && errno != ENOENT)
999                         return -errno;
1000
1001                 return 0;
1002         }
1003
1004         /* write a database file */
1005         r = mkdir_parents(path, 0755);
1006         if (r < 0)
1007                 return r;
1008
1009         r = fopen_temporary(path, &f, &path_tmp);
1010         if (r < 0)
1011                 return r;
1012
1013         /*
1014          * set 'sticky' bit to indicate that we should not clean the
1015          * database when we transition from initramfs to the real root
1016          */
1017         if (device->db_persist) {
1018                 r = fchmod(fileno(f), 01644);
1019                 if (r < 0) {
1020                         r = -errno;
1021                         goto fail;
1022                 }
1023         } else {
1024                 r = fchmod(fileno(f), 0644);
1025                 if (r < 0) {
1026                         r = -errno;
1027                         goto fail;
1028                 }
1029         }
1030
1031         if (has_info) {
1032                 const char *property, *value, *tag;
1033                 Iterator i;
1034
1035                 if (major(device->devnum) > 0) {
1036                         const char *devlink;
1037
1038                         FOREACH_DEVICE_DEVLINK(device, devlink)
1039                                 fprintf(f, "S:%s\n", devlink + strlen("/dev/"));
1040
1041                         if (device->devlink_priority != 0)
1042                                 fprintf(f, "L:%i\n", device->devlink_priority);
1043
1044                         if (device->watch_handle >= 0)
1045                                 fprintf(f, "W:%i\n", device->watch_handle);
1046                 }
1047
1048                 if (device->usec_initialized > 0)
1049                         fprintf(f, "I:"USEC_FMT"\n", device->usec_initialized);
1050
1051                 ORDERED_HASHMAP_FOREACH_KEY(value, property, device->properties_db, i)
1052                         fprintf(f, "E:%s=%s\n", property, value);
1053
1054                 FOREACH_DEVICE_TAG(device, tag)
1055                         fprintf(f, "G:%s\n", tag);
1056         }
1057
1058         r = fflush_and_check(f);
1059         if (r < 0)
1060                 goto fail;
1061
1062         r = rename(path_tmp, path);
1063         if (r < 0) {
1064                 r = -errno;
1065                 goto fail;
1066         }
1067
1068         log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty",
1069                   path, device->devpath);
1070
1071         return 0;
1072
1073 fail:
1074         log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty",
1075                         path, device->devpath);
1076         unlink(path);
1077         unlink(path_tmp);
1078
1079         return r;
1080 }
1081
1082 int device_delete_db(sd_device *device) {
1083         const char *id;
1084         char *path;
1085         int r;
1086
1087         assert(device);
1088
1089         r = device_get_id_filename(device, &id);
1090         if (r < 0)
1091                 return r;
1092
1093         path = strjoina("/run/udev/data/", id);
1094
1095         r = unlink(path);
1096         if (r < 0 && errno != ENOENT)
1097                 return -errno;
1098
1099         return 0;
1100 }