Fake the hostid of a Solaris Zone
By Julien Gabel on Saturday 17 June 2006, 20:16 - Solaris - Permalink
Using the zhostid script from Brendan Gregg
zhostid is a DTrace daemon to change the hostid to different
values for each zone. You can get
it right now and lots of other useful DTrace utilities from Brendan Gregg's
DTrace Tools dedicated web page.
Here are a little illustration of its usage:
# /usr/bin/hostid
837d47dd
#
# zlogin ngzone
[Connected to zone 'ngzone' pts/3]
Last login: Mon May 22 15:16:12 on pts/2
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
# /usr/bin/hostid
837d47dd
# exit
[Connection to zone 'ngzone' pts/3 closed]
#
# cd /tmp && chmod 740 zhostid
# grep ngzone zhostid /* Configure the desired hostid per zone. */
ngzone 20a82f32
# ./zhostid &
[1] 7330
# /usr/bin/hostid
837d47dd
#
# zlogin ngzone
[Connected to zone 'ngzone' pts/3]
Last login: Tue May 23 10:12:40 on pts/3
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
# /usr/bin/hostid
20a82f32
# exit
[Connection to zone 'ngzone' pts/3 closed]
#
# jobs
[1]+ Running ./zhostid &
# kill -TERM %1
[1]+ Killed ./zhostid
#
# zlogin ngzone
[Connected to zone 'ngzone' pts/3]
Last login: Tue May 23 10:13:07 on pts/3
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
# /usr/bin/hostid
837d47dd
# exit
[Connection to zone 'ngzone' pts/3 closed]
Using the dynamic library interposition
To use library interposition, you need to create a special shared library and set the ${LD_PRELOAD} environment variable. When ${LD_PRELOAD} is set, the dynamic linker will use the specified library before any other when it searches for shared libraries. The ${LD_PRELOAD} variable allows you to interpose any calls (including system calls) resolved through shared objects without replacing the dynamic libraries. The symbols can be redefined to collect the calling and the timing data for the function calls without recompiling or relinking the application. This can be particularly useful when all the code necessary for relinking is not available.
For the purpose of this post, we will use the gcc (and
libgcc) GNU compiler environment tools. Let's go:
# /usr/bin/hostid
835768ed
#
# PATH=/usr/sfw/bin:${PATH}
# LD_LIBRARY_PATH=/usr/sfw/lib:${LD_LIBRARY_PATH}
# export PATH LD_LIBRARY_PATH
# cd /tmp
# cat << EOF > newhostid.c
long gethostid(void) {
return 0xabcdef;
}
EOF
# gcc -fPIC -c newhostid.c
# gcc -shared -o newhostid.so newhostid.o
#
# LD_PRELOAD=/tmp/newhostid.so /* Now, let's instrument the dynamic loader to
use our freshly build object library. */
# export LD_PRELOAD
#
# /usr/bin/hostid
00abcdef
Enjoy!

Comments
hello,
i'm trying the second solution, it works for hostid, but fails with other commands:
reglisse-root% ptree 11984
ld.so.1: ptree: fatal: /tmp/newhostid.so: wrong ELF class: ELFCLASS32
Killed
reglisse-root% ldd /usr/bin/ptree
/tmp/newhostid.so
libc.so.1 => /lib/libc.so.1
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libm.so.2 => /lib/libm.so.2
/platform/SUNW,Sun-Fire-T200/lib/libc_psr.so.1
any idea?
thanks,
Well, this solution is not the proper, and with recent Solaris releases you can do the same thing as with the
zhostid, but directly from the non-global zone.Using the
LD_PRELOADtrick, didn't forget to unset the variable just after executing thehostidcommand.