Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Oct 2004 21:26:47 GMT
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 63016 for review
Message-ID:  <200410112126.i9BLQlCu093658@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=63016

Change 63016 by peter@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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200410112126.i9BLQlCu093658>