Solaris zone processes

A recent quetion I was asked: When listing processes on a system using Solaris zones, is it possible to see the user names instead of the user IDs for processes running in the zone?

Short answer: Not directly. Indirectly, yes.

Solaris zones were introduced in Solaris 10. They allow for a form of virtualization that can be used to isolate specific processes within their own virtual machine for security or other reasons. The main zone is called the global zone. It has the ability to view all files and processes for all other zones. The non-global zones can only view their own files and processes (though some of the files may be shared with the global zone, depending on the configuration).

The non-global zones can contain their own list of users, separate from the global zone. When processes are listed in the global zone (using the ps command), any processes running in a non-global zone with a user specific to that zone will display the numeric user ID instead of the user name of the process owner. This is by design and makes sense, but what if you want to display the user name instead? There is no built-in way to do this.

My solution is to build a lookup table that maps user IDs in each zone to their related user names and then make substitutions in the output as needed. The following is a one-liner that can do this (from the global zone, as root):

zoneadm list -p | perl -F: -ane '$H{$F[1]}={map{/^([^:]+):[^:]*:([^:]+)/;((0+$2)=>$1)}`cat $F[3]/root/etc/passwd`}; END{print map{s/^(\s*)(\S+)(\s+)(\d+)/"$1$2$3".$H{$2}{(0+$4)}/e;$_}`ps -efZ`}'

If you aren't root, you likely won't have the permissions to view the files required to make the above command work. If that is the case, a root cron job that creates a world-readable data file on a regular basis in the global zone containing the mapping is one way to solve the issue. That file could then be used to translate as needed. The file needs to contain only three pieces of information: the zone name, the user ID, and the user name. Personally, I would make it a simple, delimited text file with one mapping per line, but I'm sure that there are many other ways to do it.

One note about my code above that is worth pointing out: In two places, I am saying (0+$SomeVariable). This is my way of ensuring that the value is numeric and that any leading zeros are stripped off. My experience has shown that the user IDs in the output of the ps -efZ command can contain leading zeros. If you don't handle them consistently, the mapping likely will not work as expected.