]>
Commit | Line | Data |
---|---|---|
ea733a2f GKH |
1 | /* |
2 | * udev-remove.c | |
3 | * | |
ea733a2f | 4 | * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com> |
e8d569b4 | 5 | * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> |
ea733a2f GKH |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation version 2 of the License. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License along | |
17 | * with this program; if not, write to the Free Software Foundation, Inc., | |
18 | * 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 | * | |
20 | */ | |
21 | ||
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
7a947ce5 | 24 | #include <stddef.h> |
ea733a2f GKH |
25 | #include <stdio.h> |
26 | #include <fcntl.h> | |
27 | #include <unistd.h> | |
28 | #include <errno.h> | |
1ceba936 | 29 | #include <sys/stat.h> |
ea733a2f GKH |
30 | |
31 | #include "udev.h" | |
ea733a2f | 32 | |
2b41e68a | 33 | static int delete_node(struct udevice *udev) |
ea733a2f | 34 | { |
63f61c5c KS |
35 | char filename[PATH_SIZE]; |
36 | char partitionname[PATH_SIZE]; | |
e48fc108 | 37 | struct name_entry *name_loop; |
1cec1c24 | 38 | struct stat stats; |
218eae87 | 39 | int retval; |
50e5de03 | 40 | int i; |
7e89a569 | 41 | int num; |
ea733a2f | 42 | |
afe9f2fb KS |
43 | if (!list_empty(&udev->symlink_list)) { |
44 | char symlinks[512] = ""; | |
08183c4b | 45 | |
afe9f2fb KS |
46 | list_for_each_entry(name_loop, &udev->symlink_list, node) { |
47 | snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); | |
48 | filename[sizeof(filename)-1] = '\0'; | |
49 | ||
50 | if (stat(filename, &stats) != 0) { | |
51 | dbg("symlink '%s' not found", filename); | |
52 | continue; | |
53 | } | |
54 | if (udev->devt && stats.st_rdev != udev->devt) { | |
55 | info("symlink '%s' points to a different device, skip removal", filename); | |
56 | continue; | |
57 | } | |
08183c4b | 58 | |
afe9f2fb KS |
59 | info("removing symlink '%s'", filename); |
60 | unlink(filename); | |
61 | ||
62 | if (strchr(filename, '/')) | |
63 | delete_path(filename); | |
64 | ||
65 | strlcat(symlinks, filename, sizeof(symlinks)); | |
66 | strlcat(symlinks, " ", sizeof(symlinks)); | |
67 | } | |
08183c4b | 68 | |
afe9f2fb KS |
69 | remove_trailing_chars(symlinks, ' '); |
70 | if (symlinks[0] != '\0') | |
71 | setenv("DEVLINKS", symlinks, 1); | |
08183c4b | 72 | } |
73 | ||
63f61c5c KS |
74 | snprintf(filename, sizeof(filename), "%s/%s", udev_root, udev->name); |
75 | filename[sizeof(filename)-1] = '\0'; | |
ea733a2f | 76 | |
08183c4b | 77 | if (stat(filename, &stats) != 0) { |
78 | dbg("device node '%s' not found", filename); | |
1cec1c24 | 79 | return -1; |
08183c4b | 80 | } |
7e720bd4 | 81 | if (udev->devt && stats.st_rdev != udev->devt) { |
1cec1c24 KS |
82 | info("device node '%s' points to a different device, skip removal", filename); |
83 | return -1; | |
84 | } | |
85 | ||
54988802 | 86 | info("removing device node '%s'", filename); |
c1ab0461 | 87 | retval = unlink_secure(filename); |
e2eef6d4 | 88 | if (retval) |
218eae87 | 89 | return retval; |
218eae87 | 90 | |
afe9f2fb | 91 | setenv("DEVNAME", filename, 1); |
31819a1e | 92 | |
2b41e68a | 93 | num = udev->partitions; |
7e89a569 KS |
94 | if (num > 0) { |
95 | info("removing all_partitions '%s[1-%i]'", filename, num); | |
6d564166 | 96 | if (num > 255) { |
7e89a569 KS |
97 | info("garbage from udev database, skip all_partitions removal"); |
98 | return -1; | |
99 | } | |
100 | for (i = 1; i <= num; i++) { | |
63f61c5c KS |
101 | snprintf(partitionname, sizeof(partitionname), "%s%d", filename, i); |
102 | partitionname[sizeof(partitionname)-1] = '\0'; | |
c1ab0461 | 103 | unlink_secure(partitionname); |
50e5de03 KS |
104 | } |
105 | } | |
106 | ||
2b41e68a | 107 | if (strchr(udev->name, '/')) |
3d150dfb KS |
108 | delete_path(filename); |
109 | ||
218eae87 | 110 | return retval; |
ea733a2f GKH |
111 | } |
112 | ||
3d150dfb | 113 | /* |
7a947ce5 KS |
114 | * look up the sysfs path in the database to get the node name to remove |
115 | * If we can't find it, use kernel name for lack of anything else to know to do | |
3d150dfb | 116 | */ |
7a947ce5 | 117 | int udev_remove_device(struct udevice *udev) |
ea733a2f | 118 | { |
1aa1e248 | 119 | if (major(udev->devt) == 0) |
5d24c6ca | 120 | return 0; |
ea733a2f | 121 | |
1aa1e248 | 122 | if (udev_db_get_device(udev, udev->dev->devpath) == 0) { |
25103c48 KS |
123 | if (udev->ignore_remove) { |
124 | dbg("remove event for '%s' requested to be ignored by rule", udev->name); | |
125 | return 0; | |
126 | } | |
127 | dbg("remove name='%s'", udev->name); | |
128 | udev_db_delete_device(udev); | |
129 | } else { | |
1aa1e248 KS |
130 | dbg("'%s' not found in database, using kernel name '%s'", udev->dev->devpath, udev->dev->kernel_name); |
131 | strlcpy(udev->name, udev->dev->kernel_name, sizeof(udev->name)); | |
bbbe503e | 132 | } |
7ac0feeb | 133 | |
5d24c6ca | 134 | return delete_node(udev); |
ea733a2f | 135 | } |