This is a very long description of my attempts to fix the root disk.
If you want to try it and don't care about the details, (I haven't tried this yet) please break out lisafsh-tool and skip to the very end, then copy the instructions into lisafsh-tool after you've used it to open the root disk.
My interest in providing this very detailed rant is so that there's a record of exactly what I did here, so that incase I've missed something somewhere, it can be found and corrected. It's a very old school kind of thing for us Unix graybeards.
I'm hopeful that this will work, but it might not, YMMV and all that. Someone please try it on a real Lisa - I can't do this now and won't have the time or energy to attempt it until at least the weekend, and even then, I might not be able to do so...
Note that even if I did everything correctly here, there may be further corruption on the disk preventing UniPlus+ from working...
For those of you who want to attempt a fix without worrying about how it works, skip to the bottom... Well, you should at least know how to use lisafsh-tool.
So for the remaining audience of one or two insane enough to follow me into the bowels of the Unix filesystem, here we go...
Here, when I say "we", I'm referring to myself, and the reader who hopefully won't fall asleep while reading this. It's meant to be followed along as an exercise in fixing unix file systems by hand as well as an attempt to get UniPlus+ working. This process might come in handy in fixing other Unix file systems, so you never know - might be worth your time and trouble to understand what is being done here, how and why. It'll be slightly (or vastly) different on other Unixen.
You'll need a compiled lisafsh-tool for your machine (it comes with LisaEm, download: http://lisaem.sunder.net/downloads ) You'll need to know how to use it, so ask it for help after you run it like this: "lisafsh-tool root-filesystem-b.image"
You'll also need the UniPlus+ manuals (see: http://bitsavers.org/pdf/unisoft/ - specifically read page 281 of the UniPlus+ User's Manual Sections 2-6.pdf ) If you've extracted the tar floppies as per my previous post on 3/22, that will also come in handy. If you haven't, do the following:
for i in 0*.image 1*.image; do FILENAME=`echo $i | sed 's/.image//g'`; echo $FILENAME; dd if=${FILENAME}.image bs=1 skip=84 count=409600 of=tmp; dd bs=512 count=800 if=tmp of=${FILENAME}.tar; echo; done; rm tmp
Then, once you have the tar files:
for i in *.tar; do tar xvf $i; done
*BUT* please use a modern tar - some versions of tar are broken and you'll find that the files that start like this /bin/ls will overwrite the ones on your system. GNU tar is what you want. I suspect most modern tars are ok, if you don't know, skip this step, or at least make sure you don't do it as the root user.
The extracted files are useful as there's information under /usr/include and /usr/include/sys that I use. You can skip this step and just take my word for it. (The #define's are gotten from there...)
As a quickie UFS refresher:
the superblock is the thing that defines a unix volume. (forgive my lack
of eloquence here) There are typically several copies of this on the
Files are allocated via inodes, the blocks immediately following the superblock contain inodes. inodes contain details such as: is this a directory, file or device?, permissions, owner, group, size, allocated blocks, and dates for creation, modification, and access - not necessarily in that order.
When the list of blocks is too numerous to fit inside a single inode, indirection (single, double, or tripple) is used. that won't be needed here. The files we're restoring are small directories. It's possible that /bin contains more than one directory and that I've missed the second, I don't know for sure, but I suspect it's ok.
Directory entries are normal files, but they contain the file name and more importantly the inode number that contains the directory information about the file.
Using lisafsh tool, I see the following:
uniplus root disk: block 1 is superblock, block 0 is all zeroes
superblock has magic #fd187e20 at offset 1f8 in block 1. It's followed
by 00 00 00 01 - this probably means a 512 byte block is used.
- this matches the fs(4) man page for UniPlus+
sector 13 is the root dir entry - this has inode's zeroed out for /etc and /bin:
Looking around the disk image some more for text, specifically for things that I'd recognize, here are some more details:
sector 132 is /etc's dir entry sector 118 is /bin's dir entry (or part of it) sector 125 is /dev
Here's the root sector:
(I've put brackets here to highlight the important bits)
0000: 00 02 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | ". 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 1b 69 6e 73 74 61 6c . 6c 00 00 00 00 00 00 00 | ;install 0030: 00 27 69 6e 73 74 61 6c . 6c 2e 32 00 00 00 00 00 | 'install.2 0040: 00 29 69 6e 73 74 61 6c . 6c 5f 69 74 00 00 00 00 | )install_it 0050: [0000]62 69 6e 00 00 00 . 00 00 00 00 00 00 00 00 | bin 0060: [0000]64 65 76 00 00 00 . 00 00 00 00 00 00 00 00 | dev 0070: [0000]65 74 63 00 00 00 . 00 00 00 00 00 00 00 00 | etc 0080: 00 09 74 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | )t 0090: 00 0a 75 73 72 00 00 00 . 00 00 00 00 00 00 00 00 | *usr 00a0: 00 1e 69 6e 73 74 61 6c . 6c 2e 6f 6c 64 00 00 00 | >install.old 00b0: 00 05 69 6e 73 74 61 6c . 6c 5f 69 74 30 00 00 00 | %install_it0 00c0: 00 2c 69 6e 73 74 61 6c . 6c 2e 32 2e 30 00 00 00 | ,install.2.0 00d0: 00 2d 69 6e 73 74 61 6c . 6c 30 00 00 00 00 00 00 | -install0 00e0: 00 00 07 61 30 35 38 30 . 00 00 00 00 00 00 00 00 | 'a0580 00f0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 |
So /etc, /dev, and /bin were damaged. :-( It looks like they weren't rm
-rf'ed as the other files are still there, it looks like they were
accidentally deleted.
We know /etc lives at sector 132 (We'd expect /etc to contain passwd, group, mnttab, and other stuff like that.) Some unixen contained binaries in /etc. I think this is one of them - well, at least for the fsck and init programs.)
Sec 132:(0x0084)
0000: 00 08 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | (. 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 00 66 73 63 6b 31 62 . 00 00 00 00 00 00 00 00 | fsck1b 0030: 00 1c 67 72 6f 75 70 00 . 00 00 00 00 00 00 00 00 | <group 0040: 00 1d 69 6e 69 74 00 00 . 00 00 00 00 00 00 00 00 | =init 0050: 00 2a 69 6e 69 74 74 61 . 62 00 00 00 00 00 00 00 | *inittab 0060: 00 1f 6d 6b 66 73 31 62 . 00 00 00 00 00 00 00 00 | mkfs1b 0070: 00 20 70 61 73 73 77 64 . 00 00 00 00 00 00 00 00 | passwd 0080: 00 23 69 6f 63 74 6c 2e . 73 79 73 63 6f 6e 00 00 | #ioctl.syscon 0090: 00 26 6d 6e 74 74 61 62 . 00 00 00 00 00 00 00 00 | &mnttab
So lets' find some inodes that are still on the disk..
00 20 is the entry right before passwd - so inode 0x0020 - /etc/passwd's
content is at sector 247.
00 1c is the entry right before group - so inode 0x001c - /etc/group's
content is at sector 620.
So let's try and see if we can match this to an existing working file. /etc/passwd is very distinctive and easy to find...
According to the man page, the inodes start on block 2, immediately after the superblock and they have a structure similar to this. The numbers are how many bytes:
2 ushort mode
2 short nlinks
2 ushort uid
2 ushort gid
4 off_t size
40 char addr[40] (3 byte groups containing the block #'s in the file.)
4 time_t 4 time_t 4 time_t
above is 64 bytes/inode - so there are 8 inodes per each 512 byte disk sector.
So looking at the directory entry for /etc/passwd, 0x0020 is 32 in decimal. So 32*64=2048. so 2048 bytes after the start of sector 2 puts us in sector 6 (2048/512=4, we start at sector 2, so 2+4=6.)
So this should point to the very first inode on sector 6. Except that it doesn't. :-)
You see, we're off by 1 here. It turns out that inode #0 doesn't exist -
it means "deleted file"
So going back to the last inode on sector 5, we see:
(I've put brackets here to highlight the important bits)
01c0: [8124][0001][0000][0000][000001d9] [00 02 47]00 | !$ ! !Y "G 01d0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01e0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01f0: 00 00 00 00 37 a1 33 65 . 1b 39 0b d0 1b 39 0b d0 | 7!3e;9+P;9+P
mode=8124: 100444 octal (looks reasonable for /etc/passwd)
file has 1 links (itself)
uid=0, gid=0
size=0x1d9 bytes or 473 bytes, perfect (see below)
first data sector starts at 0x0247=583
We have a perfect match, the following is indeed the /etc/passwd file. *Bingo*
0000: 72 6f 6f 74 3a 61 4c 62 . 44 50 4f 32 6c 56 2e 69 | root:aLbDPO2lV.i 0010: 70 55 3a 30 3a 30 3a 3a . 2f 3a 2f 62 69 6e 2f 73 | pU:0:0::/:/bin/s 0020: 68 0a 72 6f 6f 74 63 73 . 68 3a 43 4c 42 65 33 31 | h*rootcsh:CLBe31 0030: 63 57 6c 65 36 44 6f 3a . 30 3a 30 3a 3a 2f 3a 2f | cWle6Do:0:0::/:/ 0040: 62 69 6e 2f 63 73 68 0a . 64 61 65 6d 6f 6e 3a 78 | bin/csh*daemon:x 0050: 78 78 78 78 78 78 78 78 . 78 78 78 78 3a 31 3a 31 | xxxxxxxxxxxx:1:1 0060: 3a 3a 2f 3a 0a 62 69 6e . 3a 78 78 78 78 78 78 78 | ::/:*bin:xxxxxxx 0070: 78 78 78 78 78 78 3a 32 . 3a 32 3a 3a 2f 62 69 6e | xxxxxx:2:2::/bin 0080: 3a 0a 73 79 73 3a 78 78 . 78 78 78 78 78 78 78 78 | :*sys:xxxxxxxxxx 0090: 78 78 78 3a 33 3a 33 3a . 3a 2f 62 69 6e 3a 0a 61 | xxx:3:3::/bin:*a 00a0: 64 6d 3a 78 78 78 78 78 . 78 78 78 78 78 78 78 78 | dm:xxxxxxxxxxxxx 00b0: 3a 34 3a 34 3a 3a 2f 75 . 73 72 2f 61 64 6d 3a 0a | :4:4::/usr/adm:* 00c0: 75 75 63 70 3a 3a 35 3a . 35 3a 3a 2f 75 73 72 2f | uucp::5:5::/usr/ 00d0: 73 70 6f 6f 6c 2f 75 75 . 63 70 70 75 62 6c 69 63 | spool/uucppublic 00e0: 3a 2f 75 73 72 2f 6c 69 . 62 2f 75 75 63 70 2f 75 | :/usr/lib/uucp/u 00f0: 75 73 68 65 6c 6c 0a 63 . 68 65 63 6b 3a 78 78 78 | ushell*check:xxx 0100: 78 78 78 78 78 78 78 78 . 78 78 3a 36 3a 36 3a 3a | xxxxxxxxxx:6:6:: 0110: 2f 3a 0a 6c 70 3a 78 78 . 78 78 78 78 78 78 78 78 | /:*lp:xxxxxxxxxx 0120: 78 78 78 3a 37 3a 37 3a . 6c 70 3a 2f 75 73 72 2f | xxx:7:7:lp:/usr/ 0130: 73 70 6f 6f 6c 2f 6c 70 . 3a 0a 75 73 72 36 38 3a | spool/lp:*usr68: 0140: 3a 31 30 3a 30 3a 3a 2f . 75 73 72 2f 67 75 65 73 | :10:0::/usr/gues 0150: 74 3a 2f 62 69 6e 2f 63 . 73 68 0a 77 68 6f 3a 3a | t:/bin/csh*who:: 0160: 32 32 3a 30 3a 77 68 6f . 20 63 6f 6d 6d 61 6e 64 | 22:0:who command 0170: 3a 2f 62 69 6e 3a 2f 62 . 69 6e 2f 77 68 6f 0a 67 | :/bin:/bin/who*g 0180: 75 65 73 74 3a 3a 31 30 . 30 3a 31 30 30 3a 67 75 | uest::100:100:gu 0190: 65 73 74 20 61 63 63 6f . 75 6e 74 3a 2f 75 73 72 | est account:/usr 01a0: 2f 67 75 65 73 74 3a 2f . 62 69 6e 2f 63 73 68 0a | /guest:/bin/csh* 01b0: 6d 61 63 3a 3a 31 30 30 . 3a 31 30 30 3a 4d 61 63 | mac::100:100:Mac 01c0: 69 6e 74 6f 73 68 3a 2f . 75 73 72 2f 6d 61 63 3a | intosh:/usr/mac: 01d0: 2f 62 69 6e 2f 63 73 68 . 0a 00 00 00 00 00 00 00 | /bin/csh* 01e0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01f0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 |
So now we need to find inodes that point to the proper entry for /etc and /bin
sector 132 is /etc's dir entry ( in hex 0x84) sector 118 is /bin's dir entry (or part of it) (in hex 0x76 ) sector 125 is /dev (in hex 0x7D )
We need to find inodes that match the above. - offset 13-15 are the pointer to the 1st block in a file pointed to by the inode. These are the patterns to use if you've dumped the disk to a text file using lisafsh-tool:
"00 00 84 00 |" "00 00 76 00 |" "00 00 7d 00 |"
But, we're shit out of luck as these patterns cannot be found. :-( so the inodes to these guys have also been deleted! D'Oh!
We need to create new inodes, then link the directory entries back and adjust the superblock...
Before we do, let's poke around some more... here's the root dir...
There's something funny about it...
Well, not funny, but rather, standard to all directories everywhere in
Unix...
Sec 13:(0x000d)
0000: 00 02 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | ". 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 1b 69 6e 73 74 61 6c . 6c 00 00 00 00 00 00 00 | ;install 0030: 00 27 69 6e 73 74 61 6c . 6c 2e 32 00 00 00 00 00 | 'install.2 0040: 00 29 69 6e 73 74 61 6c . 6c 5f 69 74 00 00 00 00 | )install_it 0050: 00 00 62 69 6e 00 00 00 . 00 00 00 00 00 00 00 00 | bin 0060: 00 00 64 65 76 00 00 00 . 00 00 00 00 00 00 00 00 | dev 0070: 00 00 65 74 63 00 00 00 . 00 00 00 00 00 00 00 00 | etc 0080: 00 09 74 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | )t 0090: 00 0a 75 73 72 00 00 00 . 00 00 00 00 00 00 00 00 | *usr
What's funny? The . and .. entries point to inode 0002... Hmmm, that is an idea... Why? Because those are inode numbers!
So we lost /dev /bin and /etc.
But since the deleted directories must also contain a ".." and more importantly "." directory entry, we can figure out which inode number they should be, and then we can check if those are empty or if something else clobbered them...
So /etc is at sector 132:
0000: 00 08 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | (. 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 00 66 73 63 6b 31 62 . 00 00 00 00 00 00 00 00 | fsck1b 0030: 00 1c 67 72 6f 75 70 00 . 00 00 00 00 00 00 00 00 | <group 0040: 00 1d 69 6e 69 74 00 00 . 00 00 00 00 00 00 00 00 | =init 0050: 00 2a 69 6e 69 74 74 61 . 62 00 00 00 00 00 00 00 | *inittab 0060: 00 1f 6d 6b 66 73 31 62 . 00 00 00 00 00 00 00 00 | mkfs1b 0070: 00 20 70 61 73 73 77 64 . 00 00 00 00 00 00 00 00 | passwd 0080: 00 23 69 6f 63 74 6c 2e . 73 79 73 63 6f 6e 00 00 | #ioctl.syscon 0090: 00 26 6d 6e 74 74 61 62 . 00 00 00 00 00 00 00 00 | &mnttab
.. points to inode 0002 - which from the / directory entry we already
know is the root directory's inode.
. points to 0008. Yeay! We have an inode number for the deleted /etc
directory.
If we look a bit more we notice the other stuff in this directory hasn't been deleted! Phew! That's helpful because we'd have a hard time identifying random binaries without knowing what they are!
So rm -rf / wasn't done. Or if it was, it didn't recursively remove
everything - maybe a well timed ^C? But I'd expect if someone did rm
-rf, the -rf part would start at the bottom of the tree, and not at the
directory level... Maybe it's a bug that got triggered somewhere that
deleted these dirs, or maybe rm -rf is implemented differently.
Ok, we now know that /etc lives on sector 132 (0x84) and points to inode 0008. Let's repeat with the other two dirs:
/bin which lives at sector 118 (0x76) has .. pointing to 0002 - good, that's what it should be, and . is pointing to inode # 0006.
Sec 118:(0x0076)
0000: 00 06 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | &. 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 0c 63 61 74 00 00 00 . 00 00 00 00 00 00 00 00 | ,cat 0030: 00 0d 63 68 67 72 70 00 . 00 00 00 00 00 00 00 00 | -chgrp 0040: 00 0e 63 68 6d 6f 64 00 . 00 00 00 00 00 00 00 00 | .chmod 0050: 00 0f 63 68 6f 77 6e 00 . 00 00 00 00 00 00 00 00 | /chown 0060: 00 10 63 70 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0cp 0070: 00 11 65 63 68 6f 00 00 . 00 00 00 00 00 00 00 00 | 1echo 0080: 00 12 6c 73 00 00 00 00 . 00 00 00 00 00 00 00 00 | 2ls 0090: 00 13 6d 6b 64 69 72 00 . 00 00 00 00 00 00 00 00 | 3mkdir 00a0: 00 14 6d 6b 6e 6f 64 00 . 00 00 00 00 00 00 00 00 | 4mknod 00b0: 00 15 6d 6f 75 6e 74 00 . 00 00 00 00 00 00 00 00 | 5mount 00c0: 00 16 73 68 00 00 00 00 . 00 00 00 00 00 00 00 00 | 6sh 00d0: 00 17 73 75 00 00 00 00 . 00 00 00 00 00 00 00 00 | 7su 00e0: 00 18 73 79 6e 63 00 00 . 00 00 00 00 00 00 00 00 | 8sync 00f0: 00 19 74 61 72 00 00 00 . 00 00 00 00 00 00 00 00 | 9tar 0100: 00 1a 75 6d 6f 75 6e 74 . 00 00 00 00 00 00 00 00 | :umount 0110: 00 10 6c 6e 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0ln
/dev lives at sector 125 (0x007d), .. again is 0002 . is 0007 so we know
what the inodes should be.
I don't see an entry for /null... maybe this isn't /dev? But tty0,
console syscon systty look like /dev entries to me.
(We may have trouble if the rest of /dev is damaged...)
Sec 125:(0x007d)
0000: 00 07 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | '. 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 22 63 6f 6e 73 6f 6c . 65 00 00 00 00 00 00 00 | "console 0030: 00 24 73 79 73 63 6f 6e . 00 00 00 00 00 00 00 00 | $syscon 0040: 00 24 73 79 73 74 74 79 . 00 00 00 00 00 00 00 00 | $systty 0050: 00 25 70 30 61 00 00 00 . 00 00 00 00 00 00 00 00 | %p0a 0060: 00 04 70 34 61 00 00 00 . 00 00 00 00 00 00 00 00 | $p4a 0070: 00 28 63 34 61 00 00 00 . 00 00 00 00 00 00 00 00 | (c4a 0080: 00 2b 70 61 00 00 00 00 . 00 00 00 00 00 00 00 00 | +pa 0090: 00 2e 6f 6f 6f 6f 6f 6f . 00 00 00 00 00 00 00 00 | .oooooo 00a0: 00 2f 74 74 79 30 00 00 . 00 00 00 00 00 00 00 00 | /tty0 00b0: 00 30 65 6a 65 63 74 00 . 00 00 00 00 00 00 00 00 | 0eject
So as long as those inodes weren't used by something else, let's assume that they weren't, we should be able to fix this.
To summarize:
/etc lives on sector 132 (0x84) and points to inode 0008 /bin which lives at sector 118 (0x76) points to inode 0006 /dev lives at sector 125 (0x007d), points to inode 0007
The inodes for these should all live in sector #2. Let's go there now:
0000: 80 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0010: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0020: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0030: 00 00 00 00 1e 59 6d 57 . 1e 59 6d 57 1e 59 6d 57 | >YmW>YmW>YmW
So this is inode #2 and it points to sector 13 (00 0d) which is the root directory entry. Above, therefore is inode #1, so that's why we had the off-by-one for /etc/passwd.
0040: 41 ff 00 07 00 00 00 00 . 00 00 00 f0[00 00 0d]00 | A ' p - 0050: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0060: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0070: 00 00 00 00 21 5a 46 3c . 21 5a 46 78 21 5a 46 78 | !ZF<!ZFx!ZFx
inode 3
0080: 41 ff 00 02 00 64 00 64 . 00 00 01 60 00 00 22 00 | A " d d !` " 0090: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 00a0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 00b0: 00 00 00 00 21 5a 42 53 . 1e 59 6d 7b 1e 59 6d 7b | !ZBS>Ym{>Ym{
inode 4
00c0: 89 ed 00 01 00 64 00 64 . 00 00 3c 1b 00 00 29 00 | )m ! d d <; ) 00d0: 00 30 00 00 37 00 00 3e . 00 00 45 00 00 4c 00 00 | 0 7 > E L 00e0: 53 00 00 5a 00 00 61 00 . 00 68 00 00 6f 00 00 00 | S Z a h o 00f0: 00 00 00 00 1e 6f 81 97 . 20 2d 57 07 20 2d 57 09 | >o!7 -W' -W)
inode 5
0100: 81 ed 00 01 00 64 00 64 . 00 00 00 c4 00 01 09 00 | !m ! d d D !) 0110: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0120: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0130: 00 00 00 00 21 5a 42 ff . 20 2d 57 0e 20 2d 57 0e | !ZB -W. -W.
inode 6: /bin
0140: 00 00 00 00 00 64 00 64 . 00 00 00 00 00 00 00 00 | d d 0150: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0160: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0170: 00 00 00 00 1e 6f 81 e9 . 21 5a 46 5c 21 5a 46 5c | >o!i!ZF\!ZF\
inode 7: /dev
0180: 00 00 00 00 00 64 00 64 . 00 00 00 00 00 00 00 00 | d d 0190: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01a0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01b0: 00 00 00 00 1e 6f 81 e9 . 21 5a 46 63 21 5a 46 63 | >o!i!ZFc!ZFc
inode 8: /etc
01c0: 00 00 00 00 00 64 00 64 . 00 00 00 00 00 00 00 00 | d d 01d0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01e0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01f0: 00 00 00 00 1e 6f 81 ea . 21 5a 46 67 21 5a 46 67 | >o!j!ZFg!ZFg
So sure enough inodes 6,7,8 are zeroed out in both the permissions and the blocks they point to. So we have to manually fix them. I'd imagine uid:gid of 0x64 means something like "deleted" as well.
Let's copy the inode for /usr since that's a directory.
From sector 13, we have /usr's dir-entry:
0090:[00 0a]75 73 72 00 00 00 . 00 00 00 00 00 00 00 00 | *usr
So /usr's inode #0x000a (10), that's on sector #3 since the last inode on sector 2 is inode 8:
Sec 3:(0x0003)
0000: 41 ff 00 02 00 00 00 00 . 00 00 00 20 00 00 8b 00 | A " + 0010: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0020: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0030: 00 00 00 00 21 5a 42 52 . 1b 39 09 5f 1b 39 09 5f | !ZBR;9)_;9)_
inode 10: this should point to /usr.
0040: 41 ff 00 03 00 00 00 00 . 00 00 00 30[00 00 92]00 | A # 0 2 0050: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0060: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0070: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
inode 11: (this turns out to be /usr/bin)
0080: 41 ff 00 02 00 00 00 00 . 00 00 00 40 00 00 99 00 | A " @ 9 0090: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 00a0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 00b0: 00 00 00 00 21 5a 42 52 . 1b 61 65 29 1b 61 65 29 | !ZBR;ae);ae)...
Sector 0x92 contains:
0000: 00 0a 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | *. 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 0b 62 69 6e 00 00 00 . 00 00 00 00 00 00 00 00 | +bin 0030: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0040: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 |
Ok, so I guess that's reasonable for an install disk to have just /usr/bin, and indeed, inode 11 is what points to /usr/bin...
0000: 00 0b 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | +. 0010: 00 0a 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | *.. 0020: 00 21 65 6a 65 63 74 00 . 00 00 00 00 00 00 00 00 | !eject 0030: 00 03 6c 73 37 00 00 00 . 00 00 00 00 00 00 00 00 | #ls7
and indeed this is /usr/bin... ok, ok, we're getting sidelined now, although it's good to verify everything. So back to the task at hand. We're copying the inode for /usr and modifying it so we can use it for our deleted directories...
Here it is again, the inode for /usr:
0040: 41 ff 00 03 00 00 00 00 . 00 00 00 30[00 00 92]00 | A # 0 2 0050: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0060: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0070: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
Let's leave all the fields alone for right now. The only one we care about is the pointer to the first block, we'll edit the others too, but let's look here a bit more closely.
Luckily since the directories removed only took up a single block (I think) we should be fine with replacing the data there. We'll have to also fix the sizes, but we'll get to that later. Worse, if this was the result of rm -rf, restoring these deleted inodes might work, *BUT* they've been added to the free list which will hurt us if anything further is written to the disk. But we'll deal with that later. No, really, we will.
So these guys (our deleted inodes) are all in sector 2. We'll copy the values from inode 10 (/usr) so we get the permissions right and all that. We still need to correct the sizes which will bite us in the ass if we don't. (Ignore the fact that the "text" after the | doesn't necessarily match, I'm not editing that ascii representation in the following block hex representations)
Weird, but /usr has 0003 for the number of links... This might mean
something I don't know... I'd expect just 1, but maybe it means
something else than I imagine... if you know, tell me... anyway root has
7 here... :-( that might mean something important, or it might not.
Let's stick to 3.... if it's wrong, let's hope that it doesn't mess us
up... anyway, if we can get UniPlus+ installed on a single Lisa, we can
use that Lisa to do an fsck on the hand-fixed root floppy and then fix
up any items we got wrong...
41ff is the perms/type on /usr which is probably too permissible,, but
I'll ingore it for now.. (this is 40777 octal which is world writable,
Here's our legend again, so we don't have to scroll up:
/etc lives on sector 132 (0x84) and points to inode 0008 /bin which lives at sector 118 (0x76) points to inode 0006 /dev lives at sector 125 (0x007d), points to inode 0007
So I've also edited the permissions and the 1st data block in these. Again, these dirs are only one block long as far as I can tell, so one block is what's needed... I've also copied the 3 dates in the last line from /usr (maybe they're illegal values in the deleted ones that mean something like "hi, I'm a deleted inode" so we don't trust them, but we trust the ones from /usr.)
inode 6: /bin
0140: 41 ed 00 03 00 64 00 64 . 00 00 00 00 00 00 76 00 | d d 0150: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0160: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0170: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
inode 7: /dev
0180: 41 ed 00 03 00 64 00 64 . 00 00 00 00 00 00 7d 00 | d d 0190: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01a0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01b0: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
inode 8: /etc
01c0: 41 ed 00 03 00 64 00 64 . 00 00 00 00 00 00 84 00 | d d 01d0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01e0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01f0: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
So now we have to figure out what the sizes mean... Back to inode 10 for /usr...
perms nlnk uid gid size
0040: [41ff][0003][0000][0000] .[00 00 00 30][00 00 92]00 | A # 0 2 0050: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0060: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0070: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
So 0x0000030 is 48... is that bytes? let's see the directory entry for /usr:
0000: 00 0a 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | *. 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 0b 62 69 6e 00 00 00 . 00 00 00 00 00 00 00 00 | +bin 0030: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0040: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 |
Well, it turns out it is indeed in bytes (it's all zeroes after offset 0x2f)... ok, great, so lets' look at those missing dirs again...
(well, do it yourself, I'm tired of copying and pasting...) :-)
Our updated legend:
/etc lives on sector 132 (0x84) and points to inode 0008 - this is 0xb0
bytes long
/bin which lives at sector 118 (0x76) points to inode 0006 - this is
0x120 bytes long
/dev lives at sector 125 (0x007d), points to inode 0007 - this is 0xc0
bytes long...
So let's edit those inodes to fix their sizes, and also fix ownership to root:root
again, these are the fields we care about from /usr:
perms nlnk uid gid size
0040: [41ff][0003][0000][0000] .[00 00 00 30][00 00 92]00 | A # 0 2 <- /usr
inode 6: /bin
0140: 41 ed 00 03 00 00 00 00 . 00 00 01 20 00 00 76 00 | d d 0150: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0160: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 0170: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
inode 7: /dev
0180: 41 ed 00 03 00 00 00 00 . 00 00 00 c0 00 00 7d 00 | d d 0190: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01a0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01b0: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
inode 8: /etc
01c0: 41 ed 00 03 00 00 00 00 . 00 00 00 b0 00 00 84 00 | d d 01d0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01e0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01f0: 00 00 00 00 21 5a 42 52 . 1b 39 09 61 1b 39 09 62 | !ZBR;9)a;9)b
Ok, so next, we need to fix up the entries in the root directory so that they also point to these new inodes, if we don't the installer won't be able to find anything and it won't work...
Here's our legend again:
/etc lives on sector 132 (0x84) and points to inode 0008 - this is 0xb0
bytes long
/bin which lives at sector 118 (0x76) points to inode 0006 - this is
0x120 bytes long
/dev lives at sector 125 (0x007d), points to inode 0007 - this is 0xc0
bytes long...
And here's the root directory sector:
0000: 00 02 2e 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | ". 0010: 00 02 2e 2e 00 00 00 00 . 00 00 00 00 00 00 00 00 | ".. 0020: 00 1b 69 6e 73 74 61 6c . 6c 00 00 00 00 00 00 00 | ;install 0030: 00 27 69 6e 73 74 61 6c . 6c 2e 32 00 00 00 00 00 | 'install.2 0040: 00 29 69 6e 73 74 61 6c . 6c 5f 69 74 00 00 00 00 | )install_ithere are the edits:
0050:[00 06]62 69 6e 00 00 00 . 00 00 00 00 00 00 00 00 | bin 0060:[00 07]64 65 76 00 00 00 . 00 00 00 00 00 00 00 00 | dev 0070:[00 08]65 74 63 00 00 00 . 00 00 00 00 00 00 00 00 | etc
Ok thats' good for right now...
Of course there's still the matter of the superblock to fix as it contains the free inodes list... if we don't fix it and the installer tries to create a temporary file, it'll erase our directories!!! But we'll fix it right now. :-)
We need to look for 0006 0007 0008 to undelete them. There's also a counter somewhere that says how many of them there are (nfree), but since I don't know the size of NICFREE and NICINOD, Well, assuming that they're the same as in the tar floppies we've extracted, looking in /usr/include and /usr/include/sys, we see that they are:
param.h:#define NICINOD 100 /* number of superblock inodes */ param.h:#define NICFREE 50 /* number of superblock free blocks */ these are in "longs" (daddr_t is typedef'ed as long) - so I suspect 4 bytes... so, 50*4=200 +8 (offset to first s_free entry) = 208 or 0xd0 is the end...
See the man page for fs(4) in the PDF's... p281 of the UniPlus+ User manual section 2-6.pdf for the meanings of these...
isize fsize nfree free block list starts at 8
0000:[0008][00000320][00 0a] . 00 00 02 49 00 00 01 c1 | ( # * "I !A 0010: 00 00 01 c8 00 00 01 ba . 00 00 00 3e 00 00 01 17 | !H !: > !7 0020: 00 00 01 10 00 00 01 25 . 00 00 01 1e 00 00 01 2c | !0 !% !> !, 0030: 00 00 02 e0 00 00 02 d9 . 00 00 02 d2 00 00 02 cb | "` "Y "R "K 0040: 00 00 02 c4 00 00 02 bd . 00 00 02 b6 00 00 02 af | "D "= "6 "/ 0050: 00 00 02 a8 00 00 02 a1 . 00 00 02 9a 00 00 02 93 | "( "! ": "3 0060: 00 00 02 8c 00 00 02 85 . 00 00 02 7e 00 00 02 77 | ", "% "~ "w 0070: 00 00 02 70 00 00 02 69 . 00 00 02 62 00 00 02 5b | "p "i "b "[ 0080: 00 00 02 54 00 00 02 4d . 00 00 02 46 00 00 02 3f | "T "M "F "? 0090: 00 00 02 38 00 00 02 31 . 00 00 02 2a 00 00 02 23 | "8 "1 "* "# 00a0: 00 00 02 1c 00 00 02 15 . 00 00 02 0e 00 00 02 07 | "< "5 ". "' 00b0: 00 00 02 00 00 00 01 f9 . 00 00 01 f2 00 00 01 eb | " !y !r !k 00c0: 00 00 01 e4 00 00 01 dd . 00 00 02 65 00 00 02 5e | !d !] "e "^
So here's part of the list of free inodes! need to remove the 6,7,8: And this 0003 refers to our 3 inodes that we've undeleted - and it's followed by 00's...
So that implies that we should zero out bytes d0-d7 of the superblock to complete the undelete... I think...
00d0: [0003][0006][0007][0008]. 00 00 00 00 00 00 00 00 | # & ' ( 00e0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | ... more stuff here (but irrelevant to this task)...
01d0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01e0: 00 00 00 00 00 00 00 00 . 00 00 00 00 00 00 00 00 | 01f0: 00 00 00 00 00 00 00 00 .[fd 18 7e 20][00000001] | }8~ !the magic Fs1b=1
And that should do it - I hope...
So turning all of these edits into lisafsh-tool commands (be sure to copy the lines with just the numbers, they indicate the sector number to execute the commands on.)
Our Superblock changes:
1
editsector 0xd0 00 00 00 00 00 00 00 00
The root directory changes:
13
editsector 0x50 00 06
editsector 0x60 00 07
editsector 0x70 00 07
And the inode edits:
2
editsector 0x140 41 ed 00 03 00 00 00 00 00 00 01 20 00 00 76 00
editsector 0x150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
editsector 0x160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
editsector 0x170 00 00 00 00 21 5a 42 52 1b 39 09 61 1b 39 09 62
editsector 0x180 41 ed 00 03 00 00 00 00 00 00 00 c0 00 00 7d 00
editsector 0x190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
editsector 0x1a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
editsector 0x1b0 00 00 00 00 21 5a 42 52 1b 39 09 61 1b 39 09 62
editsector 0x1c0 41 ed 00 03 00 00 00 00 00 00 00 b0 00 00 84 00
editsector 0x1d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
editsector 0x1e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
editsector 0x1f0 00 00 00 00 21 5a 42 52 1b 39 09 61 1b 39 09 62
Let's hope this does the trick... Please let me know if you've tried it
and it worked or not... Everyone else, pls keep your fingers crossed :-)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "LisaList" group.
To post to this group, send email to lisalist_at_email.domain.hidden
To unsubscribe from this group, send email to lisalist-unsubscribe_at_email.domain.hidden
For more options, visit this group at http://groups.google.com/group/lisalist?hl=en
-~----------~----~----~----~------~----~------~--~---
Received on 2008-03-25 14:13:45
This archive was generated by hypermail 2.4.0 : 2020-01-13 12:15:21 EST