Date: Sat, 17 Feb 2018 06:57:43 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329446 - head/sbin/devmatch Message-ID: <201802170657.w1H6vhaL027864@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802170657.w1H6vhaL027864>