Import NetBSD dev_mkdb(8)
Adapt libc devname(3) to make use of it, so that such device name queries are now several orders of magnitude faster. The database is created and updated at system bootup time. Change-Id: I0cbcb24c7d47577d4d6af9c8290c21ee4df9a0ff
This commit is contained in:
parent
1f761e1bea
commit
180e74704d
@ -883,6 +883,7 @@
|
|||||||
./usr/sbin/btrace minix-base
|
./usr/sbin/btrace minix-base
|
||||||
./usr/sbin/chown minix-base
|
./usr/sbin/chown minix-base
|
||||||
./usr/sbin/chroot minix-base
|
./usr/sbin/chroot minix-base
|
||||||
|
./usr/sbin/dev_mkdb minix-base
|
||||||
./usr/sbin/diskctl minix-base
|
./usr/sbin/diskctl minix-base
|
||||||
./usr/sbin/download-vulnerability-list minix-base crypto
|
./usr/sbin/download-vulnerability-list minix-base crypto
|
||||||
./usr/sbin/fbdctl minix-base
|
./usr/sbin/fbdctl minix-base
|
||||||
|
@ -3358,6 +3358,7 @@
|
|||||||
./usr/man/man8/cleantmp.8 minix-man
|
./usr/man/man8/cleantmp.8 minix-man
|
||||||
./usr/man/man8/config.8 minix-man
|
./usr/man/man8/config.8 minix-man
|
||||||
./usr/man/man8/cron.8 minix-man
|
./usr/man/man8/cron.8 minix-man
|
||||||
|
./usr/man/man8/dev_mkdb.8 minix-man
|
||||||
./usr/man/man8/devsize.8 minix-man
|
./usr/man/man8/devsize.8 minix-man
|
||||||
./usr/man/man8/dhcpd.8 minix-man
|
./usr/man/man8/dhcpd.8 minix-man
|
||||||
./usr/man/man8/diskctl.8 minix-man
|
./usr/man/man8/diskctl.8 minix-man
|
||||||
|
@ -393,6 +393,15 @@ start|autoboot)
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Now that all device files should be created, see if we need to update the
|
||||||
|
# device file database. This code is butchered from NetBSD etc/rc.d/sysdb.
|
||||||
|
DEVDIR=/dev
|
||||||
|
DEVDB=/var/run/dev.cdb
|
||||||
|
if [ ! -f "$DEVDB" -o "$DEVDIR" -nt "$DEVDB" ]
|
||||||
|
then
|
||||||
|
dev_mkdb
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$net" ]
|
if [ "$net" ]
|
||||||
then
|
then
|
||||||
# Get the nodename from the DNS and set it.
|
# Get the nodename from the DNS and set it.
|
||||||
|
@ -45,11 +45,14 @@ __RCSID("$NetBSD: devname.c,v 1.22 2012/06/03 21:42:46 joerg Exp $");
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __minix
|
||||||
|
#include <minix/dmap.h> /* for UNIX98_MINOR */
|
||||||
|
#endif /* __minix */
|
||||||
|
|
||||||
#ifdef __weak_alias
|
#ifdef __weak_alias
|
||||||
__weak_alias(devname_r,_devname_r)
|
__weak_alias(devname_r,_devname_r)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__minix)
|
|
||||||
static once_t db_opened = ONCE_INITIALIZER;
|
static once_t db_opened = ONCE_INITIALIZER;
|
||||||
static struct cdbr *db;
|
static struct cdbr *db;
|
||||||
static devmajor_t pts;
|
static devmajor_t pts;
|
||||||
@ -95,14 +98,25 @@ devname_ptslookup(dev_t dev, mode_t type, char *path, size_t len)
|
|||||||
|
|
||||||
if (type != S_IFCHR || pts == NODEVMAJOR || major(dev) != pts)
|
if (type != S_IFCHR || pts == NODEVMAJOR || major(dev) != pts)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
#ifdef __minix
|
||||||
|
/*
|
||||||
|
* MINIX3 does not use an identity mapping for /dev/pts, because the
|
||||||
|
* same major number is also used for PTY masters and legacy PTYs.
|
||||||
|
*/
|
||||||
|
if (minor(dev) < UNIX98_MINOR || !(minor(dev) & 1))
|
||||||
|
return ENOENT;
|
||||||
|
#endif /* __minix */
|
||||||
|
|
||||||
rv = snprintf(path, len, "%s%d", _PATH_DEV_PTS + sizeof(_PATH_DEV) - 1,
|
rv = snprintf(path, len, "%s%d", _PATH_DEV_PTS + sizeof(_PATH_DEV) - 1,
|
||||||
|
#ifndef __minix
|
||||||
minor(dev));
|
minor(dev));
|
||||||
|
#else /* __minix */
|
||||||
|
(minor(dev) - UNIX98_MINOR) >> 1);
|
||||||
|
#endif /* __minix */
|
||||||
if (rv < 0 || (size_t)rv >= len)
|
if (rv < 0 || (size_t)rv >= len)
|
||||||
return ERANGE;
|
return ERANGE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
devname_fts(dev_t dev, mode_t type, char *path, size_t len)
|
devname_fts(dev_t dev, mode_t type, char *path, size_t len)
|
||||||
@ -142,7 +156,6 @@ devname_r(dev_t dev, mode_t type, char *path, size_t len)
|
|||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
#if !defined(__minix)
|
|
||||||
thr_once(&db_opened, devname_dbopen);
|
thr_once(&db_opened, devname_dbopen);
|
||||||
|
|
||||||
if (db != NULL) {
|
if (db != NULL) {
|
||||||
@ -157,7 +170,6 @@ devname_r(dev_t dev, mode_t type, char *path, size_t len)
|
|||||||
|
|
||||||
if (db != NULL)
|
if (db != NULL)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
#endif /* !defined(__minix) */
|
|
||||||
rv = devname_fts(dev, type, path, len);
|
rv = devname_fts(dev, type, path, len);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_REENTRANT) && defined(__minix)
|
#if !defined(__minix) || !defined(_LIBC_REENTRANT_H)
|
||||||
|
#ifdef __minix
|
||||||
|
/*
|
||||||
|
* If _REENTRANT is not defined, the header may not be included more than once.
|
||||||
|
* This is probably a NetBSD libc bug, but for now we solve it for MINIX3 only.
|
||||||
|
*/
|
||||||
|
#define _LIBC_REENTRANT_H
|
||||||
|
#endif /* __minix */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Abstract thread interface for thread-safe libraries. These routines
|
* Abstract thread interface for thread-safe libraries. These routines
|
||||||
@ -93,6 +100,8 @@
|
|||||||
* is.
|
* is.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __minix
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
@ -124,6 +133,17 @@
|
|||||||
#define once_t pthread_once_t
|
#define once_t pthread_once_t
|
||||||
#define ONCE_INITIALIZER PTHREAD_ONCE_INIT
|
#define ONCE_INITIALIZER PTHREAD_ONCE_INIT
|
||||||
|
|
||||||
|
#else /* __minix */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int pto_done;
|
||||||
|
} once_t;
|
||||||
|
#define ONCE_INITIALIZER { .pto_done = 0 }
|
||||||
|
|
||||||
|
#endif /* __minix */
|
||||||
|
|
||||||
|
#ifdef _REENTRANT
|
||||||
|
|
||||||
#ifndef __LIBC_THREAD_STUBS
|
#ifndef __LIBC_THREAD_STUBS
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
@ -311,7 +331,6 @@ __END_DECLS
|
|||||||
#define mutexattr_settype(ma, t) __empty
|
#define mutexattr_settype(ma, t) __empty
|
||||||
#define mutexattr_destroy(ma) __empty
|
#define mutexattr_destroy(ma) __empty
|
||||||
|
|
||||||
#if !defined(__minix)
|
|
||||||
static inline int
|
static inline int
|
||||||
thr_once(once_t *once_control, void (*routine)(void))
|
thr_once(once_t *once_control, void (*routine)(void))
|
||||||
{
|
{
|
||||||
@ -321,7 +340,6 @@ thr_once(once_t *once_control, void (*routine)(void))
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(__minix) */
|
|
||||||
#define thr_sigsetmask(f, n, o) __empty
|
#define thr_sigsetmask(f, n, o) __empty
|
||||||
#define thr_self() __empty
|
#define thr_self() __empty
|
||||||
#define thr_errno() __empty
|
#define thr_errno() __empty
|
||||||
@ -331,3 +349,5 @@ thr_once(once_t *once_control, void (*routine)(void))
|
|||||||
#define FUNLOCKFILE(fp) __empty
|
#define FUNLOCKFILE(fp) __empty
|
||||||
|
|
||||||
#endif /* _REENTRANT */
|
#endif /* _REENTRANT */
|
||||||
|
|
||||||
|
#endif /* !defined(__minix) || !defined(_LIBC_REENTRANT_H) */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#define PTMX_MINOR 0 /* minor of the Unix98 clone device */
|
#define PTMX_MINOR 0 /* minor of the Unix98 clone device */
|
||||||
#define TTYPX_MINOR 128
|
#define TTYPX_MINOR 128
|
||||||
#define PTYPX_MINOR 192
|
#define PTYPX_MINOR 192
|
||||||
#define UNIX98_MINOR 256 /* start of Unix98 pairs */
|
/* UNIX98_MINOR is defined in minix/dmap.h */
|
||||||
|
|
||||||
#define TTY_IN_BYTES 256 /* tty input queue size */
|
#define TTY_IN_BYTES 256 /* tty input queue size */
|
||||||
#define TTY_OUT_BYTES 2048 /* tty output queue size */
|
#define TTY_OUT_BYTES 2048 /* tty output queue size */
|
||||||
|
@ -94,6 +94,15 @@
|
|||||||
/* Minor device numbers for the TTY driver. */
|
/* Minor device numbers for the TTY driver. */
|
||||||
# define CONS_MINOR 0 /* console device */
|
# define CONS_MINOR 0 /* console device */
|
||||||
|
|
||||||
|
/* Minor device numbers for the PTY driver. */
|
||||||
|
# define UNIX98_MINOR 256 /* Base number of UNIX98 PTYs, which
|
||||||
|
* are allocated in (master,slave)
|
||||||
|
* pairs: 256=master#0, 257=slave#0,
|
||||||
|
* 258=master#1, 259=slave#1, etc.
|
||||||
|
* This logic is shared between the
|
||||||
|
* PTY service and libc devname(3).
|
||||||
|
*/
|
||||||
|
|
||||||
#define CTRLR(n) ((n)==0 ? 3 : (8 + 2*((n)-1))) /* magic formula */
|
#define CTRLR(n) ((n)==0 ? 3 : (8 + 2*((n)-1))) /* magic formula */
|
||||||
|
|
||||||
/* Minor device numbers for log driver. */
|
/* Minor device numbers for log driver. */
|
||||||
@ -104,4 +113,3 @@
|
|||||||
# define DEV_IMGRD ((dev_t) 0x0106) /* device number of /dev/imgrd */
|
# define DEV_IMGRD ((dev_t) 0x0106) /* device number of /dev/imgrd */
|
||||||
|
|
||||||
#endif /* _DMAP_H */
|
#endif /* _DMAP_H */
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
SUBDIR= \
|
SUBDIR= \
|
||||||
\
|
\
|
||||||
chroot \
|
chroot \
|
||||||
\
|
dev_mkdb \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
|
12
usr.sbin/dev_mkdb/Makefile
Normal file
12
usr.sbin/dev_mkdb/Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||||
|
# $NetBSD: Makefile,v 1.9 2012/08/10 12:10:28 joerg Exp $
|
||||||
|
|
||||||
|
PROG= dev_mkdb
|
||||||
|
MAN= dev_mkdb.8
|
||||||
|
|
||||||
|
LDADD+= -lutil
|
||||||
|
DPADD+= ${LIBUTIL}
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
||||||
|
|
||||||
|
LDFLAGS+= -Wl,--no-fatal-warnings
|
95
usr.sbin/dev_mkdb/dev_mkdb.8
Normal file
95
usr.sbin/dev_mkdb/dev_mkdb.8
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
.\" Copyright (c) 1990, 1993
|
||||||
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of the University nor the names of its contributors
|
||||||
|
.\" may be used to endorse or promote products derived from this software
|
||||||
|
.\" without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" from: @(#)dev_mkdb.8 8.1 (Berkeley) 6/6/93
|
||||||
|
.\" $NetBSD: dev_mkdb.8,v 1.13 2012/06/03 21:42:47 joerg Exp $
|
||||||
|
.\"
|
||||||
|
.Dd June 1, 2012
|
||||||
|
.Dt DEV_MKDB 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dev_mkdb
|
||||||
|
.Nd create
|
||||||
|
.Pa /dev
|
||||||
|
database
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl c
|
||||||
|
.Op Fl o Ar database
|
||||||
|
.Op directory
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
command creates a
|
||||||
|
.Xr cdbr 3
|
||||||
|
database in
|
||||||
|
.Dq Pa /var/run/dev.cdb
|
||||||
|
which contains the names of all of the character and block special
|
||||||
|
files in the specified directory, using the file type and the
|
||||||
|
.Fa st_rdev
|
||||||
|
field as the key.
|
||||||
|
If no directory is specified, the
|
||||||
|
.Dq Pa /dev
|
||||||
|
directory is used.
|
||||||
|
.Pp
|
||||||
|
Keys are a structure containing a mode_t followed by a dev_t,
|
||||||
|
with any padding zero'd out.
|
||||||
|
The former is the type of the file (st_mode \*[Am] S_IFMT),
|
||||||
|
the latter is the st_rdev field.
|
||||||
|
.Pp
|
||||||
|
The options are as follows:
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Fl c
|
||||||
|
Create a
|
||||||
|
.Xr db 3
|
||||||
|
database for compatibility with libc versions and statically linked programs
|
||||||
|
from before
|
||||||
|
.Nx 6.0 .
|
||||||
|
The default name is
|
||||||
|
.Dq Pa /var/run/dev.db .
|
||||||
|
.It Fl o Ar database
|
||||||
|
Put the output databases in the named file.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /var/run/dev.db -compact
|
||||||
|
.It Pa /dev
|
||||||
|
Device directory.
|
||||||
|
.It Pa /var/run/dev.db
|
||||||
|
Database file.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr ps 1 ,
|
||||||
|
.Xr stat 2 ,
|
||||||
|
.Xr db 3 ,
|
||||||
|
.Xr devname 3 ,
|
||||||
|
.Xr kvm_nlist 3 ,
|
||||||
|
.Xr ttyname 3
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
command appeared in
|
||||||
|
.Bx 4.4 .
|
268
usr.sbin/dev_mkdb/dev_mkdb.c
Normal file
268
usr.sbin/dev_mkdb/dev_mkdb.c
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/* $NetBSD: dev_mkdb.c,v 1.29 2012/06/03 21:42:47 joerg Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__RCSID("$NetBSD: dev_mkdb.c,v 1.29 2012/06/03 21:42:47 joerg Exp $");
|
||||||
|
|
||||||
|
#include <sys/queue.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <cdbw.h>
|
||||||
|
#include <db.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <fts.h>
|
||||||
|
#include <paths.h>
|
||||||
|
#include <search.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <util.h>
|
||||||
|
|
||||||
|
#define HASH_SIZE 65536
|
||||||
|
#define FILE_PERMISSION S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
|
||||||
|
|
||||||
|
static struct cdbw *db;
|
||||||
|
static DB *db_compat;
|
||||||
|
static const char *db_name;
|
||||||
|
static char *db_name_tmp;
|
||||||
|
|
||||||
|
static void usage(void) __dead;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cdb_open(void)
|
||||||
|
{
|
||||||
|
db = cdbw_open();
|
||||||
|
if (db == NULL)
|
||||||
|
err(1, "opening cdb writer failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cdb_close(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(db_name_tmp, O_CREAT|O_EXCL|O_WRONLY, FILE_PERMISSION);
|
||||||
|
if (fd == -1)
|
||||||
|
err(1, "opening %s failed", db_name_tmp);
|
||||||
|
if (cdbw_output(db, fd, "NetBSD6 devdb", NULL))
|
||||||
|
err(1, "failed to write temporary database %s", db_name_tmp);
|
||||||
|
cdbw_close(db);
|
||||||
|
db = NULL;
|
||||||
|
if (close(fd))
|
||||||
|
err(1, "failed to write temporary database %s", db_name_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cdb_add_entry(dev_t dev, mode_t type, const char *relpath)
|
||||||
|
{
|
||||||
|
uint8_t *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(relpath) + 1;
|
||||||
|
buf = malloc(len + 10);
|
||||||
|
le64enc(buf, dev);
|
||||||
|
le16enc(buf + 8, type);
|
||||||
|
memcpy(buf + 10, relpath, len);
|
||||||
|
cdbw_put(db, buf, 10, buf, len + 10);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compat_open(void)
|
||||||
|
{
|
||||||
|
static HASHINFO openinfo = {
|
||||||
|
4096, /* bsize */
|
||||||
|
128, /* ffactor */
|
||||||
|
1024, /* nelem */
|
||||||
|
2048 * 1024, /* cachesize */
|
||||||
|
NULL, /* hash() */
|
||||||
|
0 /* lorder */
|
||||||
|
};
|
||||||
|
|
||||||
|
db_compat = dbopen(db_name_tmp, O_CREAT|O_EXCL|O_EXLOCK|O_RDWR|O_TRUNC,
|
||||||
|
FILE_PERMISSION, DB_HASH, &openinfo);
|
||||||
|
|
||||||
|
if (db_compat == NULL)
|
||||||
|
err(1, "failed to create temporary database %s",
|
||||||
|
db_name_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compat_close(void)
|
||||||
|
{
|
||||||
|
if ((*db_compat->close)(db_compat))
|
||||||
|
err(1, "failed to write temporary database %s", db_name_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compat_add_entry(dev_t dev, mode_t type, const char *relpath)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Keys are a mode_t followed by a dev_t. The former is the type of
|
||||||
|
* the file (mode & S_IFMT), the latter is the st_rdev field. Note
|
||||||
|
* that the structure may contain padding, so we have to clear it
|
||||||
|
* out here.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
mode_t type;
|
||||||
|
dev_t dev;
|
||||||
|
} bkey;
|
||||||
|
struct {
|
||||||
|
mode_t type;
|
||||||
|
int32_t dev;
|
||||||
|
} obkey;
|
||||||
|
DBT data, key;
|
||||||
|
|
||||||
|
(void)memset(&bkey, 0, sizeof(bkey));
|
||||||
|
key.data = &bkey;
|
||||||
|
key.size = sizeof(bkey);
|
||||||
|
data.data = __UNCONST(relpath);
|
||||||
|
data.size = strlen(relpath) + 1;
|
||||||
|
bkey.type = type;
|
||||||
|
bkey.dev = dev;
|
||||||
|
if ((*db_compat->put)(db_compat, &key, &data, 0))
|
||||||
|
err(1, "failed to write temporary database %s", db_name_tmp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the device fits into the old 32bit format, add compat entry
|
||||||
|
* for pre-NetBSD6 libc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((dev_t)(int32_t)dev != dev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(void)memset(&obkey, 0, sizeof(obkey));
|
||||||
|
key.data = &obkey;
|
||||||
|
key.size = sizeof(obkey);
|
||||||
|
data.data = __UNCONST(relpath);
|
||||||
|
data.size = strlen(relpath) + 1;
|
||||||
|
obkey.type = type;
|
||||||
|
obkey.dev = (int32_t)dev;
|
||||||
|
if ((*db_compat->put)(db_compat, &key, &data, 0))
|
||||||
|
err(1, "failed to write temporary database %s", db_name_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct stat *st;
|
||||||
|
FTS *ftsp;
|
||||||
|
FTSENT *p;
|
||||||
|
int ch;
|
||||||
|
char *pathv[2];
|
||||||
|
size_t dlen;
|
||||||
|
int compat_mode;
|
||||||
|
|
||||||
|
setprogname(argv[0]);
|
||||||
|
compat_mode = 0;
|
||||||
|
|
||||||
|
while ((ch = getopt(argc, argv, "co:")) != -1)
|
||||||
|
switch (ch) {
|
||||||
|
case 'c':
|
||||||
|
compat_mode = 1;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
db_name = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
pathv[1] = NULL;
|
||||||
|
if (argc == 1)
|
||||||
|
pathv[0] = argv[0];
|
||||||
|
else
|
||||||
|
pathv[0] = __UNCONST(_PATH_DEV);
|
||||||
|
|
||||||
|
ftsp = fts_open(pathv, FTS_NOCHDIR | FTS_PHYSICAL, NULL);
|
||||||
|
if (ftsp == NULL)
|
||||||
|
err(1, "fts_open: %s", pathv[0]);
|
||||||
|
|
||||||
|
if (db_name == NULL) {
|
||||||
|
if (compat_mode)
|
||||||
|
db_name = _PATH_DEVDB;
|
||||||
|
else
|
||||||
|
db_name = _PATH_DEVCDB;
|
||||||
|
}
|
||||||
|
easprintf(&db_name_tmp, "%s.XXXXXXX", db_name);
|
||||||
|
mktemp(db_name_tmp);
|
||||||
|
|
||||||
|
if (compat_mode)
|
||||||
|
compat_open();
|
||||||
|
else
|
||||||
|
cdb_open();
|
||||||
|
|
||||||
|
while ((p = fts_read(ftsp)) != NULL) {
|
||||||
|
if (p->fts_info != FTS_DEFAULT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
st = p->fts_statp;
|
||||||
|
if (!S_ISCHR(st->st_mode) && !S_ISBLK(st->st_mode))
|
||||||
|
continue;
|
||||||
|
dlen = strlen(pathv[0]);
|
||||||
|
while (pathv[0][dlen] == '/')
|
||||||
|
++dlen;
|
||||||
|
if (compat_mode)
|
||||||
|
compat_add_entry(st->st_rdev, st->st_mode & S_IFMT,
|
||||||
|
p->fts_path + dlen);
|
||||||
|
else
|
||||||
|
cdb_add_entry(st->st_rdev, st->st_mode & S_IFMT,
|
||||||
|
p->fts_path + dlen);
|
||||||
|
}
|
||||||
|
(void)fts_close(ftsp);
|
||||||
|
|
||||||
|
if (compat_mode)
|
||||||
|
compat_close();
|
||||||
|
else
|
||||||
|
cdb_close();
|
||||||
|
|
||||||
|
if (rename(db_name_tmp, db_name) == -1)
|
||||||
|
err(1, "rename %s to %s", db_name_tmp, db_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
(void)fprintf(stderr, "Usage: %s [-c] [-o database] [directory]\n",
|
||||||
|
getprogname());
|
||||||
|
exit(1);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user