chiark / gitweb /
libudev: also import "uevent" file when reading udev database
[elogind.git] / udev / lib / libudev-device.c
1 /*
2  * libudev - interface to udev device information
3  *
4  * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stddef.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <dirent.h>
27 #include <fcntl.h>
28 #include <sys/stat.h>
29
30 #include "libudev.h"
31 #include "libudev-private.h"
32
33 struct udev_device {
34         int refcount;
35         struct udev *udev;
36         struct udev_device *parent_device;
37         char *syspath;
38         const char *devpath;
39         const char *sysname;
40         char *devname;
41         char *subsystem;
42         struct list_head link_list;
43         struct list_head env_list;
44         char *action;
45         char *driver;
46         char *devpath_old;
47         char *physdevpath;
48         int timeout;
49         dev_t devnum;
50         unsigned long long int seqnum;
51         int num_fake_partitions;
52         int devlink_priority;
53         int ignore_remove;
54         struct list_head attr_list;
55 };
56
57 static size_t syspath_to_db_path(struct udev_device *udev_device, char *filename, size_t len)
58 {
59         size_t start;
60
61         /* translate to location of db file */
62         util_strlcpy(filename, udev_get_dev_path(udev_device->udev), len);
63         start = util_strlcat(filename, "/.udev/db/", len);
64         util_strlcat(filename, udev_device->devpath, len);
65         return util_path_encode(&filename[start], len - start);
66 }
67
68 static int device_read_uevent_file(struct udev_device *udev_device)
69 {
70         char filename[UTIL_PATH_SIZE];
71         FILE *f;
72         char line[UTIL_LINE_SIZE];
73
74         util_strlcpy(filename, udev_device->syspath, sizeof(filename));
75         util_strlcat(filename, "/uevent", sizeof(filename));
76         f = fopen(filename, "r");
77         if (f == NULL)
78                 return -1;
79
80         while (fgets(line, sizeof(line), f)) {
81                 char *pos;
82
83                 pos = strchr(line, '\n');
84                 if (pos == NULL)
85                         continue;
86                 pos[0] = '\0';
87                 device_add_property_from_string(udev_device, line);
88         }
89
90         fclose(f);
91         return 0;
92 }
93
94 static int device_read_db(struct udev_device *udev_device)
95 {
96         struct stat stats;
97         char filename[UTIL_PATH_SIZE];
98         char line[UTIL_LINE_SIZE];
99         FILE *f;
100         int rc = 0;
101
102         syspath_to_db_path(udev_device, filename, sizeof(filename));
103
104         if (lstat(filename, &stats) != 0) {
105                 info(udev_device->udev, "no db file to read %s: %s\n", filename, strerror(errno));
106                 return -1;
107         }
108         if ((stats.st_mode & S_IFMT) == S_IFLNK) {
109                 char target[UTIL_PATH_SIZE];
110                 int target_len;
111
112                 info(udev_device->udev, "found a symlink as db file\n");
113                 target_len = readlink(filename, target, sizeof(target));
114                 if (target_len > 0)
115                         target[target_len] = '\0';
116                 else {
117                         info(udev_device->udev, "error reading db link %s: %s\n", filename, strerror(errno));
118                         return -1;
119                 }
120                 dbg(udev_device->udev, "db link points to '%s'\n", target);
121                 if (asprintf(&udev_device->devname, "%s/%s", udev_get_dev_path(udev_device->udev), target) < 0)
122                         return -ENOMEM;
123                 return 0;
124         }
125
126         f = fopen(filename, "r");
127         if (f == NULL) {
128                 info(udev_device->udev, "error reading db file %s: %s\n", filename, strerror(errno));
129                 return -1;
130         }
131         while (fgets(line, sizeof(line), f)) {
132                 ssize_t len;
133                 const char *val;
134                 unsigned int maj, min;
135
136                 len = strlen(line);
137                 if (len < 4)
138                         break;
139                 line[len-1] = '\0';
140                 val = &line[2];
141
142                 switch(line[0]) {
143                 case 'N':
144                         asprintf(&udev_device->devname, "%s/%s", udev_get_dev_path(udev_device->udev), val);
145                         break;
146                 case 'M':
147                         sscanf(val, "%u:%u", &maj, &min);
148                         device_set_devnum(udev_device, makedev(maj, min));
149                         break;
150                 case 'S':
151                         util_strlcpy(filename, udev_get_dev_path(udev_device->udev), sizeof(filename));
152                         util_strlcat(filename, "/", sizeof(filename));
153                         util_strlcat(filename, val, sizeof(filename));
154                         device_add_devlink(udev_device, filename);
155                         break;
156                 case 'L':
157                         device_set_devlink_priority(udev_device, atoi(val));
158                         break;
159                 case 'T':
160                         device_set_timeout(udev_device,  atoi(val));
161                         break;
162                 case 'A':
163                         device_set_num_fake_partitions(udev_device, atoi(val));
164                         break;
165                 case 'R':
166                         device_set_ignore_remove(udev_device, atoi(val));
167                         break;
168                 case 'E':
169                         device_add_property_from_string(udev_device, val);
170                         break;
171                 }
172         }
173         fclose(f);
174
175         return rc;
176 }
177
178 struct udev_device *device_init(struct udev *udev)
179 {
180         struct udev_device *udev_device;
181
182         if (udev == NULL)
183                 return NULL;
184
185         udev_device = malloc(sizeof(struct udev_device));
186         if (udev_device == NULL)
187                 return NULL;
188         memset(udev_device, 0x00, sizeof(struct udev_device));
189         udev_device->refcount = 1;
190         udev_device->udev = udev;
191         INIT_LIST_HEAD(&udev_device->link_list);
192         INIT_LIST_HEAD(&udev_device->env_list);
193         INIT_LIST_HEAD(&udev_device->attr_list);
194         info(udev_device->udev, "udev_device: %p created\n", udev_device);
195         return udev_device;
196 }
197
198 /**
199  * udev_device_new_from_syspath:
200  * @udev: udev library context
201  * @syspath: sys device path including sys directory
202  *
203  * Create new udev device, and fill in information from the sys
204  * device and the udev database entry. The sypath is the absolute
205  * path to the device, including the sys mount point.
206  *
207  * The initial refcount is 1, and needs to be decremented to
208  * release the ressources of the udev device.
209  *
210  * Returns: a new udev device, or #NULL, if it does not exist
211  **/
212 struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)
213 {
214         char path[UTIL_PATH_SIZE];
215         struct stat statbuf;
216         struct udev_device *udev_device;
217
218         if (udev == NULL)
219                 return NULL;
220         if (syspath == NULL)
221                 return NULL;
222
223         util_strlcpy(path, syspath, sizeof(path));
224         util_strlcat(path, "/uevent", sizeof(path));
225         if (stat(path, &statbuf) != 0) {
226                 info(udev, "not a device :%s\n", syspath);
227                 return NULL;
228         }
229
230         udev_device = device_init(udev);
231         if (udev_device == NULL)
232                 return NULL;
233
234         /* resolve possible symlink to real path */
235         util_strlcpy(path, syspath, sizeof(path));
236         util_resolve_sys_link(udev, path, sizeof(path));
237         device_set_syspath(udev_device, path);
238         info(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device));
239
240         device_read_uevent_file(udev_device);
241         if (device_read_db(udev_device) >= 0)
242                 info(udev, "device %p filled with udev database data\n", udev_device);
243         return udev_device;
244 }
245
246 struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
247 {
248         char path[UTIL_PATH_SIZE];
249         const char *type_str;
250
251         if (type == 'b')
252                 type_str = "block";
253         else if (type == 'c')
254                 type_str = "char";
255         else
256                 return NULL;
257
258         snprintf(path, sizeof(path), "%s/dev/%s/%u:%u", udev_get_sys_path(udev),
259                  type_str, major(devnum), minor(devnum));
260         if (util_resolve_sys_link(udev, path, sizeof(path)) < 0)
261                 return NULL;
262
263         return udev_device_new_from_syspath(udev, path);
264 }
265
266 static struct udev_device *device_new_from_parent(struct udev_device *udev_device)
267 {
268         struct udev_device *udev_device_parent = NULL;
269         char path[UTIL_PATH_SIZE];
270         char *pos;
271
272         if (udev_device == NULL)
273                 return NULL;
274
275         util_strlcpy(path, udev_device->syspath, sizeof(path));
276         while (1) {
277                 pos = strrchr(path, '/');
278                 if (pos == path || pos == NULL)
279                         break;
280                 pos[0] = '\0';
281                 udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path);
282                 if (udev_device_parent != NULL)
283                         return udev_device_parent;
284         }
285
286         /* follow "device" link in deprecated sys /sys/class/ layout */
287         if (strncmp(udev_device->devpath, "/class/", 7) == 0) {
288                 util_strlcpy(path, udev_device->syspath, sizeof(path));
289                 util_strlcat(path, "/device", sizeof(path));
290                 if (util_resolve_sys_link(udev_device->udev, path, sizeof(path)) == 0) {
291                         udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path);
292                         if (udev_device_parent != NULL)
293                                 return udev_device_parent;
294                 }
295         }
296         return NULL;
297 }
298
299 struct udev_device *udev_device_get_parent(struct udev_device *udev_device)
300 {
301         if (udev_device->parent_device != NULL) {
302                 info(udev_device->udev, "returning existing parent %p\n", udev_device->parent_device);
303                 return udev_device->parent_device;
304         }
305         udev_device->parent_device = device_new_from_parent(udev_device);
306         return udev_device->parent_device;
307 }
308
309 /**
310  * udev_device_get_udev:
311  * @udev_device: udev device
312  *
313  * Retrieve the udev library context the device was created with.
314  *
315  * Returns: the udev library context
316  **/
317 struct udev *udev_device_get_udev(struct udev_device *udev_device)
318 {
319         if (udev_device == NULL)
320                 return NULL;
321         return udev_device->udev;
322 }
323
324 /**
325  * udev_device_ref:
326  * @udev_device: udev device
327  *
328  * Take a reference of a udev device.
329  *
330  * Returns: the passed udev device
331  **/
332 struct udev_device *udev_device_ref(struct udev_device *udev_device)
333 {
334         if (udev_device == NULL)
335                 return NULL;
336         udev_device->refcount++;
337         return udev_device;
338 }
339
340 /**
341  * udev_device_unref:
342  * @udev_device: udev device
343  *
344  * Drop a reference of a udev device. If the refcount reaches zero,
345  * the ressources of the device will be released.
346  *
347  **/
348 void udev_device_unref(struct udev_device *udev_device)
349 {
350         if (udev_device == NULL)
351                 return;
352         udev_device->refcount--;
353         if (udev_device->refcount > 0)
354                 return;
355         if (udev_device->parent_device != NULL)
356                 udev_device_unref(udev_device->parent_device);
357         free(udev_device->syspath);
358         free(udev_device->devname);
359         free(udev_device->subsystem);
360         util_name_list_cleanup(udev_device->udev, &udev_device->link_list);
361         util_name_list_cleanup(udev_device->udev, &udev_device->env_list);
362         free(udev_device->action);
363         free(udev_device->driver);
364         free(udev_device->devpath_old);
365         free(udev_device->physdevpath);
366         util_name_list_cleanup(udev_device->udev, &udev_device->attr_list);
367         info(udev_device->udev, "udev_device: %p released\n", udev_device);
368         free(udev_device);
369 }
370
371 /**
372  * udev_device_get_devpath:
373  * @udev_device: udev device
374  *
375  * Retrieve the kernel devpath value of the udev device. The path
376  * does not contain the sys mount point, and starts with a '/'.
377  *
378  * Returns: the devpath of the udev device
379  **/
380 const char *udev_device_get_devpath(struct udev_device *udev_device)
381 {
382         if (udev_device == NULL)
383                 return NULL;
384         return udev_device->devpath;
385 }
386
387 /**
388  * udev_device_get_syspath:
389  * @udev_device: udev device
390  *
391  * Retrieve the sys path of the udev device. The path is an
392  * absolute path and starts with the sys mount point.
393  *
394  * Returns: the sys path of the udev device
395  **/
396 const char *udev_device_get_syspath(struct udev_device *udev_device)
397 {
398         if (udev_device == NULL)
399                 return NULL;
400         return udev_device->syspath;
401 }
402
403 const char *udev_device_get_sysname(struct udev_device *udev_device)
404 {
405         if (udev_device == NULL)
406                 return NULL;
407         return udev_device->sysname;
408 }
409
410 /**
411  * udev_device_get_devnode:
412  * @udev_device: udev device
413  *
414  * Retrieve the device node file name belonging to the udev device.
415  * The path is an absolute path, and starts with the device directory.
416  *
417  * Returns: the device node file name of the udev device, or #NULL if no device node exists
418  **/
419 const char *udev_device_get_devnode(struct udev_device *udev_device)
420 {
421         if (udev_device == NULL)
422                 return NULL;
423         return udev_device->devname;
424 }
425
426 /**
427  * udev_device_get_subsystem:
428  * @udev_device: udev device
429  *
430  * Retrieve the subsystem string of the udev device. The string does not
431  * contain any "/".
432  *
433  * Returns: the subsystem name of the udev device, or #NULL if it can not be determined
434  **/
435 const char *udev_device_get_subsystem(struct udev_device *udev_device)
436 {
437         char subsystem[UTIL_NAME_SIZE];
438
439         if (udev_device == NULL)
440                 return NULL;
441         if (udev_device->subsystem != NULL)
442                 return udev_device->subsystem;
443
444         /* read "subsytem" link */
445         if (util_get_sys_subsystem(udev_device->udev, udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
446                 udev_device->subsystem = strdup(subsystem);
447                 return udev_device->subsystem;
448         }
449
450         /* implicit names */
451         if (strncmp(udev_device->devpath, "/module/", 8) == 0) {
452                 udev_device->subsystem = strdup("module");
453                 return udev_device->subsystem;
454         }
455         if (strstr(udev_device->devpath, "/drivers/") != NULL) {
456                 udev_device->subsystem = strdup("drivers");
457                 return udev_device->subsystem;
458         }
459         if (strncmp(udev_device->devpath, "/subsystem/", 11) == 0 ||
460             strncmp(udev_device->devpath, "/class/", 7) == 0 ||
461             strncmp(udev_device->devpath, "/bus/", 5) == 0) {
462                 udev_device->subsystem = strdup("subsystem");
463                 return udev_device->subsystem;
464         }
465         return NULL;
466 }
467
468 /**
469  * udev_device_get_devlinks:
470  * @udev_device: udev device
471  * @cb: function to be called for every device link found
472  * @data: data to be passed to the function
473  *
474  * Retrieve the device links pointing to the device file of the
475  * udev device. For every device link, the passed function will be
476  * called with the device link string.
477  * The path is an absolute path, and starts with the device directory.
478  * If the function returns 1, remaning device links will be ignored.
479  *
480  * Returns: the number of device links passed to the caller, or a negative value on error
481  **/
482 int udev_device_get_devlinks(struct udev_device *udev_device,
483                               int (*cb)(struct udev_device *udev_device, const char *value, void *data),
484                               void *data)
485 {
486         struct util_name_entry *name_loop;
487         int count = 0;
488
489         if (udev_device == NULL)
490                 return -1;
491         list_for_each_entry(name_loop, &udev_device->link_list, node) {
492                 count++;
493                 if (cb(udev_device, name_loop->name, data) != 0)
494                         break;
495         }
496         return count;
497 }
498
499 /**
500  * udev_device_get_properties:
501  * @udev_device: udev device
502  * @cb: function to be called for every property found
503  * @data: data to be passed to the function
504  *
505  * Retrieve the property key/value pairs belonging to the
506  * udev device. For every key/value pair, the passed function will be
507  * called. If the function returns 1, remaning properties will be
508  * ignored.
509  *
510  * Returns: the number of properties passed to the caller, or a negative value on error
511  **/
512 int udev_device_get_properties(struct udev_device *udev_device,
513                                 int (*cb)(struct udev_device *udev_device, const char *key, const char *value, void *data),
514                                 void *data)
515 {
516         struct util_name_entry *name_loop;
517         int count = 0;
518
519         if (udev_device == NULL)
520                 return -1;
521         list_for_each_entry(name_loop, &udev_device->env_list, node) {
522                 count++;
523                 if (cb(udev_device, name_loop->name, name_loop->value, data) != 0)
524                         break;
525         }
526         return count;
527 }
528
529 const char *udev_device_get_driver(struct udev_device *udev_device)
530 {
531         char driver[UTIL_NAME_SIZE];
532
533         if (udev_device == NULL)
534                 return NULL;
535         if (udev_device->driver != NULL)
536                 return udev_device->driver;
537         if (util_get_sys_driver(udev_device->udev, udev_device->syspath, driver, sizeof(driver)) < 2)
538                 return NULL;
539         udev_device->driver = strdup(driver);
540         return udev_device->driver;
541 }
542
543 dev_t udev_device_get_devnum(struct udev_device *udev_device)
544 {
545         if (udev_device == NULL)
546                 return makedev(0, 0);
547         return udev_device->devnum;
548 }
549
550 const char *udev_device_get_action(struct udev_device *udev_device)
551 {
552         if (udev_device == NULL)
553                 return NULL;
554         return udev_device->action;
555 }
556
557 unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
558 {
559         if (udev_device == NULL)
560                 return 0;
561         return udev_device->seqnum;
562 }
563
564 const char *udev_device_get_attr_value(struct udev_device *udev_device, const char *attr)
565 {
566         struct util_name_entry *name_loop;
567         char path[UTIL_PATH_SIZE];
568         char value[UTIL_NAME_SIZE];
569         struct stat statbuf;
570         int fd;
571         ssize_t size;
572         const char *val = NULL;
573
574         /* look for possibly already cached result */
575         list_for_each_entry(name_loop, &udev_device->attr_list, node) {
576                 if (strcmp(name_loop->name, attr) == 0) {
577                         info(udev_device->udev, "'%s' in cache '%s'\n", attr, name_loop->value);
578                         return name_loop->value;
579                 }
580         }
581
582         util_strlcpy(path, udev_device_get_syspath(udev_device), sizeof(path));
583         util_strlcat(path, "/", sizeof(path));
584         util_strlcat(path, attr, sizeof(path));
585
586         if (lstat(path, &statbuf) != 0) {
587                 info(udev_device->udev, "stat '%s' failed: %s\n", path, strerror(errno));
588                 goto out;
589         }
590
591         if (S_ISLNK(statbuf.st_mode)) {
592                 /* links return the last element of the target path */
593                 char target[UTIL_NAME_SIZE];
594                 int len;
595                 char *pos;
596
597                 len = readlink(path, target, sizeof(target));
598                 if (len > 0) {
599                         target[len] = '\0';
600                         pos = strrchr(target, '/');
601                         if (pos != NULL) {
602                                 pos = &pos[1];
603                                 info(udev_device->udev, "cache '%s' with link value '%s'\n", attr, pos);
604                                 val = util_name_list_add(udev_device->udev, &udev_device->attr_list, attr, pos, 0)->value;
605                         }
606                 }
607                 goto out;
608         }
609
610         /* skip directories */
611         if (S_ISDIR(statbuf.st_mode))
612                 goto out;
613
614         /* skip non-readable files */
615         if ((statbuf.st_mode & S_IRUSR) == 0)
616                 goto out;
617
618         /* read attribute value */
619         fd = open(path, O_RDONLY);
620         if (fd < 0) {
621                 info(udev_device->udev, "attribute '%s' can not be opened\n", path);
622                 goto out;
623         }
624         size = read(fd, value, sizeof(value));
625         close(fd);
626         if (size < 0)
627                 goto out;
628         if (size == sizeof(value))
629                 goto out;
630
631         /* got a valid value, store it in cache and return it */
632         value[size] = '\0';
633         util_remove_trailing_chars(value, '\n');
634         info(udev_device->udev, "'%s' has attribute value '%s'\n", path, value);
635         val = util_name_list_add(udev_device->udev, &udev_device->attr_list, attr, value, 0)->value;
636 out:
637         return val;
638 }
639 int device_set_syspath(struct udev_device *udev_device, const char *syspath)
640 {
641         const char *pos;
642
643         udev_device->syspath = strdup(syspath);
644         if (udev_device->syspath ==  NULL)
645                 return -ENOMEM;
646         udev_device->devpath = &udev_device->syspath[strlen(udev_get_sys_path(udev_device->udev))];
647         pos = strrchr(udev_device->syspath, '/');
648         if (pos == NULL)
649                 return -EINVAL;
650         udev_device->sysname = &pos[1];
651         return 0;
652 }
653
654 int device_set_subsystem(struct udev_device *udev_device, const char *subsystem)
655 {
656         udev_device->subsystem = strdup(subsystem);
657         if (udev_device->subsystem == NULL)
658                 return -1;
659         return 0;
660 }
661
662 int device_set_devname(struct udev_device *udev_device, const char *devname)
663 {
664         udev_device->devname = strdup(devname);
665         if (udev_device->devname == NULL)
666                 return -ENOMEM;
667         return 0;
668 }
669
670 int device_add_devlink(struct udev_device *udev_device, const char *devlink)
671 {
672         if (util_name_list_add(udev_device->udev, &udev_device->link_list, devlink, NULL, 0) == NULL)
673                 return -ENOMEM;
674         return 0;
675 }
676
677 int device_add_property(struct udev_device *udev_device, const char *key, const char *value)
678 {
679         if (util_name_list_add(udev_device->udev, &udev_device->env_list, key, value, 0) == NULL)
680                 return -ENOMEM;
681         return 0;
682 }
683
684 int device_add_property_from_string(struct udev_device *udev_device, const char *property)
685 {
686         char name[UTIL_PATH_SIZE];
687         char *val;
688
689         strncpy(name, property, sizeof(name));
690         val = strchr(name, '=');
691         if (val == NULL)
692                 return -1;
693         val[0] = '\0';
694         val = &val[1];
695         if (val[0] == '\0')
696                 val = NULL;
697         device_add_property(udev_device, name, val);
698         return 0;
699 }
700
701 int device_set_action(struct udev_device *udev_device, const char *action)
702 {
703         udev_device->action = strdup(action);
704         if (udev_device->action == NULL)
705                 return -ENOMEM;
706         return 0;
707 }
708
709 int device_set_driver(struct udev_device *udev_device, const char *driver)
710 {
711         udev_device->driver = strdup(driver);
712         if (udev_device->driver == NULL)
713                 return -ENOMEM;
714         return 0;
715 }
716
717 const char *device_get_devpath_old(struct udev_device *udev_device)
718 {
719         if (udev_device == NULL)
720                 return NULL;
721         return udev_device->devpath_old;
722 }
723
724 int device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old)
725 {
726         udev_device->devpath_old = strdup(devpath_old);
727         if (udev_device->devpath_old == NULL)
728                 return -ENOMEM;
729         return 0;
730 }
731
732 const char *device_get_physdevpath(struct udev_device *udev_device)
733 {
734         if (udev_device == NULL)
735                 return NULL;
736         return udev_device->physdevpath;
737 }
738
739 int device_set_physdevpath(struct udev_device *udev_device, const char *physdevpath)
740 {
741         udev_device->physdevpath = strdup(physdevpath);
742         if (udev_device->physdevpath == NULL)
743                 return -ENOMEM;
744         return 0;
745 }
746
747 int device_get_timeout(struct udev_device *udev_device)
748 {
749         if (udev_device == NULL)
750                 return -1;
751         return udev_device->timeout;
752 }
753
754 int device_set_timeout(struct udev_device *udev_device, int timeout)
755 {
756         udev_device->timeout = timeout;
757         return 0;
758 }
759
760 int device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum)
761 {
762         udev_device->seqnum = seqnum;
763         return 0;
764 }
765
766 int device_set_devnum(struct udev_device *udev_device, dev_t devnum)
767 {
768         udev_device->devnum = devnum;
769         return 0;
770 }
771
772 int device_get_num_fake_partitions(struct udev_device *udev_device)
773 {
774         if (udev_device == NULL)
775                 return -1;
776         return udev_device->num_fake_partitions;
777 }
778
779 int device_set_num_fake_partitions(struct udev_device *udev_device, int num)
780 {
781         udev_device->num_fake_partitions = num;
782         return 0;
783 }
784
785 int device_get_devlink_priority(struct udev_device *udev_device)
786 {
787         if (udev_device == NULL)
788                 return -1;
789         return udev_device->devlink_priority;
790 }
791
792 int device_set_devlink_priority(struct udev_device *udev_device, int prio)
793 {
794          udev_device->devlink_priority = prio;
795         return 0;
796 }
797
798 int device_get_ignore_remove(struct udev_device *udev_device)
799 {
800         if (udev_device == NULL)
801                 return -1;
802         return udev_device->ignore_remove;
803 }
804
805 int device_set_ignore_remove(struct udev_device *udev_device, int ignore)
806 {
807         udev_device->ignore_remove = ignore;
808         return 0;
809 }
810