前言
ltp源码经过编译安装后,会在安装目录下生成testscripts目录,该目录下存放了大量的脚本,是ltp测试的一部分:
liuding@liudinghu-HP-288-Pro-G2-MT:~/chuyong/ltp-full-20230127$ cd builds/testscripts/
liuding@liudinghu-HP-288-Pro-G2-MT:~/chuyong/ltp-full-20230127/builds/testscripts$ ls
autofs1.sh load_stress_all_kernel_modules.sh ltpdmmapper.sh lvmtest.sh sysfs.sh tpm_tools.sh
autofs4.sh ltp-aiodio.sh ltp-scsi_debug.sh network.sh test_realtime.sh
本次文章重点分析autofs*.sh脚本的实现细节。
1.autofs
1.1什么是autofs
Purpose
The goal of autofs is to provide on-demand mounting and race free automatic unmounting of various other filesystems. This provides two key advantages:
- There is no need to delay boot until all filesystems that might be needed are mounted. Processes that try to access those slow filesystems might be delayed but other processes can continue freely. This is particularly important for network filesystems (e.g. NFS) or filesystems stored on media with a media-changing robot.
- The names and locations of filesystems can be stored in a remote database and can change at any time. The content in that data base at the time of access will be used to provide a target for the access. The interpretation of names in the filesystem can even be programmatic rather than database-backed, allowing wildcards for example, and can vary based on the user who first accessed a name.
*以上文段节选自https://www.kernel.org/doc/html/next/filesystems/autofs.html
翻译如上文段,就可以知晓,autofs的目标是提供各种其他文件系统的自动挂载和自动卸载。autofs与mount/umount的不同之处在于,它是一种看守程序。如果它检测到用户正试图访问一个尚未挂接的文件系统,它就会自动检测该文件系统,如果存在,那么autofs会自动将其挂接。另一方面, 如果它检测到某个已挂接的文件系统在一段时间内没有被使用,那么autofs会自动将其卸载。因此一旦运行了autofs后,用户就不再需要手动完成文件系统的挂接和卸载。
1.2autofs的使用准备工作
autofs的使用,需要系统安装autofs工具。本文以ubuntu为例:
#apt install autofs
1.3autofs挂载实践
了解autofs的使用过程,有利于接下来的脚本分析。不过鉴于网上已经有很多的教程,本文不再赘述,可以参考如下文章:
https://blog.csdn.net/weixin_40228200/article/details/121583357
2.ltp的autofs*.sh源码分析
2.1测试脚本分析
autofs的测试脚本,ltp内是有两个的,分别是autofs1.sh、autofs4.sh。本次分析以autofs1.sh为例(后面会解释为什么),分析以注释的方式呈现:
#!/bin/bash
##############################################################
#
# Copyright (c) International Business Machines Corp., 2003
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# FILE : autofs1.sh
# USAGE : autofs1.sh <disk_partition>
#
# DESCRIPTION : A script that will test autofs on Linux system.
# REQUIREMENTS:
# 1) System with a floppy device with a floppy disk in it.
# 2) A spare (scratch) disk partition of 100MB or larger.
#
# HISTORY :
# 06/11/2003 Prakash Narayana (prakashn@us.ibm.com)
# 08/01/2005 Michael Reed (mreed10@us.ibm.com)
# - Added an check to see if a directory exists
# - This prevents unnessary failures
# - Correction to an echo statement
# - Added an additional error message if a floppy disk is not present
#
# CODE COVERAGE:
# 41.46% - fs/autofs/dirhash.c
# 33.33% - fs/autofs/init.c
# 27.70% - fs/autofs/inode.c
# 38.16% - fs/autofs/root.c
# 0.00% - fs/autofs/symlink.c
# 43.40% - fs/autofs/waitq.c
#
##############################################################
##############################################################
#
# Make sure that uid=root is running this script.
# Validate the command line argument as a block special device.
# Make sure that autofs package has been installed.
# Make sure that autofs module is built into the kernel or loaded.
#
##############################################################
# 检测是否具有root权限
if [ $UID != 0 ]
then
echo "FAILED: Must have root access to execute this script"
exit 1
fi
# 检测是否传入disk分区
if [ $# != 1 ]
then
echo "FAILED: Usage $0 <disk_partition>"
echo "Example: $0 /dev/hdc1"
exit 1
else
disk_partition=$1
# 检测入参的块设备是否真实存在
if [ ! -b $disk_partition ]
then
echo "FAILED: Usage $0 <block special disk_partition>"
exit 1
fi
# 在传入的分区上新建ext2格式的文件系统
mkfs -t ext2 $disk_partition
fi
# 系统需要安装rpm,autofs,否则会退出;$?用来接收autofs的返回值
rpm -q -a | grep autofs
if [ $? != 0 ]
then
echo "FAILED: autofs package is not installed"
exit 1
fi
# 查看系统是否支持autofs文件系统
grep autofs /proc/filesystems
if [ $? != 0 ]
then
echo "FAILED: autofs module is not built into the kernel or loaded"
exit 1
fi
##############################################################
#
# Pick the floppy device name from /etc/fstab
# Format (mkfs -t ext2) the floppy to ext2 file system
# Create the /etc/auto.master
# Create the /etc/auto.media
# Create /AUTOFS directory.
#
##############################################################
# 在/etc/fstab里搜索是否存在软盘
floppy_dev=`grep floppy /etc/fstab | awk '{print $1}'`
echo "Found floppy device:$floppy_dev"
if [ $floppy_dev != "" ]
then
# 格式化软盘为ext2文件系统格式
/sbin/mkfs -t ext2 $floppy_dev
if [ $? != 0 ]
then
echo "FAILED: mkfs -t ext2 $floppy_dev failed"
echo "Insert a disk into the floppy drive"
exit 1
fi
fi
if [ ! -d /AUTOFS ]
then
mkdir -m 777 /AUTOFS
fi
# 写入autofs主配置文件,/AUTOFS/MEDIA:挂载目录,/etc/auto.media:自动挂载的配置文件
echo "/AUTOFS/MEDIA /etc/auto.media" > /etc/auto.master
# 创建并配置/etc/auto.media自动挂载的配置文件,依次是挂载点、挂载文件的格式以及挂载目录
echo "floppy -fstype=ext2 :$floppy_dev" > /etc/auto.media
##############################################################
#
# Verify that "/etc/init.d/autofs start|restart|stop|status|reload"
# command works.
#
# If fails, cleanup and exit.
#
##############################################################
# 测试autofs脚本 start()
/etc/init.d/autofs start
if [ $? != 0 ]
then
rm -rf /etc/auto.master /etc/auto.media /AUTOFS
echo "FAILED: "/etc/init.d/autofs start""
exit 1
fi
echo "Resuming test, please wait..."
sleep 15
# 测试autofs脚本 stop()
/etc/init.d/autofs stop
if [ $? != 0 ]
then
rm -rf /etc/auto.master /etc/auto.media /AUTOFS
echo "FAILED: "/etc/init.d/autofs stop""
exit 1
else
/etc/init.d/autofs start
fi
echo "Resuming test, please wait..."
sleep 15
# 测试autofs脚本 reset()
/etc/init.d/autofs restart
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.media /AUTOFS
echo "FAILED: "/etc/init.d/autofs restart""
exit 1
fi
echo "Resuming test, please wait..."
sleep 15
# 查看/etc/init.d/autofs脚本运行状态
/etc/init.d/autofs status
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.media /AUTOFS
echo "FAILED: "/etc/init.d/autofs status""
exit 1
fi
# # 测试autofs脚本 reload()
/etc/init.d/autofs reload
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.media /AUTOFS
echo "FAILED: "/etc/init.d/autofs reload""
exit 1
fi
##############################################################
#
# Tryout some error code paths by:
# (1) Write into automount directory
# (2) Remove automount parent directory
# (3) Automount the floppy disk
# (4) Hit automounter timeout by sleep 60; then wakeup with error
# condition.
#
##############################################################
echo "forcing error paths and conditions..."
# 将标准输出&&标准错误信息都重定向到/dev/null,即不再显示
mkdir /AUTOFS/MEDIA/mydir >/dev/null 2>&1
rm -rf /AUTOFS >/dev/null 2>&1
# 检测自动挂载是否生效
mkdir /AUTOFS/MEDIA/floppy/test
cp /etc/auto.master /etc/auto.media /AUTOFS/MEDIA/floppy/test
sync; sync
echo "Resuming test, please wait..."
sleep 60
mkdir /AUTOFS/MEDIA/mydir >/dev/null 2>&1
rm -rf /AUTOFS >/dev/null 2>&1
##############################################################
#
# Add an entry to the /etc/auto.master and reload.
#
##############################################################
# 将传入的分区也设置为autofs自动挂载
echo "/AUTOFS/DISK /etc/auto.disk" >> /etc/auto.master
echo "disk -fstype=auto,rw,sync :$disk_partition " > /etc/auto.disk
# 执行一次重载命令
/etc/init.d/autofs reload
echo "Resuming test, please wait..."
sleep 30
# 如上述对软盘所作的测试,对分区再做一次
mkdir /AUTOFS/DISK/disk/test
cp /etc/auto.master /etc/auto.media /AUTOFS/DISK/disk/test
sync; sync
echo "Resuming test, please wait..."
sleep 60
# 检测目录是否存在
if [ -e /AUTOFS/DISK/disk/test ];
then
cd /AUTOFS/DISK/disk/test
# 进入到test目录,再执行卸载
umount /AUTOFS/DISK/disk/ >/dev/null 2>&1
# 此处应该是失败的,因为test目录目前是被占用的,如果卸载成功,则说明发生异常
if [ $? = 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.media /etc/auto.disk /AUTOFS
echo "FAILED: unmounted a busy file system!"
exit 1
fi
# 回到根目录,执行手动卸载
cd
umount /AUTOFS/DISK/disk/
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.media /etc/auto.disk /AUTOFS
echo "FAILED: Could not unmount automounted file system"
exit 1
fi
fi
#
# Mount the disk partition somewhere else and then reference automount
# point for disk partition.
#
mount -t ext2 $disk_partition /mnt/
ls -l /AUTOFS/DISK/disk
umount /mnt
#######################################################
#
# Just before exit, stop autofs and cleanup.
#
#######################################################
# 测试通过后,停止autofs脚本,删除掉挂载目录
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.media /etc/auto.disk /AUTOFS
echo "PASSED: $0 passed!"
exit 0
经过对脚本的分析,可以发现测试的内容还是比较简单的,重点都在于测试/etc/init.d/autofs脚本的各项函数,包括start()/reload()/stop()/restart()等。
2.2对脚本的改进
autofs1.sh的脚本,需要传入一个块设备,并且需要系统含有软盘设备才可以完整通过测试,而现在软盘设备已经近乎绝迹,对于系统的autofs测试,可以只利用传入的块设备完成整个测试,修改后的脚本如下:
#!/bin/bash
##############################################################
#
# Copyright (c) International Business Machines Corp., 2003
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# FILE : autofs1.sh
# USAGE : autofs1.sh <disk_partition>
#
# DESCRIPTION : A script that will test autofs on Linux system.
# REQUIREMENTS:
# 1) System with a floppy device with a floppy disk in it.
# 2) A spare (scratch) disk partition of 100MB or larger.
#
# HISTORY :
# 06/11/2003 Prakash Narayana (prakashn@us.ibm.com)
# 08/01/2005 Michael Reed (mreed10@us.ibm.com)
# - Added an check to see if a directory exists
# - This prevents unnessary failures
# - Correction to an echo statement
# - Added an additional error message if a floppy disk is not present
#
# CODE COVERAGE:
# 41.46% - fs/autofs/dirhash.c
# 33.33% - fs/autofs/init.c
# 27.70% - fs/autofs/inode.c
# 38.16% - fs/autofs/root.c
# 0.00% - fs/autofs/symlink.c
# 43.40% - fs/autofs/waitq.c
#
##############################################################
##############################################################
#
# Make sure that uid=root is running this script.
# Validate the command line argument as a block special device.
# Make sure that autofs package has been installed.
# Make sure that autofs module is built into the kernel or loaded.
#
##############################################################
# 检测是否具有root权限
if [ $UID != 0 ]
then
echo "FAILED: Must have root access to execute this script"
exit 1
fi
# 检测是否传入disk分区
if [ $# != 1 ]
then
echo "FAILED: Usage $0 <disk_partition>"
echo "Example: $0 /dev/hdc1"
exit 1
else
disk_partition=$1
# 检测入参的块设备是否真实存在
if [ ! -b $disk_partition ]
then
echo "FAILED: Usage $0 <block special disk_partition>"
exit 1
fi
# 在传入的分区上新建ext4格式的文件系统
mkfs -t ext4 $disk_partition
fi
# 检擦autofs是否安装
# 系统需要安装dpkg,autofs,否则会退出;$?用来接收autofs的返回值
dpkg -l | grep autofs
if [ $? != 0 ]
then
echo "FAILED: autofs package is not installed"
exit 1
fi
# 确认系统是否支持autofs
grep autofs /proc/filesystems
if [ $? != 0 ]
then
echo "FAILED: autofs module is not built into the kernel or loaded"
exit 1
fi
##############################################################
#
# Format (mkfs -t ext4) the partition to ext4 file system
# Create the /etc/auto.master
# Create the /etc/auto.disk
# Create /AUTOFS directory.
#
##############################################################
if [ ! -d /AUTOFS ]
then
mkdir -m 777 /AUTOFS
fi
# 写入autofs主配置文件,/AUTOFS/DISK:挂载目录,/etc/auto.disk:自动挂载的配置文件
echo "/AUTOFS/DISK /etc/auto.disk" >> /etc/auto.master
# 创建并配置/etc/auto.disk自动挂载的配置文件,依次是挂载点、挂载文件的格式以及挂载目录
echo "disk -fstype=auto,rw,sync :$disk_partition " > /etc/auto.disk
##############################################################
#
# Verify that "/etc/init.d/autofs start|restart|stop|status|reload"
# command works.
#
# If fails, cleanup and exit.
#
##############################################################
# 测试autofs脚本 start()
/etc/init.d/autofs start
if [ $? != 0 ]
then
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "FAILED: "/etc/init.d/autofs start""
exit 1
fi
echo "Resuming test, please wait..."
sleep 15
# 测试autofs脚本 stop()
/etc/init.d/autofs stop
if [ $? != 0 ]
then
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "FAILED: "/etc/init.d/autofs stop""
exit 1
else
/etc/init.d/autofs start
fi
echo "Resuming test, please wait..."
sleep 15
# 测试autofs脚本 restart()
/etc/init.d/autofs restart
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "FAILED: "/etc/init.d/autofs restart""
exit 1
fi
echo "Resuming test, please wait..."
sleep 15
# 测试autofs脚本 status()
/etc/init.d/autofs status
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "FAILED: "/etc/init.d/autofs status""
exit 1
fi
# 测试autofs脚本 reload()
/etc/init.d/autofs reload
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "FAILED: "/etc/init.d/autofs reload""
exit 1
fi
##############################################################
#
# Tryout some error code paths by:
# (1) Write into automount directory
# (2) Remove automount parent directory
# (3) Automount the target disk partiton
# (4) Hit automounter timeout by sleep 60; then wakeup with error
# condition.
#
##############################################################
echo "forcing error paths and conditions..."
# 将标准输出&&标准错误信息都重定向到/dev/null,即不再显示
mkdir /AUTOFS/DISK/mydir >/dev/null 2>&1
# 删除挂载目录
rm -rf /AUTOFS >/dev/null 2>&1
mkdir /AUTOFS/DISK/disk/test
cp /etc/auto.master /etc/auto.disk /AUTOFS/DISK/disk/test
sync; sync
echo "Resuming test, please wait..."
sleep 60
# 检查/AUTOFS/DISK/disk/test目录是否存在
if [ -e /AUTOFS/DISK/disk/test ];
then
cd /AUTOFS/DISK/disk/test
umount /AUTOFS/DISK/disk/ >/dev/null 2>&1
# umount是否成功,检测是否可以将操作中的目录取消挂载,如果卸载成功,则是异常!!
if [ $? = 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "FAILED: unmounted a busy file system!"
exit 1
fi
# 回到/目录,进行手动卸载
cd
umount /AUTOFS/DISK/disk/
if [ $? != 0 ]
then
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "FAILED: Could not unmount automounted file system"
exit 1
fi
fi
#
# Mount the disk partition somewhere else and then reference automount
# point for disk partition.
#
mount -t ext4 $disk_partition /mnt/
ls -l /AUTOFS/DISK/disk
umount /mnt
#######################################################
#
# Just before exit, stop autofs and cleanup.
#
#######################################################
# 前面的测试结束后,结束autofs运行,删除挂载目录
/etc/init.d/autofs stop
rm -rf /etc/auto.master /etc/auto.disk /AUTOFS
echo "PASSED: $0 passed!"
exit 0
改动包含以下三个方面:
- 取消软盘的挂载,全部用块设备代替
- 检测autofs的安装以ubuntu流行的dpkg代替
- 块设备的文件系统由ext2升级为ext4
2.3autofs1.sh与autofs4.sh
比较autofs4.sh与autofs1.sh,可以发现,autofs4.sh将很多步骤的执行结果隐藏了,实际测试的过程与方法并没有却别,所以,ltp的autofs测试,只需要测试一个就可以!
尾言
因为限于作者的水平,文章可能存在疏漏之处,希望发现的大神,可以不吝赐教,thanks:)