tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

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



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


Home | Main Index | Thread Index | Old Index