Sometimes it is the littlest of things which annoy you about an OS. For quite some time, when you install Solaris on a sparc box, it automatically ejects the CD for you. On the otherhand, this was not being done on x86 installs. I don't know how many times I walked away, only to come back to a rebooted machine waiting to do the install again. By the way, if this happens, pop the CD and reboot. It will be as if you had just rebooted after the first installation.
Well, the Install team has fixed this little undocumented feature. The new x86 Install program, first seen by me on Nevada b55, puts it to bed. Sweet!
In Some fun with NFSv4 and automount across a ssh tunnel, I revealed the work going on in Solaris for Mirror Mounts. The example was a desire to automount across a ssh tunnel. Well, I dusted off wont, the box from hell (being used by my son for video games) and created some zfs filesystems on it:
# zfs list NAME USED AVAIL REFER MOUNTPOINT zoo 398K 118G 24.5K /zoo zoo/home 256K 118G 35.5K /export/zfs zoo/home/braves 24.5K 118G 24.5K /export/zfs/braves zoo/home/kanigix 24.5K 118G 24.5K /export/zfs/kanigix zoo/home/loghyr 24.5K 118G 24.5K /export/zfs/loghyr zoo/home/mrx 24.5K 118G 24.5K /export/zfs/mrx zoo/home/nfsv2 24.5K 118G 24.5K /export/zfs/nfsv2 zoo/home/nfsv3 24.5K 118G 24.5K /export/zfs/nfsv3 zoo/home/nfsv4 24.5K 118G 24.5K /export/zfs/nfsv4 zoo/home/spud 24.5K 118G 24.5K /export/zfs/spud zoo/home/tdh 24.5K 118G 24.5K /export/zfs/tdh # uname -a SunOS wont 5.11 snv_55 i86pc i386 i86pc
I then opened a ssh tunnel to it on my Fedora Core 4 box and did a little bit of exploring:
[tdh@adept tdh]> uname -a Linux adept 2.6.15-1.1833_FC4 #1 Wed Mar 1 23:41:37 EST 2006 i686 i686 i386 GNU/Linux [tdh@adept ~/usenix]> ssh -fN -L "5049:wont:2049" wont Password: [tdh@adept ~/usenix]> sudo mount -o port=5049 -t nfs4 localhost:/ /nfs4/wont [tdh@adept ~/usenix]> cd /nfs4/wont [tdh@adept wont]> ls -la total 6 drwxr-xr-x 38 root root 1024 Dec 31 17:49 . drwxr-xr-x 4 root root 4096 Dec 31 18:17 .. drwxr-xr-x 4 root sys 512 Dec 31 17:50 export [tdh@adept wont]> cd export [tdh@adept export]> ls -la total 4 drwxr-xr-x 4 root sys 512 Dec 31 17:50 . drwxr-xr-x 38 root root 1024 Dec 31 17:49 .. drwxr-xr-x 11 root sys 11 Dec 31 17:50 zfs [tdh@adept export]> cd zfs [tdh@adept zfs]> ls -la total 16 drwxr-xr-x 11 root sys 11 Dec 31 17:50 . drwxr-xr-x 4 root sys 512 Dec 31 17:50 .. drwxr-xr-x 2 root sys 2 Dec 31 17:50 braves drwxr-xr-x 2 root sys 2 Dec 31 17:50 kanigix drwxr-xr-x 2 root sys 2 Dec 31 17:50 loghyr drwxr-xr-x 2 root sys 2 Dec 31 17:50 mrx drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv2 drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv3 drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv4 drwxr-xr-x 2 root sys 2 Dec 31 17:50 spud drwxr-xr-x 2 root sys 2 Dec 31 17:50 tdh [tdh@adept zfs]> cd tdh [tdh@adept tdh]> ls -la total 3 drwxr-xr-x 2 root sys 2 Dec 31 17:50 . drwxr-xr-x 11 root sys 11 Dec 31 17:50 ..
Notice that I only did one mount command. As I crossed down into the exported filesystems, the Linux 2.16 implementation of NFSv4 did the mounts automatically for me in the background. Also, note that since '/' is not exported from wont, this must be a pseudo-fs:
[tdh@adept tdh]> showmount -e wont Export list for wont: /export/zfs (everyone) /export/zfs/nfsv2 (everyone) /export/zfs/nfsv3 (everyone) /export/zfs/nfsv4 (everyone) /export/zfs/tdh (everyone) /export/zfs/loghyr (everyone) /export/zfs/kanigix (everyone) /export/zfs/mrx (everyone) /export/zfs/spud (everyone) /export/zfs/braves (everyone)
Let's export '/' and see what happens:
# share -F nfs -o rw -d "root" /
And on the Linux box:
[tdh@adept tdh]> cd /nfs4/wont [tdh@adept wont]> ls -la total 6 drwxr-xr-x 38 root root 1024 Dec 31 17:49 . drwxr-xr-x 4 root root 4096 Dec 31 18:17 .. drwxr-xr-x 4 root sys 512 Dec 31 17:50 export
What happened? Why didn't we see the root directory on wont? Well, when we did the mount command earlier, we basically got a reference to a file handle in the pseudo-fs. We need to flush this by umounting and remounting:
[tdh@adept wont]> cd [tdh@adept ~]> sudo umount /nfs4/wont/ [tdh@adept ~]> sudo mount -o port=5049 -t nfs4 localhost:/ /nfs4/wont [tdh@adept ~]> cd /nfs4/wont [tdh@adept wont]> ls -la total 67 drwxr-xr-x 38 root root 1024 Dec 31 17:49 . drwxr-xr-x 4 root root 4096 Dec 31 18:17 .. lrwxrwxrwx 1 root root 9 Dec 31 13:17 bin -> ./usr/bin drwxr-xr-x 5 root sys 512 Dec 31 14:12 boot drwxr-xr-x 2 root root 512 Dec 31 14:51 Desktop drwxr-xr-x 24 root sys 4096 Dec 31 14:42 dev drwxr-xr-x 10 root sys 512 Dec 31 14:42 devices drwxr-xr-x 2 root root 512 Dec 31 14:51 Documents drwxr-xr-x 9 root root 512 Dec 31 17:31 .dt -rwxr-xr-x 1 root root 5111 Dec 31 14:51 .dtprofile -rw------- 1 root root 16 Dec 31 17:31 .esd_auth drwxr-xr-x 87 root sys 4608 Dec 31 17:52 etc drwxr-xr-x 4 root sys 512 Dec 31 17:50 export ...
Let's walk down the paths again and see what happens:
[tdh@adept wont]> cd export [tdh@adept export]> ls -la total 5 drwxr-xr-x 4 root sys 512 Dec 31 17:50 . drwxr-xr-x 38 root root 1024 Dec 31 17:49 .. drwxr-xr-x 2 root root 512 Dec 31 13:17 home drwxr-xr-x 11 root sys 11 Dec 31 17:50 zfs [tdh@adept export]> cd zfs [tdh@adept zfs]> ls -la total 16 drwxr-xr-x 11 root sys 11 Dec 31 17:50 . drwxr-xr-x 4 root sys 512 Dec 31 17:50 .. drwxr-xr-x 2 root sys 2 Dec 31 17:50 braves drwxr-xr-x 2 root sys 2 Dec 31 17:50 kanigix drwxr-xr-x 2 root sys 2 Dec 31 17:50 loghyr drwxr-xr-x 2 root sys 2 Dec 31 17:50 mrx drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv2 drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv3 drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv4 drwxr-xr-x 2 root sys 2 Dec 31 17:50 spud drwxr-xr-x 2 root sys 2 Dec 31 17:50 tdh [tdh@adept zfs]> cd tdh [tdh@adept tdh]> ls -la total 3 drwxr-xr-x 2 root sys 2 Dec 31 17:50 . drwxr-xr-x 11 root sys 11 Dec 31 17:50 ..Let's make sure we are in the right place:
# scp sandman:/export/home/tdh/.tcshrc . Password: .tcshrc 100% |*******************************************************************| 5417 00:00 # chown tdh:staff .tcshrc # ls -la total 18 drwxr-xr-x 2 root sys 3 Dec 31 18:10 . drwxr-xr-x 11 root sys 11 Dec 31 17:50 .. -rw------- 1 tdh staff 5417 Dec 31 18:10 .tcshrc
And on the client:
[tdh@adept tdh]> ls -la total 9 drwxr-xr-x 2 root sys 3 Dec 31 18:10 . drwxr-xr-x 11 root sys 11 Dec 31 17:50 .. -rw------- 1 tdh nobody 5417 Dec 31 18:10 .tcshrc [tdh@adept tdh]> grep 10 /etc/group wheel:x:10:root
The nobody shows up for the group because there is no mapping between the string "staff" and "wheel". In NFSv3, the numeric 10 would have gone across the wire and the ls command would have spit out "wheel".
Okay, let's check to see what the Solaris client would have done:
[tdh@sandman ~]> ssh -fN -L "5049:wont:2049" wont Password: [tdh@sandman ~]> su - Password: Sun Microsystems Inc. SunOS 5.11 snv_54 October 2007 # mkdir -p /nfs4/wont # mount -o port=5049 localhost:/ /nfs4/wont # exit [tdh@sandman ~]> cd /nfs4/wont [tdh@sandman wont]> ls -la total 134 drwxr-xr-x 38 root root 1024 Dec 31 17:49 . drwxr-xr-x 3 root root 512 Dec 31 18:17 .. ... drwxr-xr-x 2 root root 512 Dec 31 14:51 Desktop drwxr-xr-x 2 root root 512 Dec 31 14:51 Documents lrwxrwxrwx 1 root root 9 Dec 31 13:17 bin -> ./usr/bin drwxr-xr-x 5 root sys 512 Dec 31 14:12 boot drwxr-xr-x 24 root sys 4096 Dec 31 14:42 dev drwxr-xr-x 10 root sys 512 Dec 31 14:42 devices drwxr-xr-x 87 root sys 4608 Dec 31 17:52 etc drwxr-xr-x 4 root sys 512 Dec 31 17:50 export ... [tdh@sandman wont]> cd export [tdh@sandman export]> ls -la total 9 drwxr-xr-x 4 root sys 512 Dec 31 17:50 . drwxr-xr-x 38 root root 1024 Dec 31 17:49 .. drwxr-xr-x 2 root root 512 Dec 31 13:17 home drwxr-xr-x 11 root sys 11 Dec 31 17:50 zfs [tdh@sandman export]> cd zfs [tdh@sandman zfs]> ls -la total 5 drwxr-xr-x 11 root sys 11 Dec 31 17:50 . drwxr-xr-x 4 root sys 512 Dec 31 17:50 ..
Okay, we have hit the crux of the problem for Mirror Mounts. We have a filesystem crossing on the server which needs to be mirrored on the client. We have to do this manually (or with an automounter if the ports are open):
[tdh@sandman zfs]> cd [tdh@sandman ~]> su - Password: Sun Microsystems Inc. SunOS 5.11 snv_54 October 2007 # mount -o port=5049 localhost:/export/zfs /nfs4/wont/export/zfs # ls -la /nfs4/wont/export/zfs total 32 drwxr-xr-x 11 root sys 11 Dec 31 17:50 . drwxr-xr-x 4 root sys 512 Dec 31 17:50 .. drwxr-xr-x 2 root sys 2 Dec 31 17:50 braves drwxr-xr-x 2 root sys 2 Dec 31 17:50 kanigix drwxr-xr-x 2 root sys 2 Dec 31 17:50 loghyr drwxr-xr-x 2 root sys 2 Dec 31 17:50 mrx drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv2 drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv3 drwxr-xr-x 2 root sys 2 Dec 31 17:50 nfsv4 drwxr-xr-x 2 root sys 2 Dec 31 17:50 spud drwxr-xr-x 2 root sys 3 Dec 31 18:10 tdh # tcsh # ls -la /nfs4/wont/export/zfs/tdh total 6 drwxr-xr-x 2 root sys 3 Dec 31 18:10 . drwxr-xr-x 11 root sys 11 Dec 31 17:50 .. # mount -o port=5049 localhost:/export/zfs/tdh /nfs4/wont/export/zfs/tdh # ls -la /nfs4/wont/export/zfs/tdh total 18 drwxr-xr-x 2 root sys 3 Dec 31 18:10 . drwxr-xr-x 11 root sys 11 Dec 31 17:50 .. -rw------- 1 tdh staff 5417 Dec 31 18:10 .tcshrc
Notice how the '/export/zfs' gave information about the child filesystems whereas '/' did not. Also, note how we get the correct group name because the '/etc/group' is the same on the two Solaris hosts. Finally, even with zfs presenting up the child filesystems, we did have to manually mount the child in order to peer into it.
So the Mirror Mounts project in the NFSv4 development team is going to fix all of this. Under the hood, the client is going to understand it is about to traverse to a different filesystem and do the equivalent of a NFSv3 mount.
I haven't blogged much about company culture and the shock I had coming to Sun. I guess I felt I was integrated. I was wrong. In many ways, I am still an outsider. Day in and out, I sit in my office at home, disconnected from the company hivemind. I sometimes get asked by people outside Sun what the plans are and I feel they get offended when I say I don't know. I'm not holding out, I literally do not know.
Sure, I could look at past actions and what I know about the business to make predictions. But at best, they are just as likely to be correct as an industry analyst. It is like Battlestar Galactica, I don't know the writers/producers, but I can predict where the story arcs are going. Can I be wrong? You betcha, which is why I watch the show anyway.
One of the things which is really exciting me about Sun right now are the UI improvements being introduced between builds 50-55 of nevada. They might have started creeping in before then, but I really started to notice along then. The difference is drastic from Solaris 9 and even Solaris 10. I'm going to write about what I think is going on, but please remember, I'm not representing Sun or even the development engineers.
We had the great browser war and before that we had the great windowing system war. Microsoft seemed to win both. Netscape Navigator won on technical merits, but the masses adopted Internet Explorer. As for the Windows versus X battle, I hated it when I was at NetApp and everyone pretty much had to use Windows and Outlook. We needed the extra internal test cycles on hosting Exchange databases, so we converted desktops to Win 2000 and then WinXP.
I think Sun lost the desire to prove it was the better desktop. Either all the engineers got old enough or turned their attention to other matters. Let the young Linux upstarts do it. And they tried, but they never won. Full disclosure, my home terminal is a WinXP box running PuTTY: a free telnet/ssh client and my backup is Fedora Core 4 Linux. My work terminal is a Sun Ray 1G connected to a Solaris Nevada b55 w2100z box. I went back to WinXP because of games and I'm very happy with PuTTY's interface to the Solaris and Linux servers I have at home.
But a funny thing happened, Apple and MAC OS X showed that you could have a BSD core and pretty UI and win people over from WinXP. The installation of new hardware, the interaction between software, etc, was so easy that non-technical people could do it. I know of a lot of diehard Solaris developers who flocked to the Mac Book Pro. And the remains of Netscape reared their head in the form of Firefox to show that the browser war wasn't over either. Suddenly, it became viable to have a non-Microsoft OS which seamlessly handled multimedia and the Internet.
Now I don't think anyone at Sun woke up and said, "You know, we could grab the desktop." I'm not even sure such secret plans exist. But just as Sun has been pouring Star Office, NFSv4, dtrace, and zfs contributions down the open source well, they have been drawing out the innovations made in Gnome, Thunderbird (the mail client which got me off of mutt by the way), Firefox, etc. And you know what, the Solaris desktop experience is pretty fun. Put a dead quiet Sun Ray thin client on someone's desk and it becomes really pleasant.
I've found that I don't have to turn from my Sun Ray 1G to my WinXP box to go look at something on the web. Or to get a crisp terminal session going. As a matter of fact, I want to retire that box to just being a game box. Or even better, I'll have it dual boot WinXP and some OpenSolaris variant. Or perhaps get Xen or vmware running on it to have it serve up a bunch of OSes. It really doesn't matter, as long as I can kick off a game whenever my son feels like pitting his skills against mine.
I just saw an interesting question on one of the internal Sun developer lists:
ssh -fN -L "3049:somehost.someext:2049" jonb@somehost.someext mount -o port=3049 localhost:/f /f
This allows you to mount a filesystem from a remote machine over a ssh tunnel. The question was why doesn't automounting also work?
so I have a /- auto_direct -nosuid,rw in auto_master /f -rw,port=3049 localhost:/f in auto_direct.
And since this is over Solaris, by default it is NFSv4 and we shouldn't need anything but port 2049. The question was why didn't this work. A good resource on this is at: Tunneling NFS traffic via ssh, which is provided by Spencer Shepler. In the comments, it specifically mentions that all you need is port 2049 for NFSv4 traffic.
In my reply on the mailing list, I pointed out that this does not apply to the auotmounter. It has to call on the server's portmapper, which is port 111. Let's repeat the experiment and see if we can prove this to be what is happening.
[tdh@sandman ~]> ssh -fN -L "3049:ultralord:2049" ultralord The authenticity of host 'ultralord (192.168.2.104)' can't be established. RSA key fingerprint is a5:e6:e6:9c:e2:9c:2e:d9:6c:d2:91:c0:ed:41:8f:38. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'ultralord,192.168.2.104' (RSA) to the list of known hosts. Password:
And
# mount -o port=3049 localhost:/f/1 /f # ls -la /f total 4 drwxr-xr-x 2 root root 512 Dec 30 15:08 . drwxr-xr-x 24 root root 512 Dec 30 15:08 .. # tcsh # ls -la /f total 4 drwxr-xr-x 2 root root 512 Dec 30 15:11 . drwxr-xr-x 24 root root 512 Dec 30 15:08 .. -rw-r--r-- 1 root root 0 Dec 30 15:11 ultralord # showmount -e localhost showmount: localhost: RPC: Program not registered
I'll claim I don't need to setup the automounter. I'll do that later to confirm things. Okay, let's try some snoop. Krap! snoop only works on non-loopback interfaces. I found a dtrace script which is supposed to work: DTrace TCP Snoop, but I need to work on it a bit more. Anyway, let's look at how showmount works over a regular interface:
[tdh@sandman ~]> showmount -e ultralord export list for ultralord: /f/1 (everyone) /f/2 (everyone)
And the snoop:
# snoop sandman ultralord
Using device /dev/hme (promiscuous mode)
sandman -> ultralord PORTMAP C GETPORT prog=100005 (MOUNT) vers=1 proto=TCP
ultralord -> sandman PORTMAP R GETPORT port=36795
sandman -> ultralord MOUNT1 C Get export list
ultralord -> sandman MOUNT1 R Get export list 2 entries
Which can be translated as:
sandman asks ultralord's portmapper: "Do you support MOUNT vers 1 over TCP?" ultralord replies: "Yeah and you can get it on port 36795." sandman then asks ultralord's mountd: "What exports do you have?" ultralord then replies: "/f/1 and /f/2"
It makes sense that the automounter would also use the mount protocol. It basically needs to do a MOUNTPROC3_DUMP (see RFC 1813) in order to determine what the server has available. In effect you would have to punch a hole for both port 111 and the port ultralord advertises mountd on. And nothing specifies that the server has to use the same port everytime.
With NFSv4, you do not need an automounter to discover all of the exports on a server. But the implementation shipped in Solaris 10 does not support the automatic mounting of new filesystems as you cross boundaries. In part, it was an engineering decision to ship NFSv4 without this functionality. You can use automounters to get some of the equivalent functionality. You also have to look at typical usuage of shares in Solaris pre-zfs - small sets of shares per server and no child shares.
The problem is given this set of shares on a server:
/ ro /f rw=.eng.sun.com,ro=@172.16 /f/1 rw=.lab.sun.com,anon=0 /f/2 rw,root=.lab.sun.com
How do you dynamically determine where you can go? We haven't specified that this is a Solaris server, so let's assume that '/', '/f', '/f/1', and '/f/2' are all different filesystems. Via the NFSv4 spec (RFC 3530) you should be able to do the following:
# mount -o vers=4 sandman:/ /sandman ... [tdh@sandman ~]> cd /sandman [tdh@sandman ~]> ls -la total 6 drwxr-xr-x 3 tdh staff 512 Dec 30 16:18 . drwxr-xr-x 5 tdh staff 512 Dec 30 16:18 .. drwxr-xr-x 2 tdh staff 512 Dec 30 16:18 f [tdh@sandman ~]> cd f [tdh@sandman ~]> ls -la total 10 drwxr-xr-x 5 tdh staff 512 Dec 30 16:18 . drwxr-xr-x 24 root root 512 Dec 30 15:07 .. drwxr-xr-x 2 tdh staff 512 Dec 30 15:11 1 drwxr-xr-x 2 tdh staff 512 Dec 30 15:11 2 drwxr-xr-x 3 tdh staff 512 Dec 30 16:18 3 [tdh@sandman ~]> cd 1 [tdh@sandman ~]> ls -la total 4 drwxr-xr-x 2 tdh staff 512 Dec 30 15:11 . drwxr-xr-x 5 tdh staff 512 Dec 30 16:18 .. -rw-r--r-- 1 tdh staff 0 Dec 30 15:11 ultralord [tdh@sandman ~]> cd ../3 [tdh@sandman ~]> ls -la total 6 drwxr-xr-x 3 tdh staff 512 Dec 30 16:21 . drwxr-xr-x 5 tdh staff 512 Dec 30 16:18 .. drwxr-xr-x 2 tdh staff 512 Dec 30 16:18 g
Under the current Solaris implementations, you would need to manually make the mounts before each of the cd commands. Except for the last, in that case you are staying on the filesystem represented by '/f'.
The NFS development team is actively working on fixing this issue, which we call Mirror Mounts. Once that functionality is in place, you will be able to explore a remote host across both a firewall and a ssh tunnel via only one port: 2049.
In Not all USB Thumbdrives are created equal, I made a zfs filesystem from a stack of 6 USB thumbdrives. Once I was done playing with them, I wanted to reformat them back to their stock configuration. No problem, right? WinXP does everything for you. Wrong. I tried to manage them via start->Control Panel->Administrative Tools->Computer Management->Storage->Disk Management(Local). Phew, what a mouthfull. Anyway, I got a menu much like this one:
You can right-click on the image to get a menu which will allow you to view the image. That way you can see it in full splendor.
No matter where I clicked, I could not change the partition. After a week or so, i.e., today, I put them in and tried again. This time instead of going to the Disk Managment tool, I clicked on the drives inside Explorer. As I clicked on them, I was told the format was unknown and did I want to reformat the drives:
I'd answer yes and get the above. Also, remember the drives were a mix of SMI and EMI labels.
So I got a NSLU2 and did a very dumb thing. Instead of formating the small USB drive, I formatted soldier, my main backup disk. Well, no use crying over spilt milk. I found I could not reformat the entire disk as WIN32, so I created 3 partitions:
Total disk size is 14593 cylinders
Cylinder size is 16065 (512 byte) blocks
Cylinders
Partition Status Type Start End Length %
========= ====== ============ ===== === ====== ===
1 Ext Win95 0 4078 4079 28
2 IFS: NTFS 4079 13317 9239 63
3 Linux native 13318 14592 1275 9
SELECT ONE OF THE FOLLOWING:
1. Create a partition
2. Specify the active partition
3. Delete a partition
4. Change between Solaris and Solaris2 Partition IDs
5. Exit (update disk configuration and exit)
6. Cancel (exit without updating disk configuration)
Enter Selection:
Okay, the first thing to note that this is output from the same b55 format program as earlier. Evidently, Solaris is able to recognize NTFS partitions. The only thing I can thing that I did differently when starting format this time was that I told it to take the default type. But, I'm not totally bought into that theory. Anyway, here is what I did do:
# format
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
2. c10t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/storage@5/disk@0,0
Specify disk (enter its number): 2
AVAILABLE DRIVE TYPES:
0. Auto configure
1. FUJITSU-MAP3735NP-0108
2. DEFAULT
3. other
Specify disk type (enter its number): 2
selecting c10t0d0
[disk formatted]
Anyway, I'm off to stuff data onto my shiny new backup disk. Note that slugo (what else would you call a NSLU2?) is still stock and pretty slow. I've got another one on order to play with. Also note that my main Solaris box is connected via VPN to Sun, so I can't connect via Samba to slugo.
Okay, I asked myself if the code in nfsv4_idmap.c has the bug I saw when I cut and paste the hash function (see Pathname hash function always picks bucket 104 for the details). Here is the macro in nfs4_idmap.c:
/*
* Pearson's string hash
*
* See: Communications of the ACM, June 1990 Vol 33 pp 677-680
* http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
*/
#define PS_HASH(msg, hash, len) \
{ \
uint_t key = 0x12345678; /* arbitrary value */ \
int i; \
\
(hash) = MOD2((key + (len)), NFSID_CACHE_ANCHORS); \
\
for (i = 0; i < ((len) - 1); i++) { \
(hash) = MOD2(((hash) + (msg)[i]), NFSID_CACHE_ANCHORS); \
(hash) = pkp_tab[(hash)]; \
} \
}
And here is one of the two callers (the other is a mirror image):
if ((rqst_c_str = utf8_to_str(u8s, &rqst_len, NULL)) == NULL) {
/*
* Illegal string, return not found.
*/
return (0);
}
/*
* Compute hash queue
*/
PS_HASH(rqst_c_str, hash, rqst_len - 1);
*hashno = hash;
So what is the value for rqst_len when it comes back from utf8_to_str()? Well, if we look in nfs4_subr.c, we see it does:
/*
* Converts a utf8 string to a C string.
* kmem_allocs a new string if not supplied
*/
char *
utf8_to_str(utf8string *str, uint_t *lenp, char *s)
{
char *sp;
char *u8p;
int len;
int i;
ASSERT(lenp != NULL);
if (str == NULL)
return (NULL);
u8p = str->utf8string_val;
len = str->utf8string_len;
if (len <= 0 || u8p == NULL) {
if (s)
*s = '\0';
return (NULL);
}
sp = s;
if (sp == NULL)
sp = kmem_alloc(len + 1, KM_SLEEP);
/*
* At least check for embedded nulls
*/
for (i = 0; i < len; i++) {
sp[i] = u8p[i];
if (u8p[i] == '\0') {
#ifdef DEBUG
zcmn_err(getzoneid(), CE_WARN,
"Embedded NULL in UTF-8 string");
#endif
if (s == NULL)
kmem_free(sp, len + 1);
return (NULL);
}
}
sp[len] = '\0';
*lenp = len + 1;
return (sp);
}
Edit: Okay, I realized the following is flawed. The code is passing in the string length to the macro - not the allocated space. The id mapping implementation will only cut off 1 character!
So the length rqst_len is the strlen(rqst_c_str) + 1. Note that strlen() does not count the string terminator in the result. Unlike my implementation in the sharetab code, this implementation will actually skip the last two characters in the string. I modified my stand alone code to mimic this:
$ ./a.out /sharem/dir1 hashes to 80 /sharem/dir2 hashes to 80 /sharem/diyu /sharem/diyu hashes to 80 .
So instead of hashing to 103, these strings hashed to 80. Does missing two characters really matter? It mainly makes the hash chain longer. And some hash implementations do not bother looking at the entire value to be hashed.
But it bugs me. This is bug 6507643.
When storing the sharetabs in memory, I want to hash on the pathname. I asked the group if there were any general purpose hash functions out there (I had done one at NetApp, but I don't have access to that code anymore). The response I got back was to use Pearson's string hash algorithm.
The NFSv4 id mapping uses it. Now I'd love to just link into that code, but it is in a different module. In an ideal world, I'd yank it out of nfsd and stick it directly in the kernel. Then I'd have to make sure it was initialized before everything else.
I didn't do that for my prototype. Instead, I cut and pasted the code over. I tweaked a variable name or two.
When I was debugging the prototype, I noticed everything ended up in hash bucket 104. Now my pathnames were pretty bland - /sharem/dir1 and /sharem/dir2, so I didn't spend too much time on it. Plus debugging the Solaris kernel is a major pain. But I'm now at that point where I need to start polishing the little things off. I realized that I don't need to go to the kernel to debug this, I could create a standalone utility to test these. With that in mind, I started to cut and paste yet again:
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/types32.h>
#define SHARETAB_HASHES 256
static uint_t pkp_tab[SHARETAB_HASHES];
#define MOD2(a, pow_of_2) (a) & ((pow_of_2) - 1)
/*
* Pearson's string hash
*
* See: Communications of the ACM, June 1990 Vol 33 pp 677-680
* http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
*/
#define SHARETAB_HASH_IT(hash, path) \
{ \
uint_t key = 0x12345678; /* arbitrary value */ \
int i, len; \
\
len = strlen((path)); \
\
(hash) = MOD2((key + len), SHARETAB_HASHES); \
\
for (i = 0; i < len - 1; i++) { \
(hash) = MOD2(((hash) + (path)[i]), SHARETAB_HASHES); \
(hash) = pkp_tab[(hash)]; \
} \
}
/*
* Initialize table in pseudo-random fashion
* for use in Pearson's string hash algorithm.
*
* See: Communications of the ACM, June 1990 Vol 33 pp 677-680
* http://www.acm.org/pubs/citations/journals/cacm/1990-33-6/p677-pearson
*/
static void
init_pkp_tab(void)
{
int i;
int j;
int k = 7;
uint_t s;
for (i = 0; i < SHARETAB_HASHES; i++)
pkp_tab[i] = i;
for (j = 0; j < 4; j++) {
for (i = 0; i < SHARETAB_HASHES; i++) {
s = pkp_tab[i];
k = MOD2((k + s), SHARETAB_HASHES);
pkp_tab[i] = pkp_tab[k];
pkp_tab[k] = s;
}
}
}
int
main(int argc, char *argv[])
{
int iHash;
char *s1 = "/sharem/dir1";
char *s2 = "/sharem/dir2";
init_pkp_tab();
SHARETAB_HASH_IT(iHash, s1);
printf("%s hashes to %d\n", s1, iHash);
SHARETAB_HASH_IT(iHash, s2);
printf("%s hashes to %d\n", s2, iHash);
return (0);
}
At first I thought it was the pow_of_2, which I couldn't find in the source code or in a man page, but this standalone compiled with no problem. The two strings hashed to 103:
$ ./a.out /sharem/dir1 hashes to 103 /sharem/dir2 hashes to 103
And a little change yields:
$ ./a.out /sharem/dir1 hashes to 103 /sharem/theend/dir2 hashes to 32
Okay, lets make the code a bit more dynamic:
int
main(int argc, char *argv[])
{
int iHash;
char *s1 = "/sharem/dir1";
char *s2 = "/sharem/dir2";
char sz[1024];
init_pkp_tab();
SHARETAB_HASH_IT(iHash, s1);
printf("%s hashes to %d\n", s1, iHash);
SHARETAB_HASH_IT(iHash, s2);
printf("%s hashes to %d\n", s2, iHash);
sz[0] = 'x';
while (1) {
s1 = gets(sz);
if (sz[0] == '.') {
break;
}
SHARETAB_HASH_IT(iHash, sz);
printf("%s hashes to %d\n", sz, iHash);
}
return (0);
}
Okay, kinda interesting:
$ ./a.out /sharem/dir1 hashes to 103 /sharem/dir2 hashes to 103 /etc/dfs /etc/dfs hashes to 117 /sharem/dir3 /sharem/dir3 hashes to 103 /shares/dir3 /shares/dir3 hashes to 2 /shares/dir2 /shares/dir2 hashes to 2 /shares/dir1 /shares/dir1 hashes to 2 /shares/dira /shares/dira hashes to 2 /shares/dirr /shares/dirr hashes to 2 .
I'm not getting 104, but I am seeing that if you have the same N-1 characters, then you will map to the same hash index regardless of the last character. Not good for a pathname hashing algorithm. Note that there could be a bug in this translation of the algorithm. To debug, I'll make the macro SHARETAB_HASH_IT into a function and then use gdb:
static uint_t
sharetab_hash_it(uint_t hash, char *path)
{
uint_t key = 0x12345678;
int i, len;
len = strlen(path);
hash = MOD2((key + len), SHARETAB_HASHES);
for (i = 0; i < len - 1; i++) {
hash = MOD2(hash + path[i], SHARETAB_HASHES);
hash = pkp_tab[hash];
}
return (hash);
}
Okay, by the way, it is a joy to use a symbolic debugger. Anyway, look at this output:
44 for (i = 0; i < len - 1; i++) {
4: path[i] = 114 'r'
3: i = 10
2: hash = 103
1: len = 12
(gdb) n
49 return (hash);
4: path[i] = 49 '1'
3: i = 11
2: hash = 103
1: len = 12
It is pretty easy to see that we are skipping over the last character. The code should read i < len.
$ ./a.out /sharem/dir1 hashes to 241 /sharem/dir2 hashes to 236 .
And the code in the id mapper has this bug.
In Perl as a team management tool for coaching, I presented a simple way to use sed to get code ready for pasting into a blog entry:
[tdh@adept teams]$ cat report.pl | sed "s/</\</g ; s/>/\>/g"
While getting ready to put up a simple C program, I tried to use this trick again:
[tdh@warlock ~/tests]> cat sharetab.c | sed "s/</\</g ; s/>/\>/g" sed: command garbled: s/</\</g ; s/>/\>/g
Okay, warlock is Solaris and adept is Linux. I verified that the script worked on adept still. To debug, I made the command simpler:
[tdh@warlock ~/tests]> cat sharetab.c | sed "s/</\</g"
It worked. So did just doing the other half of the code. Why won't the combination work? Hmm, this works:
[tdh@warlock ~/tests]> sed -e "s/</\</g" -e "s/>/\>/g" sharetab.c
Okay, I found the answer in sed \& awk, Second Edition. (Note, I have the book, can't find it in the mess of an office, and found the answer on an online copy.) It was in Chapter 5:
[1] Surprisingly, the use of semicolons to separate commands is not documented in the POSIX standard.
n;d
However, putting a space after the n command causes a syntax error. Putting a space before the d command is okay.
And if I try this, it works:
[tdh@warlock ~/tests]> sed -e "s/</\</g; s/>/\>/g" sharetab.c
I'm working on a project to put the sharetab into memory and not be on disk. One design consideration is that /etc/dfs/sharetab has to still dump the sharetab. To do that, I've used the gfs implementation (usr/src/uts/commonfs/gfs.c and usr/src/uts/common/sys/gfs.h) to provide file access to the sharetab in the kernel. The GFS code requires you to have a pseudo-fs directory. I.e., I could use /etc/dfs/shares/sharetab but not /etc/dfs/sharetab.
Since I'm pretty much copying the objfs implementation and I don't want to have /etc/dfs/shares/sharetab, I took Mark Shellenbaum's suggestion and put it in /system/dfs. Now the problem was how to make sure that a directory for /system/dfs and a symlink for /etc/dfs/sharetab -> /system/dfs/sharetab get created on systems. The first thing I found to do was to add entries in usr/src/Targetdirs:
[tdh@warlock src]> wx pdiffs Targetdirs ------- usr/src/Targetdirs ------- Index: usr/src/Targetdirs 25c25 < # ident "@(#)Targetdirs 1.183 06/11/21 SMI" --- > # ident "@(#)Targetdirs 1.184 06/12/21 SMI" 130a131 > /system/dfs \ 485a487 > /etc/dfs/sharetab \ 578a581 > $(ROOT)/system/dfs:= DIRMODE= 555 596a600 > $(ROOT)/etc/dfs/sharetab:= LINKDEST=system/dfs/sharetab
When I tried that, I got some warnings in my nightly build:
==== cpio archives build errors (DEBUG) ==== Failed to create generic root archive: 15770 blocks cpiotranslate: etc/dfs/sharetab: no packaging info cpiotranslate: system/dfs: no packaging info
Okay, the build knows to build the directory and make the link. But it doesn't know how to stuff that in the BFU archives. Seeing as how those are needed for pre-integration testing and I can't check the code in without the test results, I've got to fix these. My first attempt at that was in usr/src/pkgdefs/SUNWcsr (note I found this by grepping about for system/object):
[tdh@warlock SUNWcsr]> wx diffs prototype_com ------- usr/src/pkgdefs/SUNWcsr/prototype_com ------- 135a136 > s none etc/dfs/sharetab=../system/dfs/sharetab 417a419 > d none system/dfs 555 root root
Now note that I totally guessed at the form for the symlink. I found a symlink in my system and went for the good old cut and paste. It has failed as well:
Inconsistencies between pkgdefs and proto area:
Unit T File Name Reloc/Sym name perm owner group inode lnk maj min package(s)
------------------------------------------------------------------------------------------------------------
filea: s etc/dfs/sharetab ../system/dfs/sharetab 0 - - 0 1 0 0 SUNWcsr
fileb: s etc/dfs/sharetab system/dfs/sharetab 777 - - 0 1 - - proto
differ: symlink
Well, note that system/dfs must have been correct. Hmm, I could go look at examples from usr/src/Targetdirs, but first I want to confirm that my notation is correct. I looked in nightly and it calls makebfu. I looked in there and it calls cpiotranslate. The really, really neat thing about building Solaris is that you can find all of the tools you need in the source tree. I happened to stumble on usr/src/tools earlier in the day while looking for help with bfu. Okay, if we look in usr/src/tools/protocmp/list.h:
/* * file types */ #define CHAR_DEV_T 'c' #define BLOCK_DEV_T 'b' #define DIR_T 'd' #define FILE_T 'f' #define EDIT_T 'e' #define VOLATILE_T 'v' #define SYM_LINK_T 's' #define LINK_T 'l'
So I have the right type, now I have to figure out if it is a difference in the paths. Hmm, I wonder if instead of:
s none etc/dfs/sharetab=../system/dfs/sharetab
I should have:
s none etc/dfs/sharetab=../../system/dfs/sharetab
No, that isn't it:
Inconsistencies between pkgdefs and proto area:
Unit T File Name Reloc/Sym name perm owner group inode lnk maj min package(s)
------------------------------------------------------------------------------------------------------------
filea: s etc/dfs/sharetab ../../system/dfs/sharetab 0 - - 0 1 0 0 SUNWcsr
fileb: s etc/dfs/sharetab system/dfs/sharetab 777 - - 0 1 - - proto
differ: symlink
Okay, I think this was a step in the right direction. I.e., it is correct in this file. I think the corresponding file in usr/src/Targetdirs is hosed. It should be:
$(ROOT)/etc/dfs/sharetab:= LINKDEST=../../system/dfs/sharetab
I wanted to put an absolute and not relative symlink in here. But I can't do that due to the way the proto area is built. Look at the output from the build log:
/usr/bin/rm -f -r /brmws/ws-b/tdh/sparc/sharky/proto/root_sparc/etc/dfs/sharetab; /usr/bin/ln -s system/dfs/sharetab /brmws/ws-b/tdh/sparc/sharky/proto/root_sparc/etc/dfs/sharetab; true root /brmws/ws-b/tdh/sparc/sharky/proto/root_sparc/etc/dfs/sharetab; true bin /brmws/ws-b/tdh/sparc/sharky/proto/root_sparc/etc/dfs/sharetab
If that symlink was absolute, we would get the following:
/usr/bin/ln -s /system/dfs/sharetab /brmws/w...
We have a winner! Now let's see if it works on a live system.
bfu# ls -la /system total 8 drwxr-xr-x 5 root root 512 Dec 21 14:24 . drwxr-xr-x 36 root root 1024 Dec 21 22:11 .. dr-xr-xr-x 4 root root 4 Dec 21 22:04 contract dr-xr-xr-x 2 root root 512 Dec 21 14:24 dfs dr-xr-xr-x 305 root root 305 Dec 21 22:04 object bfu# ls -la /system/dfs total 4 dr-xr-xr-x 2 root root 512 Dec 21 14:24 . drwxr-xr-x 5 root root 512 Dec 21 14:24 .. bfu# ls -la /etc/dfs total 16 drwxr-xr-x 2 root sys 512 Dec 21 21:28 . drwxr-xr-x 88 root sys 4096 Dec 21 22:16 .. -rw-r--r-- 1 root sys 354 Dec 21 17:16 dfstab -rw-r--r-- 1 root root 68 Dec 21 17:46 fstypes lrwxrwxrwx 1 root root 25 Dec 21 22:10 sharetab -> ../../system/dfs/sharetab
And reboot!
# mkdir /sharem # mkdir /sharem/dir1 # share -F nfs -o rw,anon=0 -d "dir1" /sharem/dir1 # share - /sharem/dir1 anon=0,sec=sys,rw "dir1" # cat /system/dfs/sharetab /sharem/dir1 - nfs anon=0,sec=sys,rw dir1 # cat /etc/dfs/sharetab /sharem/dir1 - nfs anon=0,sec=sys,rw dir1 #
Of course, I need to prove that a fresh install also builds everything correctly. But that can be another night.
Time for more fun. I want to have a case-sensitive USB filesystem for backup. Ok, I ran format and fdisk (while the thing was mounted, ouch!) and tried to run newfs:
# rmmount -l /dev/dsk/c5t0d0p0:1 rmdisk,rmdisk0,WITCH # newfs /dev/dsk/c5t0d0p0:1 newfs: /dev/dsk/c5t0d0p0:1: No such file or directory # newfs /dev/dsk/c5t0d0p0 newfs: construct a new file system /dev/rdsk/c5t0d0p0: (y/n)? y mkfs: bad value for size: 0 must be between 1024 and 0 mkfs: size reset to default 0 seek error on sector -1: Error 0
I tried a bunch of variants to name the disk, but I got the clue bat across my head when I ran format again:
# format
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
2. c5t0d0 <DEFAULT cyl 1464 alt 2 hd 255 sec 63> witch
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@6/disk@0,0
Specify disk (enter its number): ^D
# newfs /dev/rdsk/c5t0d0
newfs: /dev/rdsk/c5t0d0: No such file or directory
# newfs /dev/rdsk/c5t0d0s0
newfs: construct a new file system /dev/rdsk/c5t0d0s0: (y/n)? y
Warning: 3850 sector(s) in last cylinder unallocated
/dev/rdsk/c5t0d0s0: 23503094 sectors in 3826 cylinders of 48 tracks, 128 sectors
11476.1MB in 240 cyl groups (16 c/g, 48.00MB/g, 5824 i/g)
super-block backups (for fsck -F ufs -o b=#) at:
32, 98464, 196896, 295328, 393760, 492192, 590624, 689056, 787488, 885920,
22614816, 22713248, 22811680, 22910112, 23008544, 23106976, 23205408,
23303840, 23402272, 23500704
#
Notice that I renamed the volume to be "witch" and not "WITCH". Lets try to mount the thing:
# rmmount -l /dev/dsk/c5t0d0p0:1 rmdisk,rmdisk0,WITCH # rmmount witch cannot find 'witch' # rmmount WITCH mount of WITCH /dev/dsk/c5t0d0p0:1 failed: mount: /dev/dsk/c5t0d0p0:1 is not a DOS filesystem.
I've tried ejecting it, rumount-ing it, using cfgadm to nuke, but no luck:
# rmumount WITCH usb4/4.6 usb-storage connected configured ok # eject /dev/dsk/c5t0d0p0:1 usb4/4.6 usb-storage connected configured ok # cfgadm -c disconnect usb4/4.6 Disconnect the device: /devices/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4:4.6 This operation will suspend activity on the USB device Continue (yes/no)? yes cfgadm: Hardware specific failure: Cannot issue devctl to ap_id: /devices/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4:4.6 # cfgadm -x usb_reset usb4/4.6 Reset the device: /devices/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4:4.6 This operation will suspend activity on the USB device Continue (yes/no)? yes cfgadm: Hardware specific failure: Cannot issue devctl to ap_id: /devices/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4:4.6 # cfgadm -lv usb4/4.6 Ap_Id Receptacle Occupant Condition Information When Type Busy Phys_Id usb4/4.6 connected configured ok Mfg: <undef> Product: USB 2.0 Storage Device NConfigs: 1 Config: 0 <no cfg str descr> unavailable usb-storage n /devices/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4:4.6
Okay, time to yank it and add it to another connector. What do we have now?
# rmmount -l /dev/dsk/c9t0d0s0 rmdisk,rmdisk0,/media/Storage Device # df /media/Storage Device(/dev/dsk/c9t0d0s0 ):23122940 blocks 1397756 files
Okay, the volume name doesn't matter anymore. And it shows up as "11.2 GB Volume" in the GNOME volume tool.
Even more fun, remember when it was rmmount'ed and I could format it. I can not do that now:
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
2. c9t0d0 <DEFAULT cyl 1464 alt 2 hd 255 sec 63> witch
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@5/disk@0,0
Specify disk (enter its number): 2
selecting c9t0d0: witch
[disk formatted]
Warning: Current Disk has mounted partitions.
/dev/dsk/c9t0d0s0 is currently mounted on /media/Storage Device. Please see umount(1M).
Evil is afoot! I decided to file a bug report on the allowed format under rmmount - it is 6507439.
The USB drive from Finding USB drives doesn't appear because it has an NTFS type:
usb 1-4: new high speed USB device using ehci_hcd and address 2 SCSI subsystem initialized Initializing USB Mass Storage driver... scsi0 : SCSI emulation for USB Mass Storage devices usbcore: registered new driver usb-storage USB Mass Storage support registered. usb-storage: device found at 2 usb-storage: waiting for device to settle before scanning Vendor: USB 2.0 Model: Storage Device Rev: 0100 Type: Direct-Access ANSI SCSI revision: 00 usb-storage: device scan complete SCSI device sda: 23579136 512-byte hdwr sectors (12073 MB) sda: assuming drive cache: write through SCSI device sda: 23579136 512-byte hdwr sectors (12073 MB) sda: assuming drive cache: write through sda: sda1 sd 0:0:0:0: Attached scsi disk sda [tdh@adept ~]> sudo mount /dev/sda1 /mnt mount: unknown filesystem type 'ntfs'
And soldier is of course a FAT32 disk. WinXP is good for exploring something. Okay, I can zap the data and fix that. But really, I wish something in Solaris had just told me that the drive type was NTFS and tough noogies on getting it to mount.
Hmm, as a follow-up, I am running GNOME 2.16.1. I had selected help and it took me to a 2.14 manual, so I made an easy assumption. The 'About' in the panel manager does show the version and I also noticed it when logging in as a new user for the first time.
Okay, I'vre reformatted it as a FAT32 filesystem:
# rmmount -l /dev/dsk/c5t0d0p0:1 rmdisk,rmdisk0,WITCH
Okay, this is real screwy. I can't mount it unless I have a non-privleged user logged into the console. It can't be root and I'm guessing it can't have any RBAC permissions. With a headless system, that means you have to grab the serial console and log into it as a non-root user. That resource is precious.
# df | grep -i witch /media/WITCH (/dev/dsk/c5t0d0p0:1):23544240 blocks -1 files
I try a bunch of different things and I go down paths that may appear deadend. I do that for several reasons:
Sometimes my long session captures are edits of several other sessions. Or they are a repeat of what I did earlier.
Flush with my success at getting at Finding USB Thumbdrives, I decided to tackle a problem which has bugged me for some time. I have a 120G USB drive which I use for backup. It will mount on any of my systems and I can get at my data. However, I have an old laptop drive in a USB case and I can't get at the data on my Solaris systems. What does format see?
# format
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
2. c9t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@5/disk@0,0
Specify disk (enter its number):
Note that right off the bat format likes this drive better than the thumbdrives. I also didn't have GNOME complain when I inserted it. Hmm, I added the other drive and it does get seen by GNOME, but it is not mounted. I know on earlier versions of Nevada, I was able to see it. And format does not see it, but format -e does:
# format -e
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
2. c6t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@7/disk@0,0
3. c9t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@5/disk@0,0
Specify disk (enter its number):
Okay, enough fooling with format, time to find a better tool or a way to see the data. Unlike the thumbdrives, I am not willing to nuke the data on these USB drives. Let's see what the system thinks it has for USB devices:
# cfgadm -l Ap_Id Type Receptacle Occupant Condition c1 scsi-bus connected configured unknown c2 scsi-bus connected unconfigured unknown usb0/1 unknown empty unconfigured ok usb0/2 unknown empty unconfigured ok usb0/3 unknown empty unconfigured ok usb1/1 unknown empty unconfigured ok usb1/2 unknown empty unconfigured ok usb1/3 unknown empty unconfigured ok usb2/1 unknown empty unconfigured ok usb2/2 unknown empty unconfigured ok usb2/3 unknown empty unconfigured ok usb3/1 usb-device connected configured ok usb3/2 unknown empty unconfigured ok usb4/1 unknown empty unconfigured ok usb4/2 unknown empty unconfigured ok usb4/3 unknown empty unconfigured ok usb4/4 usb-hub connected configured ok usb4/4.1 unknown empty unconfigured ok usb4/4.2 unknown empty unconfigured ok usb4/4.3 unknown empty unconfigured ok usb4/4.4 unknown empty unconfigured ok usb4/4.5 usb-storage connected configured ok usb4/4.6 unknown empty unconfigured ok usb4/4.7 usb-storage connected configured ok usb4/5 unknown empty unconfigured ok
Okay, I found email about the vold being put out to pasture. It is time to start using rmmount(1). Okay, what does that do?
[tdh@warlock ~]> rmmount cdrom /dev/dsk/c0t0d0s2 mounted at /media/suppl_2.5
Well it also mounted soldier, which is the 120G USB drive, but not the notebook drive:
[tdh@warlock ~]> df -h | grep media /dev/dsk/c0t0d0s2 428M 428M 0K 100% /media/suppl_2.5 /dev/dsk/c6t0d0p0:1 112G 37G 75G 34% /media/SOLDIER [tdh@warlock ~]> rmmount -l /dev/dsk/c6t0d0p0:1 rmdisk1,SOLDIER,/media/SOLDIER /dev/dsk/c0t0d0s2 cdrom,cdrom0,cd,cd0,sr,sr0,suppl_2.5,/media/suppl_2.5
I am actually back to where I started with my earlier bits - I can see soldier but not the other drive. It looks like GNOME doesn't understand yet that the volume manager has changed. Okay, strike that, I'm running GNOME 2.14 and the volume management doesn't become smooth until 2.16. I'm okay with that - it is called the bleeding edge for a reason.
I'm going to go play with the other drive. I'll add it to a WinXP box to see what is on it. I'll also look at it in linux to see if it knows what is up.
I added an USB 2.0 Hub and 6 1G Thumbdrives. I knew something was up when the GNOME volume manager started complaining about not being able to load the drives. So, off I went in search of the drives.
The first clue as to there location came from /var/adm/messages:
Dec 20 14:45:43 warlock usba: [ID 912658 kern.info] USB 2.0 device (usb409,50) operating at hi speed (USB 2.x) on USB 2.0 root hub: hub@4, hubd0 at bus address 2 Dec 20 14:45:43 warlock genunix: [ID 936769 kern.info] hubd0 is /pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4 Dec 20 14:45:43 warlock genunix: [ID 408114 kern.info] /pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4 (hubd0) online Dec 20 14:45:44 warlock usba: [ID 912658 kern.info] USB 2.0 device (usb154b,5) operating at hi speed (USB 2.x) on USB 2.0 external hub: storage@1, scsa2usb0 at bus address 3 Dec 20 14:45:44 warlock usba: [ID 349649 kern.info] PNY USB 2.0 FD 6E6B0800A9C3 Dec 20 14:45:44 warlock genunix: [ID 936769 kern.info] scsa2usb0 is /pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@1 Dec 20 14:45:44 warlock genunix: [ID 408114 kern.info] /pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@1 (scsa2usb0) online Dec 20 14:45:44 warlock usba: [ID 912658 kern.info] USB 2.0 device (usb930,6545) operating at hi speed (USB 2.x) on USB 2.0 external hub: storage@2, scsa2usb1 at bus address 4 Dec 20 14:45:44 warlock usba: [ID 349649 kern.info] USB Flash Memory 0351AA6042F2B926
Okay, they are there, but neither df nor format showed them:
# format
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
Specify disk (enter its number):
Hmm, I can do a prtconf -v to find them, but then I can't use the device paths I get:
# zpool create usb /dev/usb/mass-storage0 /dev/usb/mass-storage1 /dev/usb/mass-storage2 /dev/usb/mass-storage3 /dev/usb/mass-storage4 /dev/usb/mass-storage5 /dev/usb/mass-storage6 cannot use '/dev/usb/mass-storage0': must be a block device or regular file
Okay, google turned up digital camera and solaris 10 on the Sun Developer Network. Basically, it suggests using the '-e' option with format:
# format -e
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
2. c3t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@2/disk@0,0
3. c4t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@4/disk@0,0
4. c5t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@6/disk@0,0
5. c6t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@7/disk@0,0
6. c7t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@3/disk@0,0
7. c8t0d0 <drive type unknown>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@1/disk@0,0
Specify disk (enter its number): 2
The drive types are not showing up, I'll need to select them:
AVAILABLE DRIVE TYPES:
0. Auto configure
1. FUJITSU-MAP3735NP-0108
2. DEFAULT
3. other
Specify disk type (enter its number): 2
selecting c3t0d0
[disk formatted]
format> fdisk
Total disk size is 983 cylinders
Cylinder size is 2048 (512 byte) blocks
Cylinders
Partition Status Type Start End Length %
========= ====== ============ ===== === ====== ===
1 Active FAT16 LBA 0 982 983 100
Here they are much later in life:
# format -e
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <DEFAULT cyl 8914 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@0,0
1. c1t1d0 <FUJITSU-MAP3735NP-0108 cyl 8933 alt 2 hd 255 sec 63>
/pci@5,0/pci1022,7450@4/pci108e,534d@4,1/sd@1,0
2. c3t0d0 < -USB Flash Memory-5.00-983.00MB>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@2/disk@0,0
3. c4t0d0 < -USB Flash Memory-5.00-983.00MB>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@4/disk@0,0
4. c5t0d0 <PNY-USB 2.0 FD-PMAP-980.00MB>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@6/disk@0,0
5. c6t0d0 <PNY-USB 2.0 FD-PMAP-980.00MB>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@7/disk@0,0
6. c7t0d0 <PNY-USB 2.0 FD-PMAP-984.00MB>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@3/disk@0,0
7. c8t0d0 <PNY-USB 2.0 FD-PMAP-984.00MB>
/pci@0,0/pci1022,7460@6/pci108e,534d@3,2/hub@4/storage@1/disk@0,0
c7t0d0 and c8t0d0 were spares in a zfs pool and got converted from SMI to EMI labels. I have no idea why c3t0d0 and c4t0d0 have different types. And you can see that c4t0d0 and c5t0d0 both have a smaller number of cylinders.