# rm-rf.es | Administración de sistemas

Bitácora personal de un SysAdmin Gnu/Linux, Windows, BSD...

DB_File.xs:101: db.h: No such file or directory


La situación es la siguiente. Estamos compilando en Solaris 10 el módulo de Perl DB_File. El requerimiento lógico es tener instalado BerkeleyDB en el servidor así que procedemos a ello:

# pkgadd -d db-4.7.25.NC-sol10-x86-local

Ahora procedemos a la típica compilación (Elegir el compilador correcto para Perl en Solaris) y nos encontramos con uno de estos dos errores:

  cc -c -I/usr/local/include -Dbool=char -DHAS_BOOL
  -O2    -DVERSION=\"1.64\" -DXS_VERSION=\"1.64\" -fpic
  -I/usr/local/lib/perl5/i586-linux/5.00404/CORE -DmDB_Prefix_t=size_t
  -DmDB_Hash_t=u_int32_t DB_File.c
  DB_File.xs:101: db.h: No such file or directory
  LD_RUN_PATH="/lib" cc -o blib/arch/auto/DB_File/DB_File.so  -shared
  -L/usr/local/lib DB_File.o    -L/usr/local/lib -ldb
  ld: cannot open -ldb: No such file or directory

Es raro porque el fichero db.h se encuentra en la ruta de instalación de DB. El problema es que el fichero de configuración para la compilación del módulo presupone una ruta estándar que en este caso no se cumple. Así que modificamos dicho fichero de esta forma:

Antes (config.in):

	INCLUDE = /usr/local/BerkeleyDB/include
	LIB     = /usr/local/BerkeleyDB/lib

Por la ruta donde se encuentre, en mi caso /usr/local/BerkeleyDB.4.7/include/db.h:

	INCLUDE = /usr/local/BerkeleyDB.4.7/include
	LIB     = /usr/local/BerkeleyDB.4.7/lib

Y a compilar.

Elegir el compilador correcto para Perl en Solaris


Cuando compilamos módulos de Perl en Solaris (en este caso Solaris 10) hay que tener muy claro el compilador a utilizar. En esta versión de Solaris tenemos por defecto la versión 5.8.4 de Perl, la cual ha sido compilada con la suite de compilación de Sun Studio. La forma habitual de compilar módulos es la siguiente:

# perl Makefile.PL
# make
# make test
# make install

Si lo hacemos así, el sistema utilizará el compilador Sun Studio y habrá flags incompatibles, errores de compilación, etc. Lo que tenemos que hacer es forzar la utilización del compilador GNU C/C++, que por defecto lo encontraremos en /usr/sfw/bin como nos indica el Solaris Install CookBook.

Lo primero que tenemos que hacer es añadir esta ruta al PATH ya que por defecto no está:

export PATH=$PATH:/usr/sfw/bin

Para la ejecución del Makefile.PL utilizaremos perlgcc en lugar de perl a secas, está en la ruta “/usr/perl5/bin/perlgcc“. Para los make forzaremos la utilización de gmake en la ruta anteriormente citada. La lista de comandos sería la siguiente:

# /usr/perl5/bin/perlgcc Makefile.PL
# /usr/sfw/bin/gmake MAKE=/usr/sfw/bin/gmake
# /usr/sfw/bin/gmake MAKE=/usr/sfw/bin/gmake test
# /usr/sfw/bin/gmake MAKE=/usr/sfw/bin/gmake install

Solaris Zones ERROR: the zonepath must be a ZFS dataset


A la hora de crear una zona en Solaris (Solaris Zones|Solaris Containers), es imprescindible que el zonepath, que es el lugar físico en el que se va a alojar sea un sistema de ficheros zfs independiente, también llamado ZFS dataset. En caso contrario recibiremos este error a la hora de instalarla:

ERROR: No zonepath dataset; the zonepath must be a ZFS dataset.

El error es lo suficientemente descriptivo. A la hora de configurar la zona, establecemos el zonepath del siguiente modo dentro del modo de configuración de la zona:

# zonecfg -z zona01
zonecfg:zona01> set zonepath=/ruta/a/la/zona

El paso previo es entonces crear el dataset correspondiente:

# zfs create /rpool/zones
# zfs create /rpool/zones/zona01

Una vez realizado, podemos establecer como zonepath “/rpool/zones/zona01″, verificar la configuración con “verify”, hacer el “commit” e instalar la zona:

# zoneadm -z zona01 install

Introducción a SMF (Service Management Facility) en Solaris


SolarisHace unos días comentaba el paso de System V a Upstart en RHEL y Centos 6. Hoy vamos a hablar sobre Solaris y el cambio introducido a partir de Solaris 9 para la gestión de servicios.

Antes de Solaris 9 los servicios se gestionaban como en la mayoría de sistemas Unix y Linux (legacy), teníamos scripts de arranque en /etc/init.d y se creaban enlaces simbólicos contra ellos en los distintos runlevels (directorios RC) para su arranque/parada. A partir de Solaris 9 se introdujo SMF (Service Management Facility) y se ha convertido en la manera por defecto de gestionar los servicios en Solaris 10.

Los beneficios de SMF sobre el método anterior son sustanciales. Entre ellos la posibilidad de mantener monitorizados los servicios para que en el momento que se produzca una caída levanten de forma instantánea, la gestión inteligente de arranque mediante la cual el servicio tiene unas dependencias y hasta que no estén activas el servicio no está disponible, el arranque en paralelo y de forma asíncrona, etc.

Los comandos básicos para gestion de servicios en SMF son svcs, svccfg y svcadm. Mediante svcs a secas podemos ver el estado de los servicios del sistema (incluidos los del sistema antiguo legacy), a través de distintos parámetros podemos filtrar únicamente los deshabilitados, etc:

# svcs
STATE          STIME    FMRI
legacy_run      9:04:48 lrc:/etc/rc2_d/S20sysetup
legacy_run      9:04:48 lrc:/etc/rc2_d/S47pppd
legacy_run      9:04:49 lrc:/etc/rc2_d/S72autoinstall
legacy_run      9:04:49 lrc:/etc/rc2_d/S73cachefs_daemon
legacy_run      9:04:49 lrc:/etc/rc2_d/S81dodatadm_udaplt
legacy_run      9:04:49 lrc:/etc/rc2_d/S89PRESERVE
disabled        9:02:34 svc:/platform/i86pc/acpihpd:default
online          9:01:28 svc:/system/svc/restarter:default
online          9:01:35 svc:/system/early-manifest-import:default
online          9:01:38 svc:/network/netcfg:default
online          9:01:39 svc:/network/datalink-management:default
online          9:01:39 svc:/network/socket-config:default
...
...

Básicamente vemos el estado del proceso, la última vez que el servicio cambió de estado y su FMRI (Fault Management Resource Identifier). El FMRI es el identificador del servicio. El FMRI se divide en tres partes separadas por “:”. La primera el esquema (svc o lrc según el tipo de servicio), la categoría en la que se encuentra (network, system…) y el nombre del servicio, y finalmente la instancia.

Podemos ver también con detalle el estado de un único servicio con el parámetro “-x” y sus dependencias con “-d”:

# svcs -x  svc:/system/cron:default
svc:/system/cron:default (clock daemon (cron))
 State: online since  1 de noviembre de 2011 09:02:51 WET
   See: cron(1M)
   See: crontab(1)
   See: /var/svc/log/system-cron:default.log
Impact: None.
# svcs -d svc:/system/cron:default
STATE          STIME    FMRI
online          9:02:35 svc:/milestone/name-services:default
online          9:02:49 svc:/system/filesystem/local:default

Podemos verificar rápidamente cómo SMF monitoriza activamente los servicios que están bajo su control, vamos a ver el estado del servicio cron, matarlo con una señal kill y verificar que al momento SMF lo ha levantado de nuevo:

# date
martes  1 de noviembre de 2011 09:46:24 WET
# svcs -v system/cron
STATE          NSTATE        STIME    CTID   FMRI
online         -              9:02:51     62 svc:/system/cron:default
# ps -ef | grep cron
    root   441     1   0 09:02:51 ?           0:00 /usr/sbin/cron
    root   841   687   0 09:46:33 pts/1       0:00 grep cron
# kill 441
# svcs -v system/cron
STATE          NSTATE        STIME    CTID   FMRI
online         -              9:46:38     96 svc:/system/cron:default

A través de svcs también podemos ver el estado de un servicio y diagnosticarlo cuando no es satisfactorio. Encontraremos los siguientes estados: online, offline, disabled, degraded, maintenance y legacy-run. Los cuatro primeros estados están claros, online, offline, deshabilitado y degradado. Cuando un servicio está en estado maintenance es debido a que hay algún problema con el servicio y no puede ser arrancado. Como requiere nuestra intervención se pone a nuestra disposición la ruta hacia el log del servicio para verificar el origen del problema. El estado legacy-run simplemente indica que se trata de un servicio legacy.

Mediante svcadm podemos gestionar el estado de cada uno de los servicios, con los parámetros “enable”, “disable”, “refresh”, “clear”, “mark” y “restart”. Aparte de los obvios, conviene comentar que “refresh” sirve para leer de nuevo los ficheros de configuración del servicio por si se ha realizado algún cambio, “clear” sirve para resetear el servicio si se encuentra en estado de mantenimiento y “mark” para marcar un servicio como degradado, mantenimiento, etc.

Para que veáis un ejemplo de fichero xml básico para un servicio aquí tenéis uno para la gestión de Oracle iPlanet webserver 7 que instalamos hace unos días. Básicamente hemos establecido como dependencias los servicios de red, los sistemas de ficheros locales y el arranque bajo el milestone multi-user (lo que viene siendo el runlevel 3 en legacy). Después establecemos los tres comandos para el arranque, parada y reinicio del servicio:

<?xml version='1.0'?>

<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>

<service_bundle type='manifest' name='webserver7'>

<service name='network/webserver7' type='service' version='0'>
<create_default_instance enabled='true'/>
<single_instance/>
<dependency name='fs' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/system/filesystem/local'/>
</dependency>
<dependency name='net' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/network/physical'/>
</dependency>
<dependent name='webserver7_multi-user' restart_on='none' grouping='optional_all'>
<service_fmri value='svc:/milestone/multi-user'/>
</dependent>
<exec_method name='start' type='method' exec='su www -c "/opt/webserver7/bin/webserver7 start"' timeout_seconds='60'>
<method_context/>
</exec_method>
<exec_method name='stop' type='method' exec='su www -c "/opt/webserver7/bin/webserver7 stop"' timeout_seconds='60'>
<method_context/>
</exec_method>
<exec_method name='restart' type='method' exec='su www -c "/opt/webserver7/bin/webserver7 restart"' timeout_seconds='60'>
<method_context/>
</exec_method>
</service>

</service_bundle>

Para importar un servicio creado de este modo ejecutamos el siguiente comando:

# svccfg import webserver7.xml

Como siempre os recomiendo revisar las páginas man de todos estos comandos para recibir información detallada sobre cada uno de ellos, esto es una pequeña introducción que podría extenderse mucho más si entráramos en detalle de cada una de las características y posibilidades de SMF. Ahí van unas cuantas referencias para aprender más sobre Service Management Facility:

Stub Start Error en Oracle iPlanet Web Server: PHP + FastCGI


En el artículo anterior veíamos cómo activar PHP en Oracle iPlanet Web Server bajo Solaris. Una vez activado a la hora de verificar el funcionamiento de un script PHP podéis encontrar lo siguiente al acceder vía URL:

Stub Start Error
This server has encountered an internal error which prevents it from fulfilling your request. The most likely cause is a misconfiguration. Please ask the administrator to look for messages in the server’s error log.

Y al revisar los logs de error de la instancia vemos lo siguiente:

[12/Oct/2011:10:13:28] failure ( 1023): for host 192.168.1.128 trying to GET /test.php, responder-fastcgi reports: FCGI1058: Process creation failure
[12/Oct/2011:10:13:43] failure ( 1023): for host 192.168.1.128 trying to GET /test.php, responder-fastcgi reports: FCGI1058: Process creation failure

El servidor web no es capaz de lanzar los procesos fastcgi de php, esto lo podemos ver porque ni siquiera se crea el log de fastcgi (Fastcgistub.log). Según he visto en este post de un foro es un problema común en máquinas con poca memoria swap configurada. En mi caso estaba claro porque esta prueba estaba siendo realizada sobre una pequeña máquina virtual. La solución es tan simple como aumentar el tamaño del area de intercambio o añadir más. Si no os apetece tocar la swap actual porque está en uso podéis añadir una nueva con zfs:

# zfs create -V 1G rpool/swap-extra
# swap -a /dev/zvol/dsk/rpool/swap-extra
# swap -l
swapfile             dev    swaplo   blocks     free
/dev/zvol/dsk/rpool/swap 171,2         8  1048568  1048568
/dev/zvol/dsk/rpool/swap-extra 171,3         8   819192   819192

Una vez activada la nueva swap los procesos FastCGI deberían arrancar sin problemas y ejecutar los PHP sin errores.

Configurar PHP + FastCGI en Oracle iPlanet Web Server


A través del sitio web de soporte de Oracle (https://support.oracle.com) podemos descargar el patch de PHP 5.2.X disponible para la versión de Oracle iPlanet Web Server que tengamos instalada, en este caso para la 7.0.12. sobre Solaris. Este parche nos va a permitir activar PHP con FastCGI a modo de plugin del web server.

Una vez bajado el patch (p12680045_10000_Generic.zip en mi caso), procedemos a descomprimirlo y copiar la carpeta “php” resultante al directorio plugins en la ruta donde hayamos instalado el servidor web:

# cp -Rp /var/tmp/php /opt/iplanet-webserver7/plugins/

Exportamos la variable LD_LIBRARY_PATH con la ruta hacia este directorio:

# export LD_LIBRARY_PATH=/opt/iplanet-webserver7/plugins/php

Ahora, podemos hacer una verificación de que php funciona desde línea de comandos:

# cd /opt/iplanet-webserver7/plugins/php/bin && ./php -v
PHP 5.2.X (cgi-fcgi) (built: Jan XX XXXX 22:31:04)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2011 Zend Technologies

Llegado este punto, únicamente tendríamos que activar php para la instancia en la que queramos usarlo, en este caso en la instancia https-website. Para ello haremos uso del script setupPHP disponible en el directorio “php”:

# cd /opt/webserver7/plugins/php/
# ./setupPHP -instancename=https-website

UPDATED: /opt/iplanet-webserver7/https-www/config/magnus.conf
UPDATED: /opt/iplanet-webserver7/https-www/config/obj.conf
UPDATED: /opt/iplanet-webserver7/https-www/config/mime.types

Como veis en la salida del comando, automáticamente se han actualizado los ficheros de configuración de la instancia, añadiendo los handler de php, las configuraciones y directivas de FastCGI, etc.

Si utilizáis un usuario distinto de root para correr el servidor web, aseguraos de que los propietarios de los tres ficheros anteriores se mantienen bien, sino no arrancará la instancia.

Ya solo quedaría hacer el pull-config con los nuevos cambios de configuración de la instancia y el deploy. Podemos hacerlo a través de la interfaz web de administración de iPlanet Web Server o desde línea de comandos con wadm:

# /opt/iplanet-webserver7/bin/wadm [--user=admin-user] [--password-file=admin-pswd-file] [--host=admin-host] [--port=admin-port]
pull-config --config=www nodo
pull-config --config=website hostname
deploy-config website

Gestionar el storage en Solaris con zfs y zpool


disco duroLa administración de discos y sistemas de ficheros zfs en Solaris (y en BSD) es algo distinta a lo que estamos acostumbrados para otros entornos Unix y GNU/Linux (ext3, ext4…). Zfs es un sistema de ficheros de 128-bit con una gran escalabilidad, estabilidad, transaccional y con una especial seguridad en la integridad de los datos. Pero no vamos a entrar en estos detalles sino en cómo gestionar este sistema.

Los dos comandos que debemos conocer para trabajar con sistemas de ficheros zfs son zpool y zfs. zpool es la primera capa de abstracción, crea pools de discos que pueden gestionar a su vez X sistemas de ficheros. A posteriori, se pueden añadir más discos al pool y automáticamente los sistemas de ficheros reciben este espacio sin gestión extra, algo excepcional para la escalabilidad.

Vamos a añadir un pool de prueba con un disco extra que tenemos en nuestro sistema. Podemos ver los discos físicos con el comando iostat -En:

# iostat -En
c7d0             Soft Errors: 0 Hard Errors: 0 Transport Errors: 0
Model: VBOX HARDDISK   Revision:  Serial No: VB5d392fb1-ed1f Size: 7,13GB
Media Error: 0 Device Not Ready: 0 No Device: 0 Recoverable: 0
Illegal Request: 0
c7d1             Soft Errors: 0 Hard Errors: 0 Transport Errors: 0
Model: VBOX HARDDISK   Revision:  Serial No: VBf793d417-2c8e Size: 1,07GB
Media Error: 0 Device Not Ready: 0 No Device: 0 Recoverable: 0
Illegal Request: 0
c8d1             Soft Errors: 0 Hard Errors: 0 Transport Errors: 0
Model: VBOX HARDDISK   Revision:  Serial No: VBf3c2659f-ea9c Size: 1,07GB
Media Error: 0 Device Not Ready: 0 No Device: 0 Recoverable: 0
Illegal Request: 0
c8t0d0           Soft Errors: 0 Hard Errors: 6 Transport Errors: 0
Vendor: VBOX     Product: CD-ROM           Revision: 1.0  Serial No:
Size: 0,00GB
Media Error: 0 Device Not Ready: 6 No Device: 0 Recoverable: 0
Illegal Request: 0 Predictive Failure Analysis: 0

El disco c7d0 es el que engloba el sistema y su propio pool (rpool), así que creamos de momento un nuevo pool llamado rpool2 con el disco c7d1:

# zpool rpool2 c7d1

Una vez realizado, automáticamente el pool se crea y es visible con un df -h, englobando todo el espacio del disco, se monta sólo:

# df -h /rpool2
Filesystem            Size  Used Avail Use% Mounted on
rpool2                976M   31K  976M   1% /rpool2

Ahora podemos comenzar a crear sistemas de ficheros dentro del pool con el comando zfs, creamos el sistema de ficheros /rpool2/test, que se monta de forma automática:

# zfs create rpool2/test
# df -h | grep rpool2
rpool2                976M   32K  976M   1% /rpool2
rpool2/test           976M   31K  976M   1% /rpool2/test

Lo interesante de esto es que una vez establecidos los pool, en caso de necesitar agregar más espacio a alguno de ellos, es tan sencillo como agregar nuevos discos al pool, automáticamente el espacio se asignará a los sistemas de ficheros que contiene. Yo tengo otro disco c8d1 así que lo voy a agregar para aumentar al doble el espacio del pool y sus sistemas de ficheros. Usaremos el comando zpool add seguido del pool y los discos a añadir:

# zpool add rpool2 c8d1

Y ya está, nuestro pool ha aumentado al doble su capacidad sin mayor gestión:

# df -h | grep rpool2
rpool2                2,0G   32K  2,0G   1% /rpool2
rpool2/test           2,0G   31K  2,0G   1% /rpool2/test

Si queremos tener una visión global de los pool en el sistema utilizamos el comando zpool list:

# zpool list
NAME     SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
rpool   6,56G  2,93G  3,63G    44%  1.00x  ONLINE  -
rpool2  1,97G   132K  1,97G     0%  1.00x  ONLINE  -

Por supuesto, no tenemos porque dejar que todos los sistemas de ficheros dispongan de todo el espacio del pool, podemos limitarlo estableciendo quotas:

# zfs set quota=200M rpool2/test
# df -h | grep test
rpool2/test           200M   31K  200M   1% /rpool2/test

Podría decirse que esto es lo más básico, la conclusión que podemos sacar es que, es una forma distinta de trabajar los discos y sistemas de ficheros, pero una vez acostumbrados es bastante más sencilla y práctica que los sistemas de ficheros tradicionales. Podemos seguir investigando las opciones de zpool y zfs con sus páginas man. Encontraremos otras utilidades de gran importancia, por ejemplo la posibilidad de visualizar el estado de IO en los pools:

# zpool  iostat rpool2
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
rpool2       132K  1,97G      0      2  1,69K  14,6K

Os invito a investigar un poco, es un sistema lleno de posibilidades y realmente interesante, deduplicación, compresión, snapshots

Gestión de snapshots en ZFS


ZFS (sistema de archivos desarrollado por Sun Microsystems para Solaris) permite realizar snapshots del sistema de ficheros de forma instantanea a través del comando zfs snapshot. Básicamente, un snapshot es una copia exacta del sistema de ficheros que posteriormente podemos utilizar para clonar, restaurar, guardar a modo de copia antes de la realización de cambios críticos en el sistema, etc. Lo que no podemos hacer es manipularlos, los snapshots son copias de sólo lectura.

Los snapshot se almacenan en el propio disco, por lo que su utilización supone la utilización de espacio extra y no sirven como backup en caso de desastre. Inicialmente no ocupan espacio extra, pero sí lo hacen conforme la información del sistema de ficheros cambia respecto al snapshot.

Crear, destruir y renombrar un snapshot

La sintaxis básica para la creación de un snapshot es la siguiente:

# zfs snapshot sistema_de_ficheros@nombre_snapshot

Por ejemplo, para crear un snapshot de “rpool/ROOT/solaris” con nombre la fecha de hoy:

# zfs snapshot rpool/ROOT/solaris@`date +%d%m%Y`

Para eliminar el snapshot usamos el comando zfs destroy:

# zfs destroy rpool/ROOT/solaris@04102011

Y para renombrarlo:

# zfs rename rpool/ROOT/solaris@04102011 rpool/ROOT/solaris@nuevo-snap

Listar snapshots disponibles

# zfs list -t snapshot
NAME                          USED  AVAIL  REFER  MOUNTPOINT
rpool/ROOT/solaris@install   22,5M      -  2,04G  -
rpool/ROOT/solaris@04102011    37K      -  2,44G  -

Con el comando zfs list -t snapshot podemos ver un listado de todos los snapshot disponibles, los snapshots se almacenan en el directorio oculto .zfs de la ruta base donde está montado el sistema de ficheros, en el caso de los anteriores /.zfs/snapshot. De esta forma podríamos restaurar ficheros concretos del snapshot en lugar de todo:

# ls -l /.zfs/snapshot
total 5
drwxr-xr-x 24 root root 25 2011-10-03 21:17 04102011
drwxr-xr-x 24 root root 25 2011-10-03 21:17 10042011
drwxr-xr-x 24 root root 26 2011-09-22 18:42 install

También conviene revisar el espacio en disco utilizado, el comando zfs list -o space nos mostrará con detalle el espacio utilizado a nivel general, por los snapshot, subsistemas de ficheros (child), etc:

# zfs list -o space
NAME                    AVAIL   USED  USEDSNAP  USEDDS  USEDREFRESERV  USEDCHILD
rpool                   3,19G  3,27G         0   92,5K              0      3,27G
rpool/ROOT              3,19G  2,46G         0     31K              0      2,46G
rpool/ROOT/solaris      3,19G  2,46G     22,5M   2,44G              0          0
rpool/dump              3,19G   256M         0    256M              0          0
rpool/export            3,19G  26,2M         0     32K              0      26,2M
rpool/export/home       3,19G  26,2M         0     32K              0      26,2M
rpool/export/home/alex  3,19G  26,2M       20K   26,2M              0          0
rpool/swap              3,54G   544M         0    181M           364M          0

Restaurar un snapshot

Hacer un rollback o restaurar un snapshot es tan sencillo como utilizar el comando zfs rollback seguido del snapshot a restaurar. Lo que hay que tener claro son las consecuencias de restaurar un snapshot antiguo, ya que restauremos el sistema de ficheros tal y como se encontraba en el momento del snapshot.

Algo a tener en cuenta, es que únicamente podemos restaurar el snapshot más reciente. Si tuvieramos varios y quisieramos hacer rollback de uno antiguo, antes habría que eliminar los más recientes. Recibiríamos este error:

# zfs rollback rpool/ROOT/solaris@10042011
cannot rollback to 'rpool/ROOT/solaris@10042011': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
rpool/ROOT/solaris@04102011

Así que eliminaríamos el reciente y ya podríamos hacerlo, también podríamos forzar con el parámetro -r a que se eliminan automáticamente:

# zfs destroy rpool/ROOT/solaris@04102011
# zfs rollback rpool/ROOT/solaris@10042011
# zfs rollback -r rpool/ROOT/solaris@10042011