多路径配置文件自动填充脚本
多路径配置文件自动填充脚本
一、脚本介绍
1.1 脚本编写原因
最近在项目(分布式存储+虚拟化)实施的过程中,遇到了一个琐碎的事情,因为分布式存储分了很多个lun,在多路径写多路径配置文件的时候非常繁琐,故编写了一个脚本来实现这个功能。
本脚本主要是自动填充multipath.conf文件中的multipaths参数
一般来说,/etc/multipath.conf文件是这样的:
multipaths {
multipath {
wwid 3600605b00a60a980ff0000300310f370
alias mpatha
}
multipath {
wwid 3600605b00a60a980ff0000300310f371
alias mpathb
}
multipath {
wwid 3600605b00a60a980ff0000300310f372
alias mpathc
}
multipath {
wwid 3600605b00a60a980ff0000300310f373
alias mpathd
}
}
但是如果有100个lun呢?那就要一个一个multipath去添加了,非常麻烦。
二、脚本编写
2.1 获取多路径信息
首先,使用多路径命令查看多路径信息,信息的格式:
[root@arppinging /]# multipath -ll
mpatha (360a9800064665072443469563477396c) dm-0 NETAPP,LUN
size=3.5G features='0' hwhandler='0' wp=rw
`-+- policy='round-robin 0' prio=4 status=active
|- 1:0:0:0 sdb 8:16 active ready running
`- 2:0:0:0 sde 8:64 active ready running
对比上面配置文件,可知我们需要的内容是mpatha
(alias)和360a9800064665072443469563477396c
(wwid)
我将获筛选后的值写入一个文件mpath
multipath -ll | grep mpath >> mpath
得到以下内容
[root@arppinging /]# cat mpath
mpatha (360a9800064665072443469563477396c) dm-0 NETAPP,LUN
那我怎么得到 alias
和 wwid
的值呢?这时候就可以使用到我们的 awk
啦
[root@arppinging /]# dev=`awk '{print $1}' mpath`
[root@arppinging /]# wwid=`awk 'print $2' mpath`
[root@arppinging /]# echo $dev
mpatha
[root@arppinging /]# echo $wwid
(360a9800064665072443469563477396c)
由此可见wwid
并不满足我们的要求,因为在配置文件中, wwid
是没有()
的,所以我们需要使用 sed
将文本中的()
去掉,为防止有其他内容存在,将非 m
开头的行和空白行也删除
[root@arppinging /]# sed -i 's/(\|)/^[^m]/g' mpath
[root@arppinging /]# sed -i '/^[^m]\|^$/d' mpath
[root@arppinging /]# cat mpath
mpatha 360a9800064665072443469563477396c dm-0 NETAPP,LUN
再次获取值
[root@arppinging /]# wwid=`awk 'print $2' mpath`
[root@arppinging /]# echo $wwid
360a9800064665072443469563477396c
2.2 获取需要写入的内容
如何将 alias
和 wwid
写入配置文件中呢?
如果有多行数据:
[root@arppinging /]# cat mpath
mpatha 3600605b00a60a980ff0000300310f370 dm-0 LSI ,MR9261-8i
mpathb 3600605b00a60a980ff0000300310f371 dm-0 LSI ,MR9261-8i
mpathc 3600605b00a60a980ff0000300310f372 dm-0 LSI ,MR9261-8i
mpathd 3600605b00a60a980ff0000300310f373 dm-0 LSI ,MR9261-8i
mpathe 3600605b00a60a980ff0000300310f374 dm-0 LSI ,MR9261-8i
mpathf 3600605b00a60a980ff0000300310f375 dm-0 LSI ,MR9261-8i
mpathg 3600605b00a60a980ff0000300310f376 dm-0 LSI ,MR9261-8i
mpathh 3600605b00a60a980ff0000300310f377 dm-0 LSI ,MR9261-8i
mpathi 3600605b00a60a980ff0000300310f378 dm-0 LSI ,MR9261-8i
mpathj 3600605b00a60a980ff0000300310f379 dm-0 LSI ,MR9261-8i
mpathk 3600605b00a60a980ff0000300310f37a dm-0 LSI ,MR9261-8i
mpathl 3600605b00a60a980ff0000300310f37b dm-0 LSI ,MR9261-8i
mpathn 3600605b00a60a980ff0000300310f37c dm-0 LSI ,MR9261-8i
使用 while
对文本进行逐行处理,并将结果写入mpath.conf文件
while read line
do
dev=`echo $line | awk '{print $1}'`
wwin=`echo $line | awk '{print $2}'`
cat << EOF >> mpath.conf
multipath {
wwid $wwin
alias $dev
}
EOF
done < mpath
查看 mpath.conf
文件
multipath {
wwid 3600605b00a60a980ff0000300310f37b
alias mpathl
}
multipath {
wwid 3600605b00a60a980ff0000300310f37c
alias mpathn
}
2.3 定位插入位置
那么我需要在哪里插入2.3获取到的内容呢?
首先我们要明确,在配置文件中的格式是这样的:
multipaths {
multipath {
}
}
而我们获取的内容是:
multipath {
}
很明显我们需要找到外层的 multipaths {}
并在中间插入内容
[root@arppinging /]# cat -n multipath.conf | grep '\<multipaths\>'
80 multipaths {
[root@arppinging /]#
那如果没有外层的 mulitpaths {}
怎么办呢?这时候就需要加一个判断了,如果没有我们就给它添加上
cat -n multipath.conf | grep "\<multipaths\>" >/dev/null 2>&1
if [ $? -eq 0 ]
then
linenumber=`cat -n multipath.conf | grep "\<multipaths\>" | awk '{print $1}'`
else
cat << EOF >> multipath.conf
multipaths {
}
EOF
linenumber=`cat -n multipath.conf | grep "\<multipaths\>" | awk '{print $1}'`
fi
定位到该位置的行号后,那么我可以使用 sed
在mulitipath.conf文件80行后插入mpath.conf的内容
sed -i "${linenumber}r mpath.conf" multipath.conf
这样就好了!
三、完整脚本
#!/bin/bash
# date:2019/2/21
# 脚本功能:自动将wwin和盘符信息写入multipath.conf文件
# 定义文件内容优化函数,主要是删除文本中非多路径内容
mpathtext (){
echo > mpath.conf
echo > mpath
multipath -ll | grep mpath >> mpath
sed -i 's/(\|)//g' mpath
sed -i '/^[^m]\|^$/d' mpath
}
# 定义不能再/etc/目录下对配置文件操作和判断配置文件是否存在
condition (){
path=`echo $PWD | awk -F'/' '{print $2}'`
[ $path = 'etc' ] && echo -e "\033[31m[ERROR]\033[0m 请勿在/etc/目录下执行脚本" && exit 1
# cp /etc/multipath.conf ${PWD}/
# [ $? -ne 0 ] && echo "\033[31m [ERROR]\033[0m /etc/下没有multipath.conf文件" && exit 2
ls -l ${PWD}/multipath.conf 1>/dev/null 2>&1
[ $? -ne 0 ] && echo -e "\033[31m[ERROR]\033[0m 当前目录下没有multipath.conf文件" && exit 2
}
# 是否需要删除 `multipaths` 参数的所有配置
reset (){
read -p "是否删除multipath.conf文件已有的multipaths参数?[y/n][n]:" option
option=${option:-'n'}
case $option in
n)
;;
y)
linenumber=`cat -n multipath.conf | grep "\<multipaths\>" | awk '{print $1}'`
if [ ! -n "$linenumber" ];then
echo -e "无multipaths参数. \033[32m [OK]\033[0m"
else
sed -i ${linenumber},'$'d multipath.conf
echo -e "multipaths参数已经被删除. \033[32m [OK]\033[0m"
fi
;;
*)
echo -e "\033[31m[ERROR]\033[0m input error,please enter n or y"
exit 3
;;
esac
}
condition
reset
mpathtext
# 定位多路径配置文件的行,如果不存在,则创建multipaths参数。
cat -n multipath.conf | grep "\<multipaths\>" >/dev/null 2>&1
if [ $? -eq 0 ]
then
linenumber=`cat -n multipath.conf | grep "\<multipaths\>" | awk '{print $1}'`
else
cat << EOF >> multipath.conf
multipaths {
}
EOF
linenumber=`cat -n multipath.conf | grep "\<multipaths\>" | awk '{print $1}'`
fi
# 将获取到的wwin和盘符写入mpath.conf文件
while read line
do
dev=`echo $line | awk '{print $1}'`
wwin=`echo $line | awk '{print $2}'`
cat << EOF >> mpath.conf
multipath {
wwid $wwin
alias $dev
}
EOF
done < mpath
# 将mpath.conf文件插入配置文件中
sed -i "${linenumber}r mpath.conf" multipath.conf
echo -e "multipath.conf文件修改完成. \033[32m [OK]\033[0m"