diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2013-11-29 10:47:10 +0800 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2013-12-02 17:00:16 +0800 |
commit | 9de5d31f93dab36cfb451e9ad724d47311b54424 (patch) | |
tree | 47dbc8efa3f62da140d6edc045fdebf2aa73ac1c /discover/cdrom.c | |
parent | f4d1abf7d2d066ee183d9cd588f336dc63f0da00 (diff) | |
download | talos-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.c | 81 |
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); +} + |