From: wayne@tachysoft.xxx.065234.killspam.015d Sent: Monday, April 09, 2001 10:23 AM To: Info-VAX@Mvb.Saic.Com Subject: Re: CD backups. In article <9aqi1r$id2$1@newsg1.svr.pol.co.uk>, "Leigh G. Bowden" writes: > The way I read it I have to do the following: > > Attach a CD writer to a machine. > Put what ever I want to preserve onto a HDD which is less than 650MB. > Mount this HDD as /FOREIGN. > Then do a COPY disk: another_disk:[000000.cds]cd_disk.rom > This generates a few whinges but these can be ignored. > Use CDRECORD freeware utility to burn the CD with the file cd_disk.rom. > Ensure that the machine doing the burning is doing nothing else to stop > interrupting the write process. Yes, that will work. You may need to supply a /allocate= on the copy, where block-count is the next larger multiple of 100. I have found that cdrecord does not like block counts that do not fall on the correct boundary. If you only want to preserve certain files, you can skip the step where you copy the files to a regular disk and mount it as foreign. If you get a virtual disk program, such as the LDdriver program found on the freeware cdrom, you can copy the files to the virtual disk container file and burn from that. The advantage to this approach is that you can burn a cdrom of exactly the right size. You can create the virtual disk initially with the full size of 650 meg. Then after you have copied your files to it, you can check how many blocks are actually used, reinitialize the virtual disk to that size, and copy the files again. If you don't have many files, this can drastically reduce the burn time, since you aren't burning thousands of unused blocks. I use the following set of command procedures (see description after): ========================== CREATE_CONTAINER_FROM_FILES.COM $ create_verify = f$verify (f$trnlnm ("create_container_files_verify") + 0) $! $! p1 = label to use on cdrom $! p2 = top level directory name for cdrom; if blank, [000000] $! p3 = format of file input $! FILE -- single file name, with or without wildcards $! LIST -- list of file names, with or without wildcards and dest dir $! TAPE -- tape device; copy p4 directly to top directory $! SAVE -- save set; restore saveset(s) in p4 $! TSAVE -- tape save set; restore saveset(s) on tape $! p4 = files $! p5 = set ownership $! $! $ set noon $ say :== write sys$output $ label = p1 $ top_lev_direct = p2 $ file_type = p3 $ file_param = p4 $ file_owner = p5 $ $! $! $ if f$trnlnm("container_scratch_disk") .eqs. "" $ then $ say "container_scratch_disk logical not defined" $ v = f$verify (create_verify) $ exit 4 $ endif $! $ if label .eqs. "" $ then $ say "label parameter is required" $ v = f$verify (create_verify) $ exit 4 $ endif $! $ if file_type .eqs. "" $ then $ say "file_type parameter is required" $ v = f$verify (create_verify) $ exit 4 $ endif $! $! $ if file_param .eqs. "" $ then $ say "file_param parameter is required" $ v = f$verify (create_verify) $ exit 4 $ endif $! $! $! Startup LD if needed $! $ if .not. f$getdvi("lda0:","exists") then @sys$startup:ld$startup $! $! $! $ container_name = label + "_image" $ container_file = "container_scratch_disk:[cdrom_container_files]" + container_name +- ".container;1" $ credir container_scratch_disk:[cdrom_container_files] $ say "searching for container file ''container_file'" $ file = f$search(container_file,42) $ if file .nes. "" $ then $ say "container file ",container_file," already present" $ del 'container_file' $ endif $! $! $! $! Use the full container file for the first pass $! $ ld create /noback/log/size=1327100 'container_file' $ status = $status $ if .not. status $ then $ say "unable to create container file the full size of a cdrom" $ delete/log 'container_file' $ v = f$verify (create_verify) $ exit status $ endif $! $! Populate the container file $! $ call setup_container_file $ status = $status $ if .not. status $ then $ delete/log 'container_file' $ v = f$verify (create_verify) $ exit status $ endif $! $! If there is a lot of free space, then make the container file a few $! thousand blocks larger than the actual data and repopulate it. This will $! speed up the cdrom burn immensely if there is a lot of free space. $! $! $ if free_blocks .gt. 20000 $ then $ say "container file has ",free_blocks,- " blocks free---squeezing disk to ",blocks," blocks" $ delete/log 'container_file' $ ld create /noback/log/size='blocks' 'container_file' $ call setup_container_file $ status = $status $ if .not. status $ then $ delete/log 'container_file' $ v = f$verify (create_verify) $ exit status $ endif $ endif $! $ say "container file ",container_file," created" $ exit $! $! $! $setup_container_file: subroutine $ ld conn/log/symbol 'container_file' $ ownopt = "" $ if file_owner .nes. "" then ownopt = "/own=[''file_owner']" $ init/nohigh'ownopt' lda'ld_unit': 'label' $ mount lda'ld_unit': 'label' 'label' $ if top_lev_direct .eqs. "" then top_lev_direct = "000000" $ credir 'label':['top_lev_direct'] $ define cdrom_top_level 'label':['top_lev_direct'] $ dir/secur 'label':[000000] $ sho dev/ful 'label' $ call copy_the_files $ status = $status $ if .not. status $ then $ say "Unable to fit backup of ''full_filename' on CD-R" $ del cdrom_top_level:*.*;* $ else $ freeblocks = f$getdvi("''label'","freeblocks") $ free_blocks == freeblocks $ if freeblocks .gt. 20000 $ then $ maxblocks = f$getdvi("''label'","maxblock") $ blocks == maxblocks - freeblocks + 20000 $ blocks == blocks / 100 $ blocks == blocks * 100 $ if blocks .lt. 20000 then blocks == 20000 $ endif $ endif $ if status $ then $ if 0 ! file_owner .nes. "" $ then $ set file/own=['file_owner'] - 'label':['top_lev_direct'...]*.*;* $ endif $ dir/ful/nohe/notr/exclu=(*.sys,*.dir) 'label':[000000...] $ dir/secur 'label':[000000...] $ sho dev/ful 'label' $ endif $ dismount 'label' $ ld discon/log lda'ld_unit': $ exit status $endsubroutine $! $! $copy_the_files: subroutine $ call copy_'file_type $ status = $status $ if .not. status then exit 4 $endsubroutine $! $! $! $! $! $! $copy_file: subroutine ! single file name, with or without wildcards $! ! p1 = target directory $! ! p2 = target file $ targdir = p1 $ targfile = p2 $ if targdir .eqs. "" then targdir = "[''top_lev_direct']" $ if targfile .eqs. "" then targfile = file_param $ if targdir .nes. "[000000]" then credir 'label':'targdir' $ copy 'targfile' 'label':'targdir' $ status = $status $ if .not. status then exit 4 $endsubroutine $! $! $copy_list: subroutine ! list of file names, with or without wildcards $ ! and dest dir $ open/read/err=bad_file infile 'file_param' $ readloop: $ read/end=endreadloop infile inline $ inline = f$edit(inline,"compress,trim") $ the_file = f$element(0," ",inline) $ if the_file .eqs. "" then exit 4 $ the_dir = f$element(1," ",inline) $ call copy_file "''the_dir'" 'the_file' $ status = $status $ if .not. status then exit 4 $ goto readloop $ endreadloop: $ close infile $ exit $bad_file: $ exit 4 $endsubroutine $! $! $copy_tape: subroutine ! tape device; copy p4 directly to top directory $ mount/over=id 'file_param' $ targdir = "[''top_lev_direct']" $ credir 'label':'targdir' $ copy 'file_param':*.* 'label':'targdir' $ status = $status $ dismount/nounload 'file_param' $ if .not. status then exit 4 $endsubroutine $! $! $copy_save: subroutine ! save set; restore saveset(s) in p4 $ save_loop: $ saveset = f$search(file_param) $ if saveset .eqs. "" then exit $ backup/log 'saveset'/save 'label':[*] $ status = $status $ if .not. status then exit 4 $ goto save_loop $endsubroutine $! $! $copy_tsave: subroutine ! tape save set; restore saveset(s) on tape $endsubroutine ========================== COPY_CDROM_TO_CONTAINER.COM $ copy_verify = f$verify (f$trnlnm ("copy_cdrom_to_container_verify") + 0) $! $! p1 = cdrom device name $! $ set noon $ say :== write sys$output $ cdrom_device = p1 - ":" $ $ if cdrom_device .eqs. "" $ then $ say "cdrom device not specified" $ v = f$verify (copy_verify) $ exit 4 $ endif $! $! $! $ if f$trnlnm("container_scratch_disk") .eqs. "" $ then $ say "container_scratch_disk logical not defined" $ v = f$verify (copy_verify) $ exit 4 $ endif $! $! $! Startup LD if needed $! $ if .not. f$getdvi("lda0:","exists") then @sys$startup:ld$startup $! $! $! $! $! $ mount/over=id 'cdrom_device' $ label = f$getdvi(cdrom_device, "volnam") $ create/dir container_scratch_disk:[cdrom_container_files] $ container_file = "container_scratch_disk:[cdrom_container_files]" + label +- "_image.container;1" $ say "searching for container file ''container_file'" $ file = f$search(container_file,42) $ if file .eqs. "" then call create_container $ dism 'cdrom_device' $ mount/for 'cdrom_device' $ copy/overwrite 'cdrom_device': 'container_file' $ dism 'cdrom_device' $ exit $! $! $! $! $ create_container: subroutine $ freeblocks = f$getdvi("''cdrom_device'","freeblocks") $ maxblocks = f$getdvi("''cdrom_device'","maxblock") $ blocks = maxblocks - freeblocks + 20000 $ blocks = blocks / 100 $ blocks = blocks * 100 $ if blocks .lt. 20000 then blocks = 20000 $ ld create /noback/log/size='blocks' 'container_file' $ endsubroutine ========================== BACKUP_TO_CDR.COM $ backup_verify = f$verify (f$trnlnm ("backup_to_cdr_verify") + 0) $ set noon $ diag = f$trnlnm ("backup_to_cdr_verify") + 0 $ if diag $ then $ shosym = "sho sym" $ else $ shosym = "!" $ endif $! $ say :== write sys$output $ $! $ container_file = f$search("all_disks:[cdrom_container_files]*.container") $ found_something = container_file .nes. "" $! $ if found_something .and. f$trnlnm("container_scratch_disk") .eqs. "" $ then $ disk = f$parse(container_file,,,"device") - ":" $ define container_scratch_disk 'disk' $ endif $! $ if f$trnlnm("container_scratch_disk") .eqs. "" $ then $ say "container_scratch_disk logical not defined" $ v = f$verify (backup_verify) $ exit 4 $ endif $! $ call get_SCSI_bus $ status = $status $ if .not. status $ then $ v = f$verify (backup_verify) $ exit 4 $ endif $ call get_SCSI_unit $ status = $status $ if .not. status $ then $ v = f$verify (backup_verify) $ exit 4 $ endif $ call get_real_or_dummy $ status = $status $ if .not. status $ then $ v = f$verify (backup_verify) $ exit 4 $ endif $! $ container_sear = "container_scratch_disk:[cdrom_container_files]*.container" $ cdrecord = "$util:cdrecord" $ define backup_scratch container_scratch_disk:[scratch_area] $ create/dir container_scratch_disk:[scratch_area] $get_file: $ container_file = f$search(container_sear) $! $ if container_file .eqs. "" $ then $ say "no more files found in container file directory" $ v = f$verify (backup_verify) $ exit 1 $ endif $! $ say "preparing to burn container file ''container_file'" $ say "load blank CD-R into drive" $ INQUIRE ready "hit return when ready" $! $! $! Now that the container file is set up, do the actual burn $! $ if wrpar .eqs. "write" then write_param = "" $ if wrpar .eqs. "dummy" then write_param = """-dummy""" $ cdrecord_params = """-speed"" 2 " + write_param + - " ""dev=''scsi_bus_number',''scsi_unit_number',0"" " +- container_file $ shosym cdrecord_params $ say "starting the burn, please wait" $ set term/nobroad $ define/user sys$output backup_scratch:cdrecord.log $ define/user sys$error nl: $ cdrecord 'cdrecord_params' $ status = $status $ if status $ then $ how_ended = "completed successfully" $ else $ how_ended = "failed $ endif $ say "Backup of ''container_file' to CD-R has ''how_ended'..." $ set file/attr=rfm:stmlf backup_scratch:cdrecord.log $ ty backup_scratch:cdrecord.log $ set term/broad $ del backup_scratch:cdrecord.log;* $ if .not. status $ then $ say "aborting procedure" $ v = f$verify (backup_verify) $ exit status $ endif $ if wrpar .eqs. "dummy" $ then $ say "this was a dummy write, so container file will not be deleted" $ goto get_file $ endif $inq_del: $ inquire which "burn complete, delete container file? [y,n]" $ if which .eqs. "Y" $ then $ del 'container_file' $ goto get_file $ endif $ if which .eqs. "N" then goto get_file $ goto inq_del $! $! $! $get_SCSI_bus: subroutine $ scsi_bus_number == -1 $get_bus: $ say " " $ inquire SCSI_bus "On which SCSI bus does the CD writer reside (0 for dkaxxx, 1 for dkbxxx, etc " $ if SCSI_bus .eqs. "EXIT" then exit 4 $ scsi_bus_number == 'scsi_bus' $ if (scsi_bus_number .lt. 0) .or. (scsi_bus_number .gt. 15) $ then $ say " *********************************" $ say " ***** Invalid SCSI bus **********" $ say " *********************************" $ say " " $ goto get_bus $ endif $endsubroutine $! $! $! $get_SCSI_unit: subroutine $ scsi_unit_number == -1 $get_unit: $ say " " $ inquire SCSI_unit "What is the SCSI ID of the CD writer " $ if SCSI_unit .eqs. "EXIT" then exit 4 $ scsi_unit_number == 'scsi_unit' $ if (scsi_unit_number .lt. 0) .or. (scsi_unit_number .gt. 7) $ then $ say " *********************************" $ say " ***** Invalid SCSI unit **********" $ say " *********************************" $ say " " $ goto get_unit $ endif $endsubroutine $! $! $get_real_or_dummy: subroutine $get_real_or_dum: $ say " " $ inquire dummy_or_real "dummy (for testing) or real " $ if dummy_or_real .eqs. "EXIT" then exit 4 $ if (dummy_or_real .nes. "DUMMY") .and. (dummy_or_real .nes. "REAL") $ then $ say " ************************************************" $ say " ***** Invalid -- must be DUMMY or REAL *********" $ say " ************************************************" $ say " " $ goto get_real_or_dum $ endif $ wrpar=="dummy" $ if dummy_or_real .eqs. "REAL" then wrpar=="write" $! $! $endsubroutine $! $! ========================== ========================== ========================== This setup allows me to create multiple container files and burn them all back to back. Obviously, you must have enough disk space for several cdrom images, each up to 650 meg in size. The CREATE_CONTAINER_FROM_FILES command procedure accepts a list of files and copies them to a virtual disk of exactly that size. Well, except that the block count is padded to the next 100-block boundary. The COPY_CDROM_TO_CONTAINER copies an existing disk to a container file, which is similar to the method you describe in your post. The procedure is intended for duplicating cdroms, but there is no reason why it can't work with any ods-2 disk of cdrom size. Again, the resulting container is just large enough for the data, rather than the full 650 meg. The interactive BACKUP_TO_CDR procedure burns cd-rs for each of the container files you created with the other two procedures. Since a container is just a container, the container files could have been created with either or both of the other two command procedures. The burn procedure just scans the container directory until there are no more container files left. Wayne -- =============================================================================== Wayne Sewell, Tachyon Software Consulting (281)812-0738 wayne@tachysoft.xxx http://www.tachysoft.xxx/www/tachyon.html and wayne.html change .xxx to .com in addresses above, assuming you are not a spambot :-) =============================================================================== Jed Clampett, checking into hotel: "This place got a cement pond?" Ellie May: "And do yuh let critters in it?"