Saturday, February 2, 2013

Recording a (data) Blu-ray from the command line

In this post, I'll show you how to build an iso image, burn it to a Blu-ray disc, and verify that the burn was successful. These steps are for creating a data Blu-ray. Authoring a movie is a whole different subject, however if you already have the movie files created, then you can use these steps for the burn.

Nothing here is specific to Blu-ray, so these steps will work equally well with a CD or DVD, but I encountered a bug in K3B that prevents a successful burn using Blu-ray discs.

But first, let me warn you about the bug that I encountered in K3B, the GUI burner that comes with OpenSUSE. In 12.2 (and at least back to 11.3), K3B will not complete a burn.  The (closed) bug report is here: https://bugzilla.novell.com/show_bug.cgi?id=656502. Basically, with around 100MB of data left to burn, K3B will report an "input/output error" and stop. Some suggestions for working around this problem include using BD-RE (rewritable) discs instead of BD-R discs, which I didn't try. Also suggested was using the original branch of the cdrtools and using the "create image" options, neither of which worked for me. I did get the burn to work via the command line, which is why there is this post.

Back to the burning. To create a burnable image:

1. I did use the original branch of the cdrtools. I don't know if this is necessary or not, but I was convinced from what I read about this branch versus the one that ships with OpenSUSE that it was better just to use this one. First, you'll need to download the source from http://cdrecord.berlios.de/private/cdrecord.html. I used version 3.01a11. Untar it, and then do a:

make && sudo make install

You'll need to have make and gcc installed, of course. The binaries are installed in /opt/schily/bin.

2. Create the image. Say you have the files you want to burn in /home/user/disc/. Then, from /home/user, you would:

/opt/schily/bin/mkisofs -J -r -iso-level 3 -allow-multidot -allow-leading-dots -joliet-long -o IMAGE.iso disc/
 The "-J" and "-r" flags just specify how the file names are stored (specifically using Joliet and Rock Ridge) so that your file names are not mangled. "-iso-level 3" enables support for files over 4GB in size. "-allow-multidot" and "-allow-leading-dots" allow files with multiple dots and leading dots in the filename, such as ".myfile.txt". "-joliet-long" provides Joliet support for longer filenames.

You will need, of course, enough free space on your drive to store an entire copy of the files you wish to burn. It is possible to pipe the output of mkisofs into the burner in the next step, but I prefer to do it in two stages, because you'll need the image in order to perform a MD5sum in order to verify that the burn was successful.

I also found that each time you create the image, the md5sum is different. I'm not sure why this is, but my guess is that the metadata (most likely something time related) changes. So definitely keep the image until you have either written down or verified the MD5sum.

3. Burn the image. Stick a blank disc in the drive and then:

/opt/schily/bin/cdrecord dev=/dev/sr0 -v -pad -data IMAGE.iso

4. Verify the data burned. First of all, this won't work:

md5sum IMAGE.iso
dd if=/dev/sr0 | md5sum
The problem is that when you use dd to read the disc, it will invariably read some blank bytes past the end of your data resulting in a completely different MD5sum.
The easiest way to verify the data is like this:

dd if=/dev/sr0 | cmp IMAGE.iso

If this ends with:

cmp: EOF on IMAGE.iso

then it was successful. The EOF means that the end of the image file was reached without finding a difference between the two. Everything else on the disc is just padding.

The only problem here is that you will presumably delete the image at this point and if later, you want to verify that the disc is still intact (say, you want to verify that a backup disc is still in good shape six months from now), you need a way to calculate the MD5sum from the disc. You could do so with:

md5sum IMAGE.iso
dd if=/dev/sr0 bs=1 count=IMAGE_SIZE | md5sum

where image_size is just the number of bytes of the image ("ls -al IMAGE.iso" will work). However, this will take a very long time (several hours) to complete since it's reading the bytes off of the disc one at a time. You can speed this up significantly by reading the bytes off in powers of 2. As long as the size of your image file is divisible by two, you're set; I believe that all images will always be divisible by 2048 bytes. In my case, my image had a size of 16,378,150,912 bytes, which when divided by 2^14=16384 is 999,643. That left me with a verify command like this:

md5sum IMAGE.iso
dd if=/dev/sr0 bs=16384 count=999643 | md5sum

It takes a little bit of math, but it will finish in 10-20 minutes and not hours later.

Once you have the MD5sum, I suggest writing it on the disc label for later use. In my case, I only write the last four digits (out of laziness), but the chances of a disc with an error generating the same last four digits in an MD5sum is 1 in 16^4=65,536. That's good enough for me.

No comments:

Post a Comment