免费正确转换statvfs为百分比 [英] Converting statvfs to percentage free correctly

查看:123
本文介绍了免费正确转换statvfs为百分比的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有打印出以下数字的简单得要命测试程序。

I have a terribly uncomplicated test program that prints out the following numbers.

int main(int argc, char* argv[])
  struct statvfs vfs;
  statvfs(argv[1], &vfs);
  printf("f_bsize (block size): %lu\n"
       "f_frsize (fragment size): %lu\n"
       "f_blocks (size of fs in f_frsize units): %lu\n"
       "f_bfree (free blocks): %lu\n"
       "f_bavail free blocks for unprivileged users): %lu\n"
       "f_files (inodes): %lu\n"
       "f_ffree (free inodes): %lu\n"
       "f_favail (free inodes for unprivileged users): %lu\n"
       "f_fsid (file system ID): %lu\n"
       "f_flag (mount flags): %lu\n"
       "f_namemax (maximum filename length)%lu\n",
       vfs.f_bsize,
       vfs.f_frsize,
       vfs.f_blocks,
       vfs.f_bfree,
       vfs.f_bavail,
       vfs.f_files,
       vfs.f_ffree,
       vfs.f_favail,
       vfs.f_fsid,
       vfs.f_flag,
       vfs.f_namemax);

       return 0;
    }

打印出:

f_bsize (block size): 4096
f_frsize (fragment size): 4096
f_blocks (size of fs in f_frsize units): 10534466
f_bfree (free blocks): 6994546
f_bavail free blocks for unprivileged users): 6459417
f_files (inodes): 2678784
f_ffree (free inodes): 2402069
f_favail (free inodes for unprivileged users): 2402069
f_fsid (file system ID): 12719298601114463092
f_flag (mount flags): 4096
f_namemax (maximum filename length)255

DF打印出根FS:

df prints out for the root fs:

Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda5             42137864  14159676  25837672  36% /

但这里是我糊涂了。

But here is where I'm confused.

25837672 + 14159676!= 42137846(实际上39997348)

25837672+14159676 != 42137846 (actually 39997348)

因此​​,如果我是这样做的钙42137864分之14159676* 100,我得到33%没有36%作为DF打印。

Therefore if I were to do the calc 14159676 / 42137864 * 100 I get 33% not 36% as df prints.

但是,如果我calc下

But if I calc

三千九百九十九万七千三百四十八分之一千四百十五万九千六百七十六* 100,我得到了35%。

14159676 / 39997348 * 100 I get 35%.

为什么所有的数据差异在哪里是DF获得数42137864?这是否与某些转换至1k块VS系统的实际块大小是4K?

Why all the discrepencies and where is df getting the number 42137864? Is it related to some conversion to 1k blocks vs the actual system block size which is 4k?

这将被整合到我的缓存应用程序来告诉我,当驱动器在某个门槛例如... 90%之前,我开始释放了在2 ^ n的大小尺寸固定大小的块。
那么是什么我后,让我用一个合理准确%的功能。

This will be integrated into my caching app to tell me when the drive is at some threshold... e.g. 90% before I start freeing fixed size blocks that are sized in 2^n sizing. So what I'm after is a function that gives me a reasonably accurate %used.

编辑:
我现在可以配什么df,可以打印。除了使用的%。它使我们想知道准确的这一切。什么是片段大小?

I can now match what df prints. Except for the %Used. It makes we wonder how accurate all this is. What is the fragment size?

unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024;
unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024;
unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024;

printf("Total: %luK\n", total);
printf("Available: %luK\n", available);
printf("Used: %luK\n", total - free);

EDIT2:

unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024;
unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024;
unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024;
unsigned long used = total - free;

printf("Total: %luK\n", total);
printf("Available: %luK\n", available);
printf("Used: %luK\n", used);
printf("Free: %luK\n", free);

// Calculate % used based on f_bavail not f_bfree.  This is still giving out a different answer to df???
printf("Use%%: %f%%\n",  (vfs.f_blocks - vfs.f_bavail) / (double)(vfs.f_blocks) * 100.0); 

f_bsize (block size): 4096
f_frsize (fragment size): 4096
f_blocks (size of fs in f_frsize units): 10534466
f_bfree (free blocks): 6994182
f_bavail (free blocks for unprivileged users): 6459053
f_files (inodes): 2678784
f_ffree (free inodes): 2402056
f_favail (free inodes for unprivileged users): 2402056
f_fsid (file system ID): 12719298601114463092
f_flag (mount flags): 4096
f_namemax (maximum filename length)255
Total: 42137864K
Available: 25836212K
Used: 14161136K
Free: 27976728K
Use%: 38.686470%

matth@kubuntu:~/dev$ df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda5             42137864  14161136  25836212  36% /

我得到38%没有36.如果f_bfree计算我得到了33%。 DF是错误的或者这只是永远不会是准确的?如果是这样的话,那么我想依靠的是保守的一面。

I get 38% not 36. If calculated by f_bfree I get 33%. Is df wrong or is this just never going to be accurate? If this is the case then I want to lean on the side of being conservative.

推荐答案

东风 f_bavail ,不是 f_bfree 。您可能会发现它的帮助来看看源$ C ​​$ C到DF ,看看它是如何做的事情。它有一些它需要处理(例如,当使用的空间超过了可用空间,以非root用户量),但相关code对于正常情况下边缘情况是在这里:

df's data may be based on f_bavail, not f_bfree. You may find it helpful to look at the source code to df to see how it does things. It has a number of edge cases it needs to deal with (eg, when the used space exceeds the amount of space available to non-root users), but the relevant code for the normal case is here:

  uintmax_t u100 = used * 100;
  uintmax_t nonroot_total = used + available;
  pct = u100 / nonroot_total + (u100 % nonroot_total != 0);

在换句话说, 100 *用于/(使用+可用),四舍五入。从您的DF输出值堵给出了 100 * 14159676 /(14159676 + 25837672)= 35.4015371 ,这四舍五入为36%,就像 DF 计算。

In other words, 100 * used / (used + available), rounded up. Plugging in the values from your df output gives 100 * 14159676 / (14159676 + 25837672) = 35.4015371, which rounded up is 36%, just as df calculated.

这篇关于免费正确转换statvfs为百分比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆