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