varyoffvg命令的流程和理解

一、varyoffvg
varyoffvg脚本实际上是对lvaryoffvg命令的封装,以varyoffvg datavg为例,脚本主体流程如下:
流程
命令
注释
获取VGID
VGID=`getlvodm -v $VGNAME`
通过ODM,将VGName转为VGID
加锁
putlvodm -k $VGID
禁止其他影响VG的操作,包括lsvg
调用lvaryoffvg
lvaryoffvg -g $VGID
lvaryoffvg执行实际的varyoff工作
解锁
putlvodm -K $VGID

       其中lvaryoffvgputlvodm都是所谓的intermediate-level command
二、lvaryoffvg
lvaryoffvg是二进制可执行文件,看看它调用了哪些库文件。
dump -Tv /usr/sbin/lvaryoffvg
...........
[27]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_varyoffvg

............
感觉lvm_varyoffvg这个函数是lvaryoffvg命令的核心。这是个公开的函数,在/usr/include/lvm.h头文件中有定义。
struct varyoffvg

{


struct unique_id vg_id;
/* volume group id */


long
lvs_only;
/* flag to varyoff only logical volumes */


};

extern int lvm_varyoffvg(struct varyoffvg *varyoffvg);
我们可以写一个自己的命令来替代lvaryoffvg,并且让varyoffvg调用我们提供的命令。
#include <sys/types.h>
#include <lvm.h>

struct varyoffvg
{

struct unique_id vg_id;


long
lvs_only;

};
extern int lvm_varyoffvg(struct varyoffvg *varyoffvg);

__ulong32_t str2hex(char *str)
{

__ulong32_t value=0;


unsigned int i,j;



for(i=0;i<8;i++)


{


j=0;


if(str>='0'&&str<='9')


{


j=str-'0';


}


else if(str>='a'&&str<='f')


{


j=str-'a'+0xa;


}


else if(str>='A'&&str<='F')


{


j=str-'A'+0xA;


}


j=(j<<((7-i)*4));


value|=j;


}



return value;

}

int main(int argc,char *argv[])
{

int result=0;


struct varyoffvg Varyoffvg;


char *cmd=argv[0];




if(argc!=2)


{


printf("usage:%s vgid/n",cmd);


exit(-1);


}




Varyoffvg.vg_id.word4=str2hex(argv[1]+24);


Varyoffvg.vg_id.word3=str2hex(argv[1]+16);


Varyoffvg.vg_id.word2=str2hex(argv[1]+8);


Varyoffvg.vg_id.word1=str2hex(argv[1]+0);


Varyoffvg.lvs_only=0;




result=lvm_varyoffvg(&Varyoffvg);




return result;

}
ü
编译这个程序,得到my_lvaryoffvg文件,假设为/tmp/my_lvaryoffvg,权限为750

ü
创建testvg,并且varyon。为了简单起见,可以不用创建LVFS

ü
编辑/usr/sbin/varyoffvg脚本,将lvaryoffvg -g $VGID $SFLAG替换为/tmp/my_lvaryoffvg $VGID

ü
执行varyoffvg testvg,发现testvg被成功varyoff

ü
编辑/usr/sbin/varyoffvg脚本,改回原来的命令。

三、putlvodm
putlvodm具有很多参数,可以参考lvm cmds from a to z中的介绍,我们现在只关心和锁住卷组有关的内容。首先看一下它调用了哪些库文件
#dump -Tv /usr/sbin/putlvodm | grep lock
[40]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_cfglock

[41]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_free_cfg_lock

[42]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_get_cfg_lock

[43]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_free_sync_lock

[44]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_get_sync_lock

[47]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_cfglock_query

[55]
0x00000000
undef
IMP
DS EXTref libodm.a(shr.o) odm_unlock

[56]
0x00000000
undef
IMP
DS EXTref libodm.a(shr.o) odm_lock

看上去有两种锁,一种是和LVM相关的,另一种是和ODM相关。接下来再看一下putlvodm -k的效果。首先执行putlvodm -k <vgid>,然后在其他窗口中执行lsvg <vgname>。我们发现lsvg命令被hang住,过一段时间产生0516-1201报错,提示我们用chvg -u解锁。我们执行putlvodm -K <vgid>,则很快lsvg命令就恢复执行。有此可见putlvodmlsvg争夺相同的锁。那么看看lsvg命令调用了哪些库文件
#dump -Tv /usr/sbin/lsvg | grep lock
[4]
0x00000000
undef
IMP
RW EXTref
libc.a(shr.o) _libc_lock_funcs

[6]
0x00000000
undef
IMP
DS EXTref
libc.a(shr.o) _rec_mutex_unlock

[11]
0x00000000
undef
IMP
DS EXTref
libc.a(shr.o) _rec_mutex_lock

[66]
0x00000000
undef
IMP
DS EXTref liblvm.a(shr.o) lvm_cfglock

putlvodm的相比较,我们发现两个都调用了lvm_cfglock。看来就是这个子例程给vg上了锁。不过这个是未公开的子例程,我们无法直接调用。接下来看看通过kdb能观察到什么。
(0)> ttid 2dac3

SLOT NAME
STATE
TID PRI
RQ CPUID
CL WCHAN


pvthread+016D00
730 lsvg
SLEEP 02DAC3 03C
0
0 35DEBE98


NAME................ lsvg
WTYPE............... WEVENT

...............state :00000003
...............wtype :00000001

...............flags :00000000
..............flags2 :00000000

2dac3lsvg的线程ID。显然这个线程正处于sleep状态,原因应该是等待某个event。这个event的地址是0x35DEBE98,并且这个地址还会改变。(有哪位高人能通过这个地址还原event的信息?或者我理解有误,这个并不是event的地址?)
四、总结
varyoffvg的流程就是首先给VG加锁,然后调用lvaryoffvg命令执行实际操作,最后解锁。lvaryoffvg是对子例程lvm_varyoffvg的封装,我们用自己的实现替换掉lvaryoffvg命令后varyoffvg仍然可以正常工作。putlvodm执行加锁和解锁。在加锁后涉及VG的操作都hang住,包括lsvg命令,在解锁后才能继续运行。
chvg -u命令也可以为VG解锁。chvg是个脚本,可以发现-u参数最终也调用putlvodm
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值