This is from man getrusage
struct rusage {
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
long ru_maxrss; /* maximum resident set size */
long ru_ixrss; /* integral shared memory size */
long ru_idrss; /* integral unshared data size */
long ru_isrss; /* integral unshared stack size */
long ru_minflt; /* page reclaims */
long ru_majflt; /* page faults */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* messages sent */
long ru_msgrcv; /* messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary context switches */
};
However it's not specified what's the unit.
I saw FreeBSD's documentation which says it's in kilobytes, but I'm not sure about what unit it is on Linux.
It's not a standard field for the rusage structure so POSIX doesn't mandate anything about it. But on Linux
ru_maxrss (since Linux 2.6.32)
This is the maximum resident set size used (in kilobytes). For
RUSAGE_CHILDREN, this is the resident set size of the largest child,
not the maximum resident set size of the process tree.
The man page says:
ru_maxrss (since Linux 2.6.32)
This is the maximum resident set size used (in kilobytes). For RUSAGE_CHILDREN, this is the resident set size of the largest child,
not the maximum resident set size of the process tree.
So, it's expressed in kilobytes, just like in BSD.
Related
When I running df -h I can see that in /dev I use 6M and the size is 40M , and Available size is 34M .
How can I get this information with c code?
From here:
Use the statvfs API:
// header for statvfs
#include <sys/statvfs.h>
and the prototype of the statvfs is
int statvfs(const char *path, struct statvfs *buf);
The results will be filled to the buf statvfs struct:
struct statvfs {
unsigned long f_bsize; /* filesystem block size */
unsigned long f_frsize; /* fragment size */
fsblkcnt_t f_blocks; /* size of fs in f_frsize units */
fsblkcnt_t f_bfree; /* # free blocks */
fsblkcnt_t f_bavail; /* # free blocks for unprivileged users */
fsfilcnt_t f_files; /* # inodes */
fsfilcnt_t f_ffree; /* # free inodes */
fsfilcnt_t f_favail; /* # free inodes for unprivileged users */
unsigned long f_fsid; /* filesystem ID */
unsigned long f_flag; /* mount flags */
unsigned long f_namemax; /* maximum filename length */
};
The return type is:
On success, zero is returned. On error, -1 is returned, and errno is
set appropriately.
Also have a look at the man3 manpage of the statvfs command for more and detailed information.
Have you checked the source of df from Coreutils?
It uses statvfs() from sys/statvfs.h on Linux as well as on other POSIX-like systems.
I would like to add an attribute to the buffer description in the PostgreSQL source code, but when I try to initialize it I get an error of: PANIC: stuck spinlock (0x7fc1cddd0cd0) detected at freelist.c:206
The struct is described in buf_internals.h as:
typedef struct sbufdesc
{
BufferTag tag; /* ID of page contained in buffer */
BufFlags flags; /* see bit definitions above */
uint16 usage_count; /* usage counter for clock sweep code */
unsigned refcount; /* # of backends holding pins on buffer */
int wait_backend_pid; /* backend PID of pin-count waiter */
int buf_age; //<<<<<<<<<<< The age of the buffer
slock_t buf_hdr_lock; /* protects the above fields */
int buf_id; /* buffer's index number (from 0) */
int freeNext; /* link in freelist chain */
LWLockId io_in_progress_lock; /* to wait for I/O to complete */
LWLockId content_lock; /* to lock access to buffer contents */
} BufferDesc;
but it gets stuck at line 206 of freelist.c, which is just:
LockBufHdr(buf);
All I've added was an int to the struct and set it to zero in the same place all the other buffers are initialized. How could this cause a spinlock error?
It looks like running make clean first has corrected the issue.
I use stat system call on Linux and retrieve file information.
char *parent_dir; // for example: /run/atd.pid/
struct stat buf;
stat(parent_dir, &buf);
buf structure type:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
I get number of hard links like this: buf.st_nlink.
My problem is that I can't compare number of hard links to integer value. I've tried to initialize another nlink_t and then compare my variable to stat variable, but it doesn't work. I've also tried this link.
Alternative way to cast nlink_t to int, but it doesn't work. always returns the same number.
int
parse_to_int(nlink_t *source)
{
int buffer_size = sizeof(*source);
char buffer[buffer_size];
snprintf(&buffer[0], buffer_size, "%lu", (unsigned long)source);
int val = atoi(buffer);
return val;
}
Any idea?
Program output when I use parse_to_int function:
get stat for: /run/nm-dhclient-wlan0.conf/
nlink_t: 321
get stat for: /run/wpa_supplicant/
nlink_t: 321
get stat for: /run/udisks2/
nlink_t: 321
get stat for: /run/nm-dns-dnsmasq.conf/
nlink_t: 321
...
nlink_t is typedef'd as an integer type (e.g., unsigned short or unsigned int), so you should be able to cast stat.st_nlink to an unsigned or unsigned long without the compiler complaining.
Your parse_to_int() function is incorrect, because you're casting a pointer (nlink_t*) to an unsigned int, instead of the value of the nlink_t variable. But you don't need the function, just use the cast properly.
Addendum
Also make sure that you're not comparing an unsigned type to -1, which will give you unexpected results.
So I had several problems:
You can't get stat from file, if the path ends with /
There are some folders in your computer's folder list that are created by your operating system. Some kind of data in memory, interpreted as folders and files(called virtual file-system). So if you try to get i-node number from this kind of file, you get some garbage value.
You should be able to compare to a uint. If you've got more than 64k hard links I'd be surprised.
Trying to guess the size it will take to print a string representation of a nlink_t from how many bytes long the nlink_t is a bug. nlink_t may be 8 bytes but 4000000000 is more than 8 bytes of digits printed out.
The right way to find exactly the right size is to check the return value of snprintf, it'll tell you how large a buffer was actually needed (or you could punt and allocate something larger than 8. sizeof(*source) isn't a solid solution.
int size = snprintf(NULL, 0, "%lu", (unsigned long)source);
buffer = new chara[size + 1]; //+1 for a NULL
int size = snprintf(buffer, size, "%lu", (unsigned long)source);
Also, the number of hard links should be consistent unless your file system is changing. Take a look at the output of
tmp]$ ls -ld /home/
drwxr-xr-x. 5 root root 4096 Feb 3 2012 /home/
That number before the owner is the number of hard links, 5 in this case.
To get total installed RAM I can use popen("sysctl -n hw.memsize", "r"), but is there some library to get this info without running external tools?
sysctl
You can use sysctl (more detail here)
The symbols used in this section are
declared in the file sysctl.h. —
Function:
int sysctl (int *names, int nlen, void *oldval, size_t *oldlenp, void *newval, size_t newlen)
getrusage
getrusage
#include <sys/resource.h>
int getrusage(int who, struct rusage *usage);
struct rusage {
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
long ru_maxrss; /* maximum resident set size */
long ru_ixrss; /* integral shared memory size */
long ru_idrss; /* integral unshared data size */
long ru_isrss; /* integral unshared stack size */
long ru_minflt; /* page reclaims */
long ru_majflt; /* page faults */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* messages sent */
long ru_msgrcv; /* messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary context switches */
};
You can use the api getrusage
int who = RUSAGE_SELF;
struct rusage usage={0,};
int ret=0;
ret = getrusage(who, &usage);
Look up the structure of rusage and pick the values of concern to you.
How can I get exact total space of a drive using C language program running on Linux? I dont want to use shell script. Any suggestions?
statfs/statfs64
#include <sys/vfs.h> /* or <sys/statfs.h> */
int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);
From the man page:
The function statfs() returns information about a mounted file system.
path is the pathname of any file within the mounted file system.
buf is a pointer to a statfs structure defined approximately as follows:
struct statfs {
long f_type; /* type of file system (see below) */
long f_bsize; /* optimal transfer block size */
long f_blocks; /* total data blocks in file system */
long f_bfree; /* free blocks in fs */
long f_bavail; /* free blocks avail to non-superuser */
long f_files; /* total file nodes in file system */
long f_ffree; /* free file nodes in fs */
fsid_t f_fsid; /* file system id */
long f_namelen; /* maximum length of filenames */
};
You can use it like this:
struct statfs buf;
statfs("/", &buf);