用 qemu-nbd 挂载 虚拟硬盘的 脚本,2016.11.26 改进.

感谢 ubuntu挂载vdi
http://www.ubuntukylin.com/ukyli … iewthread&tid=27107
(出处: Ubuntu Kylin技术论坛)

就是 用 qemu-nbd 把 vhd 挂到 /dev/nbdX (x=0~15)
再把 /dev/nbdXp1 (X=0-15) 也就是 vhd的第一个分区 挂到 vhd所在目录里的新建目录上.
卸载 过程 与之相反
这里面需要 考虑 当前可用的 /dev/nbdX 要 0-15 的 排查, 记住 X 是多少,卸载的时候 好用到.当然这个都 是脚本自动完成的.

qemu-nbd.mount-sh-4.2.zip (2.22 KB)

vhd4.sh

#!/bin/sh
# 通过 qemu-nbd 实现 vhd 的挂载 ,事先需要安装 qemu-utils , name:vhd4.sh
# 需要事先 sudo apt-get install qemu-utils
# 在vhd所在目录新建名为 "v_disk.vhd文件名/p1" 的目录
# 判断 qemu-nbd 提供的可用于虚拟的 /dev/nbdX 共X=16个,将判断结果存入 目录 "vhd文件名.v_disk" 中的nbdx.tmp 中
# 把 vhd 文件 虚拟到 /dev/nbdX ,并把 /dev/nbdXp1 挂载到目录 "vhd文件名.v_disk/p1"

#根据vhd文件路径和名称 确定变量 VhdPath 用于建立挂载目录
VhdPath=$(realpath "$1").v_disk

#如果 位置已经被挂载,就退出。
if [ `df|grep "$VhdPath"|wc -l` -eq 1 ]  ;then
	echo 不能重复挂载!
	exit
fi

sudo mkdir "$VhdPath/p1" -p

#找出16个nbd设备中第一个可用于虚拟vhd 的设备 赋值给变量 x
#如果16个设备 均已被占用 ,那么 x=16
for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  16 ; do 
	if  ! [ -b /dev/nbd${x}p1 ] ; then 
		break
	fi
done

#如果 变量 x 不等于 16 就将第一个可用的 nbd 设备写入 挂载目录 下的 nbdx.tmp中, 并挂载 vhd 文件.
if [ $x -ne 16 ] ;then 
	echo nbd${x}>~/nbdx.tmp
	sudo mv ~/nbdx.tmp "$VhdPath/nbdx.tmp"
	echo 正在挂载......   	
	echo "`realpath "$1"` ==> /dev/nbd${x}" 
	echo "/dev/nbd${x}p1 ==> $VhdPath/p1"
	sudo modprobe nbd
	sudo qemu-nbd -c /dev/nbd${x} "`realpath "$1"`"
	#循环 直到 nbd 设备挂载成功
	while  ! [ -b /dev/nbd${x}p1 ] ; do
		sleep 1
		echo -n .
	done
	sudo mount /dev/nbd${x}p1 "$VhdPath/p1"
else 
	echo 没有可用的'"qemu-nbd"'设备来挂载虚拟硬盘!
fi
echo . && echo End ....

脚本中用到:
1.shell 脚本语句:
if ;then fi 条件语句
while ;do done 循环语句
for x in ;do done 循环语句
breek 跳出循环
! 条件的应用, 数值对比 字符串对比 运算, 特定设备判定
2.shell 命令
mount umount 分区挂载与卸载
包裹的命令结果输出传递
变量的设置
mkdir 文件夹的建立 , rm 删除, cp 拷贝,sleep 延时
read 读取文件
3.第三方软件
qume-utils (qume-nbd) 虚拟硬盘支持组件

更新下,可以一次自动挂载 虚拟盘中的全部分区。
附件 附卸载脚本。
用到了 awk ,df ,fdisk ,正则, 用来计算分析 虚拟硬盘文件分区 信息 和 挂载信息。

vhd5.sh 内容

#!/bin/sh
# 通过 qemu-nbd 实现 vhd 的挂载 ,事先需要安装 qemu-utils , name:vhd5.sh
# 需要事先 sudo apt-get install qemu-utils
# 在vhd所在目录新建名为 "v_disk.vhd文件名" 的目录
# 把 vhd 文件 虚拟到 /dev/nbdX ,并把虚拟硬盘的各分区 /dev/nbdXpY 挂载到目录 "vhd文件名.v_disk/nbdXpY"

#用法 vhd5.sh vhd文件名 

#判断是否存在vhd文件
if ! [ -f "$1" ] ;then
	echo 文件没找到!
	exit
fi

#根据vhd文件路径和名称 确定变量 VhdPath 用于建立挂载目录 和分区
VhdPath=$(realpath "$1").v_disk

#判断虚拟硬盘文件是否已经被挂载了
if [ `df --output=target | awk -v pl="${VhdPath}" -v a=0 '$0~"^" pl "/nbd[0-9]+p[0-9]+$" {a+=1} END {print a}'` -ge 1 ] ; then 
	echo 不可重复挂载!
	exit
fi

#找出16个nbd设备中第一个可用于虚拟 vhd 的设备 赋值给变量 x
#如果16个设备 均已被占用 ,那么 x=16
for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  16 ; do 
	zj=`df --output=source | awk -v x=${x} -v a="true" '$1~"^/dev/nbd[0-9]+p[0-9]+$" {if (substr($1,9,length(x))==x) { a="false" }} END {print a}'`
	if [ "$zj" = "true" ] ; then
		break
	fi
done
#如果 变量 x 不等于 16 就将第一个可用的 nbd 设备 挂载 vhd 文件.
if [ $x -ne 16 ] ;then 
	echo 正在挂载......   	
	echo "`realpath "$1"` ==> /dev/nbd${x}" 
	sudo modprobe nbd
	sudo qemu-nbd -c /dev/nbd${x} "`realpath "$1"`"
	#10秒内 循环判断 虚拟硬盘可用分区数量,用已明确 虚拟硬盘是否已经被挂载且有可用于挂载的分区,如果否,就卸之并退出。
	#挂载需要时间,而且15秒 都不能 挂上,也就可以不用挂了。	
	for n in  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  ; do 		
		echo -n .
		sleep 1
		px=`sudo fdisk -l /dev/nbd${x}|awk -v a=0 '$1~"^/dev/nbd[0-9]+p[0-9]+$"&&$6!~"^[5f]$"&&$6!="85" {a+=1} END {print a}'`
		if [ ${px} -ge 1 ] ;then 
			break
		fi
	done
	if  [ $px -eq 0 ] ;then 
		echo 虚拟硬盘文件不可用,或者没有可用分区!
		sudo qemu-nbd -d /dev/nbd${x}
		exit
	else
		echo 发现可用分区! $px
	fi

	#创建挂载目录
	sudo mkdir "$VhdPath" -p
	#找出虚拟硬盘的各个 可用分区并 逐一挂载。
	for x in `sudo fdisk -l /dev/nbd${x}|awk '$1~"^/dev/nbd[0-9]+p[0-9]+$"&&$6!~"^[5f]$"&&$6!="85" {print substr($1,6)}'` ; do 
		sudo mkdir "${VhdPath}/${x}" -p
		echo "/dev/${x} ==> ${VhdPath}/${x}"
		#循环判断分区是否成功挂载 挂载成功就进行下一分区的挂载。		
		while [ `df --output=target | awk -v a=0 -v pl="${VhdPath}/${x}" '$0~"^"pl"$" {a+=1} END {print a}'` -eq 0 ] ; do
			echo -n ..
			sudo mount /dev/${x} "${VhdPath}/${x}"
			sleep 1
		done
		echo .
	done
else 
	echo 没有可用的'"qemu-nbd"'设备来挂载虚拟硬盘!
fi
echo End ....


qemu-nbd-sh.mount.5.2.zip (3.37 KB)