[PATCH] makedevs: make special node creation idempotent
Arnout Vandecappelle (Essensium/Mind)
arnout at mind.be
Sat Nov 5 13:37:53 UTC 2016
When makedevs is called for a second time with the same device file, it
will fail because the files already exist and mknod() gives -EEXISTS.
To avoid this, check if the file already exists and if so, if it is of
the right type. The chmod and chown changes are still done.
function old new delta
makedevs_main 1086 1201 +115
.rodata 138731 138832 +101
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 216/0) Total: 216 bytes
text data bss dec hex filename
856021 15958 1968 873947 d55db busybox_old
856237 15958 1968 874163 d56b3 busybox_unstripped
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout at mind.be>
---
miscutils/makedevs.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/miscutils/makedevs.c b/miscutils/makedevs.c
index c945a13..49f011d 100644
--- a/miscutils/makedevs.c
+++ b/miscutils/makedevs.c
@@ -225,6 +225,7 @@ int makedevs_main(int argc UNUSED_PARAM, char **argv)
dev_t rdev;
unsigned i;
char *full_name_inc;
+ struct stat st;
if (type == 'p') {
mode |= S_IFIFO;
@@ -244,10 +245,23 @@ int makedevs_main(int argc UNUSED_PARAM, char **argv)
for (i = start; i <= start + count; i++) {
sprintf(full_name_inc, count ? "%s%u" : "%s", full_name, i);
rdev = makedev(major, minor + (i - start) * increment);
- if (mknod(full_name_inc, mode, rdev) < 0) {
+ if (stat(full_name_inc, &st) == 0) {
+ if ((mode & S_IFMT) != (st.st_mode & S_IFMT)) {
+ bb_error_msg("line %d: node %s exists but is of wrong file type", linenum, full_name_inc);
+ ret = EXIT_FAILURE;
+ continue;
+ }
+ if (st.st_rdev != rdev) {
+ bb_error_msg("line %d: node %s exists but is wrong device number", linenum, full_name_inc);
+ ret = EXIT_FAILURE;
+ continue;
+ }
+ } else if (mknod(full_name_inc, mode, rdev) < 0) {
bb_perror_msg("line %d: can't create node %s", linenum, full_name_inc);
ret = EXIT_FAILURE;
- } else if (chown(full_name_inc, uid, gid) < 0) {
+ continue;
+ }
+ if (chown(full_name_inc, uid, gid) < 0) {
bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc);
ret = EXIT_FAILURE;
} else if (chmod(full_name_inc, mode) < 0) {
--
2.9.3
More information about the busybox
mailing list