summaryrefslogtreecommitdiffstats
path: root/discover/cdrom.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-11-29 10:47:10 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-12-02 17:00:16 +0800
commit9de5d31f93dab36cfb451e9ad724d47311b54424 (patch)
tree47dbc8efa3f62da140d6edc045fdebf2aa73ac1c /discover/cdrom.c
parentf4d1abf7d2d066ee183d9cd588f336dc63f0da00 (diff)
downloadtalos-petitboot-9de5d31f93dab36cfb451e9ad724d47311b54424.tar.gz
talos-petitboot-9de5d31f93dab36cfb451e9ad724d47311b54424.zip
discover: Fix CDROM handling
Currently, we don't handle CDROM devices well; we'll try to mount on boot, and not detect any media changes. Also, the default rules shipping with udev will put the CDROM tray into a locked state, blocking eject from working. This change adds a set of cdrom utility functions, which the udev code can use to properly initialise cdrom devices and handle eject and media change requests. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'discover/cdrom.c')
-rw-r--r--discover/cdrom.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/discover/cdrom.c b/discover/cdrom.c
new file mode 100644
index 0000000..0e88301
--- /dev/null
+++ b/discover/cdrom.c
@@ -0,0 +1,81 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+
+#include <log/log.h>
+
+#include "cdrom.h"
+
+static int cdrom_open(const char *devpath, const char *loc)
+{
+ int fd;
+
+ fd = open(devpath, O_RDONLY | O_NONBLOCK);
+ if (fd < 0)
+ pb_log("%s: can't open %s: %s\n", loc, devpath,
+ strerror(errno));
+
+ return fd;
+}
+
+void cdrom_init(const char *devpath)
+{
+ int fd, rc;
+
+ fd = cdrom_open(devpath, __func__);
+ if (fd < 0)
+ return;
+
+ /* We disable autoclose so that any attempted mount() operation doesn't
+ * close the tray, and disable CDO_LOCK to prevent the lock status
+ * changing on open()/close()
+ */
+ rc = ioctl(fd, CDROM_CLEAR_OPTIONS, CDO_LOCK | CDO_AUTO_CLOSE);
+ if (rc < 0)
+ pb_debug("%s: CLEAR CDO_LOCK|CDO_AUTO_CLOSE failed: %s\n",
+ __func__, strerror(errno));
+
+ close(fd);
+}
+
+bool cdrom_media_present(const char *devpath)
+{
+ int fd, rc;
+
+ fd = cdrom_open(devpath, __func__);
+ if (fd < 0)
+ return false;
+
+ rc = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+
+ close(fd);
+
+ return rc == CDS_DISC_OK;
+}
+
+void cdrom_eject(const char *devpath)
+{
+ int fd, rc;
+
+ fd = cdrom_open(devpath, __func__);
+ if (fd < 0)
+ return;
+
+ /* unlock cdrom device */
+ rc = ioctl(fd, CDROM_LOCKDOOR, 0);
+ if (rc < 0)
+ pb_log("%s: CDROM_LOCKDOOR(unlock) failed: %s\n",
+ __func__, strerror(errno));
+
+ rc = ioctl(fd, CDROMEJECT, 0);
+ if (rc < 0)
+ pb_log("%s: CDROM_EJECT failed: %s\n",
+ __func__, strerror(errno));
+ close(fd);
+}
+
OpenPOWER on IntegriCloud