In the field I need some users to be able to make iso files reliably from a cdrom that is also serving as a mounted LiveCD and so I concocted a manual test case before doing any scripting. The test case fails.
ISO Duplication Test Procedure
To be specific, the manual test procedure is:
- start with an iso file of a particular customized livecd based on ubuntu-9.10
- burn a cd using this iso file with computer #1's burner
- boot cd with computer #2 -- after boot make sure /tmp has sufficient capacity to hold a copy of the iso
- use dd on computer #2 to make another iso file in /tmp
- check the file size and the md5 of the resulting iso in /tmp with the one originally used in step
Failure Of Test Case
Failure mode was copy didn't complete.
Burner was a Gateway desktop running Brasero on Ubuntu-9.10
Booter was an ASUS N laptop.
df identifies the cdrom as /dev/sr0
/tmp shows plenty of space to hold the image
dd if=/dev/sr0 of=/tmp/cdtest.iso dd: reading '/dev/sr0' Input/Output error 1022208+0 records in 1022208+0 records out 523370496 bytes (523 MB) copied ....
Original iso size is 523497472 bytes, so about 127 k is missing.
dmesg (clipped) [ 694.212395] sr 1:0:0:0: [sr0] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [ 694.212401] sr 1:0:0:0: [sr0] Sense Key : Illegal Request [current] [ 694.212406] Info fld=0x3e67e, ILI [ 694.212407] sr 1:0:0:0: [sr0] Add. Sense: Illegal mode for this track [ 694.212413] end_request: I/O error, dev sr0, sector 1022208 [ 694.212416] __ratelimit: 1 callbacks suppressed [ 694.212418] Buffer I/O error on device sr0, logical block 255552 [ 694.212419] Buffer I/O error on device sr0, logical block 255553 [ 694.212422] Buffer I/O error on device sr0, logical block 255554 [ 694.212424] Buffer I/O error on device sr0, logical block 255555 [ 694.212426] Buffer I/O error on device sr0, logical block 255556 [ 694.212428] Buffer I/O error on device sr0, logical block 255557 [ 694.212429] Buffer I/O error on device sr0, logical block 255558 [ 694.212431] Buffer I/O error on device sr0, logical block 255559 [ 694.212433] Buffer I/O error on device sr0, logical block 255560 [ 694.212434] Buffer I/O error on device sr0, logical block 255561
Thoughts? Are there some less obvious options I should be giving dd in the way of block sizes or telling it to reread on error?
*Update Succeeded on VirtualBox
Ran another copy exercise -- this time from SUN VirtualBox instead of physical hardware. This would partially test, for instance, whether the iso file itself was to blame or whether there was something peculiar software-wise. dd worked fine to recreate the iso when the livecd ran on the virtual hardware insofar as physical sizes match and md5's match.
Update #2 The cdrom's isolinux.bin and md5sum.txt FAIL md5 when read from computer #2 after booting.
Ran md5sum -c md5sum.txt on the CD's md5 sum file.
None of the file accesses complained about being unable to read the device. I would have expected a file near the end of the write to have problems.
The isolinux.bin md5 and the md5sum.txt md5 did not match. isolinux.bin is the boot-up code used at system boot to load the linux kernel and initrd -- and it worked ok. The md5sum file is, well, the md5sum file for checking the cd contents. Of the files that could have been corrupted, thats an odd pair security-wise. But there are only 12 files on the CD. If isolinux.bin is corrupted, how did it still boot ok? Strange.
Checking the VirtualBox test system, where duplicating the iso succeeded I found that md5 for isolinux.bin and md5sum.txt did not match the md5sum file. The actual md5's also matched exactly the ones read on the physical computer. This might simply mean that the md5sum file was generated before isolinux.bin was finalized or a new isolinux.bin was copied over after md5sum was made.
Note that there were no complaints about not being able to read blocks of files when going through the filesystem.
Wikipedia vs dd
Interaction with Richard T led me to think about basic cdrom reliability. The wikipedia entry for iso9660 talks about a CDROM Mode 1 that includes 288 bytes of error correcting code for every 2048 bytes of user data. For dd to produce a faithful copy, does it has to get everything correct without the benefit of the ECC? If the ECC is part of the iso9660 spec I would guess 'yes' because the dd is copying the ECC bits and the data without regard to using one to influence the other. If the ECC is part of the /dev/sr0 cdrom driver I would guess 'no'.
If the only way to get the error corrected copy is to go through the filesystem, then I'd need to use genisoimage and grab the first few sectors with dd to give genisoimage the boot sectors back, I guess. Still hoping for something from the group mind.
I'm lucky to have the original genisoimage command to master the original iso file.
So from computer #2, running the LiveCD, I tried it. That's not enough, either, but maybe we're getting closer.
apt-get install genisoimage cd /cdrom genisoimage -r -V "OurLiveCDNameIsSomethingElse" -cache-inodes -J -l -b isolinux/isolinux -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o /tmp/cdcopy.iso . Output: ...using utf-8 (detected in locale) Size of boot image is 4 sectors-> No emulation genisoimage: Read-only file system. Error opening boot image file './isolinux/isolinux.bin' for update.
At least now we know why the md5 on isolinux.bin doesn't match -- genisoimage wants to do something to it!
An Ugly Hack
OK so next thing to try was making a directory called uglyhack, and symlinking all the files from /cdrom to there, except for isolinux.bin, which gets a real copy. genisoimage takes this, and writes 0MB with no error messages. Guess genisoimage ignores symlinked files.
The good news is that this suggests an answer, but not a very pretty one:
copy all the files from the /cdrom to another, writable file system and then run genisoimage on that.
So what now?
There must be some better way to achieve this task.