zoukankan      html  css  js  c++  java
  • 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月

  • 相关阅读:
    Oracle 推出 ODAC for Entity Framework 和 LINQ to Entities Beta版
    Entity Framework Feature CTP 5系列文章
    MonoDroid相关资源
    MSDN杂志上的Windows Phone相关文章
    微软学Android Market推出 Web Windows Phone Marketplace
    使用 Visual Studio Agent 2010 进行负载压力测试的安装指南
    MonoMac 1.0正式发布
    Shawn Wildermuth的《Architecting WP7 》系列文章
    使用.NET Mobile API即51Degrees.mobi检测UserAgent
    MongoDB 客户端 MongoVue
  • 原文地址:https://www.cnblogs.com/rongpmcu/p/7662149.html
Copyright © 2011-2022 走看看