diff options
author | Sami Kerola | 2015-10-31 18:29:02 +0100 |
---|---|---|
committer | Sami Kerola | 2015-11-22 21:56:05 +0100 |
commit | 8fe1e638fa81d88e1e405f6221c7a592284c9b23 (patch) | |
tree | 7b95d5f7c2276f0ccdc5e24d97b5343d942b0d08 /lib/blkdev.c | |
parent | include/fileutils: add is_same_inode() check (diff) | |
download | kernel-qcow2-util-linux-8fe1e638fa81d88e1e405f6221c7a592284c9b23.tar.gz kernel-qcow2-util-linux-8fe1e638fa81d88e1e405f6221c7a592284c9b23.tar.xz kernel-qcow2-util-linux-8fe1e638fa81d88e1e405f6221c7a592284c9b23.zip |
lib/blkdev: add open_blkdev_or_file() function
Purpose of this function is to open a path that is potentially pointing to a
block device or file without races. The function also proper open(3) flags
are used to check the device is not busy, and finally warning is been
printed if a block device happens to be misaligned.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'lib/blkdev.c')
-rw-r--r-- | lib/blkdev.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/blkdev.c b/lib/blkdev.c index 5f495822e..a57b3672b 100644 --- a/lib/blkdev.c +++ b/lib/blkdev.c @@ -25,9 +25,15 @@ # include <sys/disk.h> #endif +#ifndef EBADFD +# define EBADFD 77 /* File descriptor in bad state */ +#endif + #include "blkdev.h" #include "c.h" #include "linux_version.h" +#include "fileutils.h" +#include "nls.h" static long blkdev_valid_offset (int fd, off_t offset) { @@ -254,6 +260,24 @@ int blkdev_is_misaligned(int fd) #endif } +int open_blkdev_or_file(const struct stat *st, const char *name, const int oflag) +{ + int fd; + + if (S_ISBLK(st->st_mode)) { + fd = open(name, oflag | O_EXCL); + } else + fd = open(name, oflag); + if (-1 < fd && !is_same_inode(fd, st)) { + close(fd); + errno = EBADFD; + return -1; + } + if (-1 < fd && S_ISBLK(st->st_mode) && blkdev_is_misaligned(fd)) + warnx(_("warning: %s is misaligned"), name); + return fd; +} + int blkdev_is_cdrom(int fd) { #ifdef CDROM_GET_CAPABILITY |