summaryrefslogtreecommitdiff
path: root/udev_remove.c
diff options
context:
space:
mode:
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>2004-11-06 14:28:01 +0100
committerGreg KH <gregkh@suse.de>2005-04-26 22:16:40 -0700
commit2b41e68a08548ce44b4d145900dab2bb04cd34f7 (patch)
treef2e96c9f150775e3673891d38a5af23d4246c826 /udev_remove.c
parent482b0ecd8fcc2651c003c6f1ae9a2d3301ecf34a (diff)
[PATCH] replace tdb database by simple lockless file database
This makes the udev operation completely lockless by storing a file for every node in /dev/.udevdb/* This solved the problem with deadlocking concurrent udev processes waiting for each other to release the file lock under heavy load.
Diffstat (limited to 'udev_remove.c')
-rw-r--r--udev_remove.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/udev_remove.c b/udev_remove.c
index cd9d27f8dc..d855fce52c 100644
--- a/udev_remove.c
+++ b/udev_remove.c
@@ -102,10 +102,9 @@ static int secure_unlink(const char *filename)
return retval;
}
-static int delete_node(struct udevice *dev)
+static int delete_node(struct udevice *udev)
{
char filename[NAME_SIZE];
- char linkname[NAME_SIZE];
char partitionname[NAME_SIZE];
int retval;
int i;
@@ -113,8 +112,8 @@ static int delete_node(struct udevice *dev)
int len;
int num;
- strfieldcpy(filename, udev_root);
- strfieldcat(filename, dev->name);
+ snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, udev->name);
+ filename[NAME_SIZE-1] = '\0';
info("removing device node '%s'", filename);
retval = secure_unlink(filename);
@@ -122,7 +121,7 @@ static int delete_node(struct udevice *dev)
return retval;
/* remove all_partitions nodes */
- num = dev->partitions;
+ num = udev->partitions;
if (num > 0) {
info("removing all_partitions '%s[1-%i]'", filename, num);
if (num > PARTITIONS_COUNT) {
@@ -137,13 +136,15 @@ static int delete_node(struct udevice *dev)
}
/* remove subdirectories */
- if (strchr(dev->name, '/'))
+ if (strchr(udev->name, '/'))
delete_path(filename);
- foreach_strpart(dev->symlink, " ", pos, len) {
+ foreach_strpart(udev->symlink, " ", pos, len) {
+ char linkname[NAME_SIZE];
+
strfieldcpymax(linkname, pos, len+1);
- strfieldcpy(filename, udev_root);
- strfieldcat(filename, linkname);
+ snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, linkname);
+ filename[NAME_SIZE-1] = '\0';
dbg("unlinking symlink '%s'", filename);
retval = unlink(filename);
@@ -154,7 +155,7 @@ static int delete_node(struct udevice *dev)
filename, strerror(errno));
return retval;
}
- if (strchr(dev->symlink, '/')) {
+ if (strchr(udev->symlink, '/')) {
delete_path(filename);
}
}
@@ -168,18 +169,14 @@ static int delete_node(struct udevice *dev)
*/
int udev_remove_device(struct udevice *udev)
{
- struct udevice db_dev;
const char *temp;
int retval;
if (udev->type != 'b' && udev->type != 'c')
return 0;
- retval = udevdb_get_dev(udev->devpath, &db_dev);
- if (retval == 0) {
- /* copy over the stored values to our device */
- memcpy(udev, &db_dev, UDEVICE_DB_LEN);
- } else {
+ retval = udevdb_get_dev(udev);
+ if (retval) {
/* fall back to kernel name */
temp = strrchr(udev->devpath, '/');
if (temp == NULL)
@@ -189,10 +186,10 @@ int udev_remove_device(struct udevice *udev)
}
dbg("remove name='%s'", udev->name);
- udevdb_delete_dev(udev->devpath);
+ udevdb_delete_dev(udev);
/* use full path to the environment */
- snprintf(udev->devname, NAME_SIZE-1, "%s%s", udev_root, udev->name);
+ snprintf(udev->devname, NAME_SIZE-1, "%s/%s", udev_root, udev->name);
return delete_node(udev);
}