orachat@seashell.seas.ucla.edu (Orachat Choedamphai) (03/23/90)
Hello, I'm trying to get the value of the variable "avenrun" from /dev/kmem. The following is a program that I used. Could someone please tell me what I did wrong or maybe someone could send me a C program that will do this job? I would appreciate any help or suggestion. Thank you in advance. _Orachat #include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/file.h> #include <a.out.h> #define UNIX "/unix" int kmemf; /* descriptor of /dev/kmem */ struct nlist nl[2]; extern int errno; main () { float avenrun[3]; (void) strcpy (nl[0].n_name, "avenrun"); (void) strcpy (nl[1].n_name, "0"); nlist(UNIX, nl); if (nl[0].n_value == 0) { fprintf (stderr, "/vmunix: No namelist\n"); exit(1); } printf ("address = %d\n", nl[0].n_value); if ((kmemf = open("/dev/kmem", O_RDONLY)) < 0) { perror ("/dev/kmem"); exit (1); } if (lseek (kmemf, (off_t)nl[0].n_value, 0) < 0) printf ("lseek failed\n");; (void) read (kmemf, (char *)avenrun, sizeof(avenrun)); printf ("load = %e,%e,%e\n", avenrun[0], avenrun[1], avenrun[2]); }
rmtodd@servalan.uucp (Richard Todd) (03/23/90)
orachat@seashell.seas.ucla.edu (Orachat Choedamphai) writes: >Hello, >I'm trying to get the value of the variable "avenrun" from /dev/kmem. The >following is a program that I used. Could someone please tell me what I did >wrong or maybe someone could send me a C program that will do this job? >I would appreciate any help or suggestion. Thank you in advance. Well, I can see two problems with the code: >... > float avenrun[3]; The avenrun array is actually an array of longs, scaled by 65536. So this should be long avenrun[3]; > (void) strcpy (nl[0].n_name, "avenrun"); > (void) strcpy (nl[1].n_name, "0"); The nlist routines require the name in the last entry to be the empty string "". Putting in "0" instead may be confusing it. > (void) read (kmemf, (char *)avenrun, sizeof(avenrun)); > printf ("load = %e,%e,%e\n", avenrun[0], avenrun[1], avenrun[2]); >} Since the values are scaled longs, this should be: printf("load = %e %e %e", avenrun[0]/65536.0, avenrun[1]/65536.0, avenrun[2]/65536.0); Alas, this sort of thing (the format of kernel variables) isn't really well documented, and it varies greatly among systems. As I recall, PDP-11s running BSD2.10 store the avenrun values as ints scaled by 256, Suns store them as floats, and getting the load average on an Encore Multimax is *really* messy. The lack of documentation for kernel internal variables is one of my really big pet peeves; basically the way you find out how avenrun[] is stored on a system (assuming you don't have kernel source) is to try interpreting the values you read in various formats until you find one that doesn't give gibberish. Bletch. -- Richard Todd rmtodd@uokmax.ecn.uoknor.edu rmtodd@chinet.chi.il.us rmtodd@servalan.uucp Motorola Skates On Intel's Head!