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