討論區快速選單
知識庫快速選單
掌握Salesforce雲端管理秘訣 網路投保旅行平安險 程式設計俱樂部Facebook粉絲團
[ 回上頁 ] [ 討論區發言規則 ]
如何使用c語言或是shell取得使用mke2fs指令格式化硬碟的進度
更改我的閱讀文章字型大小
作者 : dragonsun(阿ken)
[ 貼文 10 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/2 下午 02:53:24
請教各位先進,目前TB等級的硬碟很常見,在embeded linux系統中格式化硬碟,通常要花上幾分鐘,所以要取得進度資訊,以供參考,不知道諸位有誰做類似的動作,THANKS
作者 : ozzy123(ozzy) VC++優秀好手資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4499 | 人氣 37262 | 評價 11100 | 評價/貼文 2.47 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/2 下午 03:51:47
http://blog.chinaunix.net/space.php?uid=643653&do=blog&id=2081580
http://stackoverflow.com/questions/3736210/how-to-execute-a-shell-script-from-c-in-linux
http://www.gidforums.com/t-7414.html
http://dywang.csie.cyut.edu.tw/moodle23/dywang/rhcsaNote/node39.html

try it
作者 : ozzy123(ozzy) VC++優秀好手資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4499 | 人氣 37262 | 評價 11100 | 評價/貼文 2.47 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人dragonsun註記此篇回應為很有道理 2013/1/2 下午 04:30:38
http://bbs.csdn.net/topics/380134292
an example codes for you reference
作者 : dragonsun(阿ken)
[ 貼文 10 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/3 上午 11:52:57
這篇我目前有參考到,因為要在webUI上製作格式化進度條,需要取得目前的進度資訊,目前正在TRY,謝謝你的回覆
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/6 上午 11:29:38
可以利用dup2()或搭配一些IPC手段達成需求,參考:
http://fred-zone.blogspot.tw/2010/05/forkpipedup2-execlp.html
http://www.32133.com/labrary/178.html
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/6 上午 11:38:10
自己曾實測過兩種方法提供給你參考:
方法1 - dup2()+unnamed pipe
模擬mke2fs:
int main()
{
for(int i=1; i<=100; i++) {
fprintf(stdout, "formatting ...%d\r",i);
fflush(stdout);
usleep(10000);
}
fprintf(stdout, "formatting ...done\n");
return 0;
}
擷取mke2fs訊息:
int main()
{
    #define MYAPP "mke2fs"
    int pfd[2];
    if( pipe(pfd)<0 ) return -1;
    pid_t pid = fork();
    if( pid<0 ) return -1;

    if( 0==pid ) { // child process
     dup2(pfd[1], STDOUT_FILENO);
     close(pfd[0]);
     execlp(MYAPP, MYAPP, NULL);
     exit(0);
    }
    else { // parent process
     close(pfd[1]);
char buf[1024];
     int len;
do {
     timeval tv;
tv.tv_sec=1;
tv.tv_usec=0;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(pfd[0], &readfds);
if( select(FD_SETSIZE, &readfds, NULL, NULL, &tv)<=0 ) break;
     len=read(pfd[0], buf, sizeof(buf)-1);
if( len>0 ) {
     buf[len]=0;
     printf("Child: %s", buf);
fflush(stdout);
}
     }while( len>0 );

int status;
     waitpid(pid, &status, 0);
close(pfd[0]);
    }
    return 0;
}
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人dragonsun註記此篇回應為很有道理 2013/1/6 上午 11:54:13
方法2 - 使用named pipe (mke2fs可修改原始碼時)
模擬mke2fs(增加named pipe的處理):
int main()
{
#define NAMED_PIPE "/tmp/my_pipe"
int fd=open(NAMED_PIPE, O_WRONLY);
if( -1==fd ) return -1;

for(int i=1; i<=100; i++) {
if( -1!=fd ) {
char msg[1024];
sprintf(msg,"progress=%d\r", i);
write(fd, msg, strlen(msg));
}
fprintf(stdout, "formatting ...%d\r",i);
fflush(stdout);
usleep(10000);
}
//..略

擷取mke2fs訊息:
int main()
{
    #define MYAPP "mke2fs"
    #define NAMED_PIPE "/tmp/my_pipe"
    if( 0!=mkfifo(NAMED_PIPE, S_IFIFO|0666) ) {
     if( errno!=EEXIST ) return -1;
    }
    pid_t pid = fork();
    if( pid<0 ) return -1;

    if( 0==pid ) { // child process
    // 利用dup2()屏蔽mke2fs之stdout輸出
    /*
int fd=open("/dev/null", O_WRONLY|O_NONBLOCK);
dup2(fd, STDOUT_FILENO);
     execlp(MYAPP, MYAPP, NULL);
    */
    // 或利用system()等其他方式
     char cmd[1024];
     sprintf(cmd, "%s >> /dev/null", MYAPP);
     system(cmd);
     exit(0);
    }
    else { // parent process
     int fd=open(NAMED_PIPE, O_RDONLY);
     //..略
     do {
//..略
if( select(FD_SETSIZE, &readfds, NULL, NULL, &tv)<=0 ) break;
     len=read(fd, buf, sizeof(buf)-1);
    
     //..略
if( 0!=unlink(NAMED_PIPE) ) return -1;
return 0;
}
作者 : dragonsun(阿ken)
[ 貼文 10 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 2 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/8 下午 12:09:05
你好,目前我是使用popen("mke2fs -j -b 4096 -i 8192 /dev/sda"),parsing進度,因為只有"writing inode table"時,有顯示出數字化進度,之後就會停一段時間(讀不到任何資訊),等到write superblock infomation結束,印出"done"才結束,而且此時才印出後續訊息,這是使用這個方法的缺點.因web client端會藉由cgi去polling進度,這樣可能在後段就很難判斷,之後握我會參考你的做法試看看,
請問你有將格式化流程,數字化嗎(約略抓過接近的進度),就我所知硬碟完整格式化流程,一般是需要在程式中 一次就將分割區全部移除,在建立需要分割區之後再格式化, 這一整段的流程要量化實在又點棘手,THANKS
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/10 下午 07:49:31
使用popen()執行子行程必須等該行程結束才能取得其輸出訊息,無法即時進行監控,
參考這兒:http://www.kernel.org/doc/man-pages/online/pages/man3/popen.3.html
這段:
     The pclose() function waits for the associated process to terminate and
     returns the exit status of the command as returned by wait4(2).

針對你的case覺得要用CGI程式polling進度可能用share memory會比較容易處理
用pipe會因為read/write不同步互相卡住, 自己對mkfs/fdisk並沒有深入研究
但只要能改原始碼將工作切割後,在適當時機送出進度訊息盡量讓進度跑得順暢即可.
以下測試程式提供給你參考:

模擬fdisk:
#define SHM_KEY 0x33
#define SEM_KEY 0x44

int acquire(int semid)
{
    struct sembuf sb;
    sb.sem_num = 0;
    sb.sem_op = -1;
    sb.sem_flg = SEM_UNDO;
    return semop(semid, &sb, 1);
}
  
int release(int semid)
{
    struct sembuf sb;
    sb.sem_num = 0;
    sb.sem_op = 1;
    sb.sem_flg = SEM_UNDO;
    return semop(semid, &sb, 1);
}

int main(int argc, char *argv[])
{
int shmid=shmget(SHM_KEY, 0, 0);
int *progress=(int *)shmat(shmid, NULL, 0);
     int semid=semget(SEM_KEY, 1, 0);

for(int i=1; i<=100; i++) {

if( (-1!=semid)&&progress ) {
acquire(semid);
*progress=0+i/2;
release(semid);
}

fprintf(stdout, "fdisk ...%d\r",i);
fflush(stdout);
usleep(100*1000);
}
fprintf(stdout, "fdisk ...done\n");

if( 0!=shmdt( progress ) ) return -1;
return 0;
}

模擬mkfs:
int main(int argc, char *argv[])
{
int shmid=shmget(SHM_KEY, 0, 0);
int *progress=(int *)shmat(shmid, NULL, 0);
     int semid=semget(SEM_KEY, 1, 0);

for(int i=1; i<=100; i++) {

if( (-1!=semid)&&progress ) {
acquire(semid);
*progress=50+i/2;
release(semid);
}
//..
}



作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/10 下午 07:50:20
模擬主控程式:
int main(int argc, char *argv[])
{
//..
int shmid=shmget(SHM_KEY, sizeof(int), IPC_CREAT | 0600);
if( -1==shmid ) return -1;
int *progress=(int *)shmat(shmid, NULL, 0);
if( (void *)-1==progress ) return -1;
    *progress=0;

    int semid=semget(SEM_KEY, 1, IPC_CREAT | 0600);
if( -1==semid ) return -1;
    if( 0!=semctl(semid, 0, SETVAL, 1) ) return -1;

printf("run fdisk..\n");
system(MY_FDISK" >> /dev/null");
printf("run mkfs..\n");
system(MY_MKFS" >> /dev/null");

if( 0!=semctl(semid, 0, IPC_RMID) ) return -1;
if( 0!=shmctl(shmid, IPC_RMID, 0) ) return -1;
return 0;
}

模擬CGI:
int main(int argc, char *argv[])
{
int shmid=shmget(SHM_KEY, 0, 0);
if( -1==shmid ) return -1;

int *progress=(int *)shmat(shmid, NULL, 0);
if( (void *)-1==progress ) return -1;

     int semid=semget(SEM_KEY, 1, IPC_CREAT | 0600);
if( -1==semid ) return -1;

acquire(semid);
printf("progress=%d\n", *progress);
release(semid);

if( 0!=shmdt( progress ) ) return -1;
return 0;
}
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2013/1/10 下午 07:55:39
進行實測
[root@localhost src]# ./test_format
run fdisk..
run mkfs..


於此同時利用CGI polling進度:
[root@localhost src]# ./test_cgi
#progress=10
[root@localhost src]# ./test_cgi
#progress=25
...略
[root@localhost src]# ./test_cgi
#progress=95
[root@localhost src]# ./test_cgi
#progress=97
 板主 : yuan
 > 嵌入式系統(Embedded System) - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 嵌入式系統(Embedded System) - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
嵌入式系統(Embedded System)
1 kting 770 
2 Lingb 400 
3 sazabi 400 
4 Huah 390 
5 hawkeye 380 
6 H 360 
7 yuan 350 
8 Kenny 310 
9 ozzy 290 
10 富伯 280 
嵌入式系統(Embedded System)
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.046875