diff --git a/distrib/sets/lists/minix-base/mi b/distrib/sets/lists/minix-base/mi index d9c86886c..e3eb91afb 100644 --- a/distrib/sets/lists/minix-base/mi +++ b/distrib/sets/lists/minix-base/mi @@ -883,6 +883,7 @@ ./usr/sbin/btrace minix-base ./usr/sbin/chown minix-base ./usr/sbin/chroot minix-base +./usr/sbin/dev_mkdb minix-base ./usr/sbin/diskctl minix-base ./usr/sbin/download-vulnerability-list minix-base crypto ./usr/sbin/fbdctl minix-base diff --git a/distrib/sets/lists/minix-man/mi b/distrib/sets/lists/minix-man/mi index 994382087..1756fdeeb 100644 --- a/distrib/sets/lists/minix-man/mi +++ b/distrib/sets/lists/minix-man/mi @@ -3358,6 +3358,7 @@ ./usr/man/man8/cleantmp.8 minix-man ./usr/man/man8/config.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/dhcpd.8 minix-man ./usr/man/man8/diskctl.8 minix-man diff --git a/etc/usr/rc b/etc/usr/rc index a12a3e3a0..f8f36ad07 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -393,6 +393,15 @@ start|autoboot) 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" ] then # Get the nodename from the DNS and set it. diff --git a/lib/libc/gen/devname.c b/lib/libc/gen/devname.c index 072c61e8e..988d3cfd1 100644 --- a/lib/libc/gen/devname.c +++ b/lib/libc/gen/devname.c @@ -45,11 +45,14 @@ __RCSID("$NetBSD: devname.c,v 1.22 2012/06/03 21:42:46 joerg Exp $"); #include #include +#ifdef __minix +#include /* for UNIX98_MINOR */ +#endif /* __minix */ + #ifdef __weak_alias __weak_alias(devname_r,_devname_r) #endif -#if !defined(__minix) static once_t db_opened = ONCE_INITIALIZER; static struct cdbr *db; 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) 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, +#ifndef __minix minor(dev)); +#else /* __minix */ + (minor(dev) - UNIX98_MINOR) >> 1); +#endif /* __minix */ if (rv < 0 || (size_t)rv >= len) return ERANGE; return 0; } -#endif /* !defined(__minix) */ static int 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; -#if !defined(__minix) thr_once(&db_opened, devname_dbopen); if (db != NULL) { @@ -157,7 +170,6 @@ devname_r(dev_t dev, mode_t type, char *path, size_t len) if (db != NULL) return ENOENT; -#endif /* !defined(__minix) */ rv = devname_fts(dev, type, path, len); return rv; } diff --git a/lib/libc/include/reentrant.h b/lib/libc/include/reentrant.h index 109510388..55be7f022 100644 --- a/lib/libc/include/reentrant.h +++ b/lib/libc/include/reentrant.h @@ -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 @@ -93,6 +100,8 @@ * is. */ +#ifndef __minix + #include #include @@ -124,6 +133,17 @@ #define once_t pthread_once_t #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 __BEGIN_DECLS @@ -311,7 +331,6 @@ __END_DECLS #define mutexattr_settype(ma, t) __empty #define mutexattr_destroy(ma) __empty -#if !defined(__minix) static inline int thr_once(once_t *once_control, void (*routine)(void)) { @@ -321,7 +340,6 @@ thr_once(once_t *once_control, void (*routine)(void)) } return 0; } -#endif /* defined(__minix) */ #define thr_sigsetmask(f, n, o) __empty #define thr_self() __empty #define thr_errno() __empty @@ -331,3 +349,5 @@ thr_once(once_t *once_control, void (*routine)(void)) #define FUNLOCKFILE(fp) __empty #endif /* _REENTRANT */ + +#endif /* !defined(__minix) || !defined(_LIBC_REENTRANT_H) */ diff --git a/minix/drivers/tty/pty/tty.h b/minix/drivers/tty/pty/tty.h index 7dbb5f5c6..1fa7e9def 100644 --- a/minix/drivers/tty/pty/tty.h +++ b/minix/drivers/tty/pty/tty.h @@ -7,7 +7,7 @@ #define PTMX_MINOR 0 /* minor of the Unix98 clone device */ #define TTYPX_MINOR 128 #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_OUT_BYTES 2048 /* tty output queue size */ diff --git a/minix/include/minix/dmap.h b/minix/include/minix/dmap.h index 5cf821478..8c6560d3b 100644 --- a/minix/include/minix/dmap.h +++ b/minix/include/minix/dmap.h @@ -94,6 +94,15 @@ /* Minor device numbers for the TTY driver. */ # 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 */ /* Minor device numbers for log driver. */ @@ -104,4 +113,3 @@ # define DEV_IMGRD ((dev_t) 0x0106) /* device number of /dev/imgrd */ #endif /* _DMAP_H */ - diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 88af936f5..c8ee775ab 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -6,7 +6,7 @@ SUBDIR= \ \ chroot \ - \ + dev_mkdb \ \ \ \ diff --git a/usr.sbin/dev_mkdb/Makefile b/usr.sbin/dev_mkdb/Makefile new file mode 100644 index 000000000..598d92838 --- /dev/null +++ b/usr.sbin/dev_mkdb/Makefile @@ -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 + +LDFLAGS+= -Wl,--no-fatal-warnings diff --git a/usr.sbin/dev_mkdb/dev_mkdb.8 b/usr.sbin/dev_mkdb/dev_mkdb.8 new file mode 100644 index 000000000..1ac74ef2e --- /dev/null +++ b/usr.sbin/dev_mkdb/dev_mkdb.8 @@ -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 . diff --git a/usr.sbin/dev_mkdb/dev_mkdb.c b/usr.sbin/dev_mkdb/dev_mkdb.c new file mode 100644 index 000000000..c78cc9d05 --- /dev/null +++ b/usr.sbin/dev_mkdb/dev_mkdb.c @@ -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 +__RCSID("$NetBSD: dev_mkdb.c,v 1.29 2012/06/03 21:42:47 joerg Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); +}