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

一、脚本介绍1.1 脚本编写原因二、脚本编写2.1 获取多路径信息2.2 获取需要写入的内容2.3 定位插入位置三、完整脚本

一、脚本介绍

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 '\<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"