Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update CDROM size in Linux without ejecting the CDROM?

Tags:

linux

How can I get Linux to update its idea of the size of a CDROM without ejecting it? In otherwords, how can I mount a freshly burnt CDROM without ejecting it first?

I'm doing unattended incremental backups onto a CDROM. Every day my script uses "wodim -msinfo" and "genisoimage -C" to generate an image that is appended to the CDROM using "wodim -multi". My script then mounts the CDROM to check that the new files were correctly appended. The script can only read the new files if Linux's idea of the size of the CDROM is updated before the mount. The size is in /sys/block/sr2/size and /proc/partitions. Previously my script used "eject" then "eject -t" to get Linux to reread the CDROM. "eject -t" does not work on my new CDROM burner. How I can I get /proc/partitions updated without ejecting the CDROM?

It appears that the "wodim -msinfo" and "genisoimage -C" step also requires the CDROM to have been ejected since the previous burn to the CDROM otherwise I get the message "genisoimage: Invalid argument. Seek error on old image".

Somebody asked this question in 2003 but the answer that they received does not update the CDROM size for me. http://compgroups.net/comp.os.linux.questions/rescan-cdrom-frm-command-line/456190

#include <fcntl.h>
#include <stdio.h>
#include <linux/cdrom.h>
int main(void)
{
    int i = 0;
    int fd = open("/dev/cdrom", O_RDWR);
    if (fd == -1)
    {
            perror("Could not open cdrom");
            return 1;
    }
    if (ioctl(fd, CDROM_MEDIA_CHANGED)) perror("ioctl");
    if (ioctl(fd, CDROMRESET)) perror("ioctl CDROMRESET");
    if (ioctl(fd, CDROM_NEXT_WRITABLE, &i))
            perror("ioctl CDROM_NEXT_WRITABLE,");
    else
            printf("CDROM_NEXT_WRITABLE %d\n", i);
    if (ioctl(fd, CDROM_LAST_WRITTEN, &i))
            perror("ioctl CDROM_LAST_WRITTEN,");
    else
            printf("CDROM_LAST_WRITTEN %d\n", i);
    return 0;
}

This is exactly what happens when I create new CDROM. I have to eject it and then push it back in to get it to mount.

% genisoimage -r -V archive -input-charset ASCII -quiet /usr/lib/vlc > /tmp/libvlc.iso
% grep -H sr2 /proc/partitions ; cat /sys/block/sr2/size
/proc/partitions:  11        2          2 sr2
4
% wodim driveropts=burnfree -tao -data  dev=/dev/sr2 /tmp/libvlc.iso
wodim: Operation not permitted. Warning: Cannot raise RLIMIT_MEMLOCK limits.
Device type    : Removable CD-ROM
Version        : 0
Response Format: 2
Capabilities   : 
Vendor_info    : 'TSSTcorp'
Identification : 'CDDVDW SE-S084C '
Revision       : 'TU00'
Device seems to be: Generic mmc2 DVD-R/DVD-RW.
Using generic SCSI-3/mmc   CD-R/CD-RW driver (mmc_cdr).
Driver flags   : MMC-3 SWABAUDIO BURNFREE 
Supported modes: TAO PACKET SAO SAO/R96P SAO/R96R RAW/R16 RAW/R96P RAW/R96R
Speed set to 1764 KB/s
Starting to write CD/DVD at speed  10.0 in real TAO mode for single session.
Last chance to quit, starting real write in    0 seconds. Operation starts.
Track 01: Total bytes read/written: 17078272/17078272 (8339 sectors).
% grep -H sr2 /proc/partitions ; cat /sys/block/sr2/size
/proc/partitions:  11        2          2 sr2
4
% sudo mount /dev/sr2 /mnt
mount: /dev/sr2 is write-protected, mounting read-only
mount: wrong fs type, bad option, bad superblock on /dev/sr2,
       missing codepage or helper program, or other error

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
% grep -H sr2 /proc/partitions ; cat /sys/block/sr2/size
/proc/partitions:  11        2          2 sr2
4
% sudo mount /dev/sr2 /mnt
mount: /dev/sr2 is write-protected, mounting read-only
mount: wrong fs type, bad option, bad superblock on /dev/sr2,
       missing codepage or helper program, or other error

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
% sudo eject /dev/sr2
% #push CDRW back in
% grep -H sr2 /proc/partitions ; cat /sys/block/sr2/size
/proc/partitions:  11        2      16682 sr2
33364
% sudo mount /dev/sr2 /mnt
mount: /dev/sr2 is write-protected, mounting read-only

I have tried various hdparm options but none of them work, nor do they change the kernel's idea of the size of CDROM or allow it to be mounted.

:; sudo hdparm -z  /dev/sr2 

/dev/sr2:
 re-reading partition table
 BLKRRPART failed: Invalid argument
:; sudo hdparm -F  /dev/sr2 

/dev/sr2:
SG_IO: bad/missing sense data, sb[]:  70 00 05 00 00 00 00 0a 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SG_IO: bad/missing sense data, sb[]:  70 00 05 00 00 00 00 0a 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
:; sudo hdparm -Y  /dev/sr2 

/dev/sr2:
 issuing sleep command
SG_IO: bad/missing sense data, sb[]:  70 00 05 00 00 00 00 0a 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
:; sudo hdparm -w  /dev/sr2 

/dev/sr2:
 resetting drive
 HDIO_DRIVE_RESET failed: Invalid argument
:; grep -H sr2 /proc/partitions ; cat /sys/block/sr2/size
/proc/partitions:  11        2          2 sr2
4
:; sudo mount /dev/sr2 /mnt
mount: /dev/sr2 is write-protected, mounting read-only
mount: wrong fs type, bad option, bad superblock on /dev/sr2,
       missing codepage or helper program, or other error

       In some cases useful info is found in syslog - try
       dmesg | tail or so.

Specifying the type of the filesystem does not help.

:; grep -H sr2 /proc/partitions ; cat /sys/block/sr2/size
/proc/partitions:  11        2          2 sr2
4
:; sudo mount -t iso9660 /dev/sr2 /mnt
[sudo] password for root: 
(pam_mount.c:365): pam_mount 2.14: entering auth stage
mount: /dev/sr2 is write-protected, mounting read-only
mount: wrong fs type, bad option, bad superblock on /dev/sr2,
       missing codepage or helper program, or other error

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
(pam_mount.c:133): clean system authtok=0x7f0a33b97450 (1073741824)
:; grep -H sr2 /proc/partitions ; cat /sys/block/sr2/size
/proc/partitions:  11        2          2 sr2
4

The message that I get from dmesg(1) is

[1209552.092616] isofs_fill_super: bread failed, dev=sr2, iso_blknum=16, block=16
like image 811
Stuart Pook Avatar asked Feb 14 '15 15:02

Stuart Pook


2 Answers

I'm having the same problem with a BD drive. What worked for me is to unbind (unpower) the device and rebind it again. Here the rough steps

  • find the usb-device via "lsscsi -v"

    [11:0:0:0]   cd/dvd  TSSTcorp BDDVDW SE-506AB  TS01  /dev/sr1 
    dir: /sys/bus/scsi/devices/11:0:0:0  [/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/host11/target11:0:0/11:0:0:0]
    
  • power down the device / prepare for disconnect

    sudo bash -c "echo 2-1.2 | tee /sys/bus/usb/drivers/usb/unbind"
    
  • power up the device / connect again

    sudo bash -c "echo 2-1.2 | tee /sys/bus/usb/drivers/usb/bind"
    

Unbind / bind is a great way to reset many usb devices ...

like image 105
GMA Avatar answered Oct 13 '22 17:10

GMA


Based on GMA's answer, I was able to put together something that I think is a bit more generic:

  • find the scsi device id via "lsscsi -v"
  • cd /sys/bus/scsi/drivers/sr
  • echo the scsi id to unbind, then bind.
    • echo "1:0:0:0" > unbind
    • echo "1:0:0:0" > bind
like image 1
tcoll Avatar answered Oct 13 '22 18:10

tcoll