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