linux系统支持硬盘热插拔,linux下新硬盘的自动检测及格式化--支持硬盘的热插拔处理...

说明

可能存在bug,所以慎用!!! 且只在mbr分区格式下测试过。

parted.sh 可以用在系统起来的时候,比如rc.local脚本里面。

parted.c 需要parted.sh脚本配合使用,可以实现硬盘热插拔时的处

理,核心思想是linux下的文件系统变化通知机制。

parted 即parted.c的可执行文件。

欢迎大家一起讨论及指出其中的bug。

parted.sh的实现如下

#!/bin/sh

##################rongp 2012-6-21###############

PARTED=/sbin/parted

MOUNTED_TOP_DIR=/disks/

function mount_and_init {

mkdir $2

if mount -t ext4 $1 $2; then

echo "$1 $2 ext4 defaults 0 0" >>/etc/fstab

echo partition $1 mount to $2 is ready

else

echo mount

fi

}

function remkpart {

$PARTED -s $1 mklabel msdos #gpt

$PARTED -s $1 mkpart primary ext4 $2 $3>/dev/null #maybe use -1 instead of $3

mkfs.ext4 ${1}1 >/dev/null

MOUNT_POINT=`fdisk -l $1 | grep "Disk identifier" | awk '{print $3}'`

mount_and_init ${1}1 $MOUNTED_TOP_DIR/$MOUNT_POINT

}

function check_need_part {

ret=`fdisk -l $1 2>/dev/null | grep "Disk identifier" | awk '{print $3}'`

if [ "$ret" == "0x00000000" ]; then

return 0

else

return 1

fi

}

if [ "$1" == "" ]; then

DISK=`find /dev/ -name sd[a-z]`

else

DISK="/dev/$1"

fi

[ -d "$MOUNTED_TOP_DIR" ] || mkdir $MOUNTED_TOP_DIR

for tmpdisk in $DISK

do

check_need_part $tmpdisk

if [ "$?" == "1" ]; then

echo "$tmpdisk pass"

continue;

else

echo "$tmpdisk need "

fi

echo "make a temp partion so parted can get disk size"

$PARTED $tmpdisk mkpart primary 0 100 >/dev/null

STARTSIZE=0

#STOPSIZE='$PARTED $tmpdisk unit MB print | grep "Disk $tmpdisk" | cut -d: -f 2| cut -dM -f1` #maybe use -1 instead of STOPSIZE' #分区的结束位置

STOPSIZE=$((`fdisk -s $tmpdisk`/1000)) #分区的结束位置,和上面一句同义

remkpart $tmpdisk $STARTSIZE $STOPSIZE

done

parted.c文件实现如下

#include

#include

#include

#include

#include

#define BUF_SIZE 1024

int main(void)

{

int fd, wd;

int len = 0, pos = 0;

char buffer[BUF_SIZE];

char *path = "/dev/";

char buf[128];

struct inotify_event *event;

fd = inotify_init();

if (fd < 0) {

perror("inotify_init");

return -1;

}

wd = inotify_add_watch(fd, path, IN_CREATE | IN_DELETE/*IN_MOVED_TO*//*IN_ALL_EVENTS*/);

if (wd < 0) {

perror("inotify_add_watch");

close(fd);

return -1;

}

while(1) {

memset(buf, 0, 128);

len = read(fd, buffer, BUF_SIZE);

while(len > 0) {

event = (struct inotify_event *)(buffer+pos);

if (event->wd != wd)

break;

if (event->mask & IN_CREATE) {

if (!strncmp(event->name, "sd", strlen("sd"))

|| !strncmp(event->name, "hd", strlen("hd"))) {

sprintf(buf, "sh parted.sh %s", event->name);

system(buf);

}

}

if (event->mask & IN_DELETE) {

if (!strncmp(event->name, "sd", strlen("sd"))

|| !strncmp(event->name, "hd", strlen("hd"))) {

sprintf(buf, "fdisk -l /dev/%s 2>/dev/null | grep "Disk identifier" | awk '{print $3}'", "/sda");

char tmpbuf[128];

FILE *fp = popen(buf, "r");

fread(buf, 1, 1024, fp);

fclose(fp);

*strchr(buf, '

') = 0;

sprintf(tmpbuf, "sed -i '/%s/d' /etc/fstab", buf);

system(tmpbuf);

}

}

len -= event->len+sizeof(struct inotify_event);

pos += event->len+sizeof(struct inotify_event);

}

pos = 0;

}

close(fd);

return 0;

}

完!

2012年6月

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值