#include <errno.h>
#include <grp.h>
#include <dirent.h>
+#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
info(udev, "preserve file '%s', because it has correct dev_t\n", file);
preserve = 1;
udev_selinux_lsetfilecon(udev, file, mode);
+ /* update time stamp when we re-use the node, like on media change events */
+ utimes(file, NULL);
} else {
char file_tmp[UTIL_PATH_SIZE + sizeof(TMP_FILE_EXT)];
} else {
info(udev, "mknod(%s, %#o, (%u,%u))\n", file, mode, major(devnum), minor(devnum));
do {
- util_create_path(udev, file);
+ err = util_create_path(udev, file);
+ if (err != 0 && err != -ENOENT)
+ break;
udev_selinux_setfscreatecon(udev, file, mode);
err = mknod(file, mode, devnum);
if (err != 0)
- err = errno;
+ err = -errno;
udev_selinux_resetfscreatecon(udev);
- } while (err == ENOENT);
+ } while (err == -ENOENT);
if (err != 0) {
err(udev, "mknod(%s, %#o, (%u,%u) failed: %m\n", file, mode, major(devnum), minor(devnum));
goto exit;
info(udev, "preserve already existing symlink '%s' to '%s'\n",
slink, target);
udev_selinux_lsetfilecon(udev, slink, S_IFLNK);
+ lutimes(slink, NULL);
goto exit;
}
}
} else {
info(udev, "creating symlink '%s' to '%s'\n", slink, target);
do {
- util_create_path(udev, slink);
+ err = util_create_path(udev, slink);
+ if (err != 0 && err != -ENOENT)
+ break;
udev_selinux_setfscreatecon(udev, slink, S_IFLNK);
err = symlink(target, slink);
if (err != 0)
- err = errno;
+ err = -errno;
udev_selinux_resetfscreatecon(udev);
- } while (err == ENOENT);
+ } while (err == -ENOENT);
if (err == 0)
goto exit;
}
util_strscpyl(slink_tmp, sizeof(slink_tmp), slink, TMP_FILE_EXT, NULL);
unlink(slink_tmp);
do {
- util_create_path(udev, slink);
- udev_selinux_setfscreatecon(udev, slink, S_IFLNK);
+ err = util_create_path(udev, slink_tmp);
+ if (err != 0 && err != -ENOENT)
+ break;
+ udev_selinux_setfscreatecon(udev, slink_tmp, S_IFLNK);
err = symlink(target, slink_tmp);
if (err != 0)
- err = errno;
+ err = -errno;
udev_selinux_resetfscreatecon(udev);
- } while (err == ENOENT);
+ } while (err == -ENOENT);
if (err != 0) {
err(udev, "symlink(%s, %s) failed: %m\n", target, slink_tmp);
goto exit;
udev_device_unref(dev_db);
}
}
+ closedir(dir);
return target;
}
}
if (add) {
+ int err;
+
dbg(udev, "creating index: '%s'\n", filename);
do {
- util_create_path(udev, filename);
- symlink(udev_device_get_devpath(dev), filename);
- } while (errno == ENOENT);
+ err = util_create_path(udev, filename);
+ if (err != 0 && err != -ENOENT)
+ break;
+ err = symlink(udev_device_get_devpath(dev), filename);
+ if (err != 0)
+ err = -errno;
+ } while (err == -ENOENT);
}
}
const char *devnode;
char partitionname[UTIL_PATH_SIZE];
struct stat stats;
+ struct udev_device *dev_check;
int err = 0;
int num;
- /* remove,update symlinks, remove symlinks from name index */
+ /* remove/update symlinks, remove symlinks from name index */
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
link_update(dev, udev_list_entry_get_name(list_entry), 0);
return -1;
}
- info(udev, "removing device node '%s'\n", devnode);
- err = util_unlink_secure(udev, devnode);
- if (err)
- return err;
+ dev_check = udev_device_new_from_syspath(udev, udev_device_get_syspath(dev));
+ if (dev_check != NULL && stats.st_rdev == udev_device_get_devnum(dev_check)) {
+ /* do not remove device node if the same sys-device is re-created in the meantime */
+ info(udev, "keeping device node of existing device'%s'\n", devnode);
+ } else {
+ info(udev, "removing device node '%s'\n", devnode);
+ err = util_unlink_secure(udev, devnode);
+ }
+ udev_device_unref(dev_check);
num = udev_device_get_num_fake_partitions(dev);
if (num > 0) {