Package: src:linux
Version: 5.10.226-1
Severity: normal
X-Debbugs-Cc: [email protected]

I wrote a program to run…
        ioctl(i, CDROM_LOCKDOOR, 1)
… on /dev/cdrom aka /dev/sr0, and it executes correctly.
The program then holds the file descriptor open until SIGTERM.

However, the only effect of this is that /dev/cdrom and the other
/dev/cd-something symlink I cannot remember go away. The CD-ROM
drive is not locked.

This is on a Thinkpad X61, CD-ROM drive in docking station.

Not sure whether the model just cannot do this or udev is interfering
or something else is going on, but, for comparison, on a Thinkpad X40
(i.e. a pretty similar setup) the equivalent ioctl on MirBSD can indeed
successfully lock the drive, so at least it’s not a systematic problem
with Thinkpads.

I’m attaching a first draft (I didn’t have the tuits to fully port
cdio(1) with all of its features at the moment).

-- Package-specific info:
** Version:
Linux version 5.10.0-33-amd64 ([email protected]) (gcc-10 (Debian 
10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #1 SMP 
Debian 5.10.226-1 (2024-10-03)

** Command line:
BOOT_IMAGE=/vmlinuz-5.10.0-33-amd64 root=/dev/mapper/vg--x61p-lv--root ro 
net.ifnames=0 
rootflags=defaults,relatime,lazytime,barrier=1,data=ordered,auto_da_alloc 
vga=792 TZ=:Europe/Berlin

** Tainted: OE (12288)
 * externally-built ("out-of-tree") module was loaded
 * unsigned module was loaded

** Kernel log:
Unable to read kernel log; any relevant messages should be attached

** Model information
sys_vendor: LENOVO
product_name: 7674D67
product_version: ThinkPad X61
chassis_vendor: LENOVO
chassis_version: Not Available
bios_vendor: LENOVO
bios_version: 7NET30WW (1.11 )
board_vendor: LENOVO
board_name: 7674D67
board_version: Not Available

** Loaded modules:
snd_seq_dummy
snd_seq
snd_seq_device
fuse
cpufreq_ondemand
ctr
ccm
binfmt_misc
cpufreq_powersave
tp_smapi(OE)
thinkpad_ec(OE)
msr
snd_hda_codec_analog
snd_hda_codec_generic
iwl4965
iwlegacy
snd_hda_intel
mac80211
i915
snd_intel_dspcfg
coretemp
soundwire_intel
pcmcia
soundwire_generic_allocation
snd_soc_core
snd_compress
kvm_intel
soundwire_cadence
snd_hda_codec
cfg80211
snd_hda_core
drm_kms_helper
cec
kvm
snd_hwdep
ppdev
drm
soundwire_bus
iTCO_wdt
intel_pmc_bxt
yenta_socket
irqbypass
evdev
thinkpad_acpi
pcmcia_rsrc
snd_pcm
iTCO_vendor_support
pcmcia_core
watchdog
serio_raw
libarc4
pcspkr
i2c_algo_bit
nvram
sg
snd_timer
ledtrig_audio
snd
soundcore
rfkill
parport_pc
ac
parport
button
acpi_cpufreq
ecb
aes_generic
libaes
crypto_simd
cryptd
glue_helper
xts
dm_crypt
dm_mod
ext4
crc16
mbcache
jbd2
crc32c_generic
mmc_block
sd_mod
t10_pi
crc_t10dif
crct10dif_generic
sr_mod
cdrom
crct10dif_common
sdhci_pci
ata_generic
cqhci
e1000e
ahci
ehci_pci
uhci_hcd
ehci_hcd
libahci
sdhci
i2c_i801
ptp
ata_piix
libata
psmouse
usbcore
pps_core
scsi_mod
mmc_core
lpc_ich
i2c_smbus
usb_common
battery
video

** PCI devices:
not available

** USB devices:
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 003: ID 17ef:1000 Lenovo ThinkPad X6 UltraBase
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 002: ID 0483:2016 STMicroelectronics Fingerprint Reader
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub


-- System Information:
Debian Release: 11.11
  APT prefers oldstable-updates
  APT policy: (500, 'oldstable-updates'), (500, 'oldstable-security'), (500, 
'oldstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.10.0-33-amd64 (SMP w/2 CPU threads)
Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=C.UTF-8, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/lksh
Init: sysvinit (via /sbin/init)

Versions of packages linux-image-5.10.0-33-amd64 depends on:
ii  initramfs-tools [linux-initramfs-tool]  0.140
ii  kmod                                    28-1
ii  linux-base                              4.6

Versions of packages linux-image-5.10.0-33-amd64 recommends:
pn  apparmor             <none>
ii  firmware-linux-free  20200122-1

Versions of packages linux-image-5.10.0-33-amd64 suggests:
pn  debian-kernel-handbook  <none>
ii  grub-pc                 2.06-3~deb11u6
pn  linux-doc-5.10          <none>

Versions of packages linux-image-5.10.0-33-amd64 is related to:
pn  firmware-amd-graphics     <none>
pn  firmware-atheros          <none>
pn  firmware-bnx2             <none>
pn  firmware-bnx2x            <none>
pn  firmware-brcm80211        <none>
pn  firmware-cavium           <none>
pn  firmware-intel-sound      <none>
pn  firmware-intelwimax       <none>
pn  firmware-ipw2x00          <none>
pn  firmware-ivtv             <none>
ii  firmware-iwlwifi          20210315-3
pn  firmware-libertas         <none>
pn  firmware-linux-nonfree    <none>
pn  firmware-misc-nonfree     <none>
pn  firmware-myricom          <none>
pn  firmware-netxen           <none>
pn  firmware-qlogic           <none>
pn  firmware-realtek          <none>
pn  firmware-samsung          <none>
pn  firmware-siano            <none>
pn  firmware-ti-connectivity  <none>
pn  xen-hypervisor            <none>

-- no debconf information
/* SPDX-License-Identifier: MirOS OR CC0-1.0 */
/* © 2024 mirabilos Ⓕ MirBSD or CC0 */

#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#if 0
#define DEFAULT_CDROM "/dev/cdrom"
#else
/* udev, on 'cdio lock', drops /dev/cd* entries; gotta love progress! */
#define DEFAULT_CDROM "/dev/sr0"
#endif

enum command {
        CMD_CLOSE,
        CMD_EJECT,
        CMD_LOCK,
};

static volatile sig_atomic_t keeprunning;
/* pointer, not array */
static const char *dvname = DEFAULT_CDROM;

static void initsigs(void);
static void usage(void) __attribute__((__noreturn__));

int
main(int argc, char *argv[])
{
        int i;
        enum command cmd;

        while ((i = getopt(argc, argv, "d:f:sv")) != -1)
                switch (i) {
                case 'd':
                case 's':
                case 'v':
                        /* ignored, for MirBSD cdio(1) compatibility */
                        break;
                case 'f':
                        dvname = optarg;
                        break;
                default:
                        usage();
                }
        argc -= optind;
        argv += optind;

        if (argc != 1) /* for now */
                usage();
        if (!strcmp(*argv, "close"))
                cmd = CMD_CLOSE;
        else if (!strcmp(*argv, "eject"))
                cmd = CMD_EJECT;
        else if (!strcmp(*argv, "lock"))
                cmd = CMD_LOCK;
        else
                usage();

        /* O_NONBLOCK per <linux/cdrom.h> instructions */
        if ((i = open(dvname, O_RDONLY | O_NONBLOCK)) == -1)
                err(1, "open %s", dvname);
#define tryioctl(name, ...) do {                                \
        /* as unknown error indicator */                        \
        errno = ENOPROTOOPT;                                    \
        if (ioctl(i, name, ## __VA_ARGS__) < 0)                 \
                err(1, "ioctl(%s, %s)", dvname, #name);         \
} while (/* CONSTCOND */ 0)
        switch (cmd) {
        case CMD_CLOSE:
                if (ioctl(i, CDROMCLOSETRAY, 0) < 0)
                        err(1, "ioctl(%s, %s)", dvname, "CDROMCLOSETRAY");
                break;
        case CMD_EJECT:
                /* try unlocking first */
                if (ioctl(i, CDROM_LOCKDOOR, 0) < 0)
                        warn("ioctl(%s, %s)", dvname, "CDROM_LOCKDOOR");
                errno = ENOPROTOOPT;
                if (ioctl(i, CDROMEJECT, 0) < 0)
                        err(1, "ioctl(%s, %s)", dvname, "CDROMEJECT");
                break;
        case CMD_LOCK:
                if (ioctl(i, CDROM_LOCKDOOR, 1) < 0)
                        err(1, "ioctl(%s, %s)", dvname, "CDROM_LOCKDOOR");
                /* assert(!is_interactive); */
                initsigs();
                printf("I: locked; keeping program running until aborted...");
                fflush(NULL);
                keeprunning = 1;
                while (keeprunning)
                        pause();
                printf("\nI: signal caught, exiting\n");
                break;
        }
        close(i);
        return (0);
}

static void
usage(void)
{
        fprintf(stderr, "E: usage: cdio [-f %s] <command>\n", DEFAULT_CDROM);
        fprintf(stderr, "N: commands are: close eject lock\n");
        exit(1);
}

static void
handle_sigterm(int signo __attribute__((__unused__)))
{
        keeprunning = 0;
}

static void
initsigs(void)
{
        struct sigaction sa;

        memset(&sa, '\0', sizeof(sa));
        sa.sa_handler = &handle_sigterm;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESETHAND;
        if (sigaction(SIGTERM, &sa, NULL))
                warn("could not install SIGTERM handler");
}

Reply via email to