多路径配置文件自动填充脚本

一、脚本介绍

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

那我怎么得到 aliaswwid 的值呢?这时候就可以使用到我们的 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 获取需要写入的内容

如何将 aliaswwid 写入配置文件中呢?

如果有多行数据:

[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 '\
'     80    multipaths {
[root@arppinging /]# 

那如果没有外层的 mulitpaths {} 怎么办呢?这时候就需要加一个判断了,如果没有我们就给它添加上

cat -n multipath.conf | grep "\
" >/dev/null 2>&1 if [ $? -eq 0 ] then     linenumber=`cat -n multipath.conf | grep "\
" | awk '{print $1}'` else    cat << EOF >> multipath.conf multipaths {
} EOF     linenumber=`cat -n multipath.conf | grep "\
" | 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 "\
" | 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 "\
" >/dev/null 2>&1 if [ $? -eq 0 ] then     linenumber=`cat -n multipath.conf | grep "\
" | awk '{print $1}'` else    cat << EOF >> multipath.conf multipaths {
} EOF     linenumber=`cat -n multipath.conf | grep "\
" | 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"