天天看點

busybox中的df -h 顯示所挂載的檔案系統存儲空間使用有誤的問題

busybox版本為v1.21.1,環境為嵌入式linux系統。

之前在開發闆上實作了個u盤挂載及裝置資訊(主要是存儲空間使用情況)顯示功能。

顯示u盤存儲空間使用情況是利用busybox中的df -h指令來得到的。這個時候問題來了,發現通過這個busybox  df指令得到的資料是有問題的。

下圖中 /dev/sdb1的資訊明顯是錯的。

busybox中的df -h 顯示所挂載的檔案系統存儲空間使用有誤的問題

我的解決辦法是,找了一個輕量級df指令源碼,做了一些适當的修改,發現解決了這個問題。下面是源碼:

#include <stdio.h>  

#include <mntent.h>  

#include <string.h>  

#include <sys/vfs.h>  

static const unsigned long long G = 1024*1024*1024ull;  

static const unsigned long long M = 1024*1024;  

static const unsigned long long K = 1024;  

static char str[20];  

char* kscale(unsigned long b, unsigned long bs)  

{  

    unsigned long long size = b * (unsigned long long)bs;  

    if (size > G){

        sprintf(str, "%0.1fG", size/(G*1.0));  

        return str;  

    } else if (size > M){  

        sprintf(str, "%0.1fM", size/(1.0*M));  

        return str;  

    } else if (size > K){  

        sprintf(str, "%0.1fK", size/(1.0*K));  

        return str;  

    } else {

        sprintf(str, "%0.1fB", size*1.0);  

        return str;  

    }  

}

void usage(void)

{

    printf("Usage: litedf [-d MOUNTDIRECTION ]\n");

}

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

{

    int flag = 0;

    if (argc > 3 || 2 == argc){

        usage();

        return -1;

    }

    if (3 == argc){

        if ( 0  != strcmp(argv[1],"-d")){

            usage();

            return -1;

        }

        flag = 1;

    }

    char mount_on[50] = {0};

    strcpy(mount_on, argv[2]);

    FILE* mount_table;  

    struct mntent *mount_entry;  

    struct statfs s;  

    unsigned long blocks_used;  

    unsigned blocks_percent_used;  

    const char *disp_units_hdr = NULL;  

    mount_table = NULL;  

    mount_table = setmntent("/proc/mounts", "r");  

    if (!mount_table){

        fprintf(stderr, "set mount entry error\n");  

        return -1;  

    }  

    disp_units_hdr = "     Size";  

    printf("Filesystem           %-15sUsed Available %s Mounted on\n",  

            disp_units_hdr, "Use%");  

    while (1) {  

        const char *device;  

        const char *mount_point;

        if (mount_table) {  

            mount_entry = getmntent(mount_table);  

            if (!mount_entry) {  

                endmntent(mount_table);  

                break;  

            }  

        }

        else  

        continue;  

        device = mount_entry->mnt_fsname;  

        mount_point = mount_entry->mnt_dir;

        if ( 0 != strcmp(mount_on, mount_point) && flag == 1)

        continue;

        //fprintf(stderr, "mount info: device=%s mountpoint=%s/n", device, mount_point);

        if (statfs(mount_point, &s) != 0){

            fprintf(stderr, "statfs failed!\n");      

            continue;  

        }  

        if ((s.f_blocks > 0) || !mount_table ){

            blocks_used = s.f_blocks - s.f_bfree;  

            blocks_percent_used = 0;  

            if (blocks_used + s.f_bavail){

                blocks_percent_used = (blocks_used * 100ULL  

                            + (blocks_used + s.f_bavail)/2  

                            ) / (blocks_used + s.f_bavail);  

            }  

            if (strcmp(device, "rootfs") == 0)  

            continue;  

            printf("%-20s", device);

            char s1[20];  

            char s2[20];  

            char s3[20];  

            strcpy(s1, kscale(s.f_blocks, s.f_bsize));  

            strcpy(s2, kscale(s.f_blocks - s.f_bfree, s.f_bsize));  

            strcpy(s3, kscale(s.f_bavail, s.f_bsize));  

            printf(" %9s %9s %9s %3u%% %s\n",  

                    s1,  

                    s2,  

                    s3,  

                    blocks_percent_used, mount_point);  

        }  

    }  

    return 0;  

}

參考文章:http://blog.csdn.net/fjb2080/article/details/5990355#