Add detection mechanism which will allow to check whether a path to a
block device is a physical CDROM drive. This will be useful once we will
need to pass it to hypervisors.
The linux implementation uses an ioctl to do the detection, while the
fallback uses a simple string prefix match.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virfile.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++-
src/util/virfile.h | 2 ++
3 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d2728749fb..4f911c10a8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1781,6 +1781,7 @@ virFileGetMountSubtree;
virFileHasSuffix;
virFileInData;
virFileIsAbsPath;
+virFileIsCdrom;
virFileIsDir;
virFileIsExecutable;
virFileIsLink;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 24f866525f..ad59b7015b 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -59,8 +59,9 @@
# include <sys/statfs.h>
# if HAVE_DECL_LO_FLAGS_AUTOCLEAR
# include <linux/loop.h>
-# include <sys/ioctl.h>
# endif
+# include <sys/ioctl.h>
+# include <linux/cdrom.h>
#endif
#include "configmake.h"
@@ -1938,6 +1939,59 @@ int virFileIsMountPoint(const char *file)
}
+#if defined(__linux__)
+/**
+ * virFileIsCdrom:
+ * @filename: File to check
+ *
+ * Returns 1 if @filename is a cdrom device 0 if it is not a cdrom and -1 on
+ * error. 'errno' of the failure is preserved and no libvirt errors are
+ * reported.
+ */
+int
+virFileIsCdrom(const char *filename)
+{
+ struct stat st;
+ int fd;
+ int ret = -1;
+
+ if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) < 0)
+ goto cleanup;
+
+ if (fstat(fd, &st) < 0)
+ goto cleanup;
+
+ if (!S_ISBLK(st.st_mode)) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ /* Attempt to detect via a CDROM specific ioctl */
+ if (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) >= 0)
+ ret = 1;
+ else
+ ret = 0;
+
+ cleanup:
+ VIR_FORCE_CLOSE(fd);
+ return ret;
+}
+
+#else
+
+int
+virFileIsCdrom(const char *filename)
+{
+ if (STRPREFIX(filename, "/dev/cd", NULL) ||
+ STRPREFIX(filename, "/dev/acd", NULL))
+ return 1;
+
+ return 0;
+}
+
+#endif /* defined(__linux__) */
+
+
#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
static int
virFileGetMountSubtreeImpl(const char *mtabpath,
diff --git a/src/util/virfile.h b/src/util/virfile.h
index cd2a3867c2..8ab7d2d6a6 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -207,6 +207,8 @@ enum {
int virFileIsSharedFSType(const char *path, int fstypes) ATTRIBUTE_NONNULL(1);
int virFileIsSharedFS(const char *path) ATTRIBUTE_NONNULL(1);
int virFileIsMountPoint(const char *file) ATTRIBUTE_NONNULL(1);
+int virFileIsCdrom(const char *filename)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virFileGetMountSubtree(const char *mtabpath,
const char *prefix,
--
2.16.2