Skip to content

ioctl to detect cd drive state #262

Open
@flihp

Description

@flihp

Detecting the presence of media in the CD drive got complicated on NixOS. Attempts to mount a CD while the tray was still closing or the device still settling, the kernel shipped w/ NixOS would throw I/O errors and start resetting the CDROM device. Debian and Arch didn't, but why is a mystery for another day. I've found that using blockdev --getsize64 /dev/cdrom turns out to be a much more resilient approach even on NixOS. This will exit w/ status 0 if there's a disk in the drive and 1 if not (or probably a ton of other error cases).

The "right" way to do this (I think) is to call the relevant IOCTL directly. This requires that we:

  • figure out how to call the Linux ioctl system call
  • figure out the parameters that we must pass to ioctl in order to detect the various states required
    • blank media in drive
    • non-blank media in drive
  • get constants for the ioctl from linux/cdrom.h for whatever kernel is required

Calling an IOCTL from rust doesn't seem too hard: https://docs.rs/nix/latest/nix/sys/ioctl/

The IOCTL we need is CDROM_DRIVE_STATUS. This tells us the status of the drive which includes CDS_NO_DISC: https://github.com/torvalds/linux/blob/0bc21e701a6ffacfdde7f04f87d664d82e8a13bf/include/uapi/linux/cdrom.h#L419C9-L419C20

What's keeping us from using this method today is the last part: We need a rust package with constants from linux/cdrom.h, or some way to generate them in the oks build.rs. The NixOS linux headers can be found easy enough: https://discourse.nixos.org/t/linux-headers-not-found-dont-know-how-to-install/30508/3

Looks like there's a way to generate rust bindings from the linux kernel: https://github.com/MarcusGrass/linux-rust-bindings/tree/main. But this doesn't look like it's been updated in a while (may still work tho).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions