]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: file: Add helper to determine whether a path is a CDROM
authorPeter Krempa <pkrempa@redhat.com>
Mon, 23 Apr 2018 15:41:14 +0000 (17:41 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 7 May 2018 13:17:06 +0000 (15:17 +0200)
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@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
src/libvirt_private.syms
src/util/virfile.c
src/util/virfile.h

index 92b5e0fa2bc208aa7056d6c029e71828f88f658f..f8883dc50da2ff5c9ea46a8f3ba9ead28b95064e 100644 (file)
@@ -1781,6 +1781,7 @@ virFileGetMountSubtree;
 virFileHasSuffix;
 virFileInData;
 virFileIsAbsPath;
+virFileIsCDROM;
 virFileIsDir;
 virFileIsExecutable;
 virFileIsLink;
index d1dd35db1cc5a2ccb386debfeaaa26f6d7a8b41c..ea2a3ea7312a71c885647a27c572ed93d7fd7451 100644 (file)
@@ -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:
+ * @path: File to check
+ *
+ * Returns 1 if @path 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 *path)
+{
+    struct stat st;
+    int fd;
+    int ret = -1;
+
+    if ((fd = open(path, 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 *path)
+{
+    if (STRPREFIX(path, "/dev/cd", NULL) ||
+        STRPREFIX(path, "/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,
index 341320b3d34af356c590c6779cb095d9b768521c..6b0cbad4d1cabc2c38680d4a984fd39737465d36 100644 (file)
@@ -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 *path)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
 
 int virFileGetMountSubtree(const char *mtabpath,
                            const char *prefix,