Nadie quiere al administrador de backup
Pero lo cierto es que nadie puede vivir sin él…
Esta es una máxima bastante extendida en el proceloso mundo de la administración de máquinas. Las copia de seguridad son una lata, pero en caso de desastre nos salvan la vida. Literalmente.
Existen cantidad de métodos para realizar una buena política de salvados. Hoy vamos a dedicarle un pequeño espacio de tiempo a una de las más comunes. Ufsdump y Ufsrestores en combinación con nuestras aliadas. Las unidades de cinta.
Es importante conocer qué es lo que queremos salvar. mi experiencia me dice que no es necesario realizar un backup completo de una máquina, sino determinadas piezas de información contenida en ella. Por ejemplo, /var /opt /export/home /oracle, etc…
Conviene determinar claramente cuales son los ficheros y configuraciones impresccindibles y guardarlo a buen recaudo. Un apache se puede instalar desde cero en caso necesario, pero la configuración de cada servidor y el contenido de las páginas son temas más peliagudos.
Por otra parte, no tendremos que copiarlo todo todos los días. Hay archivos y directorios que no sufren variaciones en su contenido, mientras que otros van teniendo información nueva cada día, como una tabla de una base de datos.
Normalmente, hay dos tipos de backup:
- Completo: A realizar el primer día en que hacemos backup
- Incremental: A realizar en los días subsiguientes, y que incluirá únicamente los archivos que hayan sido modificados.
Por último, un pequeño procedimiento para copiado de filesystem completos a cinta. Solo para sus ojos…
Se copian los archivos a la cinta mediante ufsdump completo. En este caso, se realizaría un ufsdump por cada filesystem independiente.
# ufsdump 0uf /dev/rmt/numero_de_cinta /filesyetem
Ejemplos:
# ufsdump 0uf /dev/rmt/0 / # ufsdump 0uf /dev/rmt/0 /var # ufsdump 0uf /dev/rmt/0 /export/home
… etc
Si el salvado que deseamos hacer es incremental, hay que prestar atencion al dump level, que es un valor desde 0 a 9, y establece los ficheros que se van a a copiar que hayan sido modificados desde el último backup realizado a un nivel de dump inferior. Por ejemplo: Si el lunes hemos realizado un dump a nivel 2, y el martes hacemos un dump a nivel 4, en caso de que hagamos un dump a nivel 3 el miércoles copiaría asimismo todos los ficheros modificados o añadidos al sistema desde el backup del lunes.
Hay diferentes combinaciones, pero la que encuentro más adecuada es el llamado modelo de Torres de Hanoi y que viene a ser:
L: Nivel 3 M: Nivel 2 X: Nivel 5 J: Nivel 4 V: Nivel 7 S: Nivel 6 D: Nivel 0
En caso de que se quiera restaurar en un punto fijo, el comando sería:
Desde un directorio creado para contener los FS copiados (Ej: /var/tmp/restauracion)
# ufsrestore rvf /dev/rmt/numero_de_cinta ./filesyetem
Ejemplos:
# ufsrestore rvf /dev/rmt/0 ./ # ufsrestore rvf /dev/rmt/0 ./var # ufsrestore rvf /dev/rmt/0 ./export/home
Recuerden que estas cintas han de guardarse como oro en paño. En caso de que se destruyan o deterioren, es mucho trabajo tirado a la basura
Si quieren mayor información, lo cual es muy inteligente ya que estas breve pinceladas apenas explican nada, les recomiendo el muy chulo (y divertido) manual Backup & Recovery de W. Preston publicado por O’Reilly.
Braiiiiiins…
Aprovechando una consulta que me han realizado, vamos a hacer un pequeño recordatorio sobre los procesos defunct, también llamados zombies. Es una buena época del año para ello, teniendo Halloween al lado. Hasta en World of Warcraft lo zombie está de moda
Hagamos un pequeño repaso para los que se perdieran las clases.
Los procesos en los sistemas Unix cuentan con una jerarquía de ejecución, de forma que, en caso de que se necesite, un proceso puede generar procesos nuevos (denominados hijos) para realizar funciones adicionales. De hecho, este punto es absolutamente normal y un proceso padre más o menos complejo puede llegar a generar buena cantidad de procesos hijos. Pensemos en una base de datos o un servidor web, por ejemplo.
Para poner un ejemplo, he aquí la jerarquía de procesos de un servidor ssh:
root@madhatter # ptree 19963
876 /usr/lib/ssh/sshd
19963 /usr/lib/ssh/sshd
19966 /usr/lib/ssh/sshd
19968 -sh
19972 bash
20025 ptree 19963
Así podemos ver que el proceso 19963 ha generado el proceso 19966, etc…
Los procesos no acabarán completamente hasta que el padre haya elegido sus estados de salida y acabado con ellos. En caso de que exista un gran número de procesos en estado defunct, sería conveniente examinar cual es el ID del proceso padre, ya que es responsabilidad de este proceso padre identificar todos los hijos que hayan acabado y obtener su estado. En caso contrario, el proceso padre de ese proceso padre heredaría los hijos, de forma que eventualmente puedan llegar al PID 1 (Init).
Si init hereda un proceso defunct (zombie), este proceso será “segado” o eliminado de la tabla de procesos, ya que esta es una de las tareas asignadas a init.
En caso de que el número de procesos defunct en la máquina no os parezca normal, convendría vigilar qué proceso está causando ese número de zombies para depurarlo.
Como detalle adicional, si el número de procesos defunct se descontrola, en Solaris 8 no queda otra opción que rebotar la máquina, mientras que en Solaris 9 y superior se puede emplear el comando preap para eliminar estos procesos defunct.
Por cierto, mucho ojo al emplear preap, que debería ser empleado únicamente como último recurso, ya que si se usa para matar un proceso que luego intenta ser eliminado por su proceso padre esto puede dañar el proceso padre de forma impredecible.
Ah, y no intentéis utilizar kill -9 para eliminar procesos defunct, ya que no hay ningún proceso corriendo para recoger la señal de KILL y no responderá al comando.
Colega, ¿donde está mi last?
Uno de los misterios más habituales, que ha causado más de un quebradero de cabeza a los sysadmins del mundo mundial es la falta de informacióncuando hacemos un last.
Para los que no lo tengan muy claro, last es una herramienta de seguridad que indica los últimos accesos a la máquina en orden reverso. Cada línea nos va a indicar nombre de usuario, la consola (tty) desde donde conecta, nombre de máquina y el comienzo y el fin de la sesión. Utilísimo para los paranoicos en todos nosotros
Un ejemplo práctico:
root@madhatter # last root pts/4 10.10.1.229 Tue Oct 21 13:57 still logged in root sshd 10.10.1.229 Tue Oct 21 13:57 still logged in root sshd 10.10.1.229 Wed Oct 8 12:30 - 12:36 (00:05) root sshd 10.0.231.64 Wed Oct 8 11:55 - 12:25 (00:29) root pts/4 10.10.1.229 Wed Oct 8 11:30 - 12:41 (01:11) root sshd 10.10.1.229 Wed Oct 8 11:30 - 11:55 (00:25) root console :0 Tue Sep 30 12:27 still logged in root pts/2 10.10.3.43 Mon Sep 29 11:30 - 11:30 (00:00) root sshd 10.10.3.43 Mon Sep 29 11:30 - 11:30 (00:00) root pts/2 10.10.1.229 Wed Sep 24 07:25 - 07:51 (00:26) root sshd 10.10.1.229 Wed Sep 24 07:25 - 07:51 (00:26) root sshd 10.10.1.229 Thu Sep 18 14:17 - 14:32 (00:15) root pts/2 10.10.1.229 Thu Sep 18 14:15 - 14:47 (00:31) root sshd 10.10.1.229 Thu Sep 18 14:15 - 14:17 (00:01) root pts/2 10.10.1.229 Thu Sep 18 08:44 - 08:44 (00:00) [...]
Imaginemos ahora una situación como esta
root@madhatter # last wtmp begins Wed Feb 25 04:30
La cara de tonto que se te queda cuando compruebas que el fichero está actualizado
root@madhatter # ls -l /var/adm/wtmpx -rw-r--r-- 1 adm adm 43599145 Oct 21 13:28 /var/adm/wtmpx
Que forzando te manda a peinarte
root@madhatter # last -f /var/adm/wtmpx wtmp begins Wed Feb 25 04:30
Que el filesystem no está lleno
root@madhatter # df -k /var Filesystem kbytes used avail capacity Mounted on /dev/vx/dsk/bootdg/rootvol 15345315 8665186 6526676 58% /
La causa más normal de este comportamiento es corrupción de datos en el fichero /var/adm/wtmpx que es donde se almacenan los datos para sacar el last. Las causas son variadas, desde llenado temporal de ese filesystem, un backup mal realizado, truncados de ficheros o simple y pura mala práctica.
La cuestión es arreglarlo. La forma más sencilla es, simplemente, recrearlo con los permisos adecuados, haciendo copia de seguridad previa:
root@madhatter # mv /var/adm/wtmpx /var/adm/wtmpx.BAK root@madhatter # touch /var/adm/wtmpx root@madhatter # chown adm:adm /var/adm/wtmpx root@madhatter # chmod 644 /var/adm/wtmpx
Listo. En caso de que nos interese mucho guardar los datos contenidos en el fichero, hay una operativa mucho más complicada que podéis examinar a fondo.
Esto es grande… Esto es pequeño
La comprobación de que el tamaño de las cosas es elástico (ejem, ejem) y más todavía en Unix.
Como me imagino que todos sabréis, el archivo de /var/adm/lastlog registra y almacena el tiempo de login de cada usuario, sea este correcto o incorrecto. Es útil para saber quien se ha conectado, cuanto tiempo, y desde donde.
En ocasiones, me han dado un toque de atención por el excesivo tamaño de /var y concretamente el de lastlog. Yo siempre les digo que para qué andan mirando donde no deben
y luego les explico lo que me contaron a mí en su momento: El tamaño del archivo de lastlog al hacer un ls no se corresponde con su tamaño real.
El tamaño indicado al hacer un ls -l del fichero lastlog está basado en el UID más alto de los usuarios que estén conectados a la máquina. La fórmula que utiliza Solaris para esto es tamaño total de lastlog=(UID más alto de los usuarios + 1) * 28
De ésta manera, el fichero de lastlog se convierte en un fichero “disperso” en el que su tamaño real es mucho más pequeño del que pueda parecer. Para comprobarlo, vamos a seguir unos ejemplos sencillos:
Tamaño de /var actual de la máquina nuestra de pruebas:
root@madhatter # df -k /var/ Filesystem kbytes used avail capacity Mounted on /dev/vx/dsk/var 2031101 1472886 497282 75% /var
Tamaño de lastlog según ls (Aparente)
root@madhatter # ls -la /var/adm/lastlog -r--r--r-- 1 root root 1820084 Dec 10 14:17 /var/adm/lastlog root@madhatter # ls -lha /var/adm/lastlog -r--r--r-- 1 root root 1.7M Dec 10 14:17 /var/adm/lastlog
Tamaño real del mismo fichero
root@madhatter # du -ks /var/adm/lastlog 24 /var/adm/lastlog
Procedemos a vaciar el fichero lastlog y comprobamos su tamaño
root@madhatter # > lastlog
root@madhatter # ls -la lastlog
-r--r--r-- 1 root root 0 Dec 10 14:30 lastlog
root@madhatter # du -ks lastlog
0 lastlog
Así como el de /var
root@madhatter # df -k /var Filesystem kbytes used avail capacity Mounted on /dev/vx/dsk/var 2031101 1472862 497306 75% /var
Vemos que sólo ha aumentado en 24 Kb.
Ahora, entramos como usuario root. Según lo especificado en la fórmula, crece de tamaño en 28 bytes aparentes (Pero solo 1 kb real)
root@madhatter # ls -la lastlog
-r--r--r-- 1 root root 28 Dec 10 14:32 lastlog
root@madhatter # du -ks lastlog
1 lastlog
Kb que se descuenta de /var
root@madhatter # df -k /var Filesystem kbytes used avail capacity Mounted on /dev/vx/dsk/var 2031101 1472863 497305 75% /var
Ahora, procedemos a entrar con el usuario que tiene el UID mas alto en la maquina
prueba:x:65002:1::/var/tmp/usuario_prueba:/usr/bin/ksh
De nuevo, el fichero crece según la fórmula (65002+1)*28=1820084
root@madhatter # ls -la lastlog
-r--r--r-- 1 root root 1820084 Dec 10 14:35 lastlog
Pero sólo ha aumentado 23 Kb
root@madhatter # du -ks lastlog 24 lastlog
Así como /var
root@madhatter # df -k /var Filesystem kbytes used avail capacity Mounted on /dev/vx/dsk/var 2031101 1472894 497274 75% /var
Así pues no hay reserva de espacio en/var por parte de last log en lo que concierne al tamaño aparente, sino únicamente al tamaño real.
Y recordad: This is not a bug, is a feature
Espejito, espejito…
Odio Solaris Volume Manager. Si fuera por mí, lo quemaba con fuego mientras reía a carcajadas.
Pero claro, viene de serie con el sistema operativo Y entre tener que pagar una licencia de Veritas Volume Manager que cuesta un riñon y poder contar con un gestor de volúmenes por la patilla, adivina que es lo que se va a quedar la gente en una gran mayoría de los casos
Efectivamente, con uno de los gestores de volúmenes mas antiintuitivos y despreciables que existen. Para matarlos, Oiga.
Menos mal que en Solaris 10 viene incluído por defecto ZFS, que además de ser un tiro y fiable, es absurdamente sencillo de administrar, aunque lo mismo de ello hablamos otro día.
En todo caso, y para todas aquellas veces que tengamos que hacer un mirror de sistema con esta herramienta, una pequeña guía.
Supongamos que nuestra máquina tiene cuatro discos internos:
AVAILABLE DISK SELECTIONS: 0. c0t0d0 <SUN36G cyl 24620 alt 2 hd 27 sec 107> /pci@1f,4000/scsi@3/sd@0,0 1. c0t1d0 <SUN36G cyl 24620 alt 2 hd 27 sec 107> /pci@1f,4000/scsi@3/sd@1,0 2. c0t2d0 <SUN18G cyl 7506 alt 2 hd 19 sec 248> /pci@1f,4000/scsi@3/sd@2,0 3. c0t3d0 <SUN18G cyl 7506 alt 2 hd 19 sec 248> /pci@1f,4000/scsi@3/sd@3,0
Un listado de la tabla de particiones del disco de arranque muestra lo siguiente:
Total disk cylinders available: 24620 + 2 (reserved cylinders) Part Tag Flag Cylinders Size Blocks 0 root wm 0 - 4355 6.00GB (4356/0/0) 12584484 1 swap wu 4356 - 10163 8.00GB (5808/0/0) 16779312 2 backup wm 0 - 24619 33.92GB (24620/0/0) 71127180 3 unassigned wm 0 0 (0/0/0) 0 4 unassigned wm 0 0 (0/0/0) 0 5 var wm 10164 - 14519 6.00GB (4356/0/0) 12584484 6 unassigned wm 14520 - 20327 8.00GB (5808/0/0) 16779312 7 unassigned wm 20328 - 20509 256.74MB (182/0/0) 525798
Lo primero es asegurarnos de que el disco que va a hacer mirror tiene la misma tabla de particiones, para lo cual:
root@madhatter # prtvtoc /dev/rdsk/c0t0d0s2 | fmthard -s - /dev/rdsk/c0t1d0s2
Continuamos inicializando la base de metadispositivos. Emplearemos el slice 7 ya que cuenta con espacio suficiente.
root@madhatter # metadb -a -f -c3 /dev/dsk/c0t0d0s7 /dev/dsk/c0t1d0s7
Tras ello, podemos comenzar a crear los mirrors, comenzando por /
root@madhatter # metainit -f d10 1 1 c0t0d0s0 d10: Concat/Stripe is setup root@madhatter # metainit d20 1 1 c0t1d0s0 d20: Concat/Stripe is setup root@madhatter # metainit d30 -m d10 d30: Mirror is setup root@madhatter # metaroot d30
Lo mismo para swap:
root@madhatter # metainit -f d11 1 1 c0t0d0s1 d11: Concat/Stripe is setup root@madhatter # metainit d21 1 1 c0t1d0s1 d21: Concat/Stripe is setup root@madhatter # metainit d31 -m d11 d31: Mirror is setup
Para /var
root@madhatter # metainit -f d15 1 1 c0t0d0s5 d15: Concat/Stripe is setup root@madhatter # metainit d25 1 1 c0t1d0s5 d25: Concat/Stripe is setup root@tesol025 # metainit d35 -m d15 d35: Mirror is setup
Y finalmente para /var/crash
root@madhatter # metainit -f d16 1 1 c0t0d0s6 d16: Concat/Stripe is setup root@madhatter # metainit d26 1 1 c0t1d0s6 d26: Concat/Stripe is setup root@madhatter # metainit d36 -m d16 d36: Mirror is setup
Ahora podemos añadir los cambios realizados a /etc/vfstab para que se cojan los cambios en arranque. Recordemos que conviene hacer siempre una copia de seguridad antes de las modificaciones, para evitar futuras lágrimas
root@madhatter #/dev/dsk/c1d0s2 /dev/rdsk/c1d0s2 /usr ufs 1 yes - fd - /dev/fd fd - no - /proc - /proc proc - no - /dev/md/dsk/d31 - - swap - no - /dev/md/dsk/d30 /dev/md/rdsk/d30 / ufs 1 no - /dev/md/dsk/d35 /dev/md/rdsk/d35 /var ufs 1 no - /dev/md/dsk/d36 /dev/md/rdsk/d36 /var/crash ufs 2 yes - swap - /tmp tmpfs - yes -
Tras ello, realizamos un reboot de la maquina. En el momento en que este de nuevo arriba, entramos como root y comprobamos si el disco esta inicializado para arrancar desde mirror:
root@madhatter # eeprom |grep boot [...] boot-file: data not available. boot-device=disk
Tenemos que añadir el otro disco. Para ello, comprobamos cual es:
root@madhatter # prtconf -vp |grep disk
[...]
disk: '/pci@1f,4000/scsi@3/disk@0,0'
disk0: '/pci@1f,4000/scsi@3/disk@0,0'
disk1: '/pci@1f,4000/scsi@3/disk@1,0'
disk2: '/pci@1f,4000/scsi@3/disk@2,0'
disk3: '/pci@1f,4000/scsi@3/disk@3,0'
[...]
Comprobamos que ambos discos sean iguales:
root@madhatter # format
AVAILABLE DISK SELECTIONS:
[...]
1. c0t1d0 <SUN36G cyl 24620 alt 2 hd 27 sec 107>
/pci@1f,4000/scsi@3/sd@1,0
[...]
Y cambiamos los valores correspondientes:
root@madhatter # eeprom boot-device="disk disk1"
Comprobamos:
root@madhatter # eeprom |grep boot [...] boot-file: data not available. boot-device=disk disk1
Y procedemos a atachar los metadevices entre si.
# metattach d30 d20 submirror d20 is attached # metattach d31 d21 d31: submirror d21 is attached # metattach d35 d25 d35: submirror d25 is attached # metattach d36 d26
Tras ello, los disco comenzaran a realizar la sincronizacion. Podemos comprobar el estado de la misma con el comando:
root@madhatter # metastat |grep % Resync in progress: 4 % done Resync in progress: 2 % done Resync in progress: 2 % done Resync in progress: 1 % done
Una vez terminada, se habra creado correctamente el mirror.
Este disco ¿De quien es?
Los mensajes de error en almacenamiento, tanto interno como externo, en sistemas Solaris tienen la particularidad de no ser especialmente amistosos con el que los lee por primera vez. Un ejemplo:
Apr 13 06:22:06 madhatter scsi: [ID 107833 kern.warning] WARNING: /pci@7c,600000/SUNW,qlc@1/fp@0,0/ssd@w50060e8003ea6d03,49 (ssd356): Apr 13 06:22:06 madhatter SCSI transport failed: reason 'timeout': retrying command Apr 13 06:22:36 madhatter scsi: [ID 107833 kern.warning] WARNING: /pci@fc,600000/SUNW,qlc@1/fp@0,0/ssd@w50060e8003ea6d13,49 (ssd986): Apr 13 06:22:36 madhatter SCSI transport failed: reason 'timeout': retrying command Apr 13 06:23:06 madhatter scsi: [ID 107833 kern.warning] WARNING: /pci@7c,600000/SUNW,qlc@1/fp@0,0/ssd@w50060e8003ea6d03,49 (ssd356): Apr 13 06:23:06 madhatter SCSI transport failed: reason 'timeout': giving up
El problema es descodificar el chorro que sale en un disco en concreto. Afortunadamente para nosotros, Solaris pone un acceso al nombre de disco concreto dentro del directorio /dev/dsk
De este modo, se trata de una simple cuestión de filtrado.
madhatter:root:/dev/dsk# ls -l *s2 |grep w50060e8003ea6d03,49 lrwxrwxrwx 1 root root 72 Sep 5 2005 c6t50060E8003EA6D03d73s2 -> ../../devices/pci@7c,600000/SUNW,qlc@1/fp@0,0/ssd@w50060e8003ea6d03,49:c
Tachan!. Sabía que ese almacenamiento externo del todo a un euro me iba a causar problemas
¿Y si son muchos los discos que están fallando?. Ah, pues entonces viene a nosotros el poder de la shell:
madhatter:root:/dev/dsk# for i in `grep WARNING /var/adm/messages |nawk ' {print $10}'`;
do ls -arlit *s2 |nawk ' {print $10}'; done
Esto nos sacaría por pantalla únicamente el disco con problemas.
Ahora ya podemos examinar la cabecera del disco para ver si se puede leer correctamente, así como los caminos físicos, por si hubiera problemas en alguna parte de la cadena.
Otro día hablamos de las HBA, esas grandes desconocidas