Using ZFS and NFS with Textmate and Finder on a Fusion VM
June 6th, 2007 by Lou
One of the advantages of a VMware image over a real server is that you can securely access the Solaris virtual machine filesystem, from your Mac, with NFS. You don’t even need to plead with your system administrator, that would be you! Also, when you have a server vm, you can carry it with you, on your laptop. Bits are a bunch lighter than real servers. There are a couple of tricks to doing this in a way that is secure and manageable.
I’m doing this with Solaris Nevada build 64a, but most of this should work for Solaris 10 as well. Most of the differences will be with sharemgr. Consult Mr. Google for the proper methods for managing NFS on Solaris 10. But, this is development, use Solaris 11! Also, you may need to use Fusion for this, I can’t find an option to add a NIC to a Parallels vm. If there is one, this should work on Parallels too.
You might ask why would you do this? Well, if you are using the Solaris vm as a server test platform, you will want to be able to edit files on the virtual machine, even if you are using svn, Capistrano or some other mechanism to deploy files to your virtual Solaris server for testing. You may even want to edit source in-place on the virtual server, but who wants to use vi or gedit when you have TextMate? Who wants to grovel around the filesystem with cd all the time when you have Finder?
The first part of the exercise is to add a NIC to your Solaris virtual machine. We need this because we want the NFS communication on a private, closed network between your laptop and the Solaris VM on your laptop. This is less important for a home lab, which should be on a secure network behind a firewall. But if you have your Solaris vm on your laptop, and are carrying that around to other networks, you will want to protect the NFS communication.
There are alternatives to using a secure, private network for securing NFS, such as using an SNFS or even NFSv4, but these are fairly involved. The NFSv4 approach allows you to tunnel NFS simply though ssh, but on OS X it requires downloading OS X kernel source, then patching and compiling your kernel. Yeech!. Maybe some other time. (I’d really like to try the NFSv4 stuff, but the “Hail Mary” before you reboot your hacked OS X kernel is just too scary for me. I need my lappy!)
Another alternative is to use macfuse, but it has too many bugs yet, I think. I’m not real fond of kernel panics while I’m editing. SAMBA would be another way to implement this, and the only reasonable setup if you are doing something like this with a Windows machine and VMware Workstation, but that’s another blog entry.
Anyway, the option to add a NIC to your VM is fairly easy to find the Fusion machine settings dialog. You need to add a NIC and configure it as a NAT or Host Only adapter. I used NAT. All of this is assuming your first network adapter is configured as Bridged, which allows inbound communication, from other machines on the network, to your virtual Solaris server.
If you are adding the adapter to a 64bit vm, Fusion gives you an e1000 adapter by default. If you are using a 32 bit vm, stop that and change it to 64 bit! You have a big fancy Apple dual-core Intel 64bit laptop. Open the vmx file for your vm and change the line that says guestOS = "solaris10" to guestOS = "solaris10-64". I’m fairly certain you get a “pcn” adapter if you are using a 32 bit vm.
After you add the adapter and boot the Solaris vm, get a root command prompt. I use ssh from my laptop to connect. iTerm is also good. I pretty much don’t use the vm console. In fact, the image I’m using now is stripped down and doesn’t even include the X11 stuff. If you want to ssh as root, you need to edit /etc/ssh/sshd_config and change the line that says “PermitRootLogin no” to “PermitRootLogin yes”. No, DO NOT go around and do this to all your production machines and give your administrator a heart attack.
By the way, another good thing to do is to change your TERM, on your Mac from “xterm-color” to “dtterm” or “xterm”. Solaris doesn’t have “xterm-color” in its termcap database, and these other TERM settings work just fine on your Mac. If you don’t, vi is wonky on the the Solaris vm.
The reason you change it on your Mac instead of in the Solaris profile is that ssh is smart enough to inherit the TERM setting from your Mac environment to the Solaris box when you connect, and if you change it on your Mac, you never need change it again anywhere you connect to a Solaris machine. Very nice and DRY!
You can add a line like “export TERM=xterm” to the /etc/profile on your Mac. (Actually, /etc/bash_profile might be a better place for this, especially if you ever use sh or some other shell on your Mac.)
There is one more important point for setting up users on the Solaris vm. If you want the NFS home directory mounting to work as seamlessly as possible, use the same uid for Solaris users as your user on your Mac laptop. This is usually uid 501, but you should check. (In my case, its 503.) When you create users on your Solaris vm, you can specify the uid for the user you create, with something like:
useradd -u 503 -d /export/home/lou -s /usr/bin/bash lou
replacing 503 with your Mac userid, output from id and replacing lou with your user name. User names do not need to match between the Solaris vm and your laptop, but its less confusing I think. The uid, in this case 503, should match for the simplest NFS configuration. The root uid always matches, it is always 0 on every *NIX flavor I know of. All of this greatly simplifies your NFS configuration, since by default, your userids all map on all your systems.
Enough on user accounts. In order to configure the NIC and NFS, you need a root shell. Once you have a root shell on the vm, you can set up the new NIC.
[root@atlas /]# ifconfig -a
lo0: flags=2001000849 mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
e1000g0: flags=201004843 mtu 1500 index 4
inet 192.168.1.129 netmask ffff0000 broadcast 192.168.255.255
ether 0:c:29:9:cc:ba
lo0: flags=2002000849 mtu 8252 index 1
inet6 ::1/128
[root@atlas /]# ifconfig e1000g1 plumb
[root@atlas /]# ifconfig -a
lo0: flags=2001000849 mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
e1000g0: flags=201004843 mtu 1500 index 4
inet 192.168.1.129 netmask ffff0000 broadcast 192.168.255.255
ether 0:c:29:9:cc:ba
e1000g1: flags=201000842 mtu 1500 index 5
inet 0.0.0.0 netmask 0
ether 0:c:29:9:cc:c4
lo0: flags=2002000849 mtu 8252 index 1
inet6 ::1/128
[root@atlas /]# ifconfig e1000g1 DHCPdhcp start
[root@atlas /]# ifconfig -a
lo0: flags=2001000849 mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
e1000g0: flags=201004843 mtu 1500 index 4
inet 192.168.1.129 netmask ffff0000 broadcast 192.168.255.255
ether 0:c:29:9:cc:ba
e1000g1: flags=201004843 mtu 1500 index 5
inet 192.168.200.129 netmask ffffff00 broadcast 192.168.200.255
ether 0:c:29:9:cc:c4
lo0: flags=2002000849 mtu 8252 index 1
inet6 ::1/128
[root@atlas /]#
Most of this is output from ifconfig -a, but the steps are:
- Plumb the new interface:
ifconfig e1000g1 plumb - Start DHCP on the interface:
ifconfig e1000g1 dhcp start
Notice the IP address for the new interface 192.168.200.129. You should not be able to ping this from any other machine on your network. If you can, you haven’t set it in the Fusion configuration as NAT or Host Only.
Also note we are using DHCP, and Fusion is providing an IP address to the vm.
For now, we will put this IP in the hosts table in /etc/hosts on the Mac, so we can refer to the Solaris vm by name. This name should not be the same name you gave the machine on the primary interface. That would confuse name resolution. You can enable name resolution on the secondary interface by editing /etc/hosts on the Mac and adding a line like 192.168.200.129 carpo at the end of the file. carpo is the name I gave this vm on the private network. Note this name will only resolve on the Mac, but that’s ok, only the Mac can see the interface anyway!
Later, in another blog post, we will set up a caching DNS server for all of our zones and virtual machines, but for now, the entry in /etc/hosts works fine. If we keep going with this stuff, we’ll have an entire data center full of virtual servers in our Mac, right were we have absolute power to play with them. Oh, the geeky joy of it! But I digress.
Next we need to share our filesystem. If we don’t have NFS enabled, we need to start that service with svcadm -v enable -r network/nfs/server
If we have a home directory or other filesystem that we’ve established with zfs, such as described in “Amping up Zones and ZFS: Setting up ZFS“, we only need tell zfs to share the zfs filesystem of interest. We are going to add a parameter to make sure the NFS filesystem is only shared on the private network we just set up.
So, first I run a route -v get 192.168.1.129. This will tell me the IP address on the Mac interface that is bound to the private network. You should get something like:
[lou@rapture lou]$ route -v get 192.168.200.129
u: inet 192.168.200.129; u: link ; RTM_GET: Report Metrics: len 128, pid: 0, seq 1, errno 0, flags:
locks: inits:
sockaddrs:
carpo
route to: carpo
destination: carpo
interface: vmnet8
flags:
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
0 0 0 0 0 0 1500 1160
locks: inits:
sockaddrs:
carpo 0.c.29.9.cc.c4 vmnet8:0.50.56.c0.0.8 192.168.200.1
Showing at the end that 192.168.200.1 is the IP address of my Mac on the private network. This also proves that I’m getting to that magic IP from a route on the private interface. This is good. You can ping the interfaces from both sides for good measure.
Next, zfs list shows my zfs filesystems.
[root@atlas /]# zfs list
NAME USED AVAIL REFER MOUNTPOINT
zpool01 5.39M 4.89G 18K /zpool01
zpool01/home 55.5K 4.89G 26.5K /export/home
zpool01/home/lou 29K 4.89G 29K /export/home/lou
zpool01/opt 5.17M 4.89G 21K /opt
zpool01/opt/csw 2.62M 4.89G 2.62M /opt/csw
zpool01/opt/misc 2.53M 4.89G 2.53M /opt/misc
So if I want to share my /export/home/lou directory:
zfs set sharenfs=rw=192.168.200.1,root=192.168.200.1 zpool01/home/lou
where 192.168.200.1 is the IP for my Mac on the private network.
We are now ready to mount our home directory to the Mac! Open Finder, choose connect to server, and put in a url like nfs://carpo/export/home/lou, where “carpo” is the name we gave our private interface on the the Solaris vm in our /etc/hosts file and /export/home/lou is the zfs filesystem we are exporting. If everything is copecetic, we should get a Finder window with the contents of the home directory. W00t!
You should be able to edit files on your Solaris vm with TextMate, or your favorite text editor.
If you want to share your whole vm filesystem, again not recommended for production machines, simply share your root directory on the Solaris vm:
share -o rw=192.168.200.1,root=192.168.200.1 /
The url to mount this for my vm named carpo is nfs://carpo/. Now you can use TextMate on the whole Solaris vm filesystem. No more vi groveling. No X11 gnome for browsing the filesystem.
Several final nits, now that we have all this working, wen need to make a couple of things persist between reboots (or maybe not, depending on your needs).
We need to make the new interface we brought up come up every time we boot. There are two files to deal with:
- Touch
/etc/dhcp.e1000g1to create an empty file. - Create and edit
/etc/hostname.e1000g1, adding a single line with the hostname for the second interface. Remeber, this should not be the same as the entry in/etc/hostname.e1000g0
If you reboot now, you should have the secondary interface enabled automagiically after the reboot, with the same DHCP address it got before.
Lastly, we need to configure NFS permanently. First we create a share group: sharemgr create nfsprivate where nfsprivate is the name of a new share group. You can use any name you like. Next we set properties on this group. All NFS shares in this group share these properties. How DRY is that! What we want is all the shares in this group to connect only to the Mac laptop: sharemgr set -P nfs -S sys -p rw=192.168.200.1,root=192.168.200.1 nfsprivate.
Finally, we add our root share to this group: sharemgr add-share -s / nfsprivate.
That’s it, we can reboot and see if all this works!
[…] Yesterday in “Using ZFS and NFS with Textmate and Finder on a Fusion VM” I stated that “SAMBA would be … the only reasonable setup if you are doing something like this with a Windows machine and VMware Workstation.” This was a bit of an overstatement, since you can configure an NFS client on a Windows machine to do this sort of thing. Also, it appears as though Windows Services for UNIX (SFU) is now freely available from Microsoft, apparently under a combination of LGPL, GPL, and a Microsoft EULA. […]