Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

not able to read dkstat structure

13 views
Skip to first unread message

rupa

unread,
Jul 30, 2007, 5:58:05 PM7/30/07
to
Hi,

I want to programatically read disk information on AIX and below is
the code to extract that information using iostat and dkstat
structure. But I am getting some strange error while reading the
dkstat structure and before that I am getting disk count number very
large : 760596008.
If i run iostat -d then i just get 3 disks on my system.

So in nutshell i get the following error while reading the dkstat
structure
" No such device or address". The code snippet is below.


Can anyone please tell me why I am not able to get the proper offset
of iostat and henceforth offset for dskstat.

Thanks

System configuration: lcpu=8 drives=3 paths=2 vdisks=0

Disks: % tm_act Kbps tps Kb_read Kb_wrtn
hdisk1 0.1 1.5 0.2 365205 5138900
hdisk0 0.0 0.0 0.0 0 0
cd0 0.0 0.0 0.0 0 0

#include <stdio.h> /* for perror */
#include <stdlib.h>
#include <string.h> /* for memset */
#include <nlist.h>
#include <sys/types.h>
#include <sys/iostat.h>
#include <unistd.h>
#include <fcntl.h>

int kmemfd = -1;
struct nlist diskaddr[] = {
{"iostat", 0, 0, 0, 0, 0},
{NULL, 0, 0, 0, 0, 0},
};

int dk_cnt; /* number of disks in system */
caddr_t iostat_addr = 0;
struct iostat iostat;


extern int errno;
extern char *sys_errlist[];
extern int sys_nerr;

static const char * ahmGetErrStrFromErrno()
{
if (errno <= sys_nerr) {
return (sys_errlist[errno]);
} else {
return ("cannot lookup error message");
}
}

int getkmemdata(void *buf, int bufsize, caddr_t address, char
*refrstr)
{
int n,l;

/*
* Do stuff we only need to do once per invocation, like opening
* the kmem file and fetching the parts of the symbol table.
*/
if (kmemfd < 0) {
if ((kmemfd = open("/dev/kmem", O_RDONLY)) < 0) {
perror("kmem");
exit(1);
}
/*
* We only need to be root for getting access to kmem, so give up
* root permissions now!
*/
setuid(getuid());
setgid(getgid());

/*
* Set the close on exec bit for the kmem file descriptor.
*/
if (fcntl(kmemfd, F_SETFD, FD_CLOEXEC) == -1) {
perror("fcntl kmem");
close(kmemfd);
exit(1);
}
printf("Opened the file successfully , handle = %d\n", kmemfd);
}
/*
* Get the structure from the running kernel.
*/
l = lseek(kmemfd, (off_t) address, SEEK_SET);
printf("lseek for %s= %d\n", refrstr, l);
n = read(kmemfd, buf, bufsize);

printf("read for %s = %d, err = %d, errmsg = %s\n",refrstr,n, errno,
ahmGetErrStrFromErrno() );
return(n);

} /* getkmemdata */

int init_dkstat()
{
int ret;
if (!iostat_addr) {
if (knlist(diskaddr, 1, sizeof(struct nlist)) == -1)
perror("diskaddr: entry not found");
else
iostat_addr = (caddr_t) diskaddr[0].n_value;
}

ret = getkmemdata((char *) &iostat, sizeof(struct iostat),
iostat_addr, "iostat");
if (ret < 0)
return ret;

dk_cnt = iostat.dk_cnt;

printf ("diskcount = %d\n", dk_cnt);
return dk_cnt;

} /* init_dkstat */

/*
* get the dkstat list from kernel.
*/

int get_dkstat()
{
int i,ret;
struct dkstat * diskaddr;

diskaddr = (caddr_t) iostat.dkstatp;

for (i = 0; i < dk_cnt; i++) {
struct dkstat m_dkstat;

ret = getkmemdata((char *) &m_dkstat, sizeof(struct dkstat), diskaddr,
"dkstat");
if (ret < 0)
return -1;

printf("disk %d name %s\n", i, m_dkstat.diskname);
printf("disk %d next %0lx\n", i, m_dkstat.dknextp);
printf("disk %d status %0x\n", i, m_dkstat.dk_status);
printf("disk %d time %ld\n", i, m_dkstat.dk_time);
printf("disk %d xrate %ld\n", i, m_dkstat.dk_xrate);
printf("disk %d bsize %ld\n", i, m_dkstat.dk_bsize);
printf("disk %d xfers %ld\n", i, m_dkstat.dk_xfers);
printf("disk %d rblks %ld\n", i, m_dkstat.dk_rblks);
printf("disk %d wblks %ld\n", i, m_dkstat.dk_wblks);
printf("disk %d seek %ld\n", i, m_dkstat.dk_seek);
diskaddr = m_dkstat.dknextp;
}
return i;

} /* get_dkstat */

int main()
{
int diskcount;
diskcount = init_dkstat();
if (diskcount > 0)
get_dkstat();
}

iam

unread,
Jul 31, 2007, 6:39:25 AM7/31/07
to
rupa wrote:
> Hi,
>
> I want to programatically read disk information on AIX and below is
> the code to extract that information using iostat and dkstat
> structure. But I am getting some strange error while reading the
> dkstat structure and before that I am getting disk count number very
> large : 760596008.

You trying compile with gcc? Add -maix64 on command line to produce 64-
bit binaries.
gcc default is -maix32.
If using xlc, add -q64.
The address of the structures like dkstat is 64bit.

0 new messages