0

I want to get free hdd's size in a remote system with ssh.
I found this ways:
1-do it via command line: hdd's totalsize - sum of partitions size on that hdd + sum of free spaces on all partitions on that hdd;
There are some problems with this way.
first, I prefer not to use commands, because it will get way complicated , it will be full of converting types to each other. like string to float and... second is that with running command, I cannot have unmounted partitions free space.
third problem is that maybe the hdd itself be unmounted! the other way is:
2-using statvfs structure.
again, with this structure, you can have mounted hdd's free space. the code I am using :

#include <stdio.h>
#include <sys/statvfs.h>
int main(int argc, const char *argv[])
{

    const unsigned int GB = (1024 * 1024) * 1024;
    struct statvfs buffer;
    int ret = statvfs(argv[1], &buffer);

    if (!ret) {
        const double total = (double)(buffer.f_blocks * buffer.f_bsize) / GB;
        const double available = (double)(buffer.f_bfree * buffer.f_bsize) / GB;
        const double used = total - available;
        const double usedPercentage = (double)(used / total) * (double)100;
        printf("Total: %f --> %.0f\n", total, total);
        printf("Available: %f --> %.0f\n", available, available);
        printf("Used: %f --> %.1f\n", used, used);
        printf("Used Percentage: %f --> %.0f\n", usedPercentage, usedPercentage);
    }
    return ret;
}

I've seen this link: Get free space of HDD in linux
but the outputs of stat, are not similar to numbers that I see in df command's output.
I am using Qt and my os is ubuntu 18.04.
when Irun this code I get this :

heydari.f@swkb-dev2:~/projects/cpptest/build-cpptest-Desktop-Debug$ ./cpptest .
Total: 31.570432 --> 32
Available: 15.594684 --> 16
Used: 15.975748 --> 16.0
Used Percentage: 50.603513 --> 51

and my df's output is like this:

heydari.f@swkb-dev2:~$ df -H ~/projects/cpptest/build-cpptest-Desktop-Debug
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        32G   16G   14G  54% /

EDIT:

heydari.f@swkb-dev2:~/projects/cpptest/build-cpptest-Desktop-Debug$ ./cpptest .
Total: 31.570432 --> 32
Available: 13.967569 --> 14
Used: 17.602863 --> 17.6
Used Percentage: 55.757435 --> 56
fa7eme
  • 73
  • 10

1 Answers1

1

you do not give the results you have, so I can see two reasons :

First may be you have an overflow when doing buffer.f_blocks * buffer.f_bsize and buffer.f_bfree * buffer.f_bsize because your unsigned long are on 32b, so do for instance :

const double total = ((double) buffer.f_blocks) * buffer.f_bsize / GB;
const double available = ((double) buffer.f_bfree) * buffer.f_bsize / GB;

Second for df 1Gb is 1000*1000*1000 rather than 1024*1024*1024

If I execute your version on my 2Gb PI4 I get :

pi@raspberrypi:/tmp $ ./a.out .
Total: 3.338009 --> 3
Available: 0.439247 --> 0
Used: 2.898762 --> 2.9
Used Percentage: 86.841044 --> 87
pi@raspberrypi:/tmp $ 

after the modification to avoid overflow I get

pi@raspberrypi:/tmp $ ./a.out .
Total: 27.338009 --> 27
Available: 16.439247 --> 16
Used: 10.898762 --> 10.9
Used Percentage: 39.866699 --> 40
pi@raspberrypi:/tmp $ 

while df -H . gives :

pi@raspberrypi:/tmp $ df -H .
Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
/dev/root           30G     12G   17G  42% /

but

pi@raspberrypi:/tmp $ bc
30*1000*1000*1000/1024/1024/1024
27
pi@raspberrypi:/tmp $ 
bruno
  • 32,421
  • 7
  • 25
  • 37
  • I changed those two line but didn't differ. and also replaced GB's value and still same. maybe there is problem with the things that I said about unmounted hdds. while testing I give this path : `/dev/sda.`.I think there is something wrong with that. – fa7eme Jul 19 '20 at 10:47
  • I saw your edited cm now. so you are saying that this code gives hdd's free storage correctly? so why are outputs weird on my system?! – fa7eme Jul 19 '20 at 10:50
  • @fatemehheydari you do not give us the output you have nor the output given by *df*, and I do not have a magic crystal ball to guess all of that. Are you on an Ubuntu 64b to have 64b `unsigned long` ? Globally yes for me the results are ok even little rounds made by *df* – bruno Jul 19 '20 at 10:56
  • my ubuntu is 64b. I added those outputs to question. – fa7eme Jul 19 '20 at 11:01
  • @fatemehheydari rather than to do just `df` can you edit your question with the result of `df ~/projects/cpptest/build-cpptest-Desktop-Debug` and/or `df -H ~/projects/cpptest/build-cpptest-Desktop-Debug` ? that both remove useless lines and allow to be sure you compare the same partition – bruno Jul 19 '20 at 11:04
  • 1
    the result is not *wierd* (it was in my case because of overflow) just 14 rather than 16, may be *df* uses an other way to get the available size ? – bruno Jul 19 '20 at 11:17
  • I edited my question again with new output of code. can you see if it is correct now? – fa7eme Jul 19 '20 at 11:22
  • @fatemehheydari as you can see the sizes changed a lot between your 2 executions of your program, that means */home* changes fast because of other users, if you want to compare you need to execute your program and immediately *df* (the commands can be given on one line separated by ';') – bruno Jul 19 '20 at 11:28
  • I also changed f_bfree to f_bavail in my code. I read in here : https://stackoverflow.com/questions/4965355/converting-statvfs-to-percentage-free-correctly that df uses f_bavail instead of f_bfree. thanks alot. – fa7eme Jul 19 '20 at 11:32
  • @RavinderSingh13 thank you, if not through a C program it is enough to use *df* – bruno Jul 22 '20 at 21:15