blog'o thnet

To content | To menu | To search

Monday 6 October 2008

Fake The hostid Of A Solaris Zone, Updated

As a little follow-up to Fake The hostid Of A Solaris Zone, and regarding the discussion on the capacity to change the hostid of a Solaris non-global zone, it is interesting to mention these (updated) informations:

  1. The LD_PRELOAD trick proposed before is not a proper option, and is really ugly (and intrusive if you didn't unset it before continuing the execution of a program).
  2. When using Solaris 8 or Solaris 9 Containers, there is a feature called Host ID Emulation from the zonecfg utility which can do exactly that.
  3. Before the introduction of the privileges in a non-global zone with Solaris 11/06 (a.k.a. Solaris Update 3), you must run the DTrace zhostid script (daemon) within the global zone. It is not mandatory to run it from the global zone anymore. Using the appropriate dtrace_user privilege only, you can run it directly from the non-global zone:
    # zonecfg -z ngzone set limitpriv=default,dtrace_user
    # zoneadm -z ngzone boot
    # zlogin ngzone
    [Connected to zone 'ngzone' pts/5]
    Last login: Sat Oct  4 18:57:17 on pts/5
    Sun Microsystems Inc.   SunOS 5.11      snv_99  November 2008
    # /sbin/zonename 
    ngzone
    # /usr/bin/hostid
    837d47dd
    # ./zhostid &
    [1] 21506
    # /usr/bin/hostid
    20a82f32
    # ^D
    [Connection to zone 'ngzone' pts/5 closed]
    

Tuesday 16 October 2007

Error While Patching A New Boot Environment

After creating a new boot environment (BE) named beastie, see below, to upgrade a system running Solaris 8 to Solaris 10 11/06 (as I do many times in the past without a hiccup), I encounter a problem when I tried to apply the appropriate Recommended cluster patch to the new BE with this message:

# luupgrade -t -n beastie -s /var/tmp/10_Recommended

Validating the contents of the media .
The media contains 76 software patches that can be added.
All 76 patches will be added because you did not specify any specific
patches to add.
Mounting the BE .
ERROR: The boot environment  supports non-global
zones.The current boot environment does not support non-global zones.
Releases prior to Solaris 10 cannot be used to maintain Solaris 10 and
later releases that include support for non-global zones. You may only
execute the specified operation on a system with Solaris 10 (or later)
installed.

I can't find any reference to a known bug or problem after looking for this against SunSolve, Sun Support, and Googling. Has anyone already seen this error, and solved it The Right Way? As for me, I needed to boot from the BE and apply the cluster patch: this was a pain since this bundle include the -36 kernel patch which is known to be relatively disruptive, since it need two reboot to apply the entire cluster patch (it contains a new version for the kernel).

Wednesday 12 September 2007

The BrandZ Framework Enhancements

Although not very versed in BrandZ technologies, I tried the lx brand in the past, with success. But the fact is, the just supported release of the lx brand in the Solaris 8/07 release will not really help us, since it can only provide a 2.4 Linux kernel working environment which is now a bit outdated (yes, I know the most recent Linux distributions will be supported via the Xen open-source hypervisor ). Interestingly, two recent news will certainly (hopefully?) change this in the future.

The first one is the availability of an experimental Linux 2.6 support in OpenSolaris. The work has been done by a summer intern (!) in the Solaris kernel group, Evan Hoke. What a hard work done in so little time, really impressive. I just hope that the community will follow and will enhance the proposed experimental branded zone extension.

The second news is really exciting too. This is the upcoming availability of a SPARC-only brand designed to emulate the Solaris 8 kernel. Although not yet ready for use, this news is really, really amazing since this enable a more soft-upgrade to Solaris 10 by enabling the use of all the great features provided to us with this version (DTrace, ZFS, FMA, SMF, etc.) on the global zone, while running a Solaris 8 branded zone... on top of the most recent hardware (say Sun Fire V215, T1000, T2000, etc.). Wow. I just can't wait to try this out, in particular since it will be available for the last supported Solaris 8/07 release.

Monday 26 February 2007

Zones plus Resource Management Features in SX

Containers (in fact Zones plus Resource Management features) is a wonderful technology, particularly in virtualized environments. But the fact is that it is not very usable--speaking of the use of RM feature in particular--since it exists many different RM technologies, not always well integrated with Zones capability.

This is why the upcoming work on memory sets and cpu caps are so interesting, and a more-than-welcome work in order to enhance and ease the use and deployment of Containers on powerful Solaris systems.

Enjoy reading Jerry Jelinek's blog entry about this work (already in SXCE build 56!).

Thursday 5 October 2006

Zones and ZFS Integration, and New Features in OpenSolaris

The aim of this little test case is to present new features of zones, and its tightly integration with the ZFS powerful file system. In order to do so, we will:

  1. Create a specific ZFS namespace for non-global zone(s).
  2. Create a new zone.
  3. Move it to a new zonepath.
  4. Configure it automatically, using a sysidcfg file.
  5. Clone it.
  6. Duplicate the first zone using the clone.

Be sure to have a valid hostname and IP address for the two non-global zones:

# getent hosts | egrep 'beastie|watchie'
192.168.1.1   beastie.thilelli.net beastie
192.168.1.2   watchie.thilelli.net watchie

Create a valid ZFS dedicated namespace:

# zfs create -o compression=on \
   -o mountpoint=/export/zone \
   -o canmount=off pool0/zone
# zfs list -r pool0/zone
NAME         USED  AVAIL  REFER  MOUNTPOINT
pool0/zone  24.5K   228G  24.5K  /export/zone
# zfs get compression,mountpoint,canmount pool0/zone
NAME        PROPERTY     VALUE         SOURCE
pool0/zone  compression  on            local
pool0/zone  mountpoint   /export/zone  local
pool0/zone  canmount     off           local
# zfs mount | grep zone
#

Note: Since build 48 of Nevada, some new ZFS features were added. Create time properties and canmount property are two of them. Please refer to this excellent blog entry from Eric Schrock's weblog for more information on these putbacks.

Configure the different zone's informations:

# zonecfg -z beastie 'create; set autoboot=true; \
   set zonepath=/export/zone/badbeastie; add net; \
   set address=192.168.1.1/24; set physical=nge0; \
   end; verify; commit; exit'
# zonecfg -z watchie 'create; set autoboot=true; \
   set zonepath=/export/zone/watchie; add net; \
   set address=192.168.1.2/24; set physical=nge0; \
   end; verify; commit; exit'
# zoneadm list -vc
  ID NAME             STATUS         PATH
   0 global           running        /
   - beastie          configured     /export/zone/badbeastie
   - watchie          configured     /export/zone/watchie

Then, fire the zoneadm command:

# zoneadm -z beastie install
A ZFS file system has been created for this zone.
Preparing to install zone <beastie>.
Creating list of files to copy from the global zone.
[...]

Instead of configure it manually at first boot, create a configuration file which will do this task automatically for you, and start the zone:

# cat << EOF > /export/zone/badbeastie/root/etc/sysidcfg
system_locale=C
timezone=Europe/Paris
terminal=vt100
security_policy=NONE
root_password=xxxxxxxxxxxxx
timeserver=localhost
name_service=NONE
nfs4_domain=dynamic
network_interface=primary {
  hostname=beastie.thilelli.net
  ip_address=192.168.1.1
  netmask=255.255.255.0
  protocol_ipv6=no
  default_route=192.168.1.254
}
EOF
#
# zoneadm -z beastie boot && zlogin -C beastie
[Connected to zone 'beastie' console]
SunOS Release 5.11 Version snv_48 64-bit
Copyright 1983-2006 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Hostname: beastie
Loading smf(5) service descriptions: 119/119
Oct  4 04:30:22 svc.startd[3003]: svc:/system/dbus:default:
 Method "/lib/svc/method/svc-dbus start" failed with exit status 95.
Oct  4 04:30:22 svc.startd[3003]: system/dbus:default failed fatally:
 transitioned to maintenance (see 'svcs -xv' for details)
Creating new rsa public/private host key pair
Creating new dsa public/private host key pair
rebooting system due to change(s) in /etc/default/init

[NOTICE: Zone rebooting]
SunOS Release 5.11 Version snv_48 64-bit
Copyright 1983-2006 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Hostname: beastie.thilelli.net
Oct  4 13:30:40 svc.startd[3757]: svc:/system/dbus:default:
 Method "/lib/svc/method/svc-dbus start" failed with exit status 95.
Oct  4 13:30:40 svc.startd[3757]: system/dbus:default failed fatally:
 transitioned to maintenance (see 'svcs -xv' for details)

beastie.thilelli.net console login: ~.
[Connection to zone 'beastie' console closed]

Well done. Now, change the zone path to something more appropriate. Eventually, adapt the ZFS name accordingly:

# zoneadm -z beastie halt
# zoneadm -z beastie move /export/zone/beastie
# zoneadm list -vc
  ID NAME             STATUS         PATH
   0 global           running        /
   - beastie          installed      /export/zone/beastie
   - watchie          configured     /export/zone/watchie
#
# zfs list -r pool0/zone
NAME                    USED  AVAIL  REFER  MOUNTPOINT
pool0/zone              248M   227G  24.5K  /export/zone
pool0/zone/badbeastie   248M   227G   248M  /export/zone/beastie
# zfs rename pool0/zone/badbeastie pool0/zone/beastie
# zfs list -r pool0/zone
NAME                 USED  AVAIL  REFER  MOUNTPOINT
pool0/zone           248M   227G  24.5K  /export/zone
pool0/zone/beastie   248M   227G   248M  /export/zone/beastie
#
# zoneadm -z beastie boot

Wow... Very interesting feature, isn't it?!

Now, lets try the cloning feature bundle with the new zoneadm command. Do some specific non-global zone tuning before; then do:

# zlogin beastie svcadm disable system/dbus
# zoneadm -z beastie halt
# zoneadm -z watchie clone beastie
Cloning snapshot pool0/zone/beastie@SUNWzone1
Instead of copying, a ZFS clone has been created for this zone.
# zoneadm list -vc
  ID NAME             STATUS         PATH
   0 global           running        /
   - beastie          installed      /export/zone/beastie
   - watchie          installed      /export/zone/watchie
#
# zfs list -r pool0/zone/beastie
NAME                           USED  AVAIL  REFER  MOUNTPOINT
pool0/zone/beastie             251M   227G   248M  /export/zone/beastie
pool0/zone/beastie@SUNWzone1  3.77M      -   248M  -
#
# sed -e 's/beastie/watchie/' \
   -e 's/ip_address=192.168.1.1/ip_address=192.168.1.2/'
   /export/zone/beastie/root/etc/sysidcfg > \
   /export/zone/watchie/root/etc/sysidcfg

You can now enjoy the first boot of the newly created zone:

# zoneadm -z watchie boot && zlogin -C watchie 
[Connected to zone 'watchie' console]
Hostname: watchie
Creating new rsa public/private host key pair
Creating new dsa public/private host key pair

watchie.thilelli.net console login: ~.
[Connection to zone 'watchie' console closed]

Awesome features and technologies i think! Really.

Last, note that Ben Rockwood already has a well written blog entry on this very same subject... he was the first to publish it though ;)

Note: It seems there is a little bug in the snv_48 SX:CR release which prevents the expected automatically ZFS file system creation or cloning from happening properly; the action fails with an error similar to this one:

cannot create ZFS dataset <zfs_name>: 'sharenfs' must be a string

This bug is already closed and fixed, and will be available in the next Solaris Express, see Bug ID: 6468554 for more information on this one.

Saturday 17 June 2006

Fake the hostid of a Solaris Zone

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!