How to find the value of kernel.shmmax from C code
-
27-06-2021 - |
質問
I want to get the value of kernel.shmmax in C code (which I query on centos5.0, centos6.0 and ubuntu10.04 using the shell command "$ sysctl -q kernel.shmmax").
I used the following code to find it:
#include <sys/sysctl.h>
const int SHM_ERROR=1;
main(){
int name[] = {KERN_SHMMAX};
int namelen = 1;
int oldval[1];
size_t oldlen = sizeof(oldval);
int rv = sysctl(name, namelen, (void*) oldval, &oldlen, NULL, 0);
if (rv!=0) {
fprintf(stderr, "while quering for shared memory size, sysctl returned error: %s\n", strerror(errno));
return SHM_ERROR;
}
else{
return 0;
}
}
After running the code above I get the following error:
while quering for shared memory size, sysctl returned error: Not a directory
I am clueless about why I am getting this error. I googled for it and found there is some issue with the paths into which library tries to look into.
I tried running the above code with GDB but the code doesn't steps into the function sysctl, otherwise I could have provided you more information.
Data point: I am easily able to set and get kernel.shmmax from command line on all the operating systems mentioned using the following commands:
$ sysctl -q kernel.shmmax
$ sysctl -w kernel.shmmax=1000000000
Thanks
解決
You shouldn't be calling sysctl
from userspace code. From the man
page:
Glibc does not provide a wrapper for this system call; call it using syscall(2).
Or rather... don't call it: use of this system call has long been discouraged, and it is so unloved that it is likely to disappear in a future kernel version. Remove it from your programs now; use the /proc/sys interface instead.
So give this a shot instead:
#include <stdio.h>
#define SHMMAX_SYS_FILE "/proc/sys/kernel/shmmax"
int main(int argc, char **argv)
{
unsigned int shmmax;
FILE *f = fopen(SHMMAX_SYS_FILE, "r");
if (!f) {
fprintf(stderr, "Failed to open file: `%s'\n", SHMMAX_SYS_FILE);
return 1;
}
if (fscanf(f, "%u", &shmmax) != 1) {
fprintf(stderr, "Failed to read shmmax from file: `%s'\n", SHMMAX_SYS_FILE);
fclose(f);
return 1;
}
fclose(f);
printf("shmmax: %u\n", shmmax);
return 0;
}
他のヒント
I install strace and see that sysctl looks at /proc/sys/kernel/shmmax with open() call instead of _sysctl() call or syscall() call.