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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list