[go: up one dir, main page]

Menu

#8 cd_eject (): ioctl (cd_desc, CDAUDIO_EJECT) always returning -1

v1.0_(example)
pending
nobody
1
2019-05-30
2019-05-02
No

I'm using cdaudio both as a lib for use in client code, and via cdcd. Now, when trying to eject the CD (in a USB DVD drive named /dev/sr0 attached to a Raspi 3B), I get the following error message:

ioctl returned -1

I do not get any other error messages, not even though dmesg.

What puzzles me a bit, is your use of the CDAUDIO_EJECT command. I can't find it neither in linux/cdrom.h, nor in ioctl_list, but I do find a command named CDROMEJECT.

What's wrong here? Thank you.

Discussion

  • Fabrice Bauzac

    Fabrice Bauzac - 2019-05-03

    Hello,

    In src/compat.h we define:

    #ifdef CDROMEJECT
    #define CDAUDIO_EJECT CDROMEJECT
    #endif
    

    So we really use CDROMEJECT.

    The error message comes from this function in src/cdaudio.c:

    /* Eject the tray */
    int
    cd_eject(int cd_desc)
    {
      int r = ioctl(cd_desc, CDAUDIO_EJECT);
      if(r) {
        printf("ioctl returned %d\n", r);
        return -1;
      }
      return 0;
    }
    

    What we could add here is an additional print of the errno (with e.g. perror()) to better understand the error. Note that libcdaudio and cdcd are currently in search for a maintainer; if you would like to improve it, please contact me.

    The Linux kernel source says (in Documentation/ioctl/cdrom.txt):

    CDROMEJECT          Ejects the cdrom media
    
        usage:
    
          ioctl(fd, CDROMEJECT, 0);
    
        inputs:     none
    
        outputs:    none
    
        error returns:
          ENOSYS    cd drive not capable of ejecting
          EBUSY     other processes are accessing drive, or door is locked
    
        notes:
          See CDROM_LOCKDOOR, below.
    

    Probably your error is one of the errors above. For more information on what's going on, please search for information on the Linux kernel part (internet search, ask maintainers...) as I wouldn't be able to help here.

    Thanks!

    Best regards

     
  • Jacek Ruzyczka

    Jacek Ruzyczka - 2019-05-03

    Thank you for the hints. I have already decoded the errno: It gives me 5, which means "input output error" — so the error can be literally anywhere.

    UPDATE: After another user's hint, I used strace to hunt down the cause of the error. Here is its output:

    ioctl(3, CDROM_DISC_STATUS, 0)          = 100
    ioctl(3, CDROMSUBCHNL, 0x7e93e308)      = 0
    ioctl(3, CDROMEJECT, 0x1)               = -1 EIO (Input/output error)
    write(1, "ioctl returned -1\n", 18)     = 18
    

    For comparison, here is the strace output of the eject command-line utility, which works flawlessly:

    geteuid32()                             = 1000
    open("/dev/sr0", O_RDWR|O_NONBLOCK)     = 3
    ioctl(3, CDROMEJECT, 0x1)               = 0
    close(3)                                = 0
    exit_group(0)                           = ?
    +++ exited with 0 +++
    

    The ioctl command is exactly the same, but the CD drive is opened in a slightly different manner, namely in RDWR mode, in contrast to what you are doing:

    open("/dev/sr0", O_RDONLY|O_NONBLOCK)   = 3
    

    UPDATE: Looking into the sourcecode of eject reveals that they first check for whether the drive is read-write, or not, and then open it read-write or read-only: eject.c, lines 686 thru 694

     

    Last edit: Jacek Ruzyczka 2019-05-04
  • Jacek Ruzyczka

    Jacek Ruzyczka - 2019-05-07

    OK, I've adapted the cd_eject following the eject utility and recompiled the library as well as cdcd, but no use: Instead of the CD, I only get the ioctl error. See the file attached for a complete output of strace when invoking cdcd with the eject command directly from the shell.

    UPDATE: After fiddling around with the eject utility, I found out that my drive (and many others as well, I suppose) apparently would only accept SCSI commands, so it's basically a SCSI-over-USB device:

    pi@autoradio:/import/valen/autoradio $ eject -v /dev/sr0
    eject: device name is `/dev/sr0'
    eject: expanded name is `/dev/sr0'
    eject: `/dev/sr0' is not mounted
    eject: `/dev/sr0' is not a mount point
    eject: `/dev/sr0' is not a multipartition device
    eject: trying to eject `/dev/sr0' using CD-ROM eject command
    eject: CD-ROM eject command failed
    eject: trying to eject `/dev/sr0' using SCSI commands
    eject: SCSI eject succeeded
    

    cdaudio, on the other hand, seems to support CD-ROM commands only, so this way will never work. As you may see in the sourcecode of eject, it's a fairly complicated task. Who can implement this feature in cdaudio?

     

    Last edit: Jacek Ruzyczka 2019-05-08
  • Jacek Ruzyczka

    Jacek Ruzyczka - 2019-05-10

    I've now got a solution based on the eject_scsi () method from the eject utility: If the old CDROMEJECT fails, just switch to a series of SCSI commands as a fallback. Continue here: Patch #7

     
  • Jacek Ruzyczka

    Jacek Ruzyczka - 2019-05-30
    • status: open --> pending
     

Log in to post a comment.