This is a patch we've written and applied in Ubuntu to improve the atomicity of devmapper device creation somewhat, and avoid races with udev. Scott -- Scott James Remnant scott@xxxxxxxxxx
--- devmapper-1.02.20.orig/lib/libdm-common.c +++ devmapper-1.02.20/lib/libdm-common.c @@ -252,12 +252,11 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor, uid_t uid, gid_t gid, mode_t mode) { - char path[PATH_MAX]; + char path[PATH_MAX], tmppath[PATH_MAX + 7]; struct stat info; dev_t dev = MKDEV(major, minor); mode_t old_mask; - - _build_dev_path(path, sizeof(path), dev_name); + int retval; if (stat(path, &info) >= 0) { if (!S_ISBLK(info.st_mode)) { @@ -269,31 +268,39 @@ /* If right inode already exists we don't touch uid etc. */ if (info.st_rdev == dev) return 1; - - if (unlink(path) < 0) { - log_error("Unable to unlink device node for '%s'", - dev_name); - return 0; - } } + _build_dev_path(path, sizeof(path), dev_name); + strcpy (tmppath, path); + strcat (tmppath, ".dm-tmp"); + old_mask = umask(0); - if (mknod(path, S_IFBLK | mode, dev) < 0) { - log_error("Unable to make device node for '%s'", dev_name); + retval = mknod(tmppath, S_IFBLK | mode, dev); + umask(old_mask); + if (retval < 0) { + log_error("Unable to make temporary device node for '%s'", dev_name); return 0; } - umask(old_mask); - if (chown(path, uid, gid) < 0) { + if (chown(tmppath, uid, gid) < 0) { log_error("%s: chown failed: %s", path, strerror(errno)); + unlink(tmppath); return 0; } #ifdef HAVE_SELINUX - if (!dm_set_selinux_context(path, S_IFBLK)) + if (!dm_set_selinux_context(tmppath, S_IFBLK)) { + unlink(tmppath); return 0; + } #endif + if (rename(tmppath, path) < 0) { + log_error("Unable to replace device node for '%s'", dev_name); + unlink(tmppath); + return 0; + } + return 1; }
Attachment:
signature.asc
Description: This is a digitally signed message part
-- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel