not able to read dkstat structure - Aix

This is a discussion on not able to read dkstat structure - Aix ; 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 ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: not able to read dkstat structure

  1. not able to read dkstat structure

    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 /* for perror */
    #include
    #include /* for memset */
    #include
    #include
    #include
    #include
    #include

    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();
    }


  2. Re: not able to read dkstat structure

    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.


+ Reply to Thread