<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hi Jon,<br>
    <br>
    Thanks for initial review, I have provided comments below. I will
    make changes in code<br>
    and README etc as mentioned at few places in my reply.<br>
    <br>
    Thanks<br>
    Rahul<br>
    <br>
    On 3/1/2018 11:55 AM, Jonathan Helman wrote:<br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com">Hi
      Rahul, <br>
      <br>
      I have a few questions and comments below on the resource.h API
      and README. Did not check out the implementation yet. <br>
      <br>
      Jon <br>
      <br>
      On 02/28/2018 10:58 PM, Rahul Yadav wrote: <br>
      <blockquote type="cite">1: System resource Information related to 
        memory, CPU, stat, networking,
        <br>
        security etc.
        <br>
        2: Currently most of such information is read from /proc and
        /sys.
        <br>
        3: Add basic infrastructure and code for some of memory and
        network related
        <br>
        information.
        <br>
        4: Update README file with the use cases and design details.
        <br>
        5: Added example codes in README.
        <br>
        <br>
        Signed-off-by: Rahul Yadav <a class="moz-txt-link-rfc2396E" href="mailto:rahul.x.yadav@oracle.com"><rahul.x.yadav@oracle.com></a>
        <br>
        ---
        <br>
          Makefile        |  18 ++++
        <br>
          README.md       | 160 ++++++++++++++++++++++++++--
        <br>
          resmem.c        | 218 ++++++++++++++++++++++++++++++++++++++
        <br>
          resmem.h        |  16 +++
        <br>
          resnet.c        | 316
        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        <br>
          resnet.h        |  14 +++
        <br>
          resource.c      | 211 +++++++++++++++++++++++++++++++++++++
        <br>
          resource.h      | 147 ++++++++++++++++++++++++++
        <br>
          resource_impl.h |  47 +++++++++
        <br>
          9 files changed, 1137 insertions(+), 10 deletions(-)
        <br>
          create mode 100644 Makefile
        <br>
          create mode 100644 resmem.c
        <br>
          create mode 100644 resmem.h
        <br>
          create mode 100644 resnet.c
        <br>
          create mode 100644 resnet.h
        <br>
          create mode 100644 resource.c
        <br>
          create mode 100644 resource.h
        <br>
          create mode 100644 resource_impl.h
        <br>
        <br>
        diff --git a/Makefile b/Makefile
        <br>
        new file mode 100644
        <br>
        index 0000000..2c71328
        <br>
        --- /dev/null
        <br>
        +++ b/Makefile
        <br>
        @@ -0,0 +1,18 @@
        <br>
        +CC = gcc
        <br>
        +CFLAGS = -g -Wall -Werror -fPIC
        <br>
        +DEPS = resource.h res_impl.h resmem.h resnet.h
        <br>
        +OBJ = resource.o resmem.o resnet.o
        <br>
        +LIB = libresource.so
        <br>
        +TEST = test
        <br>
        +RM = rm -rf
        <br>
        +CP = cp
        <br>
        +
        <br>
        +%.o: %.c $(DEPS)
        <br>
        +    $(CC) -c -o $@ $< $(CFLAGS)
        <br>
        +
        <br>
        +all: $(OBJ)
        <br>
        +    $(CC) -shared -o $(LIB) $^ $(CFLAGS)
        <br>
        +
        <br>
        +.PHONY : clean
        <br>
        +clean:
        <br>
        +    $(RM) $(LIB) $(OBJ) $(TEST)
        <br>
        diff --git a/README.md b/README.md
        <br>
        index 960468d..97b37df 100644
        <br>
        --- a/README.md
        <br>
        +++ b/README.md
        <br>
        @@ -1,14 +1,154 @@
        <br>
          # libresource
        <br>
        +library of interfaces through which we can get system resource
        information
        <br>
        +like memory, CPU, stat, networking, device etc.
        <br>
        +Currently most of such information is read from /proc and /sys.
        <br>
          -libresource is a community effort to generate a new library
        which tools
        <br>
        -like ps, top, etc can use to get information typically garnered
        from
        <br>
        -/proc.  libresource however will attempt to virtualize the data
        according
        <br>
        -to the calling task's cgroup information.
        <br>
        +Use case:
        <br>
        +1: Ease of use -
        <br>
        +Currently applications and tools need to read this info mostly
        from
        <br>
        +/proc and /sys file-systems. In most of the cases complex
        string
        <br>
        +parsing is involved which is needed to be done in application
        <br>
        +code. With the library interfaces application can get the
        information
        <br>
        +directly and all the string parsing, if any, will be done by
        library.
        <br>
        +2: Stability -
        <br>
        +If the format in which the information is provided in /proc or
        /sys
        <br>
        +file-system is changed then the application code is changed to
        align
        <br>
        +with those changes.
        <br>
      </blockquote>
      <br>
      What is the method by which you do this? Is there a chance the
      library breaks when /proc or /sys is updated, until libresource is
      updated? <br>
    </blockquote>
    <p style="margin: 0px; padding: 0px; color: rgb(51, 51, 51);
      font-family: Arial, sans-serif; font-size: 14px; font-style:
      normal; font-variant-ligatures: normal; font-variant-caps: normal;
      font-weight: 400; letter-spacing: normal; orphans: 2; text-align:
      left; text-indent: 0px; text-transform: none; white-space: normal;
      widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;
      background-color: rgb(255, 255, 255); text-decoration-style:
      initial; text-decoration-color: initial;">If something changes in
      /proc which changes the format, then libresource code must need to
      change to pick those changes, else libresource interfaces will
      give ENODATA or such error till libresource is update. If the
      changes are done taking care of existing format, for example
      appending new info at the end of proc file, then libresource will
      keep working,  <br>
    </p>
    <p style="margin: 0px; padding: 0px; color: rgb(51, 51, 51);
      font-family: Arial, sans-serif; font-size: 14px; font-style:
      normal; font-variant-ligatures: normal; font-variant-caps: normal;
      font-weight: 400; letter-spacing: normal; orphans: 2; text-align:
      left; text-indent: 0px; text-transform: none; white-space: normal;
      widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;
      background-color: rgb(255, 255, 255); text-decoration-style:
      initial; text-decoration-color: initial;"><br>
    </p>
    <p style="margin: 0px; padding: 0px; color: rgb(51, 51, 51);
      font-family: Arial, sans-serif; font-size: 14px; font-style:
      normal; font-variant-ligatures: normal; font-variant-caps: normal;
      font-weight: 400; letter-spacing: normal; orphans: 2; text-align:
      left; text-indent: 0px; text-transform: none; white-space: normal;
      widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;
      background-color: rgb(255, 255, 255); text-decoration-style:
      initial; text-decoration-color: initial;">Basically the idea is
      that application will not need to make any code changes,
      administrator just need to update the library and it should work.
      And by making code changes to library, all applications using the
      library will start using updated information. However I understand
      that, libresource should pick such changes as soon as it is
      available in /proc (or any such file) for it to work.</p>
    <p style="margin: 10px 0px 0px; padding: 0px; color: rgb(51, 51,
      51); font-family: Arial, sans-serif; font-size: 14px; font-style:
      normal; font-variant-ligatures: normal; font-variant-caps: normal;
      font-weight: 400; letter-spacing: normal; orphans: 2; text-align:
      left; text-indent: 0px; text-transform: none; white-space: normal;
      widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;
      background-color: rgb(255, 255, 255); text-decoration-style:
      initial; text-decoration-color: initial;">Also there is a library
      version which can be checked by applications to make decisions.</p>
    <p style="margin: 10px 0px 0px; padding: 0px; color: rgb(51, 51,
      51); font-family: Arial, sans-serif; font-size: 14px; font-style:
      normal; font-variant-ligatures: normal; font-variant-caps: normal;
      font-weight: 400; letter-spacing: normal; orphans: 2; text-align:
      left; text-indent: 0px; text-transform: none; white-space: normal;
      widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;
      background-color: rgb(255, 255, 255); text-decoration-style:
      initial; text-decoration-color: initial;">With that, if there are
      any significant changes to a particular resource then resource ID
      will be suffixed with V1, V2 etc. Old version will also work in
      that case for backward compatibility.</p>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
       Also if a better way to get information comes in <br>
      <blockquote type="cite">+future, like through a syscall or a
        sysconf then again application code
        <br>
        +needs to be changed to get the benefit of it. Library will take
        care of
        <br>
        +such changes.
        <br>
        +3: Virtualization -
        <br>
        +In cases where DB is running in a virtualized environment using
        <br>
        +cgroup or namespaces, reading from /proc and /sys file-systems
        <br>
        +might not give correct information as these are not cgroup
        <br>
        +aware. Library API will take care of this e.g. if a process
        <br>
        +is running in a cgroup then library should provide information
        <br>
        +which is local to that cgroup.
        <br>
          -# contributing
        <br>
        +Design:
        <br>
        +Each resource is identified by a resource id. User land
        application should
        <br>
        +provide the id while calling the interfaces to fetch the
        information.
        <br>
        +Following are resource IDs which are already implemented.
        <br>
          -We will interact through pull requests and the issue
        tracker.  I think we
        <br>
        -should start with pull requests editing the CONTRIBUTORS so we
        can have a
        <br>
        -feel whether enough people are able to contribute or interested
        in following
        <br>
        -for the project to be successful.  We can also start pull
        requests against
        <br>
        -the specs/api.md file to discuss what that should look like.
        <br>
        +RES_MEM_ACTIVE
        <br>
        +RES_MEM_INACTIVE
        <br>
        +RES_MEM_AVAILABLE
        <br>
        +RES_MEM_FREE
        <br>
        +RES_MEM_TOTAL
        <br>
        +RES_MEM_PAGESIZE
        <br>
        +RES_MEM_SWAPFREE
        <br>
        +RES_MEM_SWAPTOTAL
        <br>
        +RES_KERN_COMPILE_TIME
        <br>
        +RES_KERN_RELEASE
        <br>
        +RES_NET_ALLIFSTAT
        <br>
        +RES_NET_IFSTAT
        <br>
        +RES_MEM_INFOALL
        <br>
        +
        <br>
        +Interfaces:
        <br>
        +1:
        <br>
        +int res_read(int res_id, void *out, void *hint, int pid, int
        flags); > +
        <br>
        +This is to read a resource information. A valid resource id
        should be provided
        <br>
        +in res_id, out should be properly allocated on the basis of
        size of resource
        <br>
        +information, hint should be given where needed. Currently pid
        and flags are
        <br>
        +not used, they are for future extensions.
        <br>
        +
        <br>
        +2:
        <br>
        +
        <br>
        +If an application wants to read multiple resource information
        in one call, it
        <br>
        +can call res_*_blk APIs to do so.
        <br>
        +
        <br>
        +2.1 structs
        <br>
        +Following struct holds information about one resource in such
        case.
        <br>
        +typedef struct res_unit {
        <br>
        +        int status;
        <br>
        +        int res_id;
        <br>
        +        void *hint;
        <br>
        +        union r_data data;
        <br>
        +} res_unit_t;
        <br>
        +
        <br>
        +An array of these form res_blk_t structure as below.
        <br>
        +typedef struct res_blk {
        <br>
        +        int res_count;
        <br>
        +        res_unit_t *res_unit[0];
        <br>
        +} res_blk_t;
        <br>
        +
        <br>
        +res_blk_t strcut is used in all res_*_blk interfaces.
        <br>
      </blockquote>
      <br>
      s/strcut/struct <br>
    </blockquote>
    Will spell check again on whole PATCH.<br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+
        <br>
        +2.2 functions
        <br>
        +res_blk_t *res_build_blk(int *res_ids, int res_count);
        <br>
        +
        <br>
        +This allocates memory for resources and initiates them
        properly. res_ids
        <br>
        +holds and array of valid resource ids and res_count holds
        number of
        <br>
        +resource ids. It also initiates struct fields properly.
        <br>
        +
        <br>
        +int res_read_blk(res_blk_t *resblk, int pid, int flags);
        <br>
        +Reading bulk resource information. Memory must be properly
        allocated and
        <br>
        +all fields should be properly filled to return error free
        resource
        <br>
        +information. res_build_blk call is suggested to allocate build
        res_blk_t
        <br>
        +structure.
        <br>
      </blockquote>
      <br>
      It seems that flags, since for future extensions, would be per
      res_unit (like the hint). Could you explain why flags is per
      res_blk? <br>
    </blockquote>
    I was thinking flags as clues for overall libresource interfaces
    instead of individual resource ids. <br>
    For example we can put a "consistent single snapshot"bit in the
    flag, which will mean that <br>
    all information fetched should show one snapshot of system resource
    i.e. for example <br>
    memfree, memtoal, and memavailble should be read at once instead of
    one<br>
    by one where values might change in middle of reads.<br>
    <br>
    For that reason they are one per interface.<br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+
        <br>
        +/* Free allocated memory from res_build_blk */
        <br>
        +extern void res_destroy_blk(res_blk_t *resblk);
        <br>
        +
        <br>
        +Example
        <br>
        +1:
        <br>
        +Reading total memory
        <br>
        +size_t stemp = 0;
        <br>
        +res_read(RES_MEM_TOTAL,&stemp,NULL, 0, 0);
        <br>
        +printf("MEMTOTAL is: %zu\n", stemp);
        <br>
        +
        <br>
        +
        <br>
        +2:
        <br>
        +reading network interface related statistics for interface
        named "lo"
        <br>
        +res_net_ifstat_t ifstat;
        <br>
        +res_read(RES_NET_IFSTAT,&ifstat, (void *)"lo",0, 0);
        <br>
        +printf("status for %s: %llu %llru\n", ifstat.ifname,
        <br>
        +    ifstat.rx_bytes,
        <br>
        +    ifstat.rx_packets
        <br>
        +    );
        <br>
        +3:
        <br>
        +Reading multiple resouce information in one call.
        <br>
      </blockquote>
      <br>
      s/resouce/resource <br>
      <br>
      <blockquote type="cite">+
        <br>
        +    res_blk_t *b = NULL;
        <br>
        +    int a[NUM] = {RES_MEM_PAGESIZE,
        <br>
        +                RES_MEM_TOTAL,
        <br>
        +                RES_MEM_AVAILABLE,
        <br>
        +                RES_MEM_INFOALL,
        <br>
        +                RES_KERN_RELEASE,
        <br>
        +                RES_NET_IFSTAT,
        <br>
        +                RES_NET_ALLIFSTAT,
        <br>
        +                RES_KERN_COMPILE_TIME
        <br>
        +                };
        <br>
        +    b = res_build_blk(a, NUM);
        <br>
        +    b->res_unit[5]->hint = (void *)"lo";
        <br>
        +
        <br>
        +    res_read_blk(b, 0, 0);
        <br>
        +
        <br>
        +    printf("pagesize %ld bytes,\n memtotal %ld kb,\n
        memavailable %ld kb,\n"
        <br>
        +            " mefree %ld kb,\n release %s,\n compile time
        %s\n",
        <br>
      </blockquote>
      <br>
      s/mefree/memfree <br>
      <br>
      <blockquote type="cite">+           
        b->res_unit[0]->data.sz,
        <br>
        +            b->res_unit[1]->data.sz,
        <br>
        +            b->res_unit[2]->data.sz,
        <br>
        +            ((res_mem_infoall_t
        *)(b->res_unit[3]->data.ptr))->memfree,
        <br>
        +            b->res_unit[4]->data.str,
        <br>
        +            b->res_unit[7]->data.str
        <br>
        +    );
        <br>
        +
        <br>
        +    res_net_ifstat_t *ip = (res_net_ifstat_t
        *)b->res_unit[5]->data.ptr;
        <br>
        +    printf("stat for interface %s: %llu %llu\n", ip->ifname,
        <br>
        +        ip->rx_bytes,
        <br>
        +        ip->rx_packets
        <br>
        +        );
        <br>
        +
        <br>
        +    int k = (int)(long long)b->res_unit[6]->hint;
        <br>
        +    res_net_ifstat_t *ipp = (res_net_ifstat_t
        *)b->res_unit[6]->data.ptr;
        <br>
        +    for (int j=0; j< k; j++) {
        <br>
        +        printf("stat for interface %s: %llu %llu\n",
        ipp[j].ifname,
        <br>
        +            ipp[j].rx_bytes,
        <br>
        +            ipp[j].rx_packets
        <br>
        +        );
        <br>
        +    }
        <br>
        +
        <br>
        +    free(ipp);
        <br>
      </blockquote>
      <br>
      What is ipp? <br>
    </blockquote>
    For some resources (very few) memory might be allocated at the time
    of read, for such resources <br>
    it needs to be freed in application code.<br>
    <br>
    I shall provide such info in man page, I am trying to figure out how
    to add man page for libraries.<br>
    For now I will update README with such info.<br>
    <br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+    res_destroy_blk(b);
        <br>
      </blockquote>
      <br>
      <br>
      <blockquote type="cite"><snip>
        <br>
      </blockquote>
      <br>
      <br>
      <blockquote type="cite">diff --git a/resource.h b/resource.h
        <br>
        new file mode 100644
        <br>
        index 0000000..963877d
        <br>
        --- /dev/null
        <br>
        +++ b/resource.h
        <br>
        @@ -0,0 +1,147 @@
        <br>
        +#ifndef    _RESOURCE_H
        <br>
        +#define    _RESOURCE_H
        <br>
        +
        <br>
        +#include <stdio.h>
        <br>
      </blockquote>
      <br>
      What is this file included for here? <br>
    </blockquote>
    It is not needed, will remove it.<br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+#include <net/if.h>
        <br>
        +
        <br>
        +/* libresource version */
        <br>
        +#define LIBRESOURCE_API_VERSION 1
        <br>
        +
        <br>
        +/* Possible status for libresource information returned */
        <br>
        +/* libresource information was fetched correctly */
        <br>
        +#define RES_STATUS_FILLED 0
        <br>
        +/* There was some error in fetching libresource information. In
        most cases
        <br>
        + * errno will be set.
        <br>
        + */
        <br>
        +#define RES_STATUS_EMPTY -1
        <br>
        +/* Resource information is not supported yet, or Invalid
        resource
        <br>
        + * information.
        <br>
      </blockquote>
      <br>
      Seems that notsupported should be differentiated from invalid
      resource info.<br>
    </blockquote>
    For library any invalid resource_id number is same as not supported<br>
    resource_id numbers, right ? or I missed something here.<br>
    <br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+ */
        <br>
        +#define RES_STATUS_NOTSUPPORTED    -2
        <br>
        +/* If partial information was read for a libresource
        information. For example
        <br>
        + * a string was read partially.
        <br>
        + */
        <br>
        +#define RES_STATUS_TRUNCATED -3
        <br>
      </blockquote>
      <br>
      How do you know which information is valid? </blockquote>
    If status is FILLED that means information is valid.<br>
    <br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com">Is this
      if you want multiple units in a block and only some of the units
      are filled?<br>
    </blockquote>
    Yes this status should be used in such cases .<br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+
        <br>
        +
        <br>
        +/* Maximum size of a resource information data type which can
        be returned
        <br>
        + * without explicitly allocating memory for it. If resource
        information
        <br>
        + * size is larger than this this a pointer to allocated memory
        will be
        <br>
        + * returned.
        <br>
        + */
        <br>
        +#define RES_UNIT_OUT_SIZE    256
        <br>
        +
        <br>
        +/* This union is used to return resource information of various
        types */
        <br>
        +union r_data {
        <br>
        +    int i;
        <br>
        +    size_t sz;
        <br>
        +    long l;
        <br>
        +    char str[RES_UNIT_OUT_SIZE];
        <br>
        +    void *ptr;
        <br>
        +};
        <br>
      </blockquote>
      <br>
      Hmm, this is a confusing idea, IMO. Maybe everything is in void
      *ptr? And then this union could be collapsed.<br>
    </blockquote>
    Even if it is a pointer application will need to know what is the
    return type in order to cast it.<br>
    With pointer there will be one extra memory dereference to get the
    data, so i thought this<br>
    is faster.<br>
    <br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+
        <br>
        +/* In case of res_read_blk, each resource information will be
        represented by
        <br>
        + * following structure.
        <br>
        + */
        <br>
        +typedef struct res_unit {
        <br>
        +    int status;
        <br>
        +    int res_id;
        <br>
        +    void *hint;
        <br>
        +    union r_data data;
        <br>
        +} res_unit_t;
        <br>
        +
        <br>
        +/* In case of bulk read (res_read_blk), this structure will
        hold all required
        <br>
        + * information needed to do so.
        <br>
        + */
        <br>
        +typedef struct res_blk {
        <br>
        +    int res_count;
        <br>
        +    res_unit_t *res_unit[0];
        <br>
        +} res_blk_t;
        <br>
        +
        <br>
        +/* Resource information is divided in broad categories and each
        <br>
        + * category is assigned a number range for its resource
        information
        <br>
        + * Memory related            (RES_MEM_*)        1024-
        <br>
        + * Network related            (RES_NET_*)        2048-
        <br>
        + * General kernel related        (RES_KERN_*)        3072-
        <br>
        + * This is done to facilitate any future optimization which can
        be made
        <br>
        + * on the basis of resource information (hashing etc ?)
        <br>
      </blockquote>
      <br>
      Should these be u64 instead of int then? <br>
    </blockquote>
    you are right, we can use unsigned in instead. Will do that.<br>
    <br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+ */
        <br>
        +#define MEM_MIN                1024
        <br>
        +#define RES_MEM_HUGEPAGEALL        1025
        <br>
        +#define RES_MEM_HUGEPAGESIZE        1026
        <br>
        +#define RES_MEM_INACTIVE        1027
        <br>
        +#define RES_MEM_INFOALL            1028
        <br>
        +#define RES_MEM_AVAILABLE        1029
        <br>
        +#define RES_MEM_FREE            1030
        <br>
        +#define RES_MEM_TOTAL            1031
        <br>
        +#define RES_MEM_PAGESIZE        1032
        <br>
        +#define RES_MEM_SHMALL            1033
        <br>
        +#define RES_MEM_SHMINFOALL        1034
        <br>
        +#define RES_MEM_SHMMAX            1035
        <br>
        +#define RES_MEM_SHMMNI            1036
        <br>
      </blockquote>
      <br>
      What is MNI? <br>
    </blockquote>
    My bad. It should be MIN, implementation for this is not in this
    patch yet, I will remove such #defines <br>
    which are not implemented.<br>
    <br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+#define RES_MEM_SWAPFREE        1037
        <br>
        +#define RES_MEM_SWAPTOTAL        1038
        <br>
        +#define RES_MEM_ACTIVE            1039
        <br>
        +#define MEM_MAX                1040
        <br>
        +
        <br>
        +#define NET_MIN                2048
        <br>
        +#define RES_NET_IFSTAT            2049
        <br>
        +#define RES_NET_ALLIFSTAT        2050
        <br>
        +#define NET_MAX                2051
        <br>
        +
        <br>
        +#define KERN_MIN            3072
        <br>
        +#define RES_KERN_COMPILE_TIME        3073
        <br>
        +#define RES_KERN_RELEASE        3074
        <br>
        +#define KERN_MAX            3075
        <br>
        +
        <br>
        +/* Structure to return RES_MEM_INFOALL resource information */
        <br>
        +typedef struct res_mem_infoall {
        <br>
        +    size_t memfree;
        <br>
        +    size_t memtotal;
        <br>
        +    size_t memavailable;
        <br>
        +    size_t active;
        <br>
        +    size_t inactive;
        <br>
        +    size_t swaptotal;
        <br>
        +    size_t swapfree;
        <br>
        +} res_mem_infoall_t;
        <br>
        +
        <br>
        +/* Structure to return RES_MEM_ALLIFSTAT resource information
        */
        <br>
        +typedef struct res_net_ifstat {
        <br>
        +    char ifname[IFNAMSIZ];
        <br>
        +    unsigned long long rx_bytes;
        <br>
        +    unsigned long long rx_packets;
        <br>
        +    unsigned long rx_errors;
        <br>
        +    unsigned long rx_dropped;
        <br>
        +    unsigned long rx_fifo_err;
        <br>
        +    unsigned long rx_frame_err;
        <br>
        +    unsigned long rx_compressed;
        <br>
        +    unsigned long rx_multicast;
        <br>
        +    unsigned long long tx_bytes;
        <br>
        +    unsigned long long tx_packets;
        <br>
        +    unsigned long tx_errors;
        <br>
        +    unsigned long tx_dropped;
        <br>
        +    unsigned long tx_fifo_err;
        <br>
        +    unsigned long tx_collisions;
        <br>
        +    unsigned long tx_carrier_err;
        <br>
        +    unsigned long tx_compressed;
        <br>
        +} res_net_ifstat_t;
        <br>
      </blockquote>
      <br>
      Maybe this struct name should have the word all in it to be
      consistent with struct res_mem_infoall? <br>
    </blockquote>
    For interfaces ifstat provides stat for one interface, allifstat
    might suggest that it is stat for all<br>
    interfaces. So I did not choose that name.<br>
    <br>
    <blockquote type="cite"
      cite="mid:5690c180-c4ca-8d5b-9a6f-be4b8c04b973@oracle.com"> <br>
      <blockquote type="cite">+
        <br>
        +/* Allocating memory and building a res_blk structure to return
        bulk
        <br>
        + * resource information.
        <br>
        + */
        <br>
        +extern res_blk_t *res_build_blk(int *res_ids, int res_count);
        <br>
        +
        <br>
        +/* Reading bulk resource information. Memory must be properly
        allocated and
        <br>
        + * all fields should be properly filled to return error free
        resource
        <br>
        + * information. res_build_blk call is suggested to allocate
        build res_blk_t
        <br>
      </blockquote>
      <br>
      s/allocate build/allocate and build <br>
      <br>
      <blockquote type="cite">+ * structure.
        <br>
        + */
        <br>
        +extern int res_read_blk(res_blk_t *resblk, int pid, int flags);
        <br>
        +
        <br>
        +/* Free allocated memory from res_build_blk */
        <br>
        +extern void res_destroy_blk(res_blk_t *resblk);
        <br>
        +
        <br>
        +/* Read a resource information. Memory for out should be
        properly allocated */
        <br>
        +extern int res_read(int res_id, void *out, void *hint, int pid,
        int flags);
        <br>
        +
        <br>
        +#endif /* RESOURCE_H */
        <br>
        <br>
      </blockquote>
    </blockquote>
    <br>
  </body>
</html>