# [udev] ACTION="remove" y script en bash (cerrado)

## galidor

Hola a todos, tengo el siguiente problema y acudo al foro como siempre con la esperanza de que alguien pueda echarme una mano.

Mi intención es hacer un script que se lance al conectar un disco duro externo y que lance una copia de seguridad sobre el mismo. Debo decir que todo esto es para montar en servidores colocados en oficinas remotas y no tienen conectado monitor ni nada parecido. La idea es que el usuario una vez por semana enchufe un determinado disco y se haga la sincronización de los datos de trabajo (por si entran a robar a la oficina y se llevan el servidor).

Creando la regla de udev con el ACTION=="add" y los valores relacionados con el disco va todo perfecto. Añado a la misma regla un RUN+="ruta_del_script" y se lanza el programa. Mi intención es utilizar el altavoz del sistema y el comando beep para avisar al usuario de la correcta finalización de la copia. Hasta ahí parece que todo es sencillo. Monto la unidad, ejecuto el rsync y si finaliza normalmente lanzo el beep y lo dejo pitando un tiempo lo suficientemente largo como para que el usuario se entere.

Bien, el problema es el siguiente. Necesito hacer un kill / killall para matar el proceso del beep cuando el disco sea desconectado para que no se quede pitando todo el tiempo que le haya marcado. Las reglas que compongo no funcionan con el ACTION=="remove". He buscado por todas partes pero no consigo encuentro nada parecido. ¿Alguien sabe cómo se generan reglas de este tipo?

¿Alguna idea? Había pensado en hacer que el script emita pitidos cada X segundos indicando que la copia está en marcha y que deje de pitar en el momento en que acabe pero no sé bien como lanzar los dos procesos de forma simultánea y matar uno de ellos cuando el otro termine correctamente.

Si se os ocurre alguna solución alternativa la agradeceré igualmente.

Gracias.

----------

## pelelademadera

a ver si esto te sirve

es para un auricular usb, pero deberia servir para tu caso

http://ubuntuforums.org/showthread.php?t=559014

por lo que lei

 *Quote:*   

> When /usr/bin/my_program is executed, various parts of the udev environment are available as environment variables, including key values such as SUBSYSTEM. You can also use the ACTION environment variable to detect whether the device is being connected or disconnected - ACTION will be either "add" or "remove" respectively.

 

deberias poner 

 *Quote:*   

> RUN+="ruta_del_script"
> 
>  RUN-="ruta_del_script"

 

----------

## galidor

Gracias por la respuesta.

Esta mañana a última hora he encontrado ese post que me has pasado y ha encaminado mi búsqueda. No he conseguido hacerlo funcionar tal cual viene ahí explicado con ENV{loquesea}=="%p". No sé bien que hace eso exactamente ni qué valor toma %p cuando haces el "add" y el "remove". No debe coincidir porque desde luego no ejecuta nada al desconectar el disco.

Al parecer lo que se debe hacer es acceder a las variables ENV{} que se muestran al ejecutar udevadm info -q all -p  $(udevadm info -q path -n /dev/sda)

```
P: /devices/pci0000:00/0000:00:1e.0/0000:01:02.3/usb1/1-6/1-6:1.0/host39/target39:0:0/39:0:0:0/block/sda

N: sda

W: 72

S: block/8:0

S: disk/by-id/usb-FUJITSU_MHT2040AT_6-0:0

S: disk/by-path/pci-0000:01:02.3-usb-0:6:1.0-scsi-0:0:0:0

E: UDEV_LOG=3

E: DEVPATH=/devices/pci0000:00/0000:00:1e.0/0000:01:02.3/usb1/1-6/1-6:1.0/host39/target39:0:0/39:0:0:0/block/sda

E: MAJOR=8

E: MINOR=0

E: DEVNAME=/dev/sda

E: DEVTYPE=disk

E: SUBSYSTEM=block

E: ID_VENDOR=FUJITSU

E: ID_VENDOR_ENC=FUJITSU\x20

E: ID_VENDOR_ID=067b

E: ID_MODEL=MHT2040AT

E: ID_MODEL_ENC=MHT2040AT\x20\x20\x20\x20\x20\x20\x20

E: ID_MODEL_ID=2507

E: ID_REVISION=0022

E: ID_SERIAL=FUJITSU_MHT2040AT_6-0:0

E: ID_SERIAL_SHORT=6

E: ID_TYPE=disk

E: ID_INSTANCE=0:0

E: ID_BUS=usb

E: ID_USB_INTERFACES=:080650:

E: ID_USB_INTERFACE_NUM=00

E: ID_USB_DRIVER=usb-storage

E: ID_PATH=pci-0000:01:02.3-usb-0:6:1.0-scsi-0:0:0:0

```

Y que sin embargo no se muestran al hacer el udevadm info -a -p  $(udevadm info -q path -n /dev/sda)

A partir de aquí el problema ha sido que la regla obtenía más de una coincidencia y ejecutaba el script varias veces hasta que he ido afinando fijándome en la salida de udevadm monitor --udev --property

Finalmente las reglas han quedado de la siguiente manera:

```

ACTION=="add", SUBSYSTEM=="block", DRIVERS=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2507", KERNEL=="sd??", SYMLINK+="usbdisk%n", RUN+="/usr/local/bin/beep_backup.sh start"

ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd?", ENV{ID_VENDOR_ID}=="067b",  ENV{ID_MODEL_ID}=="2507", RUN+="/usr/local/bin/beep_backup.sh stop"

```

En la segunda regla he añadido el KERNEL=="sd?" porque sinó ejecutaba el script una vez por cada una de las particiones del disco insertado y así lo he restringido al dispositivo en sí.

No cierro el post a expensas de que alguien me pueda explicar por qué no funciona el ENV con el %p que aparece en el enlace que me ha pasado pelelademadera o exáctamente qué es lo que he hecho y qué son esas ENV que he obtenido con el comando anterior.

Gracias.

----------

## pelelademadera

y si lo encaras del lado del script...

o sea, en el momento de enchufar el disco, lo monta, y hace el rsync, hace el beep, lo mandas como demonio con un & al final y haces un buclecito con un if

tail -f /var/log/dmesg | grep (aca pones algo que aparece en dmesg cuando desenchufas el hd)

killall beep

fi

----------

## pcmaster

 *Quote:*   

> Monto la unidad, ejecuto el rsync y si finaliza normalmente lanzo el beep y lo dejo pitando un tiempo lo suficientemente largo como para que el usuario se entere. 

 

Te falta un paso: desmontar la unidad después de que finaliza la copia y antes de lanzar el beep.   :Shocked: 

Además, sería buena idea deshabilitar la unidad. Con ello (dependiendo de la unidad externa) podría apagarse ésta (por ejemplo, igual que los pendrives que en Windows apagan el LED al ser expulsados.

El linux tambien pasaba antes al expulsar los dispositivos con un eject, y desaparecían todas las entradas de /dev. Por ejemplo, si un pendrive estaba en /dev/sdb y tenía dos particiones, al hacer el eject desaparecían los tres enlaces (sdb, sdb1, sdb2) y se apagaba el LED del pendrive. Con la versión actual no pasa, desaparecen /dev/sdb1 y /dev/sdb2 pero no /dev/sdb, y no se apaga el LED del pendrive. No sé el motivo, quizá porque los lectores internos USB dejarían de funcionar (aunque no tengan tarjeta aparecen igualmente como sdb, sdc, etc, y las particiones aparecen al meterle una tarjeta)  pero si pudieras recuperar el funcionamiento antiguo (no sé si es cosa del kernel, quizá sea más bien alguna regla de udev) solamente para unidades externas USB, podrías expulsar el disco y, si la unidad tuviese algún LED que se apagara, te bastaría decirle al usuario: enchufas el disco y cuando se apague lo desenchufas. Sin beeps ni historias raras.

 *Quote:*   

> ...ejecuto el rsync y si finaliza normalmente lanzo el beep...

 

¿Y si no finaliza normalmente?

Quizá sería más sencillo que de cara al usuario hiciese lo mismo, y te enviase a tí un mensaje de aviso.

----------

## galidor

Gracias por las sugerencias pcmaster.

He obviado el paso del desmontado de la unidad pero lo hago tal cual comentas.

El comportamiento que comentas acerca de la expulsión del dispositivo no lo había observado nunca, de todas maneras, los servidores los he montado en 6 oficinas ya y cada uno tiene un disco externo de un padre y una madre con lo que no sabría decirte si encienden o apagan luces o ninguna de las dos cosas.

Una tercera opción es hacer un pequeño dispositivo que se controle mediante el puerto paralelo y encienda y apague leds. Con las señales del paralelo puedo controlar 8 leds y podrían ser indicadores de estado de la copia. Además, el código para controlar eso he visto que es relativamente sencillo. El problema de nuevo... que son HP Proliant ML110 y ya vienen sin paralelo. Que direis... pues le pones una controladora de paralelo. Podría, pero tengo los servidores desperdigados por media españa y no es plan.

Este código que he modificado un poco enviaría 1,2 ó 4 en binario al puerto paralelo 001, 010 ó 100 controlando 3 leds que he pensado podrían ser de diferentes colores.

```
#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/io.h>

 

#define base 0x378         /* printer port base address */

#define value 1            /* numeric value to send to printer port */

  

int main(int argc, char** argv)

{

        if (ioperm(base,1,1)) fprintf(stderr, "Couldn't get the port at %x\n", base), exit(1);

        if(argc!=2)

        {

                printf("Usage:\n");

                outb(1, base);

                sleep(1);

                outb(2, base);

                sleep(1);

                outb(4, base);

                sleep(1);

                outb(0, base);

        }

        else 

        {

                switch (argv[1])

                {

                        case 'red':     outb(1,base);

                                        break;

                        case 'orange':  outb(2,base);

                                        break;

                        case 'green':   outb(4,base);

                                        break;

                        default:        outb(0,base);

                }

        }

}
```

http://www.todorobot.com.ar/proyectos/paralelo/paralelo.htm - En este enlace explican cómo valerse del paralelo para controlar algún dispositivo. Hay que tener en cuenta que las salidas TTL son de 5v.

Faltaría comprar el material para hacer el pequeño panel pero es poca cosa.

Si alguien tiene el conocimiento para hacer algo similar por puerto serie o USB sería ya fabuloso. Yo es que no llego más lejos.

P.D: Sigo sin saber bien lo que son esos ENV y cómo funciona internamente udev a ese nivel (por si alguien me puede orientar).

Gracias de nuevo.

----------

## pcmaster

Buscando en google podrías haber encontrado esto:

http://delphi.jmrds.com/?q=node/8

igual te sirve  :Very Happy: 

o este (más complicadillo): http://hackedgadgets.com/2006/11/27/pic-based-serial-controlled-rgb-led-pwm-driver/

Y si quieres dejar de hacer experimentos con gaseosa y pasarte al USB, este: http://www.todopic.com.ar/foros/index.php?topic=20451

----------

## upszot

hola.. 

me resulta muy interesante este tema... me gustaria poder ayudar pero no se nada de programar las reglas con udev...

podrian poner un enlace donde se explique como crear reglas con udev?... y si es posible galidor podrias poner un cat del archivo de las reglas que creaste asi tengo un ejemplo de como se hace eso...

la verdad que esta muy buena la idea para hacer respaldo de algunos archivos  a discco o a un pendriver   :Very Happy: 

PD: espero no molestarlos con mi peticion... pero ya que hablaban de creaciones de reglas con udev me parecio que no estaba tan sacado de lugar pedir eso... 

Saludos

----------

## pcmaster

 *upszot wrote:*   

> podrian poner un enlace donde se explique como crear reglas con udev?... 

 

man udev te explica los parámetros que puedes poner.

Y en esta página (encontrada buscando en Google) explican bastante bien cómo crear reglas de udev:

http://www.vicente-navarro.com/blog/2007/03/29/creacion-de-reglas-udev-para-personalizar-el-nombre-de-los-ficheros-de-dispositivo-de-las-memorias-usb/

----------

## galidor

Hola upszot.

Las reglas que finalmente quedaron fueron las siguientes:

```

ACTION=="add", SUBSYSTEM=="block", DRIVERS=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2507", KERNEL=="sd??", SYMLINK+="usbdisk%n", RUN+="/usr/local/bin/beep_backup.sh start"

ACTION=="remove", SUBSYSTEM=="block", KERNEL=="sd?", ENV{ID_VENDOR_ID}=="067b",  ENV{ID_MODEL_ID}=="2507", RUN+="/usr/local/bin/beep_backup.sh stop"

```

Se debe tener cuidado de no generar reglas ambiguas que den más de una coincidencia con el mismo dispositivo o se lanzará varias veces el script.

Por lo demás... supongo que para dudas sobre UDEV debería abrirse otro hilo y este debería quedar cerrado.

Gracias a todos por la colaboración.

----------

## pelelademadera

no es lo mismo poner esto?

```
ACTION=="add", SUBSYSTEM=="block", DRIVERS=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2507", KERNEL=="sd??", SYMLINK+="usbdisk%n", RUN+="/usr/local/bin/beep_backup.sh start", RUN-="/usr/local/bin/beep_backup.sh stop"
```

----------

## galidor

Pues la verdad es que no lo sé. Pero de haber empezado por ahí hubieran acabado pronto mis dolores de cabeza. Lo probaré tan pronto como me sea posible y comento.

----------

## pelelademadera

es que fue la 1º respuesta que te di.... de todas maneras, no importa, era simplemente consultarte, y ver si te podia quedar mas prolijo y leible

saludos

----------

## galidor

Algún cabezazo contra la pared me tengo que dar.

Mea culpa por no entender debidamente tu primer mensaje.

Gracias. Creo que de repente he entendido muuuuchas cosas.

----------

