AIX

AIX

Connect with fellow AIX users and experts to gain knowledge, share insights, and solve problems.


#Power
#Power
#Operatingsystems
#Servers
 View Only
  • 1.  not able to read dkstat structure

    Posted 07/27/07 07:57 PM

    Originally posted by: SystemAdmin


    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_errlisterrno);
    } 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();
    }
    #AIX-Forum


  • 2.  Re: not able to read dkstat structure

    Posted 07/30/07 06:42 AM

    Originally posted by: SystemAdmin


    Hi,
    Your technique is very interesting. How can you make sure the disk linked list doesn't change when you traverse it?

    Thanks,
    Eran.
    #AIX-Forum


  • 3.  Re: not able to read dkstat structure

    Posted 07/30/07 08:18 PM

    Originally posted by: SystemAdmin


    Well that questions comes later when I would be able to get the correct offset for dkstat from iostat.
    It seems the iostat structure itself is not read properly.
    I have the same problem as mentioned by some other person on this post:

    http://groups.google.com/group/comp.unix.aix/browse_thread/thread/601127c85240fb55/1413c18d282ab924?lnk=gst&q=iostat&rnum=8#1413c18d282ab924

    PS: I am facing the problem on aix 5.3
    #AIX-Forum


  • 4.  Re: not able to read dkstat structure

    Posted 07/30/07 09:05 PM

    Originally posted by: SystemAdmin


    This is the output from the program:

    bash-3.00# ./dkstat
    offset for iostat = 2a7c480
    Opened the file /dev/kmem successfully , handle = 3
    lseek for iostat= 44549248
    read for iostat = 12, err = 0, errmsg = Error 0
    iostat.dk_cnt = 760563240, iostat.dk_path_cnt = 0
    Offset for dkstat = f1000100
    lseek for dkstat= -251657984
    read for dkstat = -1, err = 6, errmsg = No such device or address
    PS: The offset for dkstat returned from ioststat structure doesn't look like a valid address ( f1000100 ).
    So the values that we are reading from iostat are garbage.
    #AIX-Forum


  • 5.  Re: not able to read dkstat structure

    Posted 07/31/07 09:37 PM

    Originally posted by: SystemAdmin


    I have found the solution for reading the disk information using perfstat library. I am still clueless as to why the above code won't work on AIX 5.3. It seems IBM cares least to reply queries posted on this forum.

    Anyway, for those who might fall in this problem may like to look at the following link for their solution.

    http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.prftools/doc/prftools/perfstat_api.htm

    thanks
    #AIX-Forum


  • 6.  Re: not able to read dkstat structure

    Posted 08/01/07 02:36 AM

    Originally posted by: SystemAdmin


    Anyone has any idea how to enumerate those disks from kernel mode. Obviously there is a way since the enumeration is done by the perfstat kernel extension.

    Thanks,
    Eran.
    #AIX-Forum


  • 7.  Re: not able to read dkstat structure

    Posted 08/01/07 12:34 AM

    Originally posted by: SystemAdmin


    See answer on your question in comp.unix.aix newsgroups at
    http://groups.google.com/group/comp.unix.aix/browse_thread/thread/6016ab63afe5992e
    #AIX-Forum