Fake Hostid on Solaris Zones
The hostid in Solaris non-global zones is inherited from the global zones. There are some conditions (e.g. licensed software) where it is essential that the hostid stays the same when the zone is moved from one physical host to another. There are two possible solutions how to fix this problem and give a solaris non-global zone an individual hostid.
Solaris 8/9 Branded Zone
The hostid can be set in the zone configuration. See How to Configure a solaris9 Branded Zone.
zonecfg -z myzone add attr set name=hostid set type=string set value=8090a0b0 end
Solaris 10 Native Zone
The hostid can be faked with dtrace. The script below can be used as a startup service within a non-global Solaris zone. It is based upon Brendan Gregg's zhostid which is started in the global zone instead. It requires dtrace permissions in the zone configuration.
zonecfg -z myzone "set limitpriv=default,dtrace_proc,dtrace_user"
Script /etc/init.d/fake_hostid.
#!/usr/bin/ksh # # Fake hostid of a solaris 10 zone # -------------------------------- # Based upon http://www.brendangregg.com/DTrace/zhostid # Modified to run as a startup daemon within a non-global zone. Requires # zonecfg -z myzone "set limitpriv=default,dtrace_proc,dtrace_user" # in zone configuration. # Copy it to /etc/init.d/fake_hostid and make symlinks # from /etc/rc3.d before starting license server. FAKE_HOSTID='8090a0b0' zone=`zonename` if [[ $zone == 'global' ]]; then echo "Don't run this inside a global zone!" exit 1 fi function run_dtrace { hostid_hex=$1 if [[ "$hostid_hex" == *[g-zG-Z]* ]]; then echo "ERROR2: Invalid hostid $hostid_hex. " echo "Please use hexadecimal.\n" exit 2 fi if (( ${#hostid_hex} > 11)); then # see /usr/src/uts/common/conf/param.c for limit. echo "ERROR3: Length of hostid $hostid_hex too long. " echo "Limit 11 chars.\n" exit 3 fi if [[ ! -x /usr/sbin/dtrace ]]; then echo "ERROR4: /usr/sbin/dtrace missing." exit 4 fi ### Convert hostid to decimal typeset -i10 hostid_dec hostid_dec=16#$hostid_hex ### Run DTrace in background /usr/sbin/dtrace -n ' #pragma D option destructive #pragma D option quiet #pragma D option bufsize=32k inline string hostid = "'$hostid_dec'"; syscall::systeminfo:entry { self->command = arg0; self->buffer = arg1; } syscall::systeminfo:return /zonename == "'$zone'" && self->command == 7/ { copyoutstr("'$hostid_dec'", self->buffer, 11); } syscall::systeminfo:return { self->command = 0; self->buffer = 0; }' & } case "$1" in start) run_dtrace $FAKE_HOSTID ;; stop) pkill dtrace ;; *) echo "Usage: $0 {start|stop}" ;; esac
Usage:
[root@myzone /]$ hostid 11223344 [root@myzone /]$ /etc/init.d/fake_hostid start [root@myzone /]$ hostid 9090a0b0