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-all
mailing list