summaryrefslogtreecommitdiffstats
path: root/lib/blkdev.c
diff options
context:
space:
mode:
authorSami Kerola2015-10-31 18:29:02 +0100
committerSami Kerola2015-11-22 21:56:05 +0100
commit8fe1e638fa81d88e1e405f6221c7a592284c9b23 (patch)
tree7b95d5f7c2276f0ccdc5e24d97b5343d942b0d08 /lib/blkdev.c
parentinclude/fileutils: add is_same_inode() check (diff)
downloadkernel-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.c24
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