<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>