chiark / gitweb /
sd-device: fix return codes on error
[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[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         char **buf_strv = NULL;
640         uint8_t *buf_nulstr = NULL;
641         size_t allocated_nulstr = 0, allocated_strv = 0;
642         size_t nulstr_len = 0, strv_size = 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                 buf_strv = GREEDY_REALLOC0(buf_strv, allocated_strv, strv_size + 2);
659                 if (!buf_strv)
660                         return -ENOMEM;
661
662                 buf_strv[++ strv_size] = (char *)&buf_nulstr[nulstr_len];
663                 strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
664                 nulstr_len += len + 1;
665         }
666
667         free(device->properties_nulstr);
668         free(device->properties_strv);
669         device->properties_nulstr = buf_nulstr;
670         device->properties_nulstr_len = nulstr_len;
671         device->properties_strv = buf_strv;
672
673         device->properties_buf_outdated = false;
674
675         return 0;
676 }
677
678 int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
679         int r;
680
681         assert(device);
682         assert(nulstr);
683         assert(len);
684
685         r = device_update_properties_bufs(device);
686         if (r < 0)
687                 return r;
688
689         *nulstr = device->properties_nulstr;
690         *len = device->properties_nulstr_len;
691
692         return 0;
693 }
694
695 int device_get_properties_strv(sd_device *device, char ***strv) {
696         int r;
697
698         assert(device);
699         assert(strv);
700
701         r = device_update_properties_bufs(device);
702         if (r < 0)
703                 return r;
704
705         *strv = device->properties_strv;
706
707         return 0;
708 }
709
710 int device_get_devlink_priority(sd_device *device, int *priority) {
711         int r;
712
713         assert(device);
714         assert(priority);
715
716         r = device_read_db(device);
717         if (r < 0)
718                 return r;
719
720         *priority = device->devlink_priority;
721
722         return 0;
723 }
724
725 int device_get_watch_handle(sd_device *device, int *handle) {
726         int r;
727
728         assert(device);
729         assert(handle);
730
731         r = device_read_db(device);
732         if (r < 0)
733                 return r;
734
735         *handle = device->watch_handle;
736
737         return 0;
738 }
739
740 void device_set_watch_handle(sd_device *device, int handle) {
741         assert(device);
742
743         device->watch_handle = handle;
744 }
745
746 int device_rename(sd_device *device, const char *name) {
747         _cleanup_free_ char *dirname = NULL;
748         char *new_syspath;
749         const char *interface;
750         int r;
751
752         assert(device);
753         assert(name);
754
755         dirname = dirname_malloc(device->syspath);
756         if (!dirname)
757                 return -ENOMEM;
758
759         new_syspath = strjoina(dirname, "/", name);
760
761         /* the user must trust that the new name is correct */
762         r = device_set_syspath(device, new_syspath, false);
763         if (r < 0)
764                 return r;
765
766         r = sd_device_get_property_value(device, "INTERFACE", &interface);
767         if (r >= 0) {
768                 r = device_add_property_internal(device, "INTERFACE", name);
769                 if (r < 0)
770                         return r;
771
772                 /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
773                 r = device_add_property_internal(device, "INTERFACE_OLD", interface);
774                 if (r < 0)
775                         return r;
776         } else if (r != -ENOENT)
777                 return r;
778
779         return 0;
780 }
781
782 int device_shallow_clone(sd_device *old_device, sd_device **new_device) {
783         _cleanup_device_unref_ sd_device *ret = NULL;
784         int r;
785
786         assert(old_device);
787         assert(new_device);
788
789         r = device_new_aux(&ret);
790         if (r < 0)
791                 return r;
792
793         r = device_set_syspath(ret, old_device->syspath, false);
794         if (r < 0)
795                 return r;
796
797         r = device_set_subsystem(ret, old_device->subsystem);
798         if (r < 0)
799                 return r;
800
801         ret->devnum = old_device->devnum;
802
803         *new_device = ret;
804         ret = NULL;
805
806         return 0;
807 }
808
809 int device_clone_with_db(sd_device *old_device, sd_device **new_device) {
810         _cleanup_device_unref_ sd_device *ret = NULL;
811         int r;
812
813         assert(old_device);
814         assert(new_device);
815
816         r = device_shallow_clone(old_device, &ret);
817         if (r < 0)
818                 return r;
819
820         r = device_read_db(ret);
821         if (r < 0)
822                 return r;
823
824         ret->sealed = true;
825
826         *new_device = ret;
827         ret = NULL;
828
829         return 0;
830 }
831
832 int device_new_from_synthetic_event(sd_device **new_device, const char *syspath, const char *action) {
833         _cleanup_device_unref_ sd_device *ret = NULL;
834         int r;
835
836         assert(new_device);
837         assert(syspath);
838         assert(action);
839
840         r = sd_device_new_from_syspath(&ret, syspath);
841         if (r < 0)
842                 return r;
843
844         r = device_read_uevent_file(ret);
845         if (r < 0)
846                 return r;
847
848         r = device_add_property_internal(ret, "ACTION", action);
849         if (r < 0)
850                 return r;
851
852         *new_device = ret;
853         ret = NULL;
854
855         return 0;
856 }
857
858 int device_copy_properties(sd_device *device_dst, sd_device *device_src) {
859         const char *property, *value;
860         int r;
861
862         assert(device_dst);
863         assert(device_src);
864
865         FOREACH_DEVICE_PROPERTY(device_src, property, value) {
866                 r = device_add_property(device_dst, property, value);
867                 if (r < 0)
868                         return r;
869         }
870
871         return 0;
872 }
873
874 void device_cleanup_tags(sd_device *device) {
875         assert(device);
876
877         set_free_free(device->tags);
878         device->tags = NULL;
879         device->property_tags_outdated = true;
880         device->tags_generation ++;
881 }
882
883 void device_cleanup_devlinks(sd_device *device) {
884         assert(device);
885
886         set_free_free(device->devlinks);
887         device->devlinks = NULL;
888         device->property_devlinks_outdated = true;
889         device->devlinks_generation ++;
890 }
891
892 void device_remove_tag(sd_device *device, const char *tag) {
893         assert(device);
894         assert(tag);
895
896         free(set_remove(device->tags, tag));
897         device->property_tags_outdated = true;
898         device->tags_generation ++;
899 }
900
901 static int device_tag(sd_device *device, const char *tag, bool add) {
902         const char *id;
903         char *path;
904         int r;
905
906         assert(device);
907         assert(tag);
908
909         r = device_get_id_filename(device, &id);
910         if (r < 0)
911                 return r;
912
913         path = strjoina("/run/udev/tags/", tag, "/", id);
914
915         if (add) {
916                 r = touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0444);
917                 if (r < 0)
918                         return r;
919         } else {
920                 r = unlink(path);
921                 if (r < 0 && errno != ENOENT)
922                         return -errno;
923         }
924
925         return 0;
926 }
927
928 int device_tag_index(sd_device *device, sd_device *device_old, bool add) {
929         const char *tag;
930         int r = 0, k;
931
932         if (add && device_old) {
933                 /* delete possible left-over tags */
934                 FOREACH_DEVICE_TAG(device_old, tag) {
935                         if (!sd_device_has_tag(device, tag)) {
936                                 k = device_tag(device_old, tag, false);
937                                 if (r >= 0 && k < 0)
938                                         r = k;
939                         }
940                 }
941         }
942
943         FOREACH_DEVICE_TAG(device, tag) {
944                 k = device_tag(device, tag, add);
945                 if (r >= 0 && k < 0)
946                         r = k;
947         }
948
949         return r;
950 }
951
952 static bool device_has_info(sd_device *device) {
953         assert(device);
954
955         if (!set_isempty(device->devlinks))
956                 return true;
957
958         if (device->devlink_priority != 0)
959                 return true;
960
961         if (!ordered_hashmap_isempty(device->properties_db))
962                 return true;
963
964         if (!set_isempty(device->tags))
965                 return true;
966
967         if (device->watch_handle >= 0)
968                 return true;
969
970         return false;
971 }
972
973 void device_set_db_persist(sd_device *device) {
974         assert(device);
975
976         device->db_persist = true;
977 }
978
979 int device_update_db(sd_device *device) {
980         const char *id;
981         char *path;
982         _cleanup_fclose_ FILE *f = NULL;
983         _cleanup_free_ char *path_tmp = NULL;
984         bool has_info;
985         int r;
986
987         assert(device);
988
989         has_info = device_has_info(device);
990
991         r = device_get_id_filename(device, &id);
992         if (r < 0)
993                 return r;
994
995         path = strjoina("/run/udev/data/", id);
996
997         /* do not store anything for otherwise empty devices */
998         if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) {
999                 r = unlink(path);
1000                 if (r < 0 && errno != ENOENT)
1001                         return -errno;
1002
1003                 return 0;
1004         }
1005
1006         /* write a database file */
1007         r = mkdir_parents(path, 0755);
1008         if (r < 0)
1009                 return r;
1010
1011         r = fopen_temporary(path, &f, &path_tmp);
1012         if (r < 0)
1013                 return r;
1014
1015         /*
1016          * set 'sticky' bit to indicate that we should not clean the
1017          * database when we transition from initramfs to the real root
1018          */
1019         if (device->db_persist) {
1020                 r = fchmod(fileno(f), 01644);
1021                 if (r < 0) {
1022                         r = -errno;
1023                         goto fail;
1024                 }
1025         } else {
1026                 r = fchmod(fileno(f), 0644);
1027                 if (r < 0) {
1028                         r = -errno;
1029                         goto fail;
1030                 }
1031         }
1032
1033         if (has_info) {
1034                 const char *property, *value, *tag;
1035                 Iterator i;
1036
1037                 if (major(device->devnum) > 0) {
1038                         const char *devlink;
1039
1040                         FOREACH_DEVICE_DEVLINK(device, devlink)
1041                                 fprintf(f, "S:%s\n", devlink + strlen("/dev/"));
1042
1043                         if (device->devlink_priority != 0)
1044                                 fprintf(f, "L:%i\n", device->devlink_priority);
1045
1046                         if (device->watch_handle >= 0)
1047                                 fprintf(f, "W:%i\n", device->watch_handle);
1048                 }
1049
1050                 if (device->usec_initialized > 0)
1051                         fprintf(f, "I:"USEC_FMT"\n", device->usec_initialized);
1052
1053                 ORDERED_HASHMAP_FOREACH_KEY(value, property, device->properties_db, i)
1054                         fprintf(f, "E:%s=%s\n", property, value);
1055
1056                 FOREACH_DEVICE_TAG(device, tag)
1057                         fprintf(f, "G:%s\n", tag);
1058         }
1059
1060         r = fflush_and_check(f);
1061         if (r < 0)
1062                 goto fail;
1063
1064         r = rename(path_tmp, path);
1065         if (r < 0) {
1066                 r = -errno;
1067                 goto fail;
1068         }
1069
1070         log_debug("created %s file '%s' for '%s'", has_info ? "db" : "empty",
1071                   path, device->devpath);
1072
1073         return 0;
1074
1075 fail:
1076         log_error_errno(r, "failed to create %s file '%s' for '%s'", has_info ? "db" : "empty",
1077                         path, device->devpath);
1078         unlink(path);
1079         unlink(path_tmp);
1080
1081         return r;
1082 }
1083
1084 int device_delete_db(sd_device *device) {
1085         const char *id;
1086         char *path;
1087         int r;
1088
1089         assert(device);
1090
1091         r = device_get_id_filename(device, &id);
1092         if (r < 0)
1093                 return r;
1094
1095         path = strjoina("/run/udev/data/", id);
1096
1097         r = unlink(path);
1098         if (r < 0 && errno != ENOENT)
1099                 return -errno;
1100
1101         return 0;
1102 }
1103
1104 int device_read_db_force(sd_device *device) {
1105         assert(device);
1106
1107         return device_read_db_aux(device, true);
1108 }