lunes, 15 de diciembre de 2014

Notas OOM Killer – Out Of Memory

Introducción.

Habitualmente los procesos solicitan una reserva de memoria superior a lo que necesitan usar, debido a esto el kernel tiene la habilidad de hacer «over-commit» o lo que es lo mismo… asignar más memoria de la que tiene físicamente el sistema, considerando que normalmente los procesos no llegarán a usar esta.
Cuando los procesos si llegan a usar la memoria que han reservado, el kernel ha de comenzar a matar procesos para poder mantenerse operativo. Para recuperar la memoria necesaria el kernel usa «out-of-memory killer» o «OOM killer».

Detección y Análisis.
Algunas veces hemos visto procesos que dejan de estar en ejecución o simplemente vemos los famosos mensajes por pantalla…. «…Out of memory…»
Podemos detectar si OOM esta entrando a matar procesos revisando el log del sistema..
grep -i kill /var/log/messages*
host kernel: Out of Memory: Killed process 1324 (apache).
Si se revisa la memoria en este punto, es muy posible que no nos aporte nada, ya que OOM ya esta matando procesos para mantener la memoria que el kernel necesita, por lo que estos controles deberíamos hacerlos antes de que suceda el problema.
Dicho esto….
Podemos encontrarnos con el caso en que un sistema este matando procesos, teniendo memoria libre y sin estar usando swap…. ¿por qué?
La memoria del sistema se divide en «high memory» y «low memory»
En lineas generales tenemos distinto obgetos en cada zona…

High Memory:
  • Código de procesos
  • Datos de procesos

Low Memory:
  • Buffers y Cache
  • Kernel
  • Procesos del kernel
  • Tablas de asignación de memoria de cada proceso
  • ….

El estado de la memoria es la suma de estas dos zonas.
Ya que es posible tener la «Low Memory» llena y la «High Memory» libre, podemos tener en la salida de «free -m» memoria libre y el OOM trabajando.
Para poder detallar esto tenemos:
free -lm [root@test-sys1 ~]# free -lm
total used free shared buffers cached
Mem: 498 93 405 0 15 32
Low: 498 93 405
High: 0 0 0
-/+ buffers/cache: 44 453
Swap: 1023 0 1023
Configurando comportamiento.
Una vez determinado el porque entra en acción OOM Killer, podemos realizar varias acciones….
Por un lado podemos actuar en caliente sobre los procesos, para indicarle a OOM Killer que no intente matar un determinado proceso.

Esto se realiza mediante prioridades…

Kernel 2.6.29 o superior
Prioridades: -1000 (No se eliminará) a 1000 (próximo en ser eliminado)
Kernel inferior a 2.6.29
Prioridades: -17 (No se eliminará) a 15 (próximo en ser eliminado)
Para aplicarlas basta con:
echo «-999» > /proc/[PID]/oom_adj
El automatizarlo o no…. según necesidades.

Prevenir la entrada de OOM Killer.

Para prevenir este comportamiento podemos configurar el comportamiento del kernel en cuanto a overcommit.
Existen 3 valores para overcommit_memory.

  • 0 – (Defecto) Comportamiento Heurístico. Realiza estimaciones, para asignar mas memoria de la disponible.
  • 1 – Sin comportamiento Heurístico. Asignación de memoria física.
  • 2 – En este caso deja de tener un comportamiento heuristico, cuando se supera el consumo de la swap + un porcentaje de memoria, indicado en «overcommit_ratio», por lo que siempre tendremos un % de memoria no usada para el overcommit.

Una buena práctica sería, por ejemplo (En este ejemplo, el 20% de la memoria no se usaría en el overcommit):
vi /etc/sysctl.conf
vm.overcommit_memory = 2vm.overcommit_ratio = 80
Luego ejecutamos «sysctl -p»

Links relacionados.
http://www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html
https://www.kernel.org/doc/gorman/html/understand/understand012.html
http://rm-rf.es/como-excluir-un-proceso-del-oom-killer

http://www.ecsl.cs.sunysb.edu/elibrary/linux/mm/mm.pdf

domingo, 12 de octubre de 2014

Permitir Ficheros grandes – Upload Onwcloud

Hace poco me he montado un owncloud casero y me dió algunos problemas, a la hora de poder hacer upload de los ficheros con un tamaño grande, del orden de Gb.
Revisando información en castellano, no he encontrado referencias claras, por eso dejo aquí los cambios que he necesitado. Básicamente son 2…..

1.- Tamaño máximo de subida.

Estos parámetros se pueden cambiar en el php.ini de la maquina, pero no tendrán valor ya que son sobrescritos por el «.htaccess» del owncloud, por lo que se deben modificar en el directorio web del owncloud.

Ej. Para 2Gb
php_value upload_max_filesize 2G
php_value post_max_size 2G

2.- Tiempo máximo de ejecución. (Esta es la parte menos documentada.)

Además de esto, cuanto mayor es el fichero más tiempo de ejecución necesita el cgi para hacer el upload, por lo que debemos aumentar el tiempo de ejecución o obtendremos un «Internal server error«, ya que la subida se corta. Sigue subiendo pero ya no lo almacenamos en el fichero temporal, el cual deja de crecer llegado ese punto.
Esto se puede revisar viendo crecer el fichero en «/tmp» o donde se almacene.
Estos valor los he cambiado directamente en php.ini
Dejándolos en 1h (Por defecto los tenia en 60s):

max_execution_time = 3600
max_input_time = 3600

Con estos cambios tenemos la subida de ficheros grandes solucionada.
Además de esto, he cambiado la forma por defecto de loguear de ownclud.
En el fichero:

..../owncloud/config/config.php

Definimos:

  'log_type' => 'owncloud',
  'logfile' => '/var/log/owncloud.log',
  'loglevel' => '2',
  'logdateformat' => 'F d, Y H:i:s',


Nota: También se puede tirar contra syslog y por supuesto hay varios levels de logg, en la documentación esta indicado.

viernes, 29 de agosto de 2014

Temperatura – Raspberry

Siempre había tenido la «falsa» sensación de que la raspberry no debía calentarse mucho. Como siempre llaga la hora de despertar.
Tras varias tomas aleatorias ví que la temperatura era mas menos de unos 60ºC sin tener nada de carga de trabajo.
root@RASP1:~# /opt/vc/bin/vcgencmd measure_temp
temp=60.5'C
Así que para tener una opinión mas formada he decidido tomar un muestreo cada hora, durante una semana. Al final indicare como los he obtenido, aunque no tiene misterio.

Gráficas:
21 / 22 Agosto 2014



   
23 / 24 Agosto 2014


   
25 / 26 Agosto 2014


   
27 / 28 Agosto 2014


   
Se puede ver que la temperatura media es de unos 60ºC y que hay picos de las 10h a las 12h los cuales tienen su explicación… , ya que es el momento en que el sol incide sobre las raspberry por la ventana. Los días que recuerdo tapar la luz no existen estos picos.
Por otro lado he colocado un ventilador el cual puedo encender o parar con un interruptor.  Tras dejar un día completo el ventilador funcionando la caída de temperatura es muy alta…

29 / 30 Agosto 2014 ( Ventilador ON )


   
La caída es de unos 20ºC (33%) aproximadamente. Es así como debería estar siempre.
Con estas pruebas la opción mas evidente es dejar funcionando el ventilador pero tiene un problema…..
El «sonido» más bien «ruido«, es sumamente molesto…. Ahora estoy pensando en como aislar un poco la raspberry , para atenuar lo suficiente el ruido…. caja de cartón, corcho….. Ya iré probando.

Raspberry con Ventilador y disipadores.





Para tomar las medidas he usado los siguientes mini scripts, por llamarlos algo…

En el cron de root:

#Toma Datos Control Temperatura
00 * * * * /usr/local/scripts/control_temperatura/temperaturas.sh
15 00 * * * /usr/local/scripts/control_temperatura/genera_grafica.sh
30 00 * * * rm /usr/local/scripts/control_temperatura/datos_temp.txt

temperaturas.sh


#!/bin/bash
PATH_TRAB=/usr/local/scripts/control_temperatura
if [ ! -f $PATH_TRAB/datos_temp.txt ]; then
echo "#Hora Temperatura">>$PATH_TRAB/datos_temp.txt
fi
HORA=`date +%H`
TM=`/opt/vc/bin/vcgencmd measure_temp`
TEMPERATURA=`echo ${TM:5:-2}`
echo $HORA $TEMPERATURA>>$PATH_TRAB/datos_temp.txt

genera_grafica.sh


#!/bin/bash
PATH_TRAB=/usr/local/scripts/control_temperatura
NOMBRE=grafica_`date +%d_%m_%Y`.jpg
sed -i 's/00\ /24\ /g' $PATH_TRAB/datos_temp.txt
cat $PATH_TRAB/script_plot.sh |gnuplot > `echo $PATH_TRAB/$NOMBRE`

script_plot.sh


set terminal jpeg #Formato de salida
set title "Grafica Temperatura" #Titulo
set xlabel "HORA" #Etiqueta eje x
set ylabel "TEMPERATURA" #Etiqueta eje y
set yrange [0:100] #Rango eje y
#Dibujo de la gráfica (columnas 1 y 2) tipo de línea 4 y ancho de línea 3:
plot '/usr/local/scripts/control_temperatura/datos_temp.txt' using 1:2 with linespoints linetype 4 linewidth 3 title "Temp"

Cuando tenga la chapucilla para el ruido lo colgaré.

sábado, 19 de julio de 2014

Apagado disco USB – RaspBerry

Publicación original: 19.07.2014

Tengo una raspberry conectada 24/7, en la cual tengo conectado un disco usb que uso muy poco (motivo por el que nunca se me había planteado la necesidad de poder «apagarlo» automáticamente). Hasta ahora montaba y desmontaba el disco según necesidades.

Es posible que para un proyecto futuro, me interese tener el/los disco/s montados siempre y que el SO los apague según el tiempo de inactividad.
Un compañero me comento el uso y me he puesto a mirar HDPARM

Nota:

Simplemente a modo de recordatorio, buscando info sobre el tema he visto que podemos saber si ha existido actividad en el disco consultando el fichero:

/sys/block/sda/stat

Cuando se realizan operaciones sobre el disco el valor número cambia.

cat /sys/block/sda/stat | tr -dc "[:digit:]"

HDPARM

Con mi disco he tenido unos problemas, que detallare al final. Aunque el estado «unknown» que se ve a continuación, esta relacionado con mis problemas.

Ver el estado del disco:

root@RASP1:~# hdparm -C /dev/sda1
/dev/sda1:
drive state is: unknown
root@RASP1:~#

Si todo funciona correctamente el estado debe ser «active/idle, standby»….

Ver el tiempo tras el que pasaremos a inactividad «spin-down«

root@RASP1:~# hdparm -B /dev/sda
/dev/sda:
APM_level = 120

Este valor se debe entender del siguiente modo:
  • SI Permitimos el Spin-Down: Entre 1 y 127
  • NO Permitimos el Spin-Down: Entre 128 y 254
  • El valor de 255 : Desactiva la gestión de energía avanzada del disco duro.

Cuando permitimos el spin-down, el tiempo en segundos, se obtiene multiplicando por 5 el valor dado, así un valor de 120, serán 120*5 segundos….. 10 minutos

Estableciendo el valor:

Para esto editamos el fichero de configuración de hdparm:

/etc/hdparm.conf

Y al final añadimos: (Este punto no he conseguido que funcione con mi disco)

/dev/DISCO {
  spindown_time = Valor_deseado}
Tras esto es suficiente con dejar el demonio corriendo:

/etc/init.d/hdparm restart

NOTA: Problemas con mi disco

Las pruebas las estoy haciendo con un disco WD:


root@RASP1:~# hdparm -I /dev/sda
/dev/sda:
ATA device, with non-removable media
Model Number: WDC WD5000BEVT-11A03T0
Serial Number: WD-WX30A6957814
Firmware Revision: 01.01A01
...

En este disco no he podido definir el valor en el fichero de configuración, así como ver el estado del disco, ni forzar el «apagado» del disco


root@RASP1:~# hdparm -y /dev/sda
/dev/sda:
issuing standby command
HDIO_DRIVE_CMD(standby) failed: Invalid argument

Sin embargo el disco si para cuando establezco el valor via comando:

root@RASP1:~# hdparm -B 121 /dev/sda
/dev/sda:
setting Advanced Power Management level to 0x79 (121)
HDIO_DRIVE_CMD failed: Invalid argument
APM_level = 121
root@RASP1:~# hdparm -B /dev/sda
/dev/sda:
APM_level = 121
root@RASP1:~#
root@RASP1:~#
root@RASP1:~# hdparm -B 120 /dev/sda
/dev/sda:
setting Advanced Power Management level to 0x78 (120)
HDIO_DRIVE_CMD failed: Invalid argument
APM_level = 120
root@RASP1:~# hdparm -B /dev/sda
/dev/sda:
APM_level = 120

Este valor esta en uso hasta que el disco se desconecta de la corriente. Por lo que no es un problema para mi no poder, establecerlo de manera permanente.

lunes, 14 de julio de 2014

Procesos en segundo plano – SIGHUP, NOHUP

Publicación original: 14.07.2014

Me parece interesante a modo de «chuleta» y/o recordatorio comentar un poco este tema…
Lo quiero separar en dos partes una sobre los procesos en segundo plano y otra sobre la señal SIGHUP.
  • Procesos en segundo plano
Los procesos en segundo plano son aquellos que pese a estar en ejecución no tenemos la posibilidad de interactuar con ellos.

La manera de lanzar procesos en segundo plano es añadiendo al final , de este modo el proceso quedará en ejecución pero liberará la shell, para poder seguir trabajando.

gandalf ~ # find / -name hola &
[1] 19968
gandalf ~ # ps -ef|grep find
...
[1]+  Hecho                   find / -name hola

Para poder interactuar con estos procesos necesitamos traerlos a primer plano y para realizar esta gestión tenemos los comandos jobsbg y fg

Un ejemplo…. Lanzamos dos procesos en segundo plano:

gandalf ~ # while true; do echo "ab" > /dev/null; done &
[1] 20265
gandalf ~ # while true; do echo "a" > /dev/null; done &
[2] 20266

Visualizamos los procesos en segundo plano así como su estado:

gandalf ~ # jobs
[1]-  Ejecutando              while true; do
echo "ab" > /dev/null;
done &
[2]+  Ejecutando              while true; do
echo "a" > /dev/null;
done &

Traemos uno de los procesos a primer plano y lo detenemos con Ctrl+Z

gandalf ~ # fg %1while true; do
echo "ab" > /dev/null;
done
^Z
[1]+  Detenido                while true; do
echo "ab" > /dev/null;
done

Al listar los procesos en segundo plano tenemos uno detenido y uno en ejecución.

gandalf ~ # jobs
[1]+  Detenido                while true; do
echo "ab" > /dev/null;
done
[2]-  Ejecutando              while true; do
echo "a" > /dev/null;
done &

Volvemos a poner en ejecución en background el proceso que estaba detenido.

gandalf ~ # bg %1
[1]+ while true; do
echo "ab" > /dev/null;
done &
gandalf ~ # jobs
[1]-  Ejecutando              while true; do
echo "ab" > /dev/null;
done &
[2]+  Ejecutando              while true; do
echo "a" > /dev/null;
done &

También podemos matar un proceso en background determinado

kill %2



  • SIGHUP / NOHUP
Cuando un proceso termina lanza una señal SIGHUP a los procesos que cuelgan de el, y estos reaccionan simplemente saliendo.
Esto es un problema cuando queremos dejar corriendo algún proceso en la shell en la que nos encontremos, ya que aun teniéndolos en background, al salir de la shell el proceso terminará.
Podemos evitar esto lanzado el proceso con NOHUP, lo cual hará que el proceso no «escuche» la señal SIGHUP de su proceso padre.
Para lanzar un proceso con NOHUP basta con (nohup «comando»), por ejemplo:

nohup ./script.sh arg1 arg2
nohup su - user -c "./script arg1 arg2"

Algo interesante, a tener en cuenta, es el tratamiento de la salida /entrada estandar, así como de la salida de error que hace nohup.

  • Salida estandar –> Si no esta redirigida, se redirige a $HOME/nohup.out
  • Entrada estandar –> SI no esta definida toma valor de «/dev/null»
  • Salida de error –-> Si no está definida es redirigida a la salida estandar.

domingo, 13 de julio de 2014

Cabio de Site y CMS..

Ha llegado el momento de realizar la migración que estaba preparando.
El blog estrena nueva cara y cambia de ubicación..

He migrado todo el contenido y las nuevas entradas serán publicadas en el nuevo site.


A ver que tal la experiencia.

sábado, 14 de junio de 2014

Tunning Postgres

Estos últimos días he necesitado hacerle algo de Tunning a un postgres, así que he ido ajustando los valores que comento... 

Este proceso como todos los de tunning que he visto, se trata de iterar las veces que consideremos oportuno hasta no obtener mejora y dejarlo en la 
iteración (n-1) donde obtuvimos la última mejora.
El proceso a iterar consta de 3 partes básicamente.. (Toma de datos | Configuración | Toma de datos y Análisis)

Ya sabemos todos, que lo primero es medir.... lo que no se puede medir no se puede mejorar. ( Lord Kelvin , aunque hay bastante discusión sobre esto.)

1.- Toma de datos Inicial.
Hay infinitas formas de hacer esto yo tome como referencia este pool de pruebas. (Crear una table, insertar 100000 registros, hacer la consulta completa y borrar la tabla)

\timing
create table test_tunning (id integer primary key);
insert into test_tunning values (generate_series(1,100000));
select count(*) from test_tunning;
drop table test_tunning;

P.ejemplo
postgres=# \timing
El despliegue de duración está activado.

postgres=# create table test_tunning (id integer primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY creará el índice implícito «test_tunning_pkey» para la tabla «test_tunning»
CREATE TABLE
Duración: 14,178 ms

postgres=# insert into test_tunning values (generate_series(1,100000));
INSERT 0 100000
Duración: 202,436 ms

postgres=# select count(*) from test_tunning;
 count  
--------
 100000
(1 fila)

Duración: 11,773 ms

postgres=# drop table test_tunning;
DROP TABLE
Duración: 9,565 ms



2.- Aplicando Tuning Inicial Configuración Postgres.

A). shared_buffers 
shared_buffers = 615MB 

(Del 10% al 25% (Para un servidor dedicado). Podemos comenzar con un valor cercano al 15% e ir subiéndolo) 

Al aplicar este valor cabe la posibilidad de tener que modificar dos valores del kernel, ya que si son demasiado bajos postgres no arrancara.

Para la modificación en "caliente"
sysctl -w kernel.shmall=1048576
sysctl -w kernel.shmmax=4294967296

Para dejar el cambio permanente, editamos "/etc/sysctl.conf"
kernel.shmall = 
kernel.shmmax = 


B). effective_cache_size  
effective_cache_size = 1800MB 

Este valor podemos calcularlos de dos modos, según la documentación que he podido encontrar. 

A.- Un calculo genérico es el 50% del total de la ram de la máquina. Funciona bien pero no es lo más preciso posible.

B.- Si queremos ajustar más deberíamos tomar un valor del calculo (Shared_buffers+Ram Cached)


C.) work_mem 
work_mem = 16MB 

Este valor, es el que define la memoria usada por cada usuario para realizar operaciones de ordenación en las consultas. Por defecto esta a 1MB, valor que en los sistemas actuales no tiene sentido. Pasamos a 16MB y ajustamos luego, para lo que será necesario estudiar las consultas con más detalle. He visto medida genéricas que llegan a valores máximos de (max_connections/2 )


D).  maintenance_work_mem
maintenance_work_mem=200MB

Una manera de calcular el valor inicial sería: 50Mb por cada 1Gb de Ram.

Esta es la memoria que usará para realizar las operaciones de mantenimiento. El impacto de este valor no es elevado en la mayoría de los sistemas que he podido ver.


E). checkpoint_segments
checkpoint_segments=64 

Si bajamos este valor se producirán mas checkpoints lo que ocasiona escrituras en disco.
Un valor elevado disminuye las IO a disco pero emperora el tiempode recuperación ante desastre, ya que hay mas ficheros WAL pendientes de ser escritos.


F). wal_buffers
wal_buffers=16MB

Una manera de calcular el valor inicial sería: +-3% shared_buffers

Tamaño del buffer antes de tener que ser escrito en un fichero wal
Este valor es el mismo que el de los ficheros Wal por lo que debe minimizar las IO.

G). bgwriter_delaybgwriter_delay=500ms

Para ajustar este valor solo cabe consultar carga IO.

Delay del proceso writer.
Mas tiempo --> Menor IO y mas riesgo de perdida de datos, ya que se escriben menos frecuentemente.

Menor tiempo --> Mas IO y menos riesgo de perdida de datos.




3.- Toma de datos Final (Análisis de resultados).

Se repite la toma de datos del paso anterior.

Yo personalmente he tomado muestreos 5 veces de cada ciclo (create,insert,select,drop) antes de los cambio y después. Tomando la media. 
Esto lo he repetido 2 veces. total 10 valores de cada ciclo, de los cuales me he quedado con los mejores de cada caso.




CREATE INSERT SELECT DROP
PRE-Tunning 9,159 ms 161,687 ms 11,365 ms 9,3816
POST-Tunning 7,498 ms 156,892 ms 10,892 ms 13.984 ms
Ganancia 18,1% 2,97% 3,36% -29.8%


Nota
El -29.8% no se a que se debe actualmente, (Quizás un pico en el pc) ya que estos valores están sacados de una máquina creada en mi pc, para la redacción de este post.

En entornos reales he obtenido ganancias de este tipo:

CREATE INSERT SELECT DROP
92% 17% 0,08% 22%


Tras esto como ya he comentado, deberíamos seguir ajustando hasta no obtener mejora.

miércoles, 28 de mayo de 2014

Problemas con la resolución de pantalla. Intel HD 4600 + Ubuntu14

No hace mucho, cambié el operativo de casa y decidí probar las "bondades" de un sistema LTS, así que llegué a ubuntu 14.04.

Me he encontrado con un problema que me sorprende se de aún, pero parece, es bastante comentado.

En mi caso, Ubuntu 14.04 solo me ofrece una resolución máxima, de 1024x768 con una Intel HD4600 integrada en el i5-4670, sobre un LG E2250v. Esto es completamente inaceptable, más si vienes de 1920*1080.

He probado varias formas de solucionar el problema, al final esta funcionando a 1920*1080 del siguiente modo...

1.- Verifica si estos 3 comando solucionan tu problema.... sino ajusta los valores correctamente.

xrandr --newmode monitor_1920 148.800 1920 2008 2052 2185 1080 1084 1089 1135
xrandr --addmode VGA1 monitor_1920
xrandr --output VGA1 --mode monitor_1920

Donde los valores "148.800 1920 2008 2052 2185 1080 1084 1089 1135" se deben obtener con el comando "cvt" OJO!! ESTO A MI NO ME FUNCIONÓ

Podéis ver que la salida de cvt es distinta a los valores que he usado...

# cvt 1920 1080 60
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync

De donde obtendríamos:
173.00  1920 2048 2248 2576  1080 1083 1088 1120

Los valores que he acabado usando, son de:
...
...
# 1920x1080p @ 60Hz (EIA/CEA-861B)
ModeLine "1920x1080" 148.800 1920 2008 2052 2185 1080 1084 1089 1135 +hsync +vsync #INTEL
...
...

2.- Automatiza..

Tras verificar que los 3 comando anteriores te funcionan. Simplemente se trata de crear un script que se ejecute al cargar el escritorio, para lo cual creamos dos ficheros con el siguiente contenido...

/etc/xdg/autostart/fix_resolution.desktop 

[Desktop Entry]
Name=fix resolution
Exec=/usr/local/bin/fix_resolution.sh

/usr/local/bin/fix_resolution.sh

#!/bin/sh
xrandr --newmode monitor_1920 148.800 1920 2008 2052 2185 1080 1084 1089 1135
xrandr --addmode VGA1 monitor_1920
xrandr --output VGA1 --mode monitor_1920

Le damos permisos de ejecución al ".sh"

Con esto en cada reinicio se nos aplicara la configuración manual que hemos hecho.
Seguro que hay formas mas limpias y elegantes, pero esta me ha funcionado perfectamente.


lunes, 12 de mayo de 2014

Raspberry Pi. Interruptor apagado - Control GPIO

Este post intenta abordar la necesidad que me surgió, de poder hacer un apagado ordenado de la RaspBerry.

No era viable conectarme a la misma para realizar el apagado, ni tampoco apagar de power en cada ocasión ya que eran demasiadas y corría el riesgo de dejar el sistema inconsistente.

Una de las alternativas es la de conectar la Rasp al mundo, para lo que tenemos los puetos "general purpose input output" o GPIO.

De cara al montaje siguiente, hay que tener presente que, tenemos dos implementaciones de GPIO. REV1 y REV2. Debemos adaptarlo a la nuestra, ya que hay 3 diferencias en los nombres (marcados en azul)

Nota: En mi caso GPIO Rev.1 (Pin5 --> GPIO1)

El script hace básicamente lo siguiente....
Conectamos un interruptor al pin 5 (definido como de entrada y con valor 1) y al pin 6 (GND... con valor 0), cuando activamos~(cortorcicuitamos) el interruptor, el pin 5 de entrada recibe el 0 que tenemos en GND y cambia su valor a "0"comprobamos este valor y si es "0", lanzamos el shutdown o el script deseado.

El montaje queda así.... "cutre" pero completamente operativo.


El script es el siguiente:

Se puede descargar aquí

Nota2: Un poco de teoria...
Los puertos GPIO no son accesibles hasta que se han exportado al espacio de usuario. Hasta ese momento solo el Kernel puede acceder a ellos. Por lo que es necesario el export antes de poder definir la dirección IN/OUT o el valor.
Ejemplo.
root@RASP1:/sys/class/gpio# ls -als                                             ..                                                    
0 --w-------  1 root root 4096 may 12 01:23 export                             
0 lrwxrwxrwx  1 root root  0 may 12 01:23 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
0 --w-------  1 root root 4096 may 12 01:23 unexport
-----------------------------------
                                                    
root@RASP1:/sys/class/gpio# echo "5" > ./export
root@RASP1:/sys/class/gpio# ls -als
..
0 --w------- 1 root root 4096 may 12 01:24 export
0 lrwxrwxrwx  1 root root  0 may 12 01:24 gpio5 -> ../../devices/virtual/gpio/gpio5
0 lrwxrwxrwx  1 root root    0 may 12 01:23 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
0 --w-------  1 root root 4096 may 12 01:23 unexport
-----------------------------------                                                    
root@RASP1:/sys/class/gpio# echo "5" > ./unexport
root@RASP1:/sys/class/gpio# ls -als
..
0 --w-------  1 root root 4096 may 12 01:24 export
0 lrwxrwxrwx  1 root root    0 may 12 01:23 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
0 --w-------  1 root root 4096 may 12 01:24 unexport  

Con este montaje se hizo un centro de descargas, donde tras verificar la descarga vía transmission, se realiza un apagado ordenado se saca el pen, se "usa" la descarga.
Aunque lo verdaderamente interesante es la posibilidad de dotar a la RaspBerry de "interruptores" que realicen tareas.... Copias, checkeos, arrancar servicios...






domingo, 4 de mayo de 2014

Referencia Indirecta - Bash

Este post es más una nota que un post como tal, por su extensión y sobre todo por su función.....

Hace un par de semanas necesité hacer uso del concepto de punteros en bash.
La verdad es que no se si lo había usado anteriormente, lo que si sé, es que no recordaba como hacerlo, de ahí esta nota.

El concepto se llama habitualmente referencia indirecta.

Simplemente pretendo dejar plasmada la sintaxis a modo de recordatorio, así que no me extenderé nada.....

Podemos referenciar variables de dos modos... directa o indirectamente.

Antes de BASH v.2
A="cadena resultante"
B="A"
-------------------------
echo $A
.......cadena resultante
-------------------------
echo $B
.......A
-------------------------
eval C=\$$B
echo $C
.......cadena resultante


Desde BASH v.2
A="cadena resultante"
B="A"
-------------------------
echo $A
.......cadena resultante
-------------------------
echo $B
.......A
-------------------------
echo ${!B}
.......cadena resultante

Podemos acceder al contenido de la variable A, haciendo uso de su propia referencia o de la referencia que contiene la variable B.

La referencia la obtuve del siguiente artículo.
Aquí un artículo donde se detalla perfectamente este concepto.

sábado, 29 de marzo de 2014

Arduino y Pruebas de concepto - Control vía web

Hoy, a petición de un amigo, he recuperado una prueba de concepto que hice tiempo atrás sobre arduino.

Se trata de controlar salidas de arduino vía web, sirviendo un pequeño form.

Pretendía aplicar esto para domotizar la casa, pero por distintos motivos no seguí con el proyecto.

Así que por si le sirve a alguien...
Descarga aquí

Este script, tiene un par de años mínimo y por supuesto obtuve codigo de distintas fuentes para realizar la prueba. Siento no poder citarlos ya que no los recuerdo.