In the embedded system I'm working on, I have a need to get detailed hard
drive information in a userland process. Specifically, I need the contents
of all the values in wddrives[].

While I've made it work, I've run into a few difficulties. If someone thinks
this is useful enough, I'll clean it up to make it more presentable for
inclusion, as well as a port to the ATA driver.

I added the following routine to sys/i386/isa/wd.c :


static intsysctl_hw_wddrives SYSCTL_HANDLER_ARGS{
        int error=0;
        int i;

        for (i=0;i<NWD;i++) {
                if (wddrives[i]) {
                        error=sysctl_handle_opaque(oidp,wddrives[i],sizeof(struct 
disk),req);
                        if(error) return(error);
                }
        }
        return(error);

}

SYSCTL_PROC(_hw, OID_AUTO, wddrives, CTLTYPE_OPAQUE|CTLFLAG_RD, 0, 0,
sysctl_hw_wddrives, "S","Contents of wddrives struct");


As well as the following patch to sys/sys/sysctl.h :

bash-2.02$ diff -u sysctl.h.old sysctl.h
--- sysctl.h.old        Mon Nov 29 17:58:22 1999
+++ sysctl.h    Thu Nov 25 22:58:28 1999
@@ -329,6 +329,7 @@
 #define HW_FLOATINGPT  10              /* int: has HW floating point? */
 #define HW_MACHINE_ARCH        11              /* string: machine architecture */
 #define        HW_MAXID        12              /* number of valid hw ids */
+#define        HW_WDDRIVES             13              /* wdx stats */
 
 #define CTL_HW_NAMES { \
        { 0, 0 }, \
@@ -342,6 +343,7 @@
        { "disknames", CTLTYPE_STRUCT }, \
        { "diskstats", CTLTYPE_STRUCT }, \
        { "floatingpoint", CTLTYPE_INT }, \
+       { "wddrives", CTLTYPE_STRUCT }, \
 }
 
 /*



This let me, via a sysctl, get all the disk structures' contents. Being able
to parse them was a bit of a trick though. 'struct disk' is defined in wd.c
itself, as well as having a few compile-time #ifdef's that made it hard to
include in my application. I ended up doing a cut-n-paste of the structure
into my app, including /sys/compile/kernelname/opt_wd.h to get the correct
define of CMD640.

'struct disk' also requires "/sys/i386/isa/wdreg.h" to be included to get
the structure of 'wdparms'. It's also wrapped around an #ifdef KERNEL, that
I really can't see why it's there.


In the end, doing this, which admittedly is very very messy, works:



#include "/sys/compile/DEVEL/opt_wd.h"

struct diskgeom {

(stolen directly from wd.c)

}

struct disk {

(stolen directly from wd.c)

};

#define KERNEL  /* Don't hate me for this */
#include "/sys/i386/isa/wdreg.h"
#undef KERNEL
#include <sys/dkstat.h>
#include <devstat.h>

static struct disk wddrives[NWD];       /* table of units */


void foo(void) {
unsigned int len;
int i;

  len = sizeof(struct disk) * NWD;
  for (i=0;i<NWD;i++)
        bzero(&wddrives[i], sizeof(struct disk));
  i = sysctlbyname("hw.wddrives", &wddrives[0], &len, NULL, 0);

}




Is there a better way to do this sort of thing? I was tempted to make my own
struct and have the sysctl handler fill it out, but I really ended up
needing 90% of what's in there anway, and it seemed wasteful to do that. 

Another note, is there a reason why there's no sysctl for the true amount of
physical memory? 

hw.physmem: 31076352
hw.usermem: 24109056

"physmem" really seems to be "Physical memory - kernel size". Is this
broken, or the desired behavior?


Kevin


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to