From owner-svn-src-head@freebsd.org Sun Oct 22 10:32:41 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A639AE4F387; Sun, 22 Oct 2017 10:32:41 +0000 (UTC) (envelope-from trasz@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 mx1.freebsd.org (Postfix) with ESMTPS id 81BBD162C; Sun, 22 Oct 2017 10:32:41 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v9MAWeOo094426; Sun, 22 Oct 2017 10:32:40 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v9MAWehd094425; Sun, 22 Oct 2017 10:32:40 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201710221032.v9MAWehd094425@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sun, 22 Oct 2017 10:32:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r324856 - head/libexec/rtld-elf X-SVN-Group: head X-SVN-Commit-Author: trasz X-SVN-Commit-Paths: head/libexec/rtld-elf X-SVN-Commit-Revision: 324856 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.23 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: Sun, 22 Oct 2017 10:32:41 -0000 Author: trasz Date: Sun Oct 22 10:32:40 2017 New Revision: 324856 URL: https://svnweb.freebsd.org/changeset/base/324856 Log: Don't call realpath(3) from libmap rtld code. This gets rid of a few calls to fstatat(2) at binary startup; the difference looks like this: --- przed 2017-10-14 13:55:49.983528000 +0100 +++ po 2017-10-14 14:10:39.134343000 +0100 @@ -1,15 +1,10 @@ mmap(0x0,32768,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 34366173184 (0x800623000) issetugid() = 0 (0x0) -fstatat(AT_FDCWD,"/etc",{ mode=drwxr-xr-x ,inode=1364352,size=2560,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0) -fstatat(AT_FDCWD,"/etc/libmap.conf",{ mode=-rw-r--r-- ,inode=1373288,size=102,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0) openat(AT_FDCWD,"/etc/libmap.conf",O_RDONLY|O_CLOEXEC,00) = 3 (0x3) fstat(3,{ mode=-rw-r--r-- ,inode=1373288,size=102,blksize=32768 }) = 0 (0x0) mmap(0x0,102,PROT_READ,MAP_PRIVATE,3,0x0) = 34366205952 (0x80062b000) close(3) = 0 (0x0) -fstatat(AT_FDCWD,"/usr",{ mode=drwxr-xr-x ,inode=561792,size=512,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0) -fstatat(AT_FDCWD,"/usr/local",{ mode=drwxr-xr-x ,inode=561800,size=512,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0) -fstatat(AT_FDCWD,"/usr/local/etc",{ mode=drwxr-xr-x ,inode=653279,size=1536,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0) -fstatat(AT_FDCWD,"/usr/local/etc/libmap.d",0x7fffffffcf50,AT_SYMLINK_NOFOLLOW) ERR#2 'No such file or directory' +open("/usr/local/etc/libmap.d",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,0165) ERR#2 'No such file or directory' munmap(0x80062b000,102) = 0 (0x0) openat(AT_FDCWD,"/var/run/ld-elf.so.hints",O_RDONLY|O_CLOEXEC,00) = 3 (0x3) read(3,"Ehnt\^A\0\0\0\M^@\0\0\0\M-2\0\0"...,128) = 128 (0x80) Reviewed by: kib MFC after: 2 weeks Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D12741 Modified: head/libexec/rtld-elf/libmap.c Modified: head/libexec/rtld-elf/libmap.c ============================================================================== --- head/libexec/rtld-elf/libmap.c Sun Oct 22 08:47:13 2017 (r324855) +++ head/libexec/rtld-elf/libmap.c Sun Oct 22 10:32:40 2017 (r324856) @@ -36,6 +36,8 @@ struct lmp { static TAILQ_HEAD(lmc_list, lmc) lmc_head = TAILQ_HEAD_INITIALIZER(lmc_head); struct lmc { char *path; + dev_t dev; + ino_t ino; TAILQ_ENTRY(lmc) next; }; @@ -99,45 +101,45 @@ lmc_parse_file(char *path) struct lmc *p; struct stat st; int fd; - char *rpath; char *lm_map; - rpath = realpath(path, NULL); - if (rpath == NULL) - return; - TAILQ_FOREACH(p, &lmc_head, next) { - if (strcmp(p->path, rpath) == 0) { - free(rpath); + if (strcmp(p->path, path) == 0) return; - } } - fd = open(rpath, O_RDONLY | O_CLOEXEC); + fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) { - dbg("lm_parse_file: open(\"%s\") failed, %s", rpath, + dbg("lm_parse_file: open(\"%s\") failed, %s", path, rtld_strerror(errno)); - free(rpath); return; } if (fstat(fd, &st) == -1) { close(fd); - dbg("lm_parse_file: fstat(\"%s\") failed, %s", rpath, + dbg("lm_parse_file: fstat(\"%s\") failed, %s", path, rtld_strerror(errno)); - free(rpath); return; } + + TAILQ_FOREACH(p, &lmc_head, next) { + if (p->dev == st.st_dev && p->ino == st.st_ino) { + close(fd); + return; + } + } + lm_map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (lm_map == (const char *)MAP_FAILED) { close(fd); - dbg("lm_parse_file: mmap(\"%s\") failed, %s", rpath, + dbg("lm_parse_file: mmap(\"%s\") failed, %s", path, rtld_strerror(errno)); - free(rpath); return; } close(fd); p = xmalloc(sizeof(struct lmc)); - p->path = rpath; + p->path = xstrdup(path); + p->dev = st.st_dev; + p->ino = st.st_ino; TAILQ_INSERT_HEAD(&lmc_head, p, next); lmc_parse(lm_map, st.st_size); munmap(lm_map, st.st_size); @@ -151,26 +153,19 @@ lmc_parse_dir(char *idir) struct lmc *p; char conffile[MAXPATHLEN]; char *ext; - char *rpath; - rpath = realpath(idir, NULL); - if (rpath == NULL) - return; - TAILQ_FOREACH(p, &lmc_head, next) { - if (strcmp(p->path, rpath) == 0) { - free(rpath); + if (strcmp(p->path, idir) == 0) return; - } } d = opendir(idir); - if (d == NULL) { - free(rpath); + if (d == NULL) return; - } p = xmalloc(sizeof(struct lmc)); - p->path = rpath; + p->path = xstrdup(idir); + p->dev = NODEV; + p->ino = 0; TAILQ_INSERT_HEAD(&lmc_head, p, next); while ((dp = readdir(d)) != NULL) {