Subject: Enhancing sysctl support in ld.elf_so
To: None <tech-userlevel@netbsd.org>
From: Quentin Garnier <cube@NetBSD.org>
List: tech-userlevel
Date: 06/18/2004 00:45:39
--Signature=_Fri__18_Jun_2004_00_45_39_+0200_o7hCepWNIOnJgRbM
Content-Type: multipart/mixed;
 boundary="Multipart=_Fri__18_Jun_2004_00_45_39_+0200_f5R0GPm2+z+BOjxl"


--Multipart=_Fri__18_Jun_2004_00_45_39_+0200_f5R0GPm2+z+BOjxl
Content-Type: text/plain; charset=US-ASCII
Content-Disposition: inline
Content-Transfer-Encoding: 7bit

Hi,

I made a patch to make ld.elf_so use the new sysctl API instead of the
limited functionality it has now.

It's handy, but adds 12k to ld.elf_so.

Comments?

-- 
Quentin Garnier - cube@NetBSD.org
The NetBSD Project - http://www.NetBSD.org/

--Multipart=_Fri__18_Jun_2004_00_45_39_+0200_f5R0GPm2+z+BOjxl
Content-Type: text/plain;
 name="diff"
Content-Disposition: attachment;
 filename="diff"
Content-Transfer-Encoding: 7bit

Index: load.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/load.c,v
retrieving revision 1.27
diff -u -r1.27 load.c
--- load.c	25 Nov 2003 14:36:49 -0000	1.27
+++ load.c	17 Jun 2004 21:45:59 -0000
@@ -176,9 +176,13 @@
 	Library_Xform *x = _rtld_xforms;
 	Obj_Entry *o = NULL;
 	size_t i, j;
+	struct sysctlnode *rnode;
+	int mib[CTL_MAXNAME];
+	u_int namelen;
 	bool got = false;
 	union {
 		int i;
+		u_quad_t q;
 		char s[16];
 	} val;
 
@@ -187,14 +191,28 @@
 		if (strcmp(x->name, name) != 0)
 			continue;
 
+		rnode = NULL;
+		if (sysctlgetmibinfo(x->ctlname, mib, &namelen, NULL, NULL,
+		    &rnode, SYSCTL_VERSION) == -1) {
+			xwarnx(_PATH_LD_HINTS ": unknown sysctl for %s", name);
+			break;
+		}
+		if (namelen > CTL_MAXNAME) {
+			xwarnx(_PATH_LD_HINTS ": sysctl name too long in %s", name);
+			break;
+		}
+
 		i = sizeof(val);
 
-		if (sysctl(x->ctl, x->ctlmax, &val, &i, NULL, 0) == -1) {
-			xwarnx(_PATH_LD_HINTS ": unknown sysctl for %s", name);
+		if (sysctl(mib, namelen, &val, &i, NULL, 0) == -1) {
+			xwarnx(_PATH_LD_HINTS ": invalid sysctl for %s", name);
 			break;
 		}
 
-		switch (x->ctltype[x->ctlmax - 1]) {
+		switch (SYSCTL_TYPE(rnode->sysctl_flags)) {
+		case CTLTYPE_QUAD:
+			xsnprintf(val.s, sizeof(val.s), "%" PRIu64, val.q);
+			break;
 		case CTLTYPE_INT:
 			xsnprintf(val.s, sizeof(val.s), "%d", val.i);
 			break;
@@ -202,7 +220,7 @@
 			break;
 		default:
 			xwarnx("unsupported sysctl type %d",
-			    x->ctltype[x->ctlmax - 1]);
+			    SYSCTL_TYPE(rnode->sysctl_flags));
 			break;
 		}
 
Index: paths.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/paths.c,v
retrieving revision 1.30
diff -u -r1.30 paths.c
--- paths.c	16 Mar 2004 05:25:12 -0000	1.30
+++ paths.c	17 Jun 2004 21:45:59 -0000
@@ -39,7 +39,6 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/param.h>
-#include <sys/sysctl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/gmon.h>
@@ -61,7 +60,6 @@
 static const char *getstr(const char **, const char *, const char *);
 static const char *getcstr(const char **, const char *, const char *);
 static const char *getword(const char **, const char *, const char *);
-static int matchstr(const char *, const char *, const char *);
 
 static const char WS[] = " \t\n";
 
@@ -138,21 +136,6 @@
 	return (getstr(p, ep, delim));
 }
 
-/*
- * Match `bp' against NUL terminated string pointed by `p'.
- */
-static int
-matchstr(const char *p, const char *bp, const char *ep)
-{
-	int c;
-
-	while (bp < ep)
-		if ((c = *p++) == 0 || c != *bp++)
-			return (0);
-
-	return (*p == 0);
-}
-
 static Search_Path *
 _rtld_find_path(Search_Path *path, const char *pathstr, size_t pathlen)
 {
@@ -216,49 +199,6 @@
 	}
 }
 
-struct list {
-	const struct ctlname *ctl;
-	int numentries;
-};
-
-#ifdef CTL_MACHDEP_NAMES
-static const struct ctlname ctl_machdep[] = CTL_MACHDEP_NAMES;
-#endif
-static const struct ctlname ctl_toplvl[] = CTL_NAMES;
-
-const struct list toplevel[] = {
-	{ 0, 0 },
-	{ ctl_toplvl, CTL_MAXID },
-	{ 0, -1 },
-};
-
-const struct list secondlevel[] = {
-	{ 0, 0 },			/* CTL_UNSPEC */
-	{ 0, KERN_MAXID },		/* CTL_KERN */
-	{ 0, VM_MAXID },		/* CTL_VM */
-	{ 0, VFS_MAXID },		/* CTL_VFS */
-	{ 0, NET_MAXID },		/* CTL_NET */
-	{ 0, CTL_DEBUG_MAXID },		/* CTL_DEBUG */
-	{ 0, HW_MAXID },		/* CTL_HW */
-#ifdef CTL_MACHDEP_NAMES
-	{ ctl_machdep, CPU_MAXID },	/* CTL_MACHDEP */
-#else
-	{ 0, 0 },			/* CTL_MACHDEP */
-#endif
-	{ 0, USER_MAXID },		/* CTL_USER_NAMES */
-	{ 0, DDBCTL_MAXID },		/* CTL_DDB_NAMES */
-	{ 0, 2 },			/* dummy name */
-	{ 0, -1 },
-};
-
-const struct list *lists[] = {
-	toplevel,
-	secondlevel,
-	0
-};
-
-#define CTL_MACHDEP_SIZE (sizeof(ctl_machdep) / sizeof(ctl_machdep[0]))
-
 /*
  * Process library mappings of the form:
  *	<library_name>	<machdep_variable> <value,...:library_name,...> ... 
@@ -268,7 +208,7 @@
 {
 	Library_Xform *hwptr = NULL;
 	const char *ptr, *key, *ekey, *lib, *elib, *l;
-	int i, j, k;
+	int i, j;
 	
 	dbg((" processing mapping \"%.*s\"", (int)(ep - bp), bp));
 
@@ -290,37 +230,7 @@
 
 	dbg((" sysctl \"%.*s\"", (int)(bp - ptr), ptr));
 
-	for (i = 0; (l = getstr(&ptr, bp, ".")) != NULL; i++, ptr++) {
-
-		if (lists[i] == NULL || i >= RTLD_MAX_CTL) {
-			xwarnx("sysctl nesting too deep");
-			goto cleanup;
-		}
-
-		for (j = 1; lists[i][j].numentries != -1; j++) {
-
-			if (lists[i][j].ctl == NULL)
-				continue;
-
-			for (k = 1; k < lists[i][j].numentries; k++)
-				if (matchstr(lists[i][j].ctl[k].ctl_name, l,
-				    ptr))
-					break;
-
-			if (lists[i][j].numentries == -1) {
-				xwarnx("unknown sysctl variable name `%.*s'",
-				    (int)(ptr - l), l);
-				goto cleanup;
-			}
-
-			hwptr->ctl[hwptr->ctlmax] = k;
-			hwptr->ctltype[hwptr->ctlmax++] =
-			    lists[i][j].ctl[k].ctl_type;
-		}
-	}
-
-	for (i = 0; i < hwptr->ctlmax; i++)
-		dbg((" sysctl %d, %d", hwptr->ctl[i], hwptr->ctltype[i]));
+	hwptr->ctlname = exstrdup(ptr, bp);
 
 	for (i = 0; bp++, (ptr = getword(&bp, ep, WS)) != NULL;) {
 		dbg((" ptr = %.*s", (int)(bp - ptr), ptr));
Index: rtld.h
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/rtld.h,v
retrieving revision 1.70
diff -u -r1.70 rtld.h
--- rtld.h	12 Aug 2003 09:18:49 -0000	1.70
+++ rtld.h	17 Jun 2004 21:45:59 -0000
@@ -97,9 +97,7 @@
 typedef struct _rtld_library_xform_t {
 	struct _rtld_library_xform_t *next;
 	char *name;
-	int ctl[RTLD_MAX_CTL];
-	int ctltype[RTLD_MAX_CTL];
-	int ctlmax;
+	char *ctlname;
 	struct {
 		char *value;
 		char *library[RTLD_MAX_LIBRARY];

--Multipart=_Fri__18_Jun_2004_00_45_39_+0200_f5R0GPm2+z+BOjxl--

--Signature=_Fri__18_Jun_2004_00_45_39_+0200_o7hCepWNIOnJgRbM
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (NetBSD)

iQEVAwUBQNIfG9goQloHrPnoAQKSzggAwz5jqn32+UaMH9NYIZuqBlSoIuBT8uY1
iMgZuiZcZwH9CU2Oe10Q/k9xDuwYY91rNW17uEfKxkHDqf4WbXcGhXJsm2gALImQ
0y3pz6arj0wvAMKWaY2sTjmv+bkTD20zW9AMFyLsSuqDhhUT7/amfCGe2ZGxGWmn
nO1xTg7AH8tiThw1ypeFCi2rQRcf1Jy06QYt0ojd/JFsSYlJjID+eNmwKI3r4Onx
pjZLNmHhU8WFtTr/vdWwNhApToPyM8U1tekfpDmTcRxEwPV8kLTifHJIyb0jQy44
4I3f4Rc7tLRuGEkovz3So9nmzmsp3ijh6kZxWAHNjAECqqFG1bFpJQ==
=oREZ
-----END PGP SIGNATURE-----

--Signature=_Fri__18_Jun_2004_00_45_39_+0200_o7hCepWNIOnJgRbM--