svn commit: r329446 - head/sbin/devmatch

Warner Losh imp at FreeBSD.org
Sat Feb 17 06:57:46 UTC 2018


Author: imp
Date: Sat Feb 17 06:57:43 2018
New Revision: 329446
URL: https://svnweb.freebsd.org/changeset/base/329446

Log:
  Implement --hints to read hints file directly
  
  In testing, it's often useful to copy a few files into a directory and
  kldxref them to ensure that particular cases are handled correctly.
  Add --hints (-h) to facilitate this testing and enable future
  automated testing.
  
  Sponsored by: Netflix

Modified:
  head/sbin/devmatch/devmatch.8
  head/sbin/devmatch/devmatch.c

Modified: head/sbin/devmatch/devmatch.8
==============================================================================
--- head/sbin/devmatch/devmatch.8	Sat Feb 17 06:57:38 2018	(r329445)
+++ head/sbin/devmatch/devmatch.8	Sat Feb 17 06:57:43 2018	(r329446)
@@ -33,10 +33,11 @@
 .Nd print information about unattached devices
 .Sh SYNOPSIS
 .Nm
-.Op Fl adpuv
+.Op Fl adhpuv
 .Op Fl -all
 .Op Fl -dump
-.Op Fl -nomatch
+.Op Fl -hints Ar file
+.Op Fl -nomatch Ar event
 .Op Fl -unbound
 .Op Fl -verbose
 .Sh DESCRIPTION
@@ -51,7 +52,13 @@ Include all devices, not just the ones that are unatta
 Produce a human readable dump of the
 .Pa linker.hints
 file.
-.It Fl p Fl -nomatch
+.It Fl h Fl -hints Ar file
+Use the named
+.Ar file
+instead of
+.Pa linker.hints
+guessed from the current module load path.
+.It Fl p Fl -nomatch Ar event
 Parse and use a standard NOMATCH event from
 .Xr devd 8
 for matching instead of searching the device tree.

Modified: head/sbin/devmatch/devmatch.c
==============================================================================
--- head/sbin/devmatch/devmatch.c	Sat Feb 17 06:57:38 2018	(r329445)
+++ head/sbin/devmatch/devmatch.c	Sat Feb 17 06:57:43 2018	(r329446)
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
 static struct option longopts[] = {
 	{ "all",		no_argument,		NULL,	'a' },
 	{ "dump",		no_argument,		NULL,	'd' },
+	{ "hints",		required_argument,	NULL,	'h' },
 	{ "nomatch",		required_argument,	NULL,	'p' },
 	{ "unbound",		no_argument,		NULL,	'u' },
 	{ "verbose",		no_argument,		NULL,	'v' },
@@ -55,6 +56,7 @@ static struct option longopts[] = {
 
 static int all_flag;
 static int dump_flag;
+static char *linker_hints;
 static char *nomatch_str;
 static int unbound_flag;
 static int verbose_flag;
@@ -62,47 +64,66 @@ static int verbose_flag;
 static void *hints;
 static void *hints_end;
 
+static void *
+read_hints(const char *fn, size_t *len)
+{
+	void *h;
+	int fd;
+	struct stat sb;
+
+	fd = open(fn, O_RDONLY);
+	if (fd < 0) {
+		if (errno == ENOENT)
+			return NULL;
+		err(1, "Can't open %s for reading", fn);
+	}
+	if (fstat(fd, &sb) != 0)
+		err(1, "Can't fstat %s\n", fn);
+	h = malloc(sb.st_size);
+	if (h == NULL)
+		err(1, "not enough space to read hints file of %ju bytes", (uintmax_t)sb.st_size);
+	if (read(fd, h, sb.st_size) != sb.st_size)
+		err(1, "Can't read in %ju bytes from %s", (uintmax_t)sb.st_size, fn);
+	close(fd);
+	*len = sb.st_size;
+	return h;
+}
+
 static void
 read_linker_hints(void)
 {
 	char fn[MAXPATHLEN];
-	struct stat sb;
 	char *modpath, *p, *q;
-	size_t buflen;
-	int fd;
+	size_t buflen, len;
 
-	if (sysctlbyname("kern.module_path", NULL, &buflen, NULL, 0) < 0)
-		errx(1, "Can't find kernel module path.");
-	modpath = malloc(buflen);
-	if (modpath == NULL)
-		err(1, "Can't get memory for modpath.");
-	if (sysctlbyname("kern.module_path", modpath, &buflen, NULL, 0) < 0)
-		errx(1, "Can't find kernel module path.");
-	p = modpath;
-	while ((q = strsep(&p, ";")) != NULL) {
-		snprintf(fn, sizeof(fn), "%s/linker.hints", q);
-		fd = open(fn, O_RDONLY);
-		if (fd < 0) {
-			if (errno == ENOENT)
+	if (linker_hints == NULL) {
+		if (sysctlbyname("kern.module_path", NULL, &buflen, NULL, 0) < 0)
+			errx(1, "Can't find kernel module path.");
+		modpath = malloc(buflen);
+		if (modpath == NULL)
+			err(1, "Can't get memory for modpath.");
+		if (sysctlbyname("kern.module_path", modpath, &buflen, NULL, 0) < 0)
+			errx(1, "Can't find kernel module path.");
+		p = modpath;
+		while ((q = strsep(&p, ";")) != NULL) {
+			snprintf(fn, sizeof(fn), "%s/linker.hints", q);
+			hints = read_hints(fn, &len);
+			if (hints == NULL)
 				continue;
-			err(1, "Can't open %s for reading", fn);
+			break;
 		}
-		if (fstat(fd, &sb) != 0)
-			err(1, "Can't fstat %s\n", fn);
-		hints = malloc(sb.st_size);
+		if (q == NULL) {
+			warnx("Can't read linker hints file.");
+			free(hints);
+			hints = NULL;
+			return;
+		}
+	} else {
+		hints = read_hints(linker_hints, &len);
 		if (hints == NULL)
-			err(1, "not enough space to read hints file of %ju bytes", (uintmax_t)sb.st_size);
-		if (read(fd, hints, sb.st_size) != sb.st_size)
-			err(1, "Can't read in %ju bytes from %s", (uintmax_t)sb.st_size, fn);
-		close(fd);
-		break;
+			err(1, "Can't open %s for reading", fn);
 	}
-	if (q == NULL) {
-		warnx("Can't read linker hints file.");
-		free(hints);
-		hints = NULL;
-		return;
-	}
+
 	if (*(int *)(intptr_t)hints != LINKER_HINTS_VERSION) {
 		warnx("Linker hints version %d doesn't match expected %d.",
 		    *(int *)(intptr_t)hints, LINKER_HINTS_VERSION);
@@ -110,7 +131,7 @@ read_linker_hints(void)
 		hints = NULL;
 	}
 	if (hints != NULL)
-		hints_end = (void *)((intptr_t)hints + (intptr_t)sb.st_size);
+		hints_end = (void *)((intptr_t)hints + (intptr_t)len);
 }
 
 static int
@@ -443,7 +464,7 @@ static void
 usage(void)
 {
 
-	errx(1, "devmatch [-adv]");
+	errx(1, "devmatch [-adv] [-p nomatch] [-h linker-hints]");
 }
 
 int
@@ -452,7 +473,7 @@ main(int argc, char **argv)
 	struct devinfo_dev *root;
 	int ch;
 
-	while ((ch = getopt_long(argc, argv, "adp:uv",
+	while ((ch = getopt_long(argc, argv, "adh:p:uv",
 		    longopts, NULL)) != -1) {
 		switch (ch) {
 		case 'a':
@@ -460,6 +481,9 @@ main(int argc, char **argv)
 			break;
 		case 'd':
 			dump_flag++;
+			break;
+		case 'h':
+			linker_hints = optarg;
 			break;
 		case 'p':
 			nomatch_str = optarg;


More information about the svn-src-head mailing list