• Please review our updated Terms and Rules here

BSD2.11 DD'ing to a raw (unlabeled) device

iainmaoileoin

Experienced Member
Joined
Dec 24, 2014
Messages
216
Location
inverness
I should have posted this some time ago.

I tripped over the change I made to the "raw" drivers in my BSD2.11 code that allows a complete
dd if=whatever of=/dev/rra0a bs=10240 (rra0a is an example) to or from an unlabelled disk to operate as expected.

Prior to this I discovered that a "dd" to a physical disk (so disks from rt11/rsx11/unknown origin) would not always get to write to every block.
[The kernel code tries to protect the disk label area against unwanted updates, great, but when the system has a foreign disk it has no label, so BSD forges a label to allow access, but then prevents you from writing to the area that would have contained the label - had there been one).

This aint good for making/writing disk images of foreign systems under BSD2.11.

Part of the symptoms were an EROFS ("Read Only File System") detected. This appeared (console level symptoms were the message "write error: Read-only file system").

To address this issue, in /usr/src/sys/sys/ufs_disksubr.c
- at about line 401- I added the u.u_uid to the "if" statement. The effect of this is that the superuser has full unfettered access to the entire disk.
Without this statement some early blocks on the disk (which ones depended on the settings of the default label) would
NOT be written to.

/*
* Check for write to write-protected label area. This does not include
* sector 0 which is the boot block.
*/
if (bp->b_blkno + pi->p_offset <= LABELSECTOR &&
bp->b_blkno + pi->p_offset + sz > LABELSECTOR &&
!(bp->b_flags & B_READ) && !(dk->dk_flags & DKF_WLABEL) &&
u.u_uid )
{
bp->b_error = EROFS;
goto bad;
}


This is not ideal. What I should do is detect when a "pretend" disk label is manufactured and apply the flag in that case only.
But, for what I am doing that would be overkill.

So now I can dd if=/dev/rra0a of=disk-image from a foreign disk to make a backup copy and
dd if=disk-image of=/dev/rra0a to replace that image on a disk :cool:
 
I remember finally figuring out that I had to make a similar change to allow a 'dd' write to an entire foreign disk on 2.11BSD when I was doing this a couple of years ago. I forget exactly how I changed it. It didn't occur to me to make it uid based for just the superuser. I might have done something to unconditionally bypass the disklabel sector check completely, unless I figured out some way to set the DKF_WLABEL flag. I'll have to see if I can find any notes on what I did.
 
OK, found some my notes on this when I took another look at this in April 2014. No kernel source code change is required:


After taking a further look, the DKF_WLABEL flag that is checked by the kernel mode routine partition_check() in src/sys/sys/ufs_disksubr.c is set or cleared by the routine ioctldisklabel() in the same source file when handling the DIOCWLABEL ioctl.

The DIOCWLABEL ioctl is issued by the user mode disklabel utility in the source file src/bin/disklabel/disklabel.c

It appears that the usage "disklabel -N disk" should disable write access to the disk label area and the usage "disklabel -W disk" should enable write access to the disk label area, where disk should be the device you were using in your case.


I just confirmed that after using "disklabel -W" on the raw disk device then you can then dd to the entire disk without encountering the "Read-only file system" error.

# dd if=/dev/rra1a of=rx33.dsk bs=512
ra1: RX33 size=2400
2400+0 records in
2400+0 records out

# ls -l
total 1200
-rw-r----- 1 root 1228800 Jun 8 22:56 rx33.dsk

# dd if=rx33.dsk of=/dev/rra1a bs=512
write: Read-only file system
2+0 records in
2+0 records out

# disklabel -W /dev/rra1a

# dd if=rx33.dsk of=/dev/rra1a bs=512
2400+0 records in
2400+0 records out
 
Thank you for the clarification.
I learn something new every day, and 2 things on a Sunday.

I will back out my change - it is probably pretty dangerous and not needed.

I note you were using /dev/rr. On my BSD if I use /dev/r for a dd I get a complete read/write of the disk - but with a few blocks (perhaps just 1 block) missing at about sector 2 of the disk.

I see that the error message "x0a is entire disk: no disk label" does not actually say "so the operation you have just carried out did not do what you expected!.

I remember a lecture by Prof James Alty from about 40 years ago where he was talking about the error messages from systems and the "user feedback" that such messages gave.
He had the ICL George 3 OS as a basis .... "you have filled your new file" would come out periodically. The bit in invisible ink said "and if you dont quit now you have just knacked the file".
The "ed" editor in Unix also got his attention to. "?" you goofed, I goofed or the system is in trouble, and "??" you really goofed, I really goofed or the system is in real trouble!

I went back a version, yes
# dd if=test.rl02 of=/dev/rl0a bs=10240
Oct 4 20:08:06 pdp11 vmunix: rl0a is entire disk: no disk label
....
cmp -l /dev/rl0a test.rl02
515 0 30
517 0 222
519 0 2
521 0 26
523 0 1
527 0 354
528 0 117
529 0 310
531 0 1
535 0 252
539 0 100
541 0 377
543 0 100
545 0 377
546 0 1

IMHO that is not good - the dd continues past the write issue, but leaves a block unwritten and, NO, I dont fancy tracing that bug.

I agree the use of the raw device does terminate when it should.

On a timing front I see you are a "raw" user:

4% root -> time dd if=test.rl02 of=/dev/rl0a bs=10240
Oct 4 20:30:29 pdp11 vmunix: rl0a is entire disk: no disk label
time dd if=xxdp25.rl02 of=/dev/rrl0a bs=10240
1024+0 records in
1024+0 records out
0.2u 168.5s 4:30.84 62.0% 17302+10244io 13ov 0sw
5% root--> time dd if=test.rl02 of=/dev/rrl0a bs=10240
Oct 4 20:35:01 pdp11 vmunix: rl0a is entire disk: no disk label
1024+0 records in
1024+0 records out
0.3u 88.7s 2:26.90 60.0% 10291+4io 13ov 0sw


So the raw driver - *cuts mem copies* - is almost twice as fast.
 
Back
Top