Ucarp and Solaris Shared-IP Zones

By | February 17, 2010

I wanted to try Ucarp, the userland daemon to use the CARP protocol, to manage a virtual address for automatic failover between two MySQL hosts.

The only problem was, I wanted to do that with Solaris shared-IP zones. They don’t really have complete (promiscuous mode) access to their IP interfaces. The interfaces are rather virtual interfaces for the global zone which are forwarded to a particular zone. So that means, ucarp has to run on the global zone as well. But how would it know which zone/interface to manage?

So I modified the ucarp sources a bit to run a little /usr/sbin/zoneadm -z <zonename> list -p before sending the `I’m alive package’. Afterwards I was thinking about making this a bit more generic to simply allow the user to provide a special check-script to ucarp, which would influence the alive state. But that’s not done yet.

So ucarp would only send it’s broadcasts when the physical interface is up AND the zone in question is alive. The configuration of the additional virtual interface for the zone is easily done with the default arguments. Just add the <zonename> as an extra parameter for the up-/down- scripts.

The if-up.sh script I use:

#!/bin/bash
# <interface name> <virtual address> <optional extra parameter>

if [ $# -gt 2 ]
then
  z_zone="zone"
fi

interface=$1
vaddr=$2
shift 2

/usr/sbin/ifconfig $interface addif $vaddr netmask + broadcast + up

if [ ! -z "$z_zone" ]
then
  # we need the virtual interface!!
  vinterface=`/usr/sbin/ifconfig -a | \
    awk '$1 !~ /^(ether|inet|lo|zone)/ { interface=$1; } $1 == "inet" && $2 == "'$vaddr'" { print substr(interface, 0, length(interface) - 1); exit; }'`

  if [ ! -z "$vinterface" ]
  then
    fgrep -s ':' <<<$vinterface

    if [ $? -eq 0 ]
    then
      /usr/sbin/ifconfig $vinterface $z_zone "$@"
    fi
  fi
fi

And the if-down.sh as well;-)

#!/bin/bash
# <interface name> <virtual address> <optional extra parameter>

interface=$1
vaddr=$2
shift 2

# we need the virtual interface!!
vinterface=`/usr/sbin/ifconfig -a | awk '$1 !~ /^(ether|inet|lo|zone)/ { interface=$1; } $1 == "inet" && $2 == "'$vaddr'" { print substr(interface, 0, length(interface) - 1); exit; }'`

if [ ! -z "$vinterface" ]
then
  fgrep -s ':' <<<$vinterface
  if [ $? -eq 0 ]
  then
    /usr/sbin/ifconfig $vinterface down unplumb
  fi
fi

I played with that and it seems to work as expected. My little patch for the curious ones is hier;-)

Have fun;-)

— Marco

2 thoughts on “Ucarp and Solaris Shared-IP Zones

  1. FooFoo_2

    Hi Marco,

    thank you very much for this patch! That’s exactly what I was looking for. Just a small question about it: in my test infrastructure, I only have one server running multiple zones and I would like to test Ucarp with two zones running on this same host. So I tried to start two instances of Ucarp as follow (my host is 192.168.12.11, the virtual floating address is 192.168.12.10 and my zones are my-zone-1 and my-zone-2):

    ======================
    ./ucarp –nomcast –interface=nge0 –srcip=192.168.12.11 \
    –vhid=1 –pass=mypassword –addr=192.168.12.10 \
    –upscript=/etc/ucarp/vip-up.sh \
    –downscript=/etc/ucarp/vip-down.sh \
    –zone=my-zone-1 –xparam=my-zone-1

    ./ucarp –nomcast –interface=nge0 –srcip=192.168.12.11 \
    –vhid=1 –pass=mypassword –addr=192.168.12.10 \
    –upscript=/etc/ucarp/vip-up.sh \
    –downscript=/etc/ucarp/vip-down.sh \
    –zone=my-zone-2 –xparam=my-zone-2
    ======================

    … but unfortunately they don’t see each other’s advertisement. In your opinion, is that a limitation of the multicast/broadcast or would it be possible to handle this particular case with your patch?

    Thank you in advance for a short feedback and Best Regards,
    FooFoo_2

  2. mw46d Post author

    I don’t think two zones on the same host could be handled that way. the global zone would not know what to do because all packets would go out/come in through the same interface.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.