[comp.unix.aix] How does knlist

varun@nerdy.Eng.Sun.COM (Varun Mehta) (08/14/90)

I'm trying to read disk info from the kernel using the knlist command
and it keeps returning with an Invalid argument error.  I've read the man
page and I think I got everything right except maybe the Size argument.
i.e:
int knlist(NList, NumberOfElements, Size)
  struct nlist *NList;
  int NumberOfElements;
  int Size;

    Parameters
  
      NList     Points to an array of nlist structures.
  
      NumberOfElements  Specifies the number of structures in the ar-
  ray of nlist structures.
  
      Size      Specifies the size of each structure.
                                      ^^^^^^^^^^^^^^
How does one pass the size of each structure in one int??

I'm also uncertain how to follow the iostat.dkstatp pointer in /dev/mem.
I'm including the program below.  I'd appreciate any help with it,
Thanks,
Varun Mehta
Sun Microsystems, Inc.

#include <stdio.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <nlist.h>
#include <sys/iostat.h>
#include <fcntl.h>

struct nlist nl[] = {
#define X_DKSTAT	0
	{ "iostat" },
};
#define NUM_ELEMENTS	1
struct stats {
	struct iostat iostat;
	struct dkstat dkstat;
} s1, s2;

main()
{
	int fd, i;
	fd = open("/dev/mem", O_RDONLY);
	i = knlist(nl, NUM_ELEMENTS, sizeof(struct iostat));
	if( i == -1) {
		perror("knlist error");
		exit(1);
	}
	for(i = 0; i < NUM_ELEMENTS; i++) {
		if(nl[i].n_value == 0) {
			printf("%s not found\n", nl[i]._n._n_name);
			exit(2);
		}
	}
	lseek(fd, nl[X_DKSTAT].n_value, SEEK_SET);
	read(fd, &(s1.iostat), sizeof(struct iostat));
	lseek(fd, s1.iostat.dkstatp, SEEK_SET);
	read(fd, &(s1.dkstat), sizeof(struct dkstat));
	printf("Disk name %32c\n", s1.dkstat.diskname);
	printf("Disk busy time %d\n", s1.dkstat.dk_time);
}

jeffe@sandino.austin.ibm.com (Peter Jeffe 512.823.4091) (08/16/90)

In article <140607@sun.Eng.Sun.COM> varun@nerdy.Eng.Sun.COM (Varun Mehta) writes:
>I'm trying to read disk info from the kernel using the knlist command
>and it keeps returning with an Invalid argument error.  I've read the man
>page and I think I got everything right except maybe the Size argument.
>i.e:
>int knlist(NList, NumberOfElements, Size)
>  struct nlist *NList;
>  int NumberOfElements;
>  int Size;
>...
>      Size      Specifies the size of each structure.
>                                      ^^^^^^^^^^^^^^
>How does one pass the size of each structure in one int??

It means the sizeof(*NList).  Don't ask me why, but they say it's a sanity
check; if you pass something other than sizeof(struct nlist), it gives you
an EINVAL.

>I'm also uncertain how to follow the iostat.dkstatp pointer in /dev/mem.
>I'm including the program below.  I'd appreciate any help with it,

The iostat.dkstatp points to a linked list of struct dkstat's; the link
is dkstat.dknextp.  The value of these pointers (starting from iostat.dkstatp)
is where you want to read in memory, so it's where you seek to.

Here's what you need to do to get it working:

21,22c21,27
< 	fd = open("/dev/mem", O_RDONLY);
< 	i = knlist(nl, NUM_ELEMENTS, sizeof(struct iostat));
---
> 	int count;  /* number of dkstat structs in list */
> 	struct dkstat *dp;  /* ptr to current dkstat */
> 	if ((fd = open("/dev/mem", O_RDONLY)) <= 0) {  /* always a good idea */
> 		perror("/dev/mem");
> 		exit(1);
> 	}
> 	i = knlist(nl, NUM_ELEMENTS, sizeof(struct nlist));  /* last arg */
35c40,43
< 	lseek(fd, s1.iostat.dkstatp, SEEK_SET);
---
> 	/* step though list of dkstat structs */
> 	for (dp = s1.iostat.dkstatp, count = s1.iostat.dk_cnt; count && dp;
> 	    --count, dp = s1.dkstat.dknextp) {
> 	lseek(fd, dp, SEEK_SET);  /* seek to position in /dev/mem */
37c45
< 	printf("Disk name %32c\n", s1.dkstat.diskname);
---
> 	printf("Disk name %s\n", s1.dkstat.diskname);  /* it's a string */
38a47
> 	}

Hope this helps!
-------------------------------------------------------------------------------
Peter Jeffe   ...uunet!cs.utexas.edu!ibmaus!auschs!sandino.austin.ibm.com!jeffe
        first they want a disclaimer, then they make you pee in a jar,
                   then they come for you in the night