Tengo un terriblemente sencillo programa de prueba que imprime los números siguientes.

es decir,

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;
    }

Imprime:

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 imprime en la raíz fs:

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

Pero aquí es donde estoy confundido.

25837672+14159676 != 42137846 (en realidad 39997348)

Por lo tanto, si yo fuera a hacer la calc 14159676 /42137864 * 100 puedo obtener el 33% no 36% como df impresiones.

Pero si me calc

14159676 /39997348 * 100 puedo obtener un 35%.

Por qué todas las discrepancias y donde df es obtener el número 42137864? Se relaciona con algunos de conversión a 1k bloques vs el sistema actual de tamaño de bloque que es 4k?

Este será integrado en mi almacenamiento en caché de la aplicación para que me diga cuando la unidad está en el umbral… por ejemplo, el 90% antes de que yo comenzara a liberar bloques de tamaño fijo que son del tamaño de 2^n el tamaño.
Así que lo que busco es una función que me da un razonablemente precisas %utiliza.

EDITAR:
Ahora puedo coincidir con lo que el df se imprime. Excepto para el %de uso. Hace que nos preguntamos cómo exacta de todo esto. ¿Cuál es el tamaño de los fragmentos?

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%

[email protected]:~/dev$ df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda5             42137864  14161136  25836212  36% /

Puedo obtener el 38% no 36. Si se calcula por f_bfree puedo obtener el 33%. Es df mal o es que esto nunca va a ser exacto? Si este es el caso, entonces quiero que te apoyes en el lado de ser conservador.

InformationsquelleAutor Matt | 2011-02-11

5 Comentarios

  1. 17

    df‘s de datos puede estar basada en f_bavail, no f_bfree. Usted puede encontrar que es útil mirar el el código fuente para el df para ver cómo hace las cosas. Tiene un número de casos de borde que necesita para lidiar con (por ejemplo, cuando el espacio utilizado excede la cantidad de espacio disponible para usuarios no root), pero el código correspondiente para el caso normal está aquí:

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

    En otras palabras, 100 * used /(used + available), redondeando hacia arriba. El taponamiento en los valores de los df de salida da 100 * 14159676 /(14159676 + 25837672) = 35.4015371, que redondeado es de 36%, así como df calculado.

    • El df código no es particularmente fácil de seguir. Es que no es posible calcular el %de uso del detalle impreso por el df?
    • El hombre que no tiene sentido para mí. Show me.
    • Ver mi respuesta actualizada. Puedo conseguir los números que caen todos en torno al 36%. He intentado buscar en el df codebase pero esto no era en absoluto fácil de seguir.
  2. 5

    En su Edición #2, el porcentaje de Uso de cálculo debe ser actualizado para que coincida df salida:

    100.0 * (double) (vfs.f_blocks - vfs.f_bfree) / (double) (vfs.f_blocks - vfs.f_bfree + vfs.f_bavail)

    Razonamiento:

    Usa = f_blocks – f_bfree

    Hacer uso = f_bavail

    df % = Usa /(Utilizado + Avail)

  3. 2

    Este es el más cercano que tengo a la coincidencia de la salida de df -h usados porcentaje:

    const uint GB = (1024 * 1024) * 1024;
    
    struct statvfs buffer;
    int ret = statvfs(diskMountPoint.c_str(), &buffer);
    
    const double total = ceil((double)(buffer.f_blocks * buffer.f_frsize) / GB);
    const double available = ceil((double)(buffer.f_bfree * buffer.f_frsize) / GB);
    const double used = total - available;
    const double usedPercentage = ceil((double)(used / total) * (double)100);
    
    return usedPercentage;
  4. 0

    Parece que me confundo cuando me lidiar con este problema. Espero el siguiente código C es útil para alguien que busca porcentaje de espacio utilizado:

        /*                                                                                                                                                                                                                                                                     
         * It is helpful to use a picture to aid the calculation of disk space.                                                                                                                                                                                                
         *                                                                                                                                                                                                                                                                     
         * |<--------------------- f_blocks ---------------------------->|                                                                                                                                                                                                     
         *                 |<---------------- f_bfree ------------------>|                                                                                                                                                                                                     
         *                                                                                                                                                                                                                                                                     
         * ---------------------------------------------------------------                                                                                                                                                                                                     
         * | USED          | f_bavail                | Reserved for root |                                                                                                                                                                                                     
         * ---------------------------------------------------------------                                                                                                                                                                                                     
         *                                                                                                                                                                                                                                                                     
         * We want the percentage of used blocks vs. all the                                                                                                                                                                                                                   
         * non-reserved blocks: USED /(USED + f_bavail)                                                                                                                                                                                                                       
         */
        fsblkcnt_t used = fs_stats.f_blocks - fs_stats.f_bfree;
        double fraction_used = (double) used / ((double) used + (double) fs_stats.f_bavail);
        uint8_t percent_used = (uint8_t) ((fraction_used * 100.0) + 0.5); //Add 0.5 for rounding

Dejar respuesta

Please enter your comment!
Please enter your name here