Re: *oldlenp comes back with wrong value in helper sysctl_createv() function

Emile 'iMil' Heitor <[email protected]>
Newsgroups gmane.os.netbsd.devel.kernel
Message-ID <[email protected]>
> The helper function produces the value that is returned in *oldlenp.
> 
> If you happen to use CTL_DESCRIBE (e.g. running sysctl -d), it's
> not your helper function being called but the sysctl_describe helper
> that returns a value of 1024.
> 
> Maybe you can show your helper routine and how you call sysctl ?

sure, I call sysctl this way: sysctl debug.tslog

here's the helper function code:

static int
sysctl_debug_tslog(SYSCTLFN_ARGS)
{
	char buf[LINE_MAX] = "";
	char *where = oldp;
	size_t slen, i, limit;
	int error = 0;
	static size_t needed = 0;

	/* Come back with the right size */
	/* here at second call, *oldlenp == 1024 */
	if (*oldlenp < needed) {
		*oldlenp = needed;
		return 0; /* will be back with correct size */
	}
	/* Add data logged within the kernel. */
	limit = MIN(nrecs, nitems(timestamps));
	for (i = 0; i < limit; i++) {
		snprintf(buf, LINE_MAX, "0x%x %llu",
			timestamps[i].lid,
			(unsigned long long)timestamps[i].tsc);
		switch (timestamps[i].type) {
		case TS_ENTER:
			strcat(buf, " ENTER");
			break;
		case TS_EXIT:
			strcat(buf, " EXIT");
			break;
		case TS_THREAD:
			strcat(buf, " THREAD");
			break;
		case TS_EVENT:
			strcat(buf, " EVENT");
			break;
		}
		snprintf(buf, LINE_MAX, "%s %s", buf,
			timestamps[i].f ? timestamps[i].f : "(null)");
		if (timestamps[i].s)
			snprintf(buf, LINE_MAX, "%s %s\n", buf,
				timestamps[i].s);
		else
			strcat(buf, "\n");

		slen = strlen(buf) + 1;

		if (where == NULL) /* 1st pass, calculate needed */
			needed += slen;
		else {
			if (i > 0)
				where--; /* overwrite last \0 */
			if ((error = copyout(buf, where, slen)))
				break;
			where += slen;
		}
	}
	/* Come back with an address */
	if (oldp == NULL)
		*oldlenp = needed;

	return error;
}

Here's the setup:

SYSCTL_SETUP(sysctl_tslog_setup, "tslog sysctl")
{
	sysctl_createv(NULL, 0, NULL, NULL,
		CTLFLAG_PERMANENT|CTLFLAG_READONLY,
		CTLTYPE_STRING, "tslog",
		SYSCTL_DESCR("Dump recorded event timestamps"),
		sysctl_debug_tslog, 0, NULL, 0,
		CTL_DEBUG, CTL_CREATE, CTL_EOL);
}

-- 
------------------------------------------------------------------------
Emile `iMil' Heitor <imil@{home.imil.net,NetBSD.org}> | https://imil.net
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.