Implement the hw.disknames and hw.diskstats sysctl's that have been listed

in <sys/sysctl.h> since day one but never implemented.
This commit is contained in:
simonb 2002-01-27 12:41:07 +00:00
parent 7942602380
commit ed6b438e40
5 changed files with 163 additions and 20 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sysctl.3,v 1.82 2002/01/15 02:36:40 wiz Exp $
.\" $NetBSD: sysctl.3,v 1.83 2002/01/27 12:41:07 simonb Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@ -204,7 +204,7 @@ The string and integer information available for the CTL_HW level
is detailed below.
The changeable column shows whether a process with appropriate
privilege may change the value.
.Bl -column "Second level nameXXXXXX" integerXXX -offset indent
.Bl -column "Second level nameXXXXXX" "struct disk_sysctlXXX" -offset indent
.It Sy Pa Second level name Type Changeable
.It HW\_MACHINE string no
.It HW\_MODEL string no
@ -217,6 +217,8 @@ privilege may change the value.
.\".It HW\_DISKSTATS struct no
.It HW\_MACHINE\_ARCH string no
.It HW\_ALIGNBYTES integer no
.It HW\_DISKNAMES string no
.It HW\_DISKSTATS struct disk_sysctl no
.El
.Pp
.Bl -tag -width "123456"
@ -235,8 +237,16 @@ The bytes of physical memory.
The bytes of non-kernel memory.
.It Li HW_PAGESIZE
The software page size.
.\".It Fa HW_DISKNAMES
.\".It Fa HW_DISKSTATS
.It Li HW_DISKNAMES
The list of (space separated) disk device names on the system.
.It Li HW_DISKSTATS
Return statistical information on the disk devices on the system.
An array of
.Va struct disk_sysctl
structures is returned,
whose size depends on the current number of such objects in the system.
The third level name is the size of the
.Va struct disk_sysctl .
.It Li HW_MACHINE_ARCH
The machine cpu class.
.It Li HW_ALIGNBYTES

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sysctl.c,v 1.97 2001/11/12 15:25:17 lukem Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.98 2002/01/27 12:41:08 simonb Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.97 2001/11/12 15:25:17 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.98 2002/01/27 12:41:08 simonb Exp $");
#include "opt_ddb.h"
#include "opt_insecure.h"
@ -571,9 +571,15 @@ hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen, struct proc *p)
{
/* all sysctl names at this level are terminal */
if (namelen != 1)
return (ENOTDIR); /* overloaded */
/* All sysctl names at this level, except for a few, are terminal. */
switch (name[0]) {
case HW_DISKSTATS:
/* Not terminal. */
break;
default:
if (namelen != 1)
return (ENOTDIR); /* overloaded */
}
switch (name[0]) {
case HW_MACHINE:
@ -595,6 +601,10 @@ hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
return (sysctl_rdint(oldp, oldlenp, newp, PAGE_SIZE));
case HW_ALIGNBYTES:
return (sysctl_rdint(oldp, oldlenp, newp, ALIGNBYTES));
case HW_DISKNAMES:
return (sysctl_disknames(oldp, oldlenp));
case HW_DISKSTATS:
return (sysctl_diskstats(name + 1, namelen - 1, oldp, oldlenp));
case HW_CNMAGIC: {
char magic[CNS_LEN];
int error;

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_disk.c,v 1.32 2001/11/30 01:31:30 enami Exp $ */
/* $NetBSD: subr_disk.c,v 1.33 2002/01/27 12:41:08 simonb Exp $ */
/*-
* Copyright (c) 1996, 1997, 1999, 2000 The NetBSD Foundation, Inc.
@ -78,17 +78,16 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.32 2001/11/30 01:31:30 enami Exp $");
__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.33 2002/01/27 12:41:08 simonb Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/syslog.h>
#include <sys/time.h>
#include <sys/disklabel.h>
#include <sys/disk.h>
#include <sys/sysctl.h>
/*
* A global list of all disks attached to the system. May grow or
@ -96,6 +95,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.32 2001/11/30 01:31:30 enami Exp $")
*/
struct disklist_head disklist; /* TAILQ_HEAD */
int disk_count; /* number of drives in global disklist */
struct simplelock disklist_slock = SIMPLELOCK_INITIALIZER;
/*
* Seek sort for disks. We depend on the driver which calls us using b_resid
@ -394,10 +394,14 @@ disk_find(char *name)
if ((name == NULL) || (disk_count <= 0))
return (NULL);
for (diskp = disklist.tqh_first; diskp != NULL;
diskp = diskp->dk_link.tqe_next)
if (strcmp(diskp->dk_name, name) == 0)
simple_lock(&disklist_slock);
for (diskp = TAILQ_FIRST(&disklist); diskp != NULL;
diskp = TAILQ_NEXT(diskp, dk_link))
if (strcmp(diskp->dk_name, name) == 0) {
simple_unlock(&disklist_slock);
return (diskp);
}
simple_unlock(&disklist_slock);
return (NULL);
}
@ -434,7 +438,9 @@ disk_attach(struct disk *diskp)
/*
* Link into the disklist.
*/
simple_lock(&disklist_slock);
TAILQ_INSERT_TAIL(&disklist, diskp, dk_link);
simple_unlock(&disklist_slock);
++disk_count;
}
@ -450,7 +456,9 @@ disk_detach(struct disk *diskp)
*/
if (--disk_count < 0)
panic("disk_detach: disk_count < 0");
simple_lock(&disklist_slock);
TAILQ_REMOVE(&disklist, diskp, dk_link);
simple_unlock(&disklist_slock);
/*
* Free the space used by the disklabel structures.
@ -530,3 +538,98 @@ disk_resetstat(struct disk *diskp)
splx(s);
}
int
sysctl_disknames(void *vwhere, size_t *sizep)
{
char buf[DK_DISKNAMELEN + 1];
char *where = vwhere;
struct disk *diskp;
size_t needed, left, slen;
int error, first;
first = 1;
error = 0;
needed = 0;
left = *sizep;
simple_lock(&disklist_slock);
for (diskp = TAILQ_FIRST(&disklist); diskp != NULL;
diskp = TAILQ_NEXT(diskp, dk_link)) {
if (where == NULL)
needed += strlen(diskp->dk_name) + 1;
else {
memset(buf, 0, sizeof(buf));
if (first) {
strncpy(buf, diskp->dk_name, sizeof(buf));
first = 0;
} else {
buf[0] = ' ';
strncpy(buf + 1, diskp->dk_name, sizeof(buf - 1));
}
buf[DK_DISKNAMELEN] = '\0';
slen = strlen(buf);
if (left < slen + 1)
break;
/* +1 to copy out the trailing NUL byte */
error = copyout(buf, where, slen + 1);
if (error)
break;
where += slen;
needed += slen;
left -= slen;
}
}
simple_unlock(&disklist_slock);
*sizep = needed;
return (error);
}
int
sysctl_diskstats(int *name, u_int namelen, void *vwhere, size_t *sizep)
{
struct disk_sysctl sdisk;
struct disk *diskp;
char *where = vwhere;
size_t tocopy, left;
int error;
if (where == NULL) {
*sizep = disk_count * sizeof(struct disk_sysctl);
return (0);
}
if (namelen == 0)
tocopy = sizeof(sdisk);
else
tocopy = name[0];
error = 0;
left = *sizep;
memset(&sdisk, 0, sizeof(sdisk));
simple_lock(&disklist_slock);
for (diskp = TAILQ_FIRST(&disklist); diskp != NULL;
diskp = TAILQ_NEXT(diskp, dk_link)) {
if (left < sizeof(struct disk_sysctl))
break;
strncpy(sdisk.dk_name, diskp->dk_name, sizeof(sdisk.dk_name));;
sdisk.dk_xfer = diskp->dk_xfer;
sdisk.dk_seek = diskp->dk_seek;
sdisk.dk_bytes = diskp->dk_bytes;
sdisk.dk_attachtime_sec = diskp->dk_attachtime.tv_sec;
sdisk.dk_attachtime_usec = diskp->dk_attachtime.tv_usec;
sdisk.dk_timestamp_sec = diskp->dk_timestamp.tv_sec;
sdisk.dk_timestamp_usec = diskp->dk_timestamp.tv_usec;
sdisk.dk_time_sec = diskp->dk_time.tv_sec;
sdisk.dk_time_usec = diskp->dk_time.tv_usec;
sdisk.dk_busy = diskp->dk_busy;
error = copyout(&sdisk, where, min(tocopy, sizeof(sdisk)));
if (error)
break;
where += tocopy;
left -= tocopy;
}
simple_unlock(&disklist_slock);
return (error);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: disk.h,v 1.16 2000/05/16 05:45:53 thorpej Exp $ */
/* $NetBSD: disk.h,v 1.17 2002/01/27 12:41:09 simonb Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@ -131,6 +131,24 @@ struct disk {
struct cpu_disklabel *dk_cpulabel;
};
#define DK_DISKNAMELEN 16
/* The following structure is 64-bit alignment safe */
struct disk_sysctl {
char dk_name[DK_DISKNAMELEN];
int32_t dk_busy;
int32_t pad;
u_int64_t dk_xfer;
u_int64_t dk_seek;
u_int64_t dk_bytes;
u_int32_t dk_attachtime_sec;
u_int32_t dk_attachtime_usec;
u_int32_t dk_timestamp_sec;
u_int32_t dk_timestamp_usec;
u_int32_t dk_time_sec;
u_int32_t dk_time_usec;
};
struct dkdriver {
void (*d_strategy) __P((struct buf *));
#ifdef notyet

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysctl.h,v 1.70 2001/10/05 19:05:06 eeh Exp $ */
/* $NetBSD: sysctl.h,v 1.71 2002/01/27 12:41:08 simonb Exp $ */
/*
* Copyright (c) 1989, 1993
@ -444,7 +444,7 @@ struct kinfo_proc2 {
#define HW_PHYSMEM 5 /* int: total memory */
#define HW_USERMEM 6 /* int: non-kernel memory */
#define HW_PAGESIZE 7 /* int: software page size */
#define HW_DISKNAMES 8 /* strings: disk drive names */
#define HW_DISKNAMES 8 /* string: disk drive names */
#define HW_DISKSTATS 9 /* struct: diskstats[] */
#define HW_MACHINE_ARCH 10 /* string: machine architecture */
#define HW_ALIGNBYTES 11 /* int: ALIGNBYTES for the kernel */
@ -460,7 +460,7 @@ struct kinfo_proc2 {
{ "physmem", CTLTYPE_INT }, \
{ "usermem", CTLTYPE_INT }, \
{ "pagesize", CTLTYPE_INT }, \
{ "disknames", CTLTYPE_STRUCT }, \
{ "disknames", CTLTYPE_STRING }, \
{ "diskstats", CTLTYPE_STRUCT }, \
{ "machine_arch", CTLTYPE_STRING }, \
{ "alignbytes", CTLTYPE_INT }, \
@ -650,6 +650,8 @@ int sysctl_struct(void *, size_t *, void *, size_t, void *, int);
int sysctl_rdstruct(void *, size_t *, void *, const void *, int);
int sysctl_rdminstruct(void *, size_t *, void *, const void *, int);
int sysctl_clockrate(void *, size_t *);
int sysctl_disknames(void *, size_t *);
int sysctl_diskstats(int *, u_int, void *, size_t *);
int sysctl_vnode(char *, size_t *, struct proc *);
int sysctl_ntptime(void *, size_t *);
#ifdef GPROF