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