diff options
author | NeilBrown <neilb@suse.de> | 2010-08-30 00:48:48 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-08-30 00:48:48 +0200 |
commit | 6df6a774bff2fc6e2ab3f4092620ab7657c984aa (patch) | |
tree | c5ea27c154b4f01a164ab9b3174845acb3f2ca7e /util.c | |
parent | Allow --incremental to add spares to an array. (diff) | |
download | mdadm-6df6a774bff2fc6e2ab3f4092620ab7657c984aa.tar.xz mdadm-6df6a774bff2fc6e2ab3f4092620ab7657c984aa.zip |
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 '')
-rw-r--r-- | util.c | 26 |
1 files changed, 20 insertions, 6 deletions
@@ -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; } |