Bueno publico esto por si se me olbida ya se que estara aqui:
Este artículo es una receta por pasos para exportar un disco USB NTFS conectado a una máquina GNU/Linux hacia una máquina Windows o a otra Linux. Asumo que la distribución es Debian o alguno de sus derivados.
Conectar un disco duro por puerto USB es una solución lenta pero muy efectiva para ampliar prácticamente sin límite la capacidad de almacenamiento de nuestro repositorio de música, vídeo, etc. Actualmente existen en el mercado carcasas que permiten conectar discos duros PATA o SATA al puerto USB.
He elegido NTFS como sistema de ficheros porque tiene soporte tanto en Windows como en Linux, así que si quisiera conectar unos de los discos directamente en Windows, no habría ningún problema.
Podríamos también construir un array de discos configurado como volumen RAID para aumentar la velocidad de acceso a los datos y la fiabilidad del almacenamiento. En mi caso particular, prefiero no ponerlos en RAID para poder después usarlos individualmente en caso necesario (y no tener que tomar el RAID completo).
Lo primero: UTF-8
Es un fastidio montar una unidad de red y ver las eñes y los acentos en el nombre de los ficheros sustituidos por los caracteres ?, _, % o ver que faltan ficheros/directorios o que estos son inaccesibles. Empecemos por poner orden en la Torre de Babel.
En la máquina Linux debemos usar UTF-8 para codificar los caracteres, esto se hace cambiando el locale del sistema (la configuración regional y la codificación de los caracteres). Debemos generar el locale correspondiente a nuestro país terminado en UTF-8. Por ejemplo: para España es es_ES.UTF-8
$ dpkg-reconfigure locales
Ahora cambiamos el locale predeterminado que usará nuestro sistema editando el fichero /etc/environment, que debe contener la línea LANG="es_ES.UTF-8". Una vez editado este fichero la variable de entorno $LANG debe valer "es_ES.UTF-8" (hay que reiniciar)
$ echo $LANG
UTF-8 también en la conexión SSH
Muchas veces ocurre que, estando conectados a una máquina UNIX a través de SSH, vemos caracteres raros en el terminal y pensamos que es por causa de la configuración del servidor pero en realidad puede que la causa esté en el propio cliente de SSH que estamos utilizando.
El servidor OpenSSH usado en Linux (sshd) permite que el cliente, durante el establecimiento de la conexión, le indique la codificación que debe usar para enviar los caracteres. Esto sólo es cierto a partir de la versión 3.9p1 de OpenSSH.
Si estamos usando putty, el cliente de SSH para Windows, podemos decirle que le indique a OpenSSH que use UTF-8. En las opciones, Window \rightarrow Translation, debemos seleccionar UTF-8. Una vez que veamos correctamente los acentos y eñes, ya podemos estar seguros de que la conexión SSH no está falseando los nombres, de que vemos lo que hay.
Asignar un nombre fijo al disco con udev
El kernel Linux tiene un componente llamado udev que permite, entre otras cosas, asignar un nombre fijo de dispositivo en el directorio /dev a cada uno de nuestros periféricos. Esto evita que dependiendo del puerto USB en que conectamos un stick USB unas veces sea /dev/sda, otras /dev/sdb, etc.
Vamos a escribir un fichero de reglas para decirle a udev que asigne nombres fijos de dispositivo a nuestro discos duros externos. Primero listamos las propiedades del disco en cuestión. Al conectar el disco, Linux puede detectar como sda, sdb, sdc, etc. Para averiguar qué letra le asigna podemos consultar las últimas trazas del kernel
$ dmesg
Luego tecleamos (para sda):
$ udevinfo -a -p /sys/block/sda
vemos que propiedades tiene, elegimos algunas que lo identifiquen unívocamente y luego escribimos las reglas en el fichero /etc/udev/misreglas.rules, yo he elegido la propiedad ATTRS{model}
# Disco de 160GB Carcasa USB
SUBSYSTEM=="block", ATTRS{model}=="G160E0", KERNEL=="sd?1", NAME="%k", SYMLINK="usbvolumeA"
# Disco de 160GB Flash NAND
SUBSYSTEM=="block", ATTRS{model}=="6L200P0", KERNEL=="sd?1", NAME="%k", SYMLINK="usbvolumeB"
Más información sobre la sintáxis del fichero de reglas.
las reglas anteriores consiguen que esos dos discos duros externos USB, identificados por su propiedad ATTRS{model}, se llamen siempre /dev/usbvolumeA y /dev/usbvolumeB respectivamente. Ahora ya podemos escribir un fichero /etc/fstab como el siguiente:
/dev/usbvolumeA /mnt/usbvolumeA ntfs-3g user,exec,uid=javg,silent,umask=0,locale=es_ES.UTF-8 0 0
/dev/usbvolumeB /mnt/usbvolumeB ntfs-3g user,exec,uid=javg,silent,umask=0,locale=es_ES.UTF-8 0 0
y podremos estar seguro de que los discos siempre se montarán bien independientemente del orden en el que los conectemos y de las ranuras USB que usemos para conectarlas. Obviamente, las reglas udev que hemos escrito son válidas sólo para esos discos en concreto, si cambiamos esos discos por otros tendremos que cambiar también el fichero /etc/udev/misreglas.rules
El driver ntfs-3g
Para montar una particion NTFS en Linux, hay que instalar el driver ntfs-3g
$ apt-get install ntfs-3g
y añadir al fichero /etc/fstab las líneas de configuración correspondientes al disco que queremos montar. En la sección anterior aparece un fichero fstab de ejemplo, que es el que uso yo para montar mis discos. Se supone que los discos ya están formateados con NTFS sino primero hay que darles formato con NTFSprogs.
$ apt-get install ntfsprogs
$ mkntfs /dev/sdX
La opción locale usada en mi fstab no es estrictamente necesaria pero conviene ponerla por si el script de arranque del sistema no establece el locale predeterminado "a tiempo" antes de montar los discos. Las particiones NTFS utilizan UTF-16 internamente para codificar el nombre de los ficheros. Esta opción le dice a ntfs-3g que convierta UTF-16 al locale indicado, en este caso a UTF-8.
Rendimiento
El rendimiento se ve afectado por toda clase de circunstancias, lo primero que hay que ver es lo siguiente:
* ¿qué velocidad de transferencia tienen de los puertos USB?
Un puerto USB 1.1 (12Mbps) es casi inservible para conectar un disco duro externo porque el rendimiento sería paupérrimo (1MB/s como máximo). Por otro lado, a veces ocurre que nuestro ordenador tiene puertos USB 2.0 (480Mbps) pero Linux los detecta como USB 1.1. Al teclear lsmod debemos asegurarnos de que el driver usado es ehci (usb 2.0) y no uhci (usb 1.1). Revisar /etc/modprobe.d/blacklist por si ehci está incluido en la lista de controladores que no deben cargarse al arrancar.
La velocidad de tranferencia en mi caso, con discos SATA en caja USB 2.0, es la siguiente:
javg@frink:/dev$ sudo hdparm -t usbvolumeA
usbvolumeA:
Timing buffered disk reads: 80 MB in 3.02 seconds = 26.46 MB/sec
javg@frink:/dev$ sudo hdparm -t usbvolumeB
usbvolumeB:
Timing buffered disk reads: 78 MB in 3.04 seconds = 25.70 MB/sec
Las tasas de transferencia anteriores son las máximas posibles por que son las que se obtienen mediante la lectura de sectores contiguos del disco. Una lectura más realista siempre será "a saltos", el cabezal lector del disco tendrá que ir saltando aleatoriamente de sector en sector en distintas partes del disco y la velocidad de lectura, por tanto, será menor.
* ¿qué rendimiento tiene el driver ntfs-3g?
* ¿qué eficiencia tiene el protocolo samba? ¿qué tamaño tienen sus búferes de tx rx?
* ¿qué ancho de banda tiene la red ethernet?
* ¿qué tráfico reciben los switches ethernet? ¿hay congestión en ellos?
En mi caso, como los discos son accesibles a través de una red ethernet de 100Mbps el cuello de botella estará siempre en la propia red. La tasa de transferencia típica del protocolo CIFFs (samba) es de a unos 7MB/s de media lo cual es perfectamente razonable. La tasa máxima es de 10.7MB/s y se consigue usando el protocolo FTP (modo binario), que es uno de los más eficientes.
Tasa de transferencia
Protocolo Tasa de transferencia (kbytes/s) % del ancho de banda nominal (100Mbps)
FTP(binary) 10789 89
CIFS 7100 58
Samba
Instalar samba
$ apt-get install samba
el fichero de configuración /etc/samba/smb.conf contiene la lista de recusos exportados, pueden ser directorios, impresoras, etc. Una configuración mínima que permite exportar un recurso sin que pida nombre de usuario y contraseña
[global]
workgroup = MIGRUPO
server string = %h server
security = share
guest only = yes
guest account = invitado
dns proxy = no
[usbvolumeA]
comment = Volumen A
path = /mnt/usbvolumeA
browseable = yes
writable = yes
create mask = 0775
directory mask = 0775
[usbvolumeB]
comment = Volumen B
path = /mnt/usbvolumeB
browseable = yes
writable = yes
create mask = 0775
directory mask = 0775
cada vez que cambiemos el fichero de configuración debemos reiniciar el servicio
$ /etc/init.d/samba restart
Las versiones actuales de Samba no necesitan ninguna configuración especial para ver bien los acentos y eñes en el cliente Windows que monta la unidad de red.
Papelera de reciclaje en Samba
Sin ella, el borrado de un fichero es permanente y es muy difícil recuperarlo. Para añadir esta funcionalidad hay que utilizar el módulo recycle
[usbvolumeA]
comment = Volumen A
path = /mnt/usbvolumeA
browseable = yes
writable = yes
create mask = 0775
directory mask = 0775
vfs objects = recycle
config-file = /etc/samba/recycle.conf
recycle:repository = /mnt/usbvolumeA/recycle
recycle:directory_mode = 770
recycle:keeptree = Yes
recycle:versions = Yes
recycle:touch_mtime = yes
y en el fichero de configuración /etc/samba/recycle.conf ponemos esto:
name = Recycle Bin
mode = KEEP_DIRECTORIES|VERSIONS|TOUCH
maxsize = 0
A partir de ahora cada vez que eliminemos un fichero, este irá a parar al directorio /mnt/usbvolumeA/recycle, podemos usar una tarea de cron para vaciar todos los ficheros que tengan una antigüedad superior, por ejemplo, a los 30 días:
@daily find /mnt/usbvolumeA/recycle/* -mtime +30 -exec rm {} \;
Montar el disco de red en la máquina cliente
En Windows
Entrar en Mis sitios de red \rightarrow y buscar el nombre de nuestro servidor Linux. Haz click con el botón derecho en el recurso compartido y "Asignar unidad de red...". Así de simple.
En Linux
Si quereos montar el disco desde otra máquina Linux, hay que instalar el paquete smbfs
$ apt-get install smbfs
y añadir al fichero /etc/fstab las siguientes líneas
//frink/usbvolumeA /mnt/usbvolumeA smbfs user,exec,guest,uid=javg,iocharset=utf8 0 0
//frink/usbvolumeB /mnt/usbvolumeB smbfs user,exec,guest,uid=javg,iocharset=utf8 0 0
Si nos muestra el error "mount error 79 = Can not access a needed shared library" eso es porque no has tecleado bien el nombre del código de caracteres (se pone "utf8" no "utf-8"). Las opciones de montaje se pueden ver en
$ man mount.cifs
Nombres de fichero corruptos
Si una vez exportado el disco y montado en Windows o en Linux, el nombre de los ficheros contiene caracteres extraños, no se te ocurra cambiarlos a mano ni escribir nuevos ficheros en el disco pues, como ya he dicho, internamente están codificados en UTF-16, o sea, que están bien codificados. El problema no está en el sistema de ficheros NTFS del disco sino en el locale del sistema Linux servidor, el driver ntfs-3g o bien en el servidor Samba o en las opciones de montaje, pero no en NTFS.
Haz una prueba: si puedes ver correctamente los nombres de fichero en Windows conectando el disco directamente en la máquina Windows, entonces puedes estar seguro de que el problema no está en el disco NTFS. Revisa la configuración del servidor y reinicia las máquinas si es necesario