PERFORCE change 63016 for review
Peter Wemm
peter at FreeBSD.org
Mon Oct 11 14:26:49 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=63016
Change 63016 by peter at peter_melody on 2004/10/11 21:26:18
Make the i386 sysctl binary work on amd64. This covers
most of the visible fields. Things like kern.proc.* and the
netstat structs are a nightmare. I think I'm going to cry.
Affected files ...
.. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_misc.c#17 edit
.. //depot/projects/hammer/sys/kern/kern_exec.c#36 edit
.. //depot/projects/hammer/sys/kern/kern_sysctl.c#16 edit
.. //depot/projects/hammer/sys/kern/kern_tc.c#15 edit
.. //depot/projects/hammer/sys/kern/kern_xxx.c#8 edit
.. //depot/projects/hammer/sys/sys/sysctl.h#20 edit
.. //depot/projects/hammer/sys/vm/vm_meter.c#11 edit
Differences ...
==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_misc.c#17 (text+ko) ====
@@ -1198,44 +1198,26 @@
int
freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
{
- int error, name[CTL_MAXNAME + 2];
- u_char buf[256];
+ int error, name[CTL_MAXNAME];
size_t j, oldlen;
if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
return (EINVAL);
-
- name[0] = 0; /* Internal sysctl function */
- name[1] = 4; /* This is magic */
- error = copyin(uap->name, &name[2], uap->namelen * sizeof(int));
+ error = copyin(uap->name, name, uap->namelen * sizeof(int));
if (error)
return (error);
-
mtx_lock(&Giant);
-
- j = sizeof(buf);
- error = kernel_sysctl(td, name, uap->namelen + 2, buf, &j, 0, 0, &j);
- if (error == 0 && j >= sizeof(u_int)) {
- int kind = *(u_int *)buf;
- if ((kind & CTLTYPE) == CTLTYPE_LONG ||
- (kind & CTLTYPE) == CTLTYPE_ULONG) {
- printf("sysctl LONG!\n");
- /* do conversion */
- }
- }
-
if (uap->oldlenp)
oldlen = fuword32(uap->oldlenp);
else
oldlen = 0;
error = userland_sysctl(td, name, uap->namelen,
uap->old, &oldlen, 1,
- uap->new, uap->newlen, &j);
+ uap->new, uap->newlen, &j, SCTL_MASK32);
if (error && error != ENOMEM)
goto done2;
- if (uap->oldlenp) {
+ if (uap->oldlenp)
suword32(uap->oldlenp, j);
- }
done2:
mtx_unlock(&Giant);
return (error);
==== //depot/projects/hammer/sys/kern/kern_exec.c#36 (text+ko) ====
@@ -104,8 +104,8 @@
int error;
p = curproc;
-#if defined(__amd64__) || defined(__ia64__)
- if (req->oldlen == sizeof(unsigned int)) {
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
unsigned int val;
val = (unsigned int)p->p_sysent->sv_psstrings;
error = SYSCTL_OUT(req, &val, sizeof(val));
@@ -123,8 +123,8 @@
int error;
p = curproc;
-#if defined(__amd64__) || defined(__ia64__)
- if (req->oldlen == sizeof(unsigned int)) {
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
unsigned int val;
val = (unsigned int)p->p_sysent->sv_usrstack;
error = SYSCTL_OUT(req, &val, sizeof(val));
==== //depot/projects/hammer/sys/kern/kern_sysctl.c#16 (text+ko) ====
@@ -828,20 +828,35 @@
sysctl_handle_long(SYSCTL_HANDLER_ARGS)
{
int error = 0;
- long tmpout;
+ long tmplong;
+#ifdef SCTL_MASK32
+ int tmpint;
+#endif
/*
* Attempt to get a coherent snapshot by making a copy of the data.
*/
if (!arg1)
return (EINVAL);
- tmpout = *(long *)arg1;
- error = SYSCTL_OUT(req, &tmpout, sizeof(long));
+ tmplong = *(long *)arg1;
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
+ tmpint = tmplong;
+ error = SYSCTL_OUT(req, &tmpint, sizeof(int));
+ } else
+#endif
+ error = SYSCTL_OUT(req, &tmplong, sizeof(long));
if (error || !req->newptr)
return (error);
- error = SYSCTL_IN(req, arg1, sizeof(long));
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
+ error = SYSCTL_IN(req, &tmpint, sizeof(int));
+ *(long *)arg1 = (long)tmpint;
+ } else
+#endif
+ error = SYSCTL_IN(req, arg1, sizeof(long));
return (error);
}
@@ -965,7 +980,7 @@
int
kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
- size_t *oldlenp, void *new, size_t newlen, size_t *retval)
+ size_t *oldlenp, void *new, size_t newlen, size_t *retval, int flags)
{
int error = 0;
struct sysctl_req req;
@@ -973,6 +988,7 @@
bzero(&req, sizeof req);
req.td = td;
+ req.flags = flags;
if (oldlenp) {
req.oldlen = *oldlenp;
@@ -1015,7 +1031,7 @@
int
kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
- void *new, size_t newlen, size_t *retval)
+ void *new, size_t newlen, size_t *retval, int flags)
{
int oid[CTL_MAXNAME];
size_t oidlen, plen;
@@ -1026,12 +1042,12 @@
oidlen = sizeof(oid);
error = kernel_sysctl(td, oid, 2, oid, &oidlen,
- (void *)name, strlen(name), &plen);
+ (void *)name, strlen(name), &plen, flags);
if (error)
return (error);
error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp,
- new, newlen, retval);
+ new, newlen, retval, flags);
return (error);
}
@@ -1256,7 +1272,7 @@
error = userland_sysctl(td, name, uap->namelen,
uap->old, uap->oldlenp, 0,
- uap->new, uap->newlen, &j);
+ uap->new, uap->newlen, &j, 0);
if (error && error != ENOMEM)
goto done2;
if (uap->oldlenp) {
@@ -1275,7 +1291,8 @@
*/
int
userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
- size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval)
+ size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval,
+ int flags)
{
int error = 0;
struct sysctl_req req;
@@ -1283,6 +1300,7 @@
bzero(&req, sizeof req);
req.td = td;
+ req.flags = flags;
if (oldlenp) {
if (inkernel) {
==== //depot/projects/hammer/sys/kern/kern_tc.c#15 (text+ko) ====
@@ -92,8 +92,9 @@
static struct bintime boottimebin;
struct timeval boottime;
-SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
- &boottime, timeval, "System boottime");
+static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD,
+ NULL, 0, sysctl_kern_boottime, "S,timeval", "System boottime");
SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
@@ -116,6 +117,20 @@
static void tc_windup(void);
+static int
+sysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
+{
+#ifdef SCTL_MASK32
+ int tv[2];
+
+ if (req->flags & SCTL_MASK32) {
+ tv[0] = boottime.tv_sec;
+ tv[1] = boottime.tv_usec;
+ return SYSCTL_OUT(req, tv, sizeof(tv));
+ } else
+#endif
+ return SYSCTL_OUT(req, &boottime, sizeof(boottime));
+}
/*
* Return the difference between the timehands' counter value now and what
* was when we copied it to the timehands' offset_count.
==== //depot/projects/hammer/sys/kern/kern_xxx.c#8 (text+ko) ====
@@ -192,7 +192,7 @@
len = sizeof (uap->name->sysname);
mtx_lock(&Giant);
error = userland_sysctl(td, name, 2, uap->name->sysname, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0);
@@ -200,7 +200,7 @@
name[1] = KERN_HOSTNAME;
len = sizeof uap->name->nodename;
error = userland_sysctl(td, name, 2, uap->name->nodename, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0);
@@ -208,7 +208,7 @@
name[1] = KERN_OSRELEASE;
len = sizeof uap->name->release;
error = userland_sysctl(td, name, 2, uap->name->release, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->release + sizeof(uap->name->release) - 1, 0);
@@ -217,7 +217,7 @@
name = KERN_VERSION;
len = sizeof uap->name->version;
error = userland_sysctl(td, name, 2, uap->name->version, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->version + sizeof(uap->name->version) - 1, 0);
@@ -241,7 +241,7 @@
name[1] = HW_MACHINE;
len = sizeof uap->name->machine;
error = userland_sysctl(td, name, 2, uap->name->machine, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0);
==== //depot/projects/hammer/sys/sys/sysctl.h#20 (text+ko) ====
@@ -120,6 +120,11 @@
#define REQ_LOCKED 1 /* locked and not wired */
#define REQ_WIRED 2 /* locked and wired */
+/* definitions for sysctl_req 'flags' member */
+#if defined(__amd64__) || defined(__ia64__)
+#define SCTL_MASK32 1 /* 32 bit emulation */
+#endif
+
/*
* This describes the access space for a sysctl request. This is needed
* so that we can use the interface from the kernel or from user-space.
@@ -136,6 +141,7 @@
size_t newidx;
int (*newfunc)(struct sysctl_req *, void *, size_t);
size_t validlen;
+ int flags;
};
SLIST_HEAD(sysctl_oid_list, sysctl_oid);
@@ -617,13 +623,13 @@
int kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
size_t *oldlenp, void *new, size_t newlen,
- size_t *retval);
+ size_t *retval, int flags);
int kernel_sysctlbyname(struct thread *td, char *name,
void *old, size_t *oldlenp, void *new, size_t newlen,
- size_t *retval);
+ size_t *retval, int flags);
int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
size_t *oldlenp, int inkernel, void *new, size_t newlen,
- size_t *retval);
+ size_t *retval, int flags);
int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
int *nindx, struct sysctl_req *req);
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
==== //depot/projects/hammer/sys/vm/vm_meter.c#11 (text+ko) ====
@@ -85,8 +85,24 @@
SYSCTL_UINT(_vm, OID_AUTO, v_free_severe,
CTLFLAG_RW, &cnt.v_free_severe, 0, "");
-SYSCTL_STRUCT(_vm, VM_LOADAVG, loadavg, CTLFLAG_RD,
- &averunnable, loadavg, "Machine loadaverage history");
+static int
+sysctl_vm_loadavg(SYSCTL_HANDLER_ARGS)
+{
+#ifdef SCTL_MASK32
+ u_int32_t la[4];
+
+ if (req->flags & SCTL_MASK32) {
+ la[0] = averunnable.ldavg[0];
+ la[1] = averunnable.ldavg[1];
+ la[2] = averunnable.ldavg[2];
+ la[3] = averunnable.fscale;
+ return SYSCTL_OUT(req, la, sizeof(la));
+ } else
+#endif
+ return SYSCTL_OUT(req, &averunnable, sizeof(averunnable));
+}
+SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT|CTLFLAG_RD,
+ NULL, 0, sysctl_vm_loadavg, "S,loadavg", "Machine loadaverage history");
static int
vmtotal(SYSCTL_HANDLER_ARGS)
More information about the p4-projects
mailing list