سؤال

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top