Disco virtual
Existen muchos métodos para crear y montar máquinas virtuales y también muchos formatos. Por lo general utilizamos hipervisores para crearlas y ponerlas en producción. Pero hablamos de sistemas completos virtualizados.
Y si solo queremos crear un disco virtual vacío, bien sea para almacenar archivos o para crear unidades de disco en red y muchos otros usos. En este caso, muchos afirman que compartir un disco físico es mejor, más fiable y simple, y tienen toda la razón, pero hay algunos escenarios en que tenemos un solo disco y necesitamos crear volúmenes independientes para el manejo de archivos privados y públicos para muchos usuarios o propósitos, y para lograrlo tendríamos que hacer tantas particiones como volúmenes necesitemos, en cambio, los discos virtuales, al ser tratados por los sistemas operativos como archivos, podrían ser una buena alternativa de solución, ya que es mejor tener muchos discos virtuales (archivos) dentro de un solo disco físico, que un disco físico con un montón de particiones. Y sin mencionar que es más sencillo hacer un backup de un disco virtual que de un físico.
Existen muchos formatos para los discos virtuales, tales como .vhd o .vhdx (Microsoft Virtual PC / Hyper-V), .vmdk (VMware), .vdi (Oracle VirtualBox), .img (archivos binarios), etc, etc; algunos de los cuales pertenecen al estándar abierto Open Virtualization Format.
Estos discos se crean en dependencia de su tamaño, por ejemplo Fixed Size (Tamaño Fijo. Este formato es el más parecido a un disco físico. Tienen un tamaño establecido en su creación, sin importar la cantidad de datos), Dynamically Expanding (Expansión Dinámica. Se incrementa a medida que el disco se va llenando) y Differencing (Diferenciales), siendo los de Tamaño Fijo los más confiables.
Para crearlos podemos hacer uso de hipervisores, como Virtualbox, pero el procedimiento es algo engorroso, ya que primero hay que crear la VM y luego convertir el disco de formato VDI a otro formato más amigable como IMG.
Y si solo queremos crear un disco virtual vacío, bien sea para almacenar archivos o para crear unidades de disco en red y muchos otros usos. En este caso, muchos afirman que compartir un disco físico es mejor, más fiable y simple, y tienen toda la razón, pero hay algunos escenarios en que tenemos un solo disco y necesitamos crear volúmenes independientes para el manejo de archivos privados y públicos para muchos usuarios o propósitos, y para lograrlo tendríamos que hacer tantas particiones como volúmenes necesitemos, en cambio, los discos virtuales, al ser tratados por los sistemas operativos como archivos, podrían ser una buena alternativa de solución, ya que es mejor tener muchos discos virtuales (archivos) dentro de un solo disco físico, que un disco físico con un montón de particiones. Y sin mencionar que es más sencillo hacer un backup de un disco virtual que de un físico.
Existen muchos formatos para los discos virtuales, tales como .vhd o .vhdx (Microsoft Virtual PC / Hyper-V), .vmdk (VMware), .vdi (Oracle VirtualBox), .img (archivos binarios), etc, etc; algunos de los cuales pertenecen al estándar abierto Open Virtualization Format.
Estos discos se crean en dependencia de su tamaño, por ejemplo Fixed Size (Tamaño Fijo. Este formato es el más parecido a un disco físico. Tienen un tamaño establecido en su creación, sin importar la cantidad de datos), Dynamically Expanding (Expansión Dinámica. Se incrementa a medida que el disco se va llenando) y Differencing (Diferenciales), siendo los de Tamaño Fijo los más confiables.
Para crearlos podemos hacer uso de hipervisores, como Virtualbox, pero el procedimiento es algo engorroso, ya que primero hay que crear la VM y luego convertir el disco de formato VDI a otro formato más amigable como IMG.
VBoxManage clonehd --format RAW MyDisk.vdi MyDisk.imgY luego montarlo en dependencia del tipo de partición que tengan:
mount -t ntfs -o loop,rw MyDisk.img /mntEl rey por excelencia para estos menesteres es Gparted...
Gparted Interface |
Que con su potente e intuitiva interfaz gráfica podemos particionar nuestros discos virtuales de acuerdo a nuestras necesidades.
GParted Create Partition |
Sin embargo, para aquellos que no disponen de entorno gráfico está Parted, ideal para trabajar por terminal.
Advertencia:
Antes de avanzar debemos aclarar algo. Recomendaremos el uso de formatos de imágenes flexibles y dinámicos, como VHD/VHDX (vea sus diferencias en el post Comprender y trabajar con archivos VHD/X), VDI (nativo de Virtualbox. Lea Cómo montar la imagen de disco de VirtualBox (VDI) para acceder al sistema de archivos de VM en Ubuntu), entre otros, sin embargo en este post nos referiremos exclusivamente al formato .img, no porque sea mejor o peor que los anteriores, sino porque es más universal, por ser binario, y a la creación de estas imágenes con el programa dd.
Existen otras opciones para crear imágenesestas imágenes rápidamente, tales como:
truncate -s 10G 10GB_HDD.img fallocate -l 10G 10GB_HDD.img
Pero debe saber que truncate se usa en un sistema de archivos que admita archivos dispersos (como ext4), pero fallocate no. Un archivo disperso es aquel en el que las unidades de asignación que componen el archivo no se asignan realmente hasta que se utilizan, sin embargo, los metadatos del archivo ocuparán un espacio considerable. Este tipo de archivo tiene ventajas y desventajas. Un archivo no disperso tiene sus bloques (unidades de asignación) asignados con anticipación. Además ni
fallocate
, ni truncate
pueden establecer el contenido del archivo a un valor especificado, como es el caso de dd
, en cambio, el contenido de un archivo asignado con fallocate
o truncate
puede ser cualquier valor de basura que existía en las unidades asignadas durante la creación y este comportamiento puede o no ser deseado. Adicionalmente estas opciones tienen limitaciones en cuanto a su uso en determinados sistemas de archivos. fallocate
es similar a dd
, en cuanto a que ambos pre-asignan bloques a un archivo, pero, a diferencia de dd
, que escribe ceros en estos bloques, fallocate
se limita a pre-asignar el espacio, si escribir el archivo.
dd
es el más lento, ya que en realidad escribe el valor o fragmento de datos a toda la secuencia de archivo como se especifica con ella son las opciones de línea de comandos, pero es más seguro. Hay limitación en cuanto al tamaño (máx 2GB), pero existe un truco y es asignar el tamaño en megabytes a la opción count
. Por ejemplo:
# 4GB size in megabytes dd if=/dev/urandom of=4GB_HDD.img bs=1M count=4096
# 10GB size in megabytes dd if=/dev/urandom of=10GB_HDD.img bs=1M count=10240
En el siguiente ejemplo, vamos a automatizar la creación de un disco virtual en formato
.img.
Lo podemos adaptar, cambiando los valores de las variables. Por ejemplo, el script establece mydisk.img
como el nombre de la imagen, la partición msdos y 1 GB de tamaño (o sea 1024) y la etiqueta de la partición mydisk
. Y al lanzar la pregunta sobre el sistema de archivos, debemos escribir: ext4, fat32, ntfs o hfs (puede agregar más opciones): #!/bin/bash # variables myuser=user # your user account mountpoint="/home/$myuser/disk" # path to mount point folder pathimg="/home/$myuser/img" # path to .img folder vdisk="$pathimg/mydisk.img" # path .img file vptable="msdos" # msdos, gpt vsize="1024" # MB/MiB vlabel=mydisk # disk label vbs="1M" # 1M or 1k/2k/4k/16k ptype="primary" # primary/logical/extended # create path if doesn't exist if [ ! -d $route ]; then mkdir -p $route; chmod a+rwx -R * $route; fi if [ ! -d $pathimg ]; then mkdir -p $pathimg; chmod a+rwx -R * $pathimg; fi # create img dd if=/dev/zero | pv | dd of=$vdisk iflag=fullblock bs=$vbs count=$vsize && sync # format ntfs/fat32/ext4 function pntfs(){ parted $vdisk \ mklabel $vptable \ mkpart $ptype ntfs 2048s 100% \ set 1 lba on \ align-check optimal 1 mkntfs -Q -v -F -L "$vlabel" $vdisk ntfsresize -i -f -v $vdisk ntfsresize --force --force --no-action $vdisk ntfsresize --force --force $vdisk fdisk -lu $vdisk } function pfat32(){ parted $vdisk \ mklabel $vptable \ mkpart $ptype fat32 2048s 100% \ set 1 lba on \ align-check optimal 1 mkfs.fat -F32 -v -I -n "$vlabel " $vdisk fsck.fat -a -w -v $vdisk fdisk -lu $vdisk } function pext4(){ parted $vdisk \ mklabel $vptable \ mkpart $ptype 2048s 100% mkfs.ext4 -F -L "$vlabel" $vdisk parted -s $vdisk align-check optimal 1 e2fsck -f -y -v -C 0 $vdisk resize2fs -p $vdisk fdisk -lu $vdisk } function phfs(){ # for mac #apt-get install hfsutils hformat -l "$vlabel" $vdisk #To mount #mount -t hfs -o loop image.img mountpoint } read -p "Enter File System (e.g. ntfs, fat32, ext4, hfs): " pset case $pset in "ntfs") pntfs ;; "fat32") pfat32 ;; "ext4") pext4 ;; "hfs") phfs ;; *) echo "unknown option" ;; esac
Si no va a utilizar el 100% del espacio del disco, sino un espacio específico, reemplace:
mkpart primary $vptable 2048s 100%
Por:
mkpart primary $vptable 1 $vsize
Donde $vsize es la variable que almacena el tamaño exacto del disco que va a usar, en MB/MiB.
Nota: Si utiliza GPT en lugar de msdos, hay cambios significativos, por tanto el script deberá adaptarlo o no le servirá, ya que GPT no admite particiones extendidas/lógicas. Para mayor información pulse AQUI
Montaje del Disco Virtual
Montaje del Disco Virtual
Hay varias maneras de montar un disco virtual, ya sea de forma automática, con el inicio del sistema o manualmente.
Nota: reemplace "/path_to/" o /path_to/mountpoint" por las rutas hacia la imagen de disco y carpeta de montaje
Método 1: GUI
Linux utiliza Loop Device para el tratamiento de las imágenes de disco (ISO, IMG, etc). Los loops son dispositivos de bucle (/dev/loop*) que hacen que los archivos sean accesibles como dispositivos de bloque (Para mayor información visite How to use loop devices.). Por tanto, montar el disco virtual .img es similar a como si lo hiciéramos con una imagen .ISO (botón derecho sobre la imagen .img, y seleccionar "montador de imágenes de disco") y el sistema la enviará al loop que esté desocupado.
Método 2: Terminal
También puede montarla desde la consola a un punto de anclaje específico. Tenga en cuenta que "mount" requiere privilegios, por tanto, si no está trabajando desde root, o quiere que el usuario desde el que trabaja tenga acceso a la carpeta, debe cambiar el propietario de la misma y habilitar su escritura:
También puede montarla desde la consola a un punto de anclaje específico. Tenga en cuenta que "mount" requiere privilegios, por tanto, si no está trabajando desde root, o quiere que el usuario desde el que trabaja tenga acceso a la carpeta, debe cambiar el propietario de la misma y habilitar su escritura:
mount -o loop,rw,sync /path_to/filename.img /path_to/mountpoint sudo chown $USER:$USER /path_to/mountpoint sudo chmod 777 /path_to/mountpoint
También puede montar el disco virtual especificando el loop:
losetup loop1 /path_to/filename.img
Pero es importante que verifique la disponibilidad del loop antes y después de montar el disco virtual:
ls /dev/loop* losetup --list NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE /dev/loop1 0 0 0 0 /path_to/filename.img
Si queremos verificar la imagen montada en loop con Gparted:
sudo -H gparted /dev/loopx
Y para desmontar:
# umount sudo losetup -d /dev/loopx
Proceso completo con
losetup:
losetup -f /dev/loop8 sudo losetup -P /dev/loop8 /path_to/filename.img sudo losetup -l /dev/loop8 0 0 0 0 /path_to/filename.img 0 512 # edit /etc/fstab and put the line: # /path/to/loop/device /path_to/mountpoint auto loop 0 0 # example: /dev/loop8 /path_to/mountpoint ext4 defaults 0 0 # and: sudo mount -a
Método 3: Con
bindfs
sudo mkdir /mnt/disk # edit fstab and add line: /path_to/filename.img /mnt/disk auto defaults 0 0 sudo mount -a sudo -u $USER bindfs -n /mnt/disk /path_to/mountpoint
Método 4: bash script (recomendado)
#!/bin/bash myuser="user" # your user dst="/home/$myuser/vdisk" # path to mount point img="/home/$myuser/img/test.img" # path to .img file case "$1" in 'start') # mount echo "Mounting Virtual Disk..." # create destination folder if doesn't exist if [ ! -d "$dst" ]; then sudo -u "$myuser" mkdir -p "$dst"; fi > /dev/null # mount mount -v -o loop "$img" "$dst" echo "Virtual Disk Mount: $(date)" | tee -a /var/log/syslog ;; 'stop') echo "Umounting Virtual Disk..." # umount umount "$dst" echo "Virtual Disk Umount: $(date)" | tee -a /var/log/syslog ;; *) echo "Usage: $0 { start | stop }" ;; esac
Para iniciarlo o detenerlo:
sudo ./mountimg.sh start sudo ./mountimg.sh stop
Para iniciarlo con el sistema, edite crontab y agregue la tarea:
sudo crontab -e @reboot /path_to/mountimg.sh start
Uniendo ambos scripts:
Este es un bash script que unifica tanto el montaje/desmontaje de la imagen, como su creación. Se usa
sudo ./vdisk.sh start sudo ./vdisk.sh stop
Cambie las variables y valores según sus necesidades:
#!/bin/bash # This script create, format and mount/umount Virtual Hard Disk (VHD) image (.img) # check dependencies pkg='libnotify-bin' if apt-get -qq install $pkg; then echo "OK" else echo "Error installing $pkg. Abort" exit fi # CHANGE VALUES AND PATHS # your user account myuser="your_user" # path to mount point folder (change it) mountpoint="/home/$myuser/vdisk" # path to .img folder (change it) myvhd="/home/$myuser/myvhd" # path to .img file (e.g: 4GB_HDD.img) (change it) myimg="$myvhd/1GB_HDD.img" # choose type: msdos, gpt vptable="msdos" # Large .img file in MB/MiB (e.g: 4096 = 4GB) vsize="1024" # disk label vlabel="mydisk" # 1M or 1k/2k/4k/16k vbs="1M" # partition: primary/logical/extended ptype="primary" # create and format disk .img function create_img(){ # create img dd if=/dev/zero | pv | dd of=$myimg iflag=fullblock bs=$vbs count=$vsize && sync # format ntfs function pntfs(){ parted $myimg \ mklabel $vptable \ mkpart $ptype ntfs 2048s 100% \ set 1 lba on \ align-check optimal 1 mkntfs -Q -v -F -L "$vlabel" $myimg ntfsresize -i -f -v $myimg ntfsresize --force --force --no-action $myimg ntfsresize --force --force $myimg fdisk -lu $myimg } # format fat32 function pfat32(){ parted $myimg \ mklabel $vptable \ mkpart $ptype fat32 2048s 100% \ set 1 lba on \ align-check optimal 1 mkfs.fat -F32 -v -I -n "$vlabel " $myimg fsck.fat -a -w -v $myimg fdisk -lu $myimg } # format ext4 function pext4(){ parted $myimg \ mklabel $vptable \ mkpart $ptype 2048s 100% mkfs.ext4 -F -L "$vlabel" $myimg parted -s $myimg align-check optimal 1 e2fsck -f -y -v -C 0 $myimg resize2fs -p $myimg fdisk -lu $myimg } # format hfs function phfs(){ # for mac #apt-get install hfsutils hformat -l "$vlabel" $myimg # To mount #mount -t hfs -o loop image.img mountpoint } read -p "Enter File System (e.g. ntfs, fat32, ext4, hfs): " pset case $pset in "ntfs") pntfs ;; "fat32") pfat32 ;; "ext4") pext4 ;; "hfs") phfs ;; *) echo "unknown option" ;; esac } case "$1" in 'start') # if no mount point exists, create it if [ ! -d $mountpoint ]; then mkdir -p $mountpoint; chmod a+rwx -R * $mountpoint; fi # if no img folder exists, create it if [ ! -d $myvhd ]; then mkdir -p $myvhd; chmod a+rwx -R * $myvhd; fi # if no .img exists, create it if [ ! -f $myimg ]; then create_img; fi # mount .img echo "Mount VHD-IMG..." mount -o loop,rw,sync "$myimg" "$mountpoint" chmod a+rwx -R * "$mountpoint" notify-send "VHD-IMG Mount:" "$(date)" -i checkbox echo "VHD-IMG Mount: $(date)" | tee -a /var/log/syslog ;; 'stop') # umount .img echo "Umount VHD-IMG..." umount "$mountpoint" ;; *) echo "Usage: $0 { start | stop }" ;; esac
Método 5: Con
kpartx
kpartx
, un pequeño programa que detecta las particiones en una imagen de disco y genera en /dev/loopXX
los mapeos necesarios para poder montarlas como si fueran particiones en un disco real.
Lista el mapeo de particiones que se agregarían con la opción -a
kpartx -l mydisk.img
Agrega/Monta la partición del disco virtual en
/dev/loopXX
(según el comando anterior): kpartx -a mydisk.img
Para crear (verificar si existe el mapeo, de lo contrario hágalo en el
loop
): mkfs.ext4 /dev/loopXX
Elimina/desmonta el mapeo de la partición:
kpartx -d mydisk.img
A continuación un script para montar/desmontar una imagen con
kpartx
#!/bin/bash # Mount/Umount .img with kpartx # your user account myuser="user" # path to mount point folder mountpoint="/home/$myuser/vdisk" # path to .img folder myvhd="/home/$myuser/ssd/test" # path to .img file (e.g: 4GB_HDD.img) myimg="$myvhd/1GB_HDD.img" case "$1" in 'start') # mount .img echo "Mount VHD-IMG..." kpartx -a -v "$myimg" for f in $(losetup --list | grep "$myvhd" | awk '{print $1}'); do mount $f "$mountpoint"; done ;; 'stop') # umount .img echo "Umount VHD-IMG..." umount "$mountpoint" if [ -n "`kpartx -d -v "$myimg"`" ]; then echo "VHD-IMG Umount: $(date)" | tee -a /var/log/syslog else echo "No Mounted Image" fi ;; *) echo "Usage: $0 { start | stop }" ;; esac
Para más opciones visite Kpartx
Importante
- Para los casos de discos virtuales con varias particiones, lo más recomendado es realizar el proceso directamente en el dispositivo de bucle
/dev/loopXX
en lugar de la imagen .img
, ya que el comando mkfs
eventualmente podría destruir las particiones. Para estos casos utilice el script de GracefulRestart
- También puede crear la imagen de disco virtual con Gparted, siguiendo el tutorial de Kos
- Otro script similar es el imgKreator de Nagren
- Los scripts bash están diseñados para crear/montar/desmontar .im con una sola partición primaria
- Para más opciones lea parted (8) - Linux Man Pages
- En algunas versiones de Ubuntu y en algunos administradores de archivos, si monta la imagen
.img
directamente a un directorio con fstab
, puede aparecer duplicada, por tanto no se recomienda - Para montar una imagen de disco .img en Windows podemos usar la aplicación OSFMount
OSFMount |
Post a Comment