PROBLEM: A machine's hostid is a number that is supposed to uniquely identify the machine. For the Solaris OS, hostids are 32-bit integers. Solaris 10, Solaris Nevada, and OpenSolaris currently store a single hostid in kernel memory as a decimal string named hw_serial. The hostid is shared among the global zone (GZ) and all non-global zones (NGZs) of the host machine. In other words, users that execute the hostid(1) command and processes that query the machine's hostid via sysinfo(2) from within an NGZ will receive the hostid of the host machine. There are two problems with the status quo: (1) Using zones to consolidate systems that have applications that rely on hostids to enforce licensing restrictions is problematic Any application that relies on hostids to enforce licensing restrictions cannot be run within zones when the hostids of the zones' host systems differ from that of the system for which the application was licensed. Customers can contact the application's licensors to relicense the application, but this is not always possible (e.g., the licensor no longer exists). Customers with such applications might be reluctant to use zones to consolidate systems because doing so would most likely incapacitate their applications. (2) If a zone that has licensed software that uses hostids to enforce licensing restrictions is migrated to another machine (e.g., via zone detach/attach), then if the new machine's hostid differs from that of the zone's originating machine, then the licensed software will be incapacitated. Several customers have requested that individual NGZs be allowed to emulate hostids to solve the above two problems (see [1] for a partial list of these customers). I propose to meet these customers' requests by adding a new zonecfg(1M) zone property, hostid, that users can set to makes NGZs emulate hostids. In other words, each NGZ could have its own hostid. Such an enhancement will resolve the above issues, provide a more complete virtualization solution to customers, and "ease adoption of the zones feature." [1] Hostid emulation is already implemented in Solaris 10 for Solaris 8 and Solaris 9 Containers. My solution will add hostid emulation to native- and sn1- branded zones in Solaris Nevada and provide a new framework for hostid emulation in Solaris 8 and Solaris 9 Containers in Solaris 10. The Solaris 8 and 9 brands will support both the already-existing "add attr hostid" interface and the new hostid property interface in zonecfg(1M). IMPORTED INTERFACES: GLOBAL VARIABLES: hw_serial Contract Private EXPORTED INTERFACES: FUNCTIONS: zone_get_hostid Consolidation Private Declared in usr/src/uts/common/sys/zone.h Defined in usr/src/uts/common/os/zone.c CONSTANTS: HW_INVALID_HOSTID Consolidation Private Defined in usr/src/uts/common/sys/systeminfo.h HW_HOSTID_LEN Consolidation Private Defined in usr/src/uts/common/sys/systeminfo.h ZONECFG(1M) ATTRIBUTES: hostid Committed TECHNICAL DESCRIPTION: There are currently at least two methods of emulating hostids within zones: (1) Run a destructive DTrace script that intercepts sysinfo(SI_HW_SERIAL) calls and returns a custom hostid for each zone. [1] [2] (2) Use LD_PRELOAD to intercept sysinfo(2) and return custom hostids. [1] It would be preferable to standardize zone hostid emulation and integrate it into kernel structures and already-existing zone tools (zonecfg(1M) and zoneadmd(1M)) so that customers would not have to rely on less efficient and more ad-hoc methods. My solution for NGZ hostid emulation is to add a 32-bit integral field to the zone structure zone_t that will contain the zone's hostid or HW_INVALID_HOSTID (-1) if the zone does not emulate a hostid. The GZ's hostid will be the host machine's hostid, which will be stored in hw_serial. NGZs will not emulate hostids by default. The new interface function zone_get_hostid() will have the following C prototype: uint32_t zone_get_hostid(zone_t *) zone_get_hostid() will return the hostid of the specified zone or the machine's hostid if the specified zone is NULL or if the zone does not emulate a hostid. If sysinfo(2) is used to query the machine's hostid, then sysinfo(2) will yield the caller's zone's hostid if the zone emulates a hostid. Otherwise, sysinfo(2) will yield the host machine's hostid. HW_HOSTID_LEN is the minimum string size needed to hold a hostid returned by sysinfo(2). Users will be able to configure a zone's hostid via the zonecfg(1M) tool. A zone's configured hostid will be stored in the zone's XML configuration file as the root property 'hostid'. zonecfg(1M) will only accept hexadecimal hostid strings of no more than eight digits. The hostid strings can be optionally prefixed with '0x' or '0X' and can contain uppercase or lowercase hexadecimal digits. Setting a zone's hostid to 0xFFFFFFFF, the value of HW_INVALID_HOSTID, results in an error. Changing a zone's hostid configuration with zonecfg(1M) will not update the hostid of a running instance of that zone. Users will not be able to modify the hostid of the GZ (i.e., the machine's hostid) with zonecfg(1M). A zone's zone_hostid field is set by zoneadmd(1M) when the zone is readied. zoneadmd(1M) will examine the hostid property stored in the configuration file of a zone that is transitioning to the ready state and fail to ready the zone if the hostid is invalid. (Validity is established according to the criteria set forth in the previous paragraph.) Thus readying, booting, or rebooting a zone with an invalid hostid in its configuration file will fail. Both native- and sn1-branded zones will be capable of emulating hostids. However, lx-branded zones will forbid hostid emulation because supported Linux distributions (e.g., CentOS) retrieve hostids from /etc/hostid rather than kernel memory (as in Solaris OS). Zone administrators desiring to change an lx-branded zone's hostid can modify the zone's /etc/hostid file. Solaris 10 users will be able to configure a Solaris 8 or 9 container's hostid through the already-existing "add attr hostid" interface and new hostid property interface in zonecfg(1M). RELATED BUGIDS: 6580939 RFE: provide unique hostid for each non-global zone 4160584 Support use of something other than hostid to lock software to 4762207 Fix the hostid generation in x86 RELATED ARC CASES: PSARC/2007/078: Hostid for x86 systems PSARC/2005/471: BrandZ: Support for non-native zones PSARC/2002/174: Virtualization and Namespace Isolation in Solaris REFERENCE DOCUMENTS: [1] 6580939 RFE: provide unique hostid for each non-global zone (http://monaco.sfbay.sun.com/detail.jsf?cr=6580939) [2] Ramblings from Richard's Ranch: spoofing hostids (http://blogs.sun.com/relling/entry/spoofing_hostids) PSARC/2007/078: Hostid for x86 systems (http://sac.sfbay/PSARC/2007/078/mail) Frank Hofmann's Weblog: The dark side of the source - hostids (http://blogs.sun.com/ambiguous/entry/introducing_myself) MODIFIED MAN PAGES: System Administration Commands sysdef(1M) NAME sysdef - output system definition SYNOPSIS /usr/sbin/sysdef [-i] [-n namelist] /usr/sbin/sysdef [-h] [-d] [-i] [-D] DESCRIPTION The sysdef utility outputs the current system definition in tabular form. It lists all hardware devices, as well as pseudo devices, system devices, loadable modules, and the values of selected kernel tunable parameters. It generates the output by analyzing the named bootable operating system file (namelist) and extracting the confi- guration information from it. The default system namelist is /dev/kmem. OPTIONS -i Prints the configuration information from /dev/kmem. This is the default and only needs to be specified if the configuration informa- tion from both /dev/kmem and the system file specified with the "-n namelist" option is needed. -nnamelist Specifies a namelist other than the default (/dev/kmem). The namelist specified must be a valid bootable operating system. -h Prints the identifier of the current host in --> hexadecimal. If sysdef -h is executed within --> a non-global zone and the zone emulates a host --> identifier, then the zone's host identifier is --> printed. This numeric value is not guaranteed to be unique. -d The output includes the configuration of sys- tem peripherals formatted as a device tree. [...] ____________________________________________________________ | ATTRIBUTE TYPE | ATTRIBUTE VALUE | |_____________________________|_____________________________| | Availability | SUNWcsu | |_____________________________|_____________________________| SEE ALSO --> hostid(1), zones(5), prtconf(1M), nlist(3ELF), attributes(5) SunOS 5.11 Last change: 1 Jun 2007 3 User Commands hostid(1) NAME hostid - print the numeric identifier of the current host SYNOPSIS /usr/bin/hostid DESCRIPTION The hostid command prints the identifier of the current host --> in hexadecimal. If it is executed within a non-global zone --> that emulates a host identifier, then the emulated host --> identifier is printed. This numeric value is likely to differ when hostid is run on a different machine. ATTRIBUTES See attributes(5) for descriptions of the following attri- butes: ____________________________________________________________ | ATTRIBUTE TYPE ATTRIBUTE VALUE | | Availability SUNWcsu | |___________________________________________________________| SEE ALSO --> sysinfo(2), gethostid(3C), zones(5), attributes(5) SunOS 5.11 Last change: 14 Sep 1992 1 Standard C Library Functions gethostid(3C) NAME gethostid - get an identifier for the current host SYNOPSIS #include long gethostid(void); DESCRIPTION The gethostid() function returns the 32-bit identifier for the current host. If the hardware capability exists, this identifier is taken from platform-dependent stable storage; otherwise it is a randomly generated number. It is not guaranteed to be unique. --> --> If the calling thread's process is executing within a non- --> global zone that emulates a host identifier, then the --> zone's emulated 32-bit host identifier is returned. ATTRIBUTES See attributes(5) for descriptions of the following attri- butes: ____________________________________________________________ | ATTRIBUTE TYPE | ATTRIBUTE VALUE | |_____________________________|_____________________________| | Interface Stability | Standard | |_____________________________|_____________________________| | MT-Level | MT-Safe | |_____________________________|_____________________________| SEE ALSO --> hostid(1), sysinfo(2), zones(5), attributes(5), standards(5) SunOS 5.11 Last change: 21 May 2007 1 System Calls sysinfo(2) NAME sysinfo - get and set system information strings SYNOPSIS #include int sysinfo(int command, char *buf, long count); DESCRIPTION The sysinfo() function copies information relating to the operating system on which the process is executing into the buffer pointed to by buf. It can also set certain informa- tion where appropriate commands are available. The count parameter indicates the size of the buffer. The POSIX P1003.1 interface (see standards(5)) sysconf(3C) provides a similar class of configuration information, but returns an integer rather than a string. The values for command are as follows: SI_SYSNAME Copy into the array pointed to by buf the string that would be returned by uname(2) in the sysnamefield. This is the name of the implementation of the operating sys- tem, for example, SunOS or UTS. [...] SI_HW_PROVIDER Copies the name of the hardware manufacturer into the array pointed to by buf. SI_HW_SERIAL Copy into the array pointed to by buf a string which is the ASCII representation of the hardware-specific serial number of the physical machine on which the function is executed. This might be implemented in Read-Only Memory, using software constants set when building the operating system, or by other means, and might contain non-numeric --> characters. If the function is executed within a non- --> global zone that emulates a host identifier, then the --> ASCII representation of the zone's host identifier is --> copied into the array pointed to by buf. It is anticipated that manufacturers will not issue the same "serial number" to more than one physical machine. The pair of strings returned by SI_HW_PROVIDER and SI_HW_SERIAL is not guaranteed to be unique across all vendor's SVR4 implementations and could change over the lifetime of a given system. SI_SRPC_DOMAIN Copies the Secure Remote Procedure Call domain name into the array pointed to by buf. [...] A good estimation for count is 257, which is likely to cover all strings returned by this interface in typical installa- tions. SEE ALSO boot(1M), dhcpagent(1M), getisax(2), uname(2), gethostid(3C), gethostname(3C), sysconf(3C), isalist(5), --> zones(5), privileges(5), standards(5) SunOS 5.11 Last change: 15 Apr 2008 5 Standards, Environments, and Macros zones(5) NAME zones - Solaris application containers DESCRIPTION The zones facility in Solaris provides an isolated environ- ment for running applications. Processes running in a zone are prevented from monitoring or interfering with other activity in the system. Access to other processes, network interfaces, file systems, devices, and inter-process commun- ication facilities are restricted to prevent interaction between processes in different zones. [...] Networking A zone has its own port number space for TCP, UDP, and SCTP applications and typically one or more separate IP addresses (but some configurations of Trusted Extensions share IP address(es) between zones). For the IP layer (IP routing, ARP, IPsec, IP Filter, and so on) a zone can either share the configuration and state with the global zone (a shared-IP zone), or have its distinct IP layer configuration and state (an exclusive-IP zone). If a zone is to be connected to the same datalink, that is, be on the same IP subnet or subnets as the global zone, then it is appropriate for the zone to use the shared IP instance. If a zone needs to be isolated at the IP layer on the net- work, for instance being connected to different VLANs or different LANs than the global zone and other non-global zones, then for isolation reasons the zone should have its exclusive IP. A shared-IP zone is prevented from doing certain things towards the network (such as changing its IP address or sending spoofed IP or Ethernet packets), but an exclusive-IP zone has more or less the same capabilities towards the net- work as a separate host that is connected to the same net- work interface. In particular, the superuser in such a zone can change its IP address and spoof ARP packets. The shared-IP zones are assigned one or more network inter- face names and IP addresses in zonecfg(1M). The network interface name(s) must also be configured in the global zone. The exclusive-IP zones are assigned one or more network interface names in zonecfg(1M). The network interface names must be exclusively assigned to that zone, that is, it (or they) can not be assigned to some other running zone, nor can they be used by the global zone. SunOS 5.11 Last change: 23 Jan 2007 4 Standards, Environments, and Macros zones(5) The full IP-level functionality in the form of DHCP client, IPsec and IP Filter, is available in exclusive-IP zones and not in shared-IP zones. --> ->Host Identifiers --> A zone is capable of emulating a 32-bit host identifier, --> which can be configured via zonecfg(1M), for the purpose --> of system consolidation. If a zone emulates a host --> identifier, then commands such as hostid(1) and sysdef(1M) --> as well as C interfaces such as sysinfo(2) and gethostid(3C) --> that are executed within the context of the zone will --> display or return the zone's emulated host identifier rather --> than the host machine's identifier. ATTRIBUTES See attributes(5) for descriptions of the following attri- butes: ____________________________________________________________ | ATTRIBUTE TYPE | ATTRIBUTE VALUE | |_____________________________|_____________________________| | Availability | SUNWcsu | |_____________________________|_____________________________| SEE ALSO zlogin(1), zonename(1), in.rlogind(1M), sshd(1M), zoneadm(1M), zonecfg(1M), getzoneid(3C), kill(2), priocntl(2), ucred_get(3C), proc(4), attributes(5), brands(5), privileges(5), crgetzoneid(9F) SunOS 5.11 Last change: 23 Jan 2007 5 System Administration Commands zonecfg(1M) NAME zonecfg - set up zone configuration SYNOPSIS zonecfg -z zonename zonecfg -z zonename subcommand zonecfg -z zonename -f command_file zonecfg help DESCRIPTION The zonecfg utility creates and modifies the configuration of a zone. Zone configuration consists of a number of resources and properties. [...] Properties Each resource type has one or more properties. There are also some global properties, that is, properties of the con- figuration as a whole, rather than of some particular resource. The following properties are supported: (global) zonename (global) zonepath (global) autoboot (global) bootargs (global) pool (global) limitpriv (global) brand (global) cpu-shares --> (global) --> --> hostid SunOS 5.11 Last change: 2 Apr 2008 3 [...] The following table summarizes resources, property-names, and types: resource property-name type (global) zonename simple (global) zonepath simple (global) autoboot simple (global) bootargs simple (global) pool simple (global) limitpriv simple (global) brand simple (global) ip-type simple --> (global) hostid simple (global) cpu-shares simple (global) max-lwps simple (global) max-msg-ids simple (global) max-sem-ids simple (global) max-shm-ids simple (global) max-shm-memory simple (global) scheduling-class simple fs dir simple special simple raw simple type simple options list of simple inherit-pkg-dir dir simple net address simple physical simple device match simple rctl name simple value list of complex attr name simple type simple value simple dataset name simple dedicated-cpu ncpus simple or range importance simple SunOS 5.11 Last change: 2 Apr 2008 11 [...] global: brand The zone's brand type. A zone that is not assigned a brand is considered a "native" zone. global: ip-type A zone can either share the IP instance with the global zone, which is the default, or have its own exclusive instance of IP. This property takes the values shared and exclusive. --> --> --> global: hostid --> --> A zone can emulate a 32-bit host identifier to ease --> system consolidation. A zone's hostid property is empty --> by default, meaning that the zone does not emulate a --> host identifier. Zone host identifiers must be --> hexadecimal values between 0 and FFFFFFFE. A '0x' or --> '0X' prefix is optional. Both uppercase and lowercase --> hexadecimal digits are acceptable. fs: dir, special, raw, type, options Values needed to determine how, where, and so forth to mount file systems. See mount(1M), mount(2), fsck(1M), and vfstab(4). SunOS 5.11 Last change: 2 Apr 2008 7