6 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation version 2 of the License.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 #include "udev_libc_wrapper.h"
35 #include "udev_utils.h"
36 #include "udev_version.h"
41 static int delete_path(const char *path)
46 pos = strrchr(path, '/');
49 pos = strrchr(path, '/');
51 /* don't remove the last one */
52 if ((pos == path) || (pos == NULL))
60 if (errno == ENOTEMPTY)
62 dbg("rmdir(%s) failed with error '%s'",
63 path, strerror(errno));
66 dbg("removed '%s'", path);
71 static int delete_node(struct udevice *udev)
73 char filename[PATH_SIZE];
74 char partitionname[PATH_SIZE];
75 struct name_entry *name_loop;
81 list_for_each_entry(name_loop, &udev->symlink_list, node) {
82 snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name);
83 filename[sizeof(filename)-1] = '\0';
85 if (stat(filename, &stats) != 0) {
86 dbg("symlink '%s' not found", filename);
89 if (udev->devt && stats.st_rdev != udev->devt) {
90 info("symlink '%s' points to a different device, skip removal", filename);
94 dbg("removing symlink '%s'", filename);
97 if (strchr(filename, '/'))
98 delete_path(filename);
101 snprintf(filename, sizeof(filename), "%s/%s", udev_root, udev->name);
102 filename[sizeof(filename)-1] = '\0';
104 if (stat(filename, &stats) != 0) {
105 dbg("device node '%s' not found", filename);
108 if (udev->devt && stats.st_rdev != udev->devt) {
109 info("device node '%s' points to a different device, skip removal", filename);
113 info("removing device node '%s'", filename);
114 retval = unlink_secure(filename);
118 num = udev->partitions;
120 info("removing all_partitions '%s[1-%i]'", filename, num);
122 info("garbage from udev database, skip all_partitions removal");
125 for (i = 1; i <= num; i++) {
126 snprintf(partitionname, sizeof(partitionname), "%s%d", filename, i);
127 partitionname[sizeof(partitionname)-1] = '\0';
128 unlink_secure(partitionname);
132 if (strchr(udev->name, '/'))
133 delete_path(filename);
139 * look up the sysfs path in the database to get the node name to remove
140 * If we can't find it, use kernel name for lack of anything else to know to do
142 int udev_remove_device(struct udevice *udev)
146 if (udev->type != DEV_BLOCK && udev->type != DEV_CLASS)
149 if (udev_db_get_device(udev, udev->devpath) == 0) {
150 if (udev->ignore_remove) {
151 dbg("remove event for '%s' requested to be ignored by rule", udev->name);
154 dbg("remove name='%s'", udev->name);
155 udev_db_delete_device(udev);
157 /* fall back to kernel name */
158 temp = strrchr(udev->devpath, '/');
161 strlcpy(udev->name, &temp[1], sizeof(udev->name));
162 dbg("'%s' not found in database, falling back on default name", udev->name);
165 /* use full path to the environment */
166 snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name);
167 udev->devname[sizeof(udev->devname)-1] = '\0';
169 return delete_node(udev);