From owner-svn-src-head@freebsd.org Sat Feb 17 06:57:46 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 21967F1445D; Sat, 17 Feb 2018 06:57:46 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8A6216ACDB; Sat, 17 Feb 2018 06:57:43 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 94F5B19444; Sat, 17 Feb 2018 06:57:43 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w1H6vhND027866; Sat, 17 Feb 2018 06:57:43 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1H6vhaL027864; Sat, 17 Feb 2018 06:57:43 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201802170657.w1H6vhaL027864@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Sat, 17 Feb 2018 06:57:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329446 - head/sbin/devmatch X-SVN-Group: head X-SVN-Commit-Author: imp X-SVN-Commit-Paths: head/sbin/devmatch X-SVN-Commit-Revision: 329446 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Feb 2018 06:57:46 -0000 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;