diff options
author | kay.sievers@vrfy.org <kay.sievers@vrfy.org> | 2004-04-02 22:16:38 -0800 |
---|---|---|
committer | Greg KH <gregkh@suse.de> | 2005-04-26 21:35:14 -0700 |
commit | 49747bdc374d6f98846e86d57016d8009aacb1cb (patch) | |
tree | 9581ea3277ba22fc5e7b54d6b8977a8ed91ed680 | |
parent | b6bf0b123635cb0902a95d9d6d4584edef43ed19 (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.c | 62 |
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)); |