summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>2004-04-02 22:16:38 -0800
committerGreg KH <gregkh@suse.de>2005-04-26 21:35:14 -0700
commit49747bdc374d6f98846e86d57016d8009aacb1cb (patch)
tree9581ea3277ba22fc5e7b54d6b8977a8ed91ed680
parentb6bf0b123635cb0902a95d9d6d4584edef43ed19 (diff)
[PATCH] tweak node unlink handling
Based on a patch from Olaf Hering we remove the node now only if the requested dev_t is different from the already existing node, so any run of udevstart should preserve the inode number of the node file. syslog while the right node is already there: creating device node '/udev/hda' make_node: preserve file '/udev/hda', cause it has correct dev_t make_node: chmod(/udev/hda, 060600) syslog for wrong file already there: creating device node '/udev/hda' make_node: already present file '/udev/hda' unlinked make_node: chmod(/udev/hda, 060600) syslog for directory with same name already there: creating device node '/udev/hda' make_node: unlink(/udev/hda) failed with error '21'
-rw-r--r--udev-add.c62
1 files changed, 29 insertions, 33 deletions
diff --git a/udev-add.c b/udev-add.c
index 20599822d3..5dc46cf2a7 100644
--- a/udev-add.c
+++ b/udev-add.c
@@ -105,29 +105,46 @@ static int create_path(char *file)
return 0;
}
-static int make_node(char *filename, int major, int minor, unsigned int mode, uid_t uid, gid_t gid)
+static int make_node(char *file, int major, int minor, unsigned int mode, uid_t uid, gid_t gid)
{
- int retval;
+ struct stat stats;
+ int retval = 0;
+
+ if (stat(file, &stats) != 0)
+ goto create;
+
+ /* preserve node with already correct numbers, to not change the inode number */
+ if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) &&
+ (stats.st_rdev == makedev(major, minor))) {
+ dbg("preserve file '%s', cause it has correct dev_t", file);
+ goto perms;
+ }
+
+ if (unlink(file) != 0)
+ dbg("unlink(%s) failed with error '%s'", file, strerror(errno));
+ else
+ dbg("already present file '%s' unlinked", file);
- retval = mknod(filename, mode, makedev(major, minor));
+create:
+ retval = mknod(file, mode, makedev(major, minor));
if (retval != 0) {
dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
- filename, mode, major, minor, strerror(errno));
+ file, mode, major, minor, strerror(errno));
goto exit;
}
- dbg("chmod(%s, %#o)", filename, mode);
- if (chmod(filename, mode) != 0) {
- dbg("chmod(%s, %#o) failed with error '%s'",
- filename, mode, strerror(errno));
+perms:
+ dbg("chmod(%s, %#o)", file, mode);
+ if (chmod(file, mode) != 0) {
+ dbg("chmod(%s, %#o) failed with error '%s'", file, mode, strerror(errno));
goto exit;
}
if (uid != 0 || gid != 0) {
- dbg("chown(%s, %u, %u)", filename, uid, gid);
- if (chown(filename, uid, gid) != 0) {
+ dbg("chown(%s, %u, %u)", file, uid, gid);
+ if (chown(file, uid, gid) != 0) {
dbg("chown(%s, %u, %u) failed with error '%s'",
- filename, uid, gid, strerror(errno));
+ file, uid, gid, strerror(errno));
goto exit;
}
}
@@ -167,23 +184,6 @@ static void set_to_local_user(char *user)
endutent();
}
-static int unlink_entry(char *filename)
-{
- struct stat stats;
- int retval = 0;
-
- if (lstat(filename, &stats) == 0) {
- if ((stats.st_mode & S_IFMT) != S_IFDIR) {
- retval = unlink(filename);
- if (retval) {
- dbg("unlink(%s) failed with error '%s'",
- filename, strerror(errno));
- }
- }
- }
- return retval;
-}
-
static int create_node(struct udevice *dev, int fake)
{
char filename[NAME_SIZE];
@@ -253,7 +253,6 @@ static int create_node(struct udevice *dev, int fake)
}
if (!fake) {
- unlink_entry(filename);
info("creating device node '%s'", filename);
if (make_node(filename, dev->major, dev->minor, dev->mode, uid, gid) != 0)
goto error;
@@ -270,7 +269,6 @@ static int create_node(struct udevice *dev, int fake)
for (i = 1; i <= dev->partitions; i++) {
strfieldcpy(partitionname, filename);
strintcat(partitionname, i);
- unlink_entry(partitionname);
make_node(partitionname, dev->major,
dev->minor + i, dev->mode, uid, gid);
}
@@ -304,11 +302,9 @@ static int create_node(struct udevice *dev, int fake)
strfieldcat(linktarget, &dev->name[tail]);
- if (!fake)
- unlink_entry(filename);
-
dbg("symlink(%s, %s)", linktarget, filename);
if (!fake) {
+ unlink(filename);
if (symlink(linktarget, filename) != 0)
dbg("symlink(%s, %s) failed with error '%s'",
linktarget, filename, strerror(errno));