By Jeffrey Carl and Matt Loschert
This is the first chapter in a series of observations, representing the adventures of a couple of BSD admins (one with a lot of prior MacOS experience, the other with more on the BSD side) poking around the command line on an iBook laptop running Apple’s Mac OS X Public Beta. We’ll attempt to provide a few notes and observations that may make a BSD admin’s work with Mac OS X easier.
Mac vs. Unix
Right up front, I should mention what a strange animal Mac OS X is. Since 1984, the Mac OS has always been about the concept that “my OS should work easily, without my knowing how it works.” Unix has always been about the idea that “I should be able to control every aspect of my OS, even if it isn’t always easy to figure out how.” Apple – whose very name is anathema to many Unix admins – is now trying to combine both, in the world’s first BSD-based OS that is likely to ship 500,000 copies in its first year.
Apple isn’t alone in this hybridization effort; Microsoft will presumably ship “Whistler,” its NT/2000-based consumer OS, sometime in mid-2001. It appears that everywhere, the rush is on to deliver consumer OSes based on the kernels of server operating systems. In the long run, this is probably a Good Thing®, but Mac OS X and MS Whistler will have to introduce millions of desktop users to the advantages and problems of server OS design that we as server OS admins have been dealing with for years. Real protected memory and pre-emptive multitasking, sure … but also real multi-user systems and all of the permission and driver complexities that requires, as well. However, both Microsoft and Apple are investing the time and effort into developing a real user-friendly interface that your grandmother could configure (sorry, KDE and GNOME). It should be interesting to watch.
If you, like most other Internet server admins with a fully-functional brain stem, prefer Unix over the NT kernel, then Mac OS X will be the first true consumer OS that you will ever feel comfortable with. And, whether you love or hate Apple, it’s worth your time to get acquainted with Mac OS X and what it offers to a BSD Unix administrator.
Right now, there are a lot of questions out there about Mac OS X and its attempts to marry a BSD / Mach microkernel with an all-singing, all-dancing Mac GUI. This is largely because there is unfortunately a comparatively small crossover between Mac administrators and Unix administrators (much like the slim crossover between supermodels and serious “Dungeons and Dragons” players). Though neither Jeff nor Matt is a total über-guru in Mac OS or BSD, we’ll attempt to bridge the gap a little and give the average BSD admin an idea of what he or she will see if they peek around under the hood of Mac OS X Public Beta. Much of this is “first impression” notes and questions, without too much outside research behind it; explanations or clarifications from those who have more detailed answers are gratefully appreciated.
On a side note, Matt and Jeff will both use “I” rather than “we” in this article as we go, since we are both members of the FreeBSD Borg Collective and think of ourselves as one entity. 😉
Poking Under the Hood: First Impressions
To examine the hidden Unix world on OS X, navigate in the GUI to Applications >> Utilities >> Terminal. The first thing you may notice is that – as you might expect – the default shell is tcsh. You’ll quickly find that many of the user apps you’d expect in a typical Unix installation are there, plus a few extras and minus a few others (showing the refreshing influence of many developers, each pushing for the inclusion of their favorite tools). Interestingly, pico is there, although Pine is not; Emacs and vi are there, also (ed may be there, but I didn’t check since I thought everyone who might use ed was fossilized and hanging on display in a museum by now). Other fun inclusions are gawk, biff, formail, less, locate, groff, perl 5.6, wget, procmail, fetchmail, and an openssh-based client and server.
The first thing that I do when beginning to work on a new system is to set my shell and copy over my personal config files. When presented with the Mac OS X shell prompt, I was pleased to see that it was tcsh; but at the same time I was a little confused at how to customize it. Usually, I just drop my .cshrc file in ~/, and off I go. Well, ~/ in this case is /Users/myusername. This is unlike the normal /usr/home or /home that most admins are used to. Would tcsh be able to find my .cshrc there?
Well, since I didn’t have the machine network-connected while I was originally exploring, and I was too lazy to hand-copy parts of my personal .cshrc file over to this directory, I instead began poking around /etc looking at how the default .cshrc worked. I quickly found a small csh.cshrc which contained a single line sourcing /usr/share/init/tcsh/rc. This is where it gets interesting.
This rc file sets up a very cool method of providing standard system shell features that can be overriden by each Mac OS X user (assuming he/she realizes that the “shell” does not refer to the funky computer case). The rc file first checks to see if the user has a ~/Library/init/tcsh directory. If so, it sets this as the tcsh initialization directory; otherwise it sets the /usr/share/init/tcsh directory as the default. It then proceeds to source other files in the default directory including, for instance, environment, aliases, and completions files which each in turn source files (if they exist) found in the abovementioned tcsh initialization directory.
In this way, the system provides some powerful “standard” features, but still gives the experienced user the ability to override anything and everything. I dropped some customizations in my personal ~/Library/init/tcsh directory and immediately felt at home. Without a doubt, the old school UNIX curmudgeons will hate the built-in shortcuts, but I still must applaud the developers for making an attempt at providing a useful set of features for the “new” user. No one will ever agree on a standard set, but it’s good to see that the average Mac “What is this, some kind of DOS prompt?” user will have a very functional command line, should he/she choose to explore it. I must admit that some of these completions can be a little annoying though, while typing quickly.
When you drop to the shell, you’ll notice that you’re logged in with the “user name” you selected for yourself when you installed the OS. When you create a user during the installation process, you are informed that “you will be an administrator of this computer.” Yet, when in the shell, you take a look at /etc/passwd, you’ll see no entry for your username. Nonetheless, if you su to “root,” you’ll notice that root’s password is the same as the administrative user you created. Even stranger, although you are an “administrator,” as long as you’re logged in as that user, you still don’t have the permissions of “root.” What’s going on here? Well, it turns out that this functionality has been co-opted by Apple’s NeXT-inherited Net Info (which I will describe below).
I couldn’t resist running dmesg to see what would come up. To my surprise, the output was pretty boring. The most bizarre thing was that a packet filter was enabled, but with a default to open policy and no logging. An open firewall … why? If they weren’t planning to enable firewall rules, why compile packet filtering code into the kernel in the first place? At this point, I felt I had to do at least a little searching for some sign that this had been considered at one point. Well, /etc held no clues, and there was nothing obvious in /var (the only other probable location I could think of). I guess they simply wanted to leave the door conveniently ajar should they choose to go back and reconsider the decision.
When I visit a machine, I am always curious to check out /etc. This directory usually reveals some interesting information about the operating system and/or the administrator. In this case, while touring the usual suspects, I noticed something that, again, I did not expect. The wheel group listed in /etc/group did not contain any users (it seemed like some Communist Linux system!). You typically expect to find root along with at least one administrative user account in /etc/group. In this case, wheel was empty, leaving me to wonder why they even kept the concept, since this functionality had apparently been folded into an alternate privilege manager. As I found out, this functionality is also handled by NetInfo.
While checking out /etc/syslog.conf, I noted that quite a bit of system information gets routed to /dev/console, as one would expect. What was strange was that later while exploring /var/tmp (to look for tell-tale temp files), I found a file named console.log. It appeared to contain a file version of the most recent couple of console messages. I verified that identical (albeit fewer) entries appear when using the GUI-based console viewer. I’m no super OS guru … but this strikes me as a strange hack. Why not simply send the same information to a standard log file via syslog and have the GUI console app read from that? That’s what syslog’s there for! Maybe someone else out there can shed some light on this one.
Another oddity was /etc/resolv.conf. It was symlinked to /var/run/resolv.conf, which seemed a little strange. Even more so when /var/run/resolv.conf turned out to be non-existent. Okay … well, there was no named running (I checked) and the resolver man pages gave no clue. So what was going on here? Apparently something odd, since a quick nslookup responded with the DNS server listed as being the local machine. No named, no resolv.conf, how about /etc/hosts? Well, /etc/hosts had no special magic in it, but it did have a note mentioning that the file is only consulted while the machine is in single-user mode. At all other times, the request is handled by lookupd working through the facilities provided by NetInfo. Hmm … NetInfo was beginning to sound very interesting.
After a bit of roaming around, I became curious as to whether root would have a home directory on the machine. Given the difference in user and administrator handling on Mac OS X, I wasn’t even sure that root would have a home directory. But, lo and behold, there was ~root under /var (or more properly /private/var since it’s a symlink) with a set of default files and directories resembling any other user in /Users. None of this should have come as a surprise to me since /etc/passwd contained this information.
While exploring the system, you’ll find some interesting services enabled. I was surprised to see the nfs daemon running. Thus, it didn’t faze me when I found the portmap daemon (a service required in order to run nfs) hanging around. Finding nfs active was unexpected, since I would only run it if necessary, due to potential security concerns.
Another surprise was seeing a full-fledged NTP daemon running. It was cool to see this service as a standard part of Mac OS; but I thought it a bit strange though to do continuous high accuracy time synchronization via ntp for a desktop, consumer OS. Why not use ntp’s little brother, ntpdate, on a periodic basis for this same functionality? Do Mac OS users really need the accuracy of continuous ntp, when a functionally similar result could be obtained without the security risk of running another network daemon?
The answer is that, for now, “yes they do.” Since the introduction of Mac OS 9, Mac users have been given the default option of using NTP to synchronize their desktop clocks via NTP servers, and it appears that Apple wants to give Mac OS X users (presumably in a server setting) the option of running an NTP server for other Macs on a LAN/WAN.
Speaking of network services, a little netstat lovin’ showed a couple of other interesting tidbits. The machine was not as quiet network-wise as I had expected. Along with the nfs, portmap, and ntp network activity, I found listening sockets open on ports 752 and 755, with an active connection to port 752 from another local privileged port.
After some man page reading and poking at a few of the running daemons, I was able to narrow things down a little. I found that HUP-ing lookupd (an interface daemon to NetInfo) caused the active connection to be disconnected and reestablished (obvious since the new connection originated from a new port). I also found that HUP-ing nibindd (the NetInfo binder, a sort of librarian for NetInfo) caused the listening sockets to be closed and reappear on new ports. That struck me as quite odd. I would have expected them to re-bind to the same ports. Even with these addresses changing, lookupd somehow knew where to find the ports, as I saw new connections established shortly after the HUP signal was received.
Not knowing much about NetInfo, I was curious why this service was implemented using tcp sockets. I assumed that the service must be distributed, available to and from remote hosts. Otherwise, the developers probably would have implemented this using Unix domain sockets since they are substantially faster and are safer for local-only protocols. Not having much background on NetInfo at the time, I was somewhat puzzled.
Welding the Hood Shut
Apple’s longstanding (since Mac System 1.0 in 1984) policy has been to prevent users from screwing up their systems by hiding important items from them, or making it difficult to access the cool things that they might play with and hose their hard drive. This attitude has extended to OS X, and things like header files, gcc and gdb are not present (although these were included in Apple’s earlier “developers-only” previews of Mac OS X), not that the average Mac user would be able to “accidentally” damage their system with gcc.
Not to worry, though; the Mach / BSD portion of Mac OS X is maintained separately as an open-source operating system that Apple calls “Darwin.” In fact, a uname -a at the command line in MOSXPB reveals:
Darwin ibook 1.2 Darwin Kernel Version 1.2: Wed Aug 30 23:32:53 PDT 2000; root:xnu/xnu-103.obj~1/RELEASE_PPC Power Macintosh powerpc
You can get the abovementioned developer goodies (and much more) by downloading Darwin or following the CVS snapshots for various packages.
At the root of the filesystem, it’s not hard to see that most of what you would expect to find is there somewhere; it may just be in a different place than you expected. The first thing you’ll likely notice is that a lot of what’s there is being hidden from the user by the MacOS X GUI. The Mac OS has always had its share of hidden files (for volume settings, the desktop database, etc.) However, you’ll notice a file in / called “.hidden” which lists the items in / that the GUI hides. The contents of .hidden are:
bin (the Unix directory for binaries needed before /usr is mounted)
cores (a link to /private/cores; a directory – theoretically, a uniform location for placing Unix core dumps)
Desktop DB (the GUI desktop database for files, icons, etc.)
Desktop DF (don’t remember what this does)
Desktop Folder (for items that are shown on the desktop)
dev (the Unix devices directory)
etc (a link to /private/etc; contains normal Unix configuration files and other normal /etc stuff)
lib (listed, but not present in /)
lost+found (the Unix directory for “orphaned” files after an unclean system shutdown. Classic Mac OS users are used to looking in the Trash for temp files saved after a crash or other emergency shutdown)
mach (a link to mach.sym)
mach_kernel (the Mach kernel itself)
mach.sym (listed as a Mach-O executable for PowerPC, but I’m not sure exactly what it does. Any Darwin users out there with more knowledge should correct me.)
private (contains var, tmp, etc, cores and a Mac OS X directory called Drivers, whose relationship to /dev is unclear)
sbin (Unix system binaries traditionally needed before /usr mounts)
SystemFolderX (not present in /; may be a typo or used in the future?)
tmp (a link to /private/tmp; the Unix temporary files directory)
Trash (files selected in the GUI to be deleted)
usr (just about everything in BSD Unix these days 😉 )
var (Unix directory meant once upon a time for “variable” files – mail, FTP, PID files, and other goodies)
VM Storage (the classic MacOS virtual memory filesystem – usually equal to the size of physical memory + swap space)
A brief digression about .hidden: Editing this file and adding any directory or file name will cause the GUI to hide the item. For example, edit this file in the shell and add ‘Foo,’ create a directory in / with that name, log out and log back in, and it won’t be seen.
However, it isn’t as simple as it sounds. Strangely, there’s an item in / called “TheVolumeSettingsFolder” whose name isn’t in .hidden, but still doesn’t show up in the GUI. This indicates that there is more to what’s shown and hidden in the GUI than just the “.hidden” file. Also, adding a “.hidden” file to another directory than “/” does not appear to cause files of that name to be hidden in that directory. Furthermore, /.hidden does not prevent files with those names from appearing in lower directories, nor does it hide directories in lower directories when an absolute path is placed in .hidden. If anyone can clear this up for me, I’d love to know what’s at work here.
Getting back on track: You’ll notice that all of the traditional BSD file hierarchies are present, although the GUI hides them from the user so that they are unaware that these Unix directory structures exist. Furthermore, some of the directories you see are in fact soft links to unusual places (as mentioned, etc, tmp and var are all links to inside /private; I refuse to speculate why without having several drinks of neat Scotch first). Also, unlike previous incarnations of the Mac OS, the user is unable to rename the “System” directory from the GUI.
As a brief aside, it should be noted that Apple’s great struggle here (and the immensity of their effort should be appreciated) is to combine the classic Mac OS “I can move or rename damn near anything I want” ethos with Unix’s “it’s named that way for a reason” ethos. How Apple chooses to resolve this dilemma in the final release will speak volumes about their dilemma over (I’m ashamed to admit I’ve forgotten who put it this way, but it’s brilliant) an OS that “the user controls,” versus an OS that “allows you to use it.” And, let’s face it, Unix has always been the latter.
Also, logical or physical volumes are listed under “/” using their “name.” Rather than use a Unix filesystem hierarchy, DOS’s A: or C: drives or even Windows 9x’s “My Computer,” Mac users have always been able to name their hard drives or partitions arbitrarily. Each drive or partition thereof was then always mounted and visible on the desktop. If I have a drive in my computer which I’ve named “Jeff’s Drive,” you’ll see it from the shell as: /Jeff’s\ Drive, and all of its file and directory contents are viewable underneath it. Similarly, if a user installs MOSX PB on a drive with Mac OS 9 already installed, at installation time their old files and directory hierarchies are all moved to a directory called “Mac OS 9” in /.
** What is strange about the above?? It sounds very UNIXy. As an example, many people mount their floppy drives as ‘/floppy’, but nothing is preventing them from mounting the drives as ‘/Cool\ Ass \Plastic\ Coaster\ Partition’. **
NetInfo & Friends
Well, by the time I got this far, I realized that this article wouldn’t really be complete without some discussion of the mysterious NetInfo. I also knew that a little bit of research was in order. While searching, I learned that NetInfo is a distributed configuration database consisting of information that would normally be queried through a half-dozen separate sub-systems on a typical UNIX platform. For example, NetInfo encompasses user and group authentication and privilege information, name service information, and local and remote service information, to name just a few.
When the NetInfo system is running (i.e. when the system is not in single-user mode), it supercedes the information provided in the standard /etc configuration files, as well as being favored as an information source by system services, such as the resolver. The Apple engineers have accomplished this by hooking a check into each libc system data lookup function to see if NetInfo is running. If so, NetInfo is consulted, otherwise the standard files or services are used.
The genius of NetInfo is that it provides a uniform way of accessing and manipulating all system and network configuration information. A traditional UNIX program can call the standard libc system lookup functions and use NetInfo without knowing anything about it. On the other hand, MacOSX-centric programs may directly talk to NetInfo using a common access and update facility for all types of information. No longer does one have to worry about updating multiple configuration files in multiple formats, then restarting one or more system daemon or daemons as necessary.
The other benefit of the system is that it is designed to be network-aware from the ground up. If information cannot be found on the local system, NetInfo may query upward to a possibly more knowledgable information host.
NetInfo also knows how to forward requests to the apropriate traditional services if it does not have the requisite information. It can hook into dns, nis, and other well-known services, all without the knowledge of the application making the initial data request.
NetInfo is a complex beast, easily worth an article of its own. If you want more information, here are a few tips. I found that reading NetInfo man pages was frustrating. Most of the pages tended to heavily use NetInfo-related terms and concepts with little to no definition. Nevertheless, if interested, check out netinfo(5) (netinfo(3) is simply the API definition), netinfod(8), nibindd(8), and lookupd(8). However, the best information that I found was on Apple’s Tech Info Library at http://til.info.apple.com/techinfo.nsf/artnum/n60038?OpenDocument&macosxs.
Getting More Information
Finally, for a great resource on all things Darwin, don’t go to Apple’s website (publicsource.apple.com/projects/darwin/). Instead, go to www.darwinfo.org, and you’ll find lots of great stuff, including the excellent “Unofficial Darwin FAQ.”
If you don’t have access to MacOS X Public Beta but would like to read its man pages to get a better idea of how some of these commands are implemented, you can find a collection of MOSXPB/Darwin man pages online at www.osxfaq.com/man.
Jeff and Matt hope this little tour has been semi-informative and has raised the curiosity of the few brave souls who have made it to the end of this MacOS travelogue. Next time we will take a look at … and discuss …. See you next time.