summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-08-30 08:48:48 +1000
committerNeilBrown <neilb@suse.de>2010-08-30 08:48:48 +1000
commit6df6a774bff2fc6e2ab3f4092620ab7657c984aa (patch)
treec5ea27c154b4f01a164ab9b3174845acb3f2ca7e /util.c
parentef83fe7cba7355d3da330325e416747b0696baef (diff)
Allow dev_open to work on read-only /dev
/dev could be read-only in which case we cannot make devices there. So dev_open should first try to use an existing device name, and if that doesn't work try creating a node in /dev or /tmp. Reported-by: Paweł Sikora <pluto@agmk.net> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'util.c')
-rw-r--r--util.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/util.c b/util.c
index 0b9949ab..c9bdd6eb 100644
--- a/util.c
+++ b/util.c
@@ -959,19 +959,33 @@ int dev_open(char *dev, int flags)
int minor;
if (!dev) return -1;
+ flags |= O_DIRECT;
major = strtoul(dev, &e, 0);
if (e > dev && *e == ':' && e[1] &&
(minor = strtoul(e+1, &e, 0)) >= 0 &&
*e == 0) {
- snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d",
- (int)getpid(), major, minor);
- if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
- fd = open(devname, flags|O_DIRECT);
- unlink(devname);
+ char *path = map_dev(major, minor, 0);
+ if (path)
+ fd = open(path, flags);
+ if (fd < 0) {
+ snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d:%d",
+ (int)getpid(), major, minor);
+ if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
+ fd = open(devname, flags);
+ unlink(devname);
+ }
+ }
+ if (fd < 0) {
+ snprintf(devname, sizeof(devname), "/tmp/.tmp.md.%d:%d:%d",
+ (int)getpid(), major, minor);
+ if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
+ fd = open(devname, flags);
+ unlink(devname);
+ }
}
} else
- fd = open(dev, flags|O_DIRECT);
+ fd = open(dev, flags);
return fd;
}