• 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 <stdio.h>
        #include <string.h>
        #include <stdlib.h>
    
        #include <unistd.h>
        #include <sys/inotify.h>
    
        #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月

  • 相关阅读:
    K2 BPM_携手东航物流,领跑全球航空物流业_全球领先的工作流引擎
    K2 BPM_如何将RPA的价值最大化?_全球领先的工作流引擎
    Sqlserver 增删该查----查
    U3D Resources AssetBundle资源打包
    Sqlserver 触发器
    Sqlserver 游标
    U3D 协程和www
    U3D 数据在安卓设备上的存储,加载
    U3D SQLite数据库
    U3D 装备的添加和移除(Unity3D)
  • 原文地址:https://www.cnblogs.com/rongpmcu/p/7662149.html
Copyright © 2020-2023  润新知