commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hurd] 01/07: New upstream snapshot


From: Samuel Thibault
Subject: [hurd] 01/07: New upstream snapshot
Date: Mon, 11 Sep 2017 07:10:06 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch master
in repository hurd.

commit 0925d4300c4841334ac4f6734b8c28597b149462
Author: Samuel Thibault <address@hidden>
Date:   Sun Sep 10 23:06:39 2017 +0000

    New upstream snapshot
---
 Makeconf                              |   4 +-
 Makefile                              |   1 -
 NEWS                                  |   7 +
 aclocal.m4                            |   4 +
 auth/auth.c                           |   6 +-
 boot/boot.c                           |  12 +-
 config.make.in                        |   5 +-
 configure.ac                          |   3 +
 console-client/console.c              |   5 +-
 console-client/driver.c               |   6 +-
 console-client/ncursesw.c             |  16 +-
 console-client/pc-kbd.c               |   8 +-
 console-client/vga-dynacolor.c        |  10 +-
 console-client/vga-dynafont.c         |   6 +-
 console-client/vga-support.c          |   4 +-
 console-client/vga.c                  |  14 +-
 console-client/xkb/compose.c          |   6 +-
 console-client/xkb/kstoucs.c          |   4 +-
 console-client/xkb/xkbtimer.c         |   4 +-
 console/console.c                     |  10 +-
 console/display.c                     |  16 +-
 console/pager.c                       |  10 +-
 daemons/Makefile                      |   2 +-
 daemons/runttys.c                     |   8 +-
 defpager/backing.c                    |   4 +-
 eth-multiplexer/dev_stat.c            | 121 ++++-
 eth-multiplexer/device_impl.c         |  14 +-
 eth-multiplexer/ethernet.c            |  51 ++-
 eth-multiplexer/ethernet.h            |   1 +
 eth-multiplexer/vdev.c                |  14 +-
 eth-multiplexer/vdev.h                |   2 +
 exec/elfcore.c                        |  14 +-
 exec/exec.c                           |   4 +-
 exec/hashexec.c                       |   2 +-
 exec/hostarch.c                       |   2 +-
 exec/main.c                           |  14 +-
 exec/priv.h                           |   2 +-
 ext2fs/balloc.c                       |  10 +-
 ext2fs/dir.c                          |  58 +--
 ext2fs/ext2fs.h                       |  40 +-
 ext2fs/getblk.c                       |   2 +-
 ext2fs/hyper.c                        |   4 +-
 ext2fs/ialloc.c                       |   8 +-
 ext2fs/inode.c                        |  18 +-
 ext2fs/pager.c                        |  46 +-
 ext2fs/pokel.c                        |   6 +-
 ext2fs/truncate.c                     |   4 +-
 ext2fs/xattr.c                        |   8 +-
 fatfs/dir.c                           |  36 +-
 fatfs/fat.c                           |  28 +-
 fatfs/inode.c                         |  20 +-
 fatfs/main.c                          |   6 +-
 fatfs/pager.c                         |   8 +-
 fatfs/virt-inode.c                    |   8 +-
 ftpfs/conn.c                          |   4 +-
 ftpfs/dir.c                           |   5 +-
 ftpfs/node.c                          |   2 +-
 hostmux/leaf.c                        |   2 +-
 hurd/process.defs                     |   6 +-
 isofs/inode.c                         |   2 +-
 isofs/lookup.c                        |   4 +-
 isofs/main.c                          |   4 +-
 isofs/pager.c                         |   8 +-
 isofs/rr.c                            |  10 +-
 libbpf/bpf_impl.c                     |  30 +-
 libbpf/queue.c                        |  24 +-
 libcons/cons-switch.c                 |   4 +-
 libcons/dir-changed.c                 |   8 +-
 libcons/file-changed.c                |   4 +-
 libcons/vcons-close.c                 |   4 +-
 libcons/vcons-refresh.c               |   2 +-
 libcons/vcons-remove.c                |   4 +-
 libdiskfs/boot-start.c                | 117 ++---
 libdiskfs/console.c                   |   6 +-
 libdiskfs/dir-clear.c                 |   8 +-
 libdiskfs/dir-init.c                  |   4 +-
 libdiskfs/dir-link.c                  |   2 +-
 libdiskfs/dir-lookup.c                |   4 +-
 libdiskfs/dir-renamed.c               |  12 +-
 libdiskfs/disk-pager.c                |  10 +-
 libdiskfs/diskfs-pager.h              |   2 +-
 libdiskfs/diskfs.h                    |  17 +-
 libdiskfs/file-get-source.c           |   2 +-
 libdiskfs/file-get-trans.c            |   8 +-
 libdiskfs/file-getfh.c                |   2 +-
 libdiskfs/file-set-trans.c            |   6 +-
 libdiskfs/fsys-getfile.c              |   3 +-
 libdiskfs/fsys-getroot.c              |   3 +-
 libdiskfs/fsys-goaway.c               |   9 +-
 libdiskfs/fsys-options.c              |   6 +-
 libdiskfs/fsys-syncfs.c               |   7 +-
 libdiskfs/get-source.c                |   2 +-
 libdiskfs/init-init.c                 |  14 +-
 libdiskfs/init-main.c                 |   4 +-
 libdiskfs/init-startup.c              |   6 +-
 libdiskfs/io-map-cntl.c               |   2 +-
 libdiskfs/io-reauthenticate.c         |   2 +-
 libdiskfs/io-write.c                  |   2 +-
 libdiskfs/lookup.c                    |   2 +-
 libdiskfs/name-cache.c                |   4 +-
 libdiskfs/node-cache.c                |  10 +-
 libdiskfs/node-drop.c                 |   6 +-
 libdiskfs/priv.h                      |   2 +-
 libdiskfs/protid-make.c               |   6 +-
 libdiskfs/rdwr-internal.c             |   2 +-
 libdiskfs/trans-callback.c            |   2 +-
 libfshelp/fetch-control.c             |   4 +-
 libfshelp/fetch-root.c                |   4 +-
 libfshelp/get-identity.c              |   4 +-
 libfshelp/lock-acquire.c              |  12 +-
 libfshelp/start-translator-long.c     |   4 +-
 libftpconn/unix.c                     |   9 +-
 libhurd-slab/slab.c                   |  10 +-
 libnetfs/dir-lookup.c                 |   4 +-
 libnetfs/file-get-children.c          |   4 +-
 libnetfs/file-get-source.c            |   6 +-
 libnetfs/file-set-translator.c        |   6 +-
 libnetfs/get-source.c                 |   2 +-
 libnetfs/io-reauthenticate.c          |   2 +-
 libnetfs/netfs.h                      |  11 +-
 libnetfs/trans-callback.c             |   2 +-
 libpager/data-return.c                |   6 +-
 libpager/demuxer.c                    |  12 +-
 libpager/pager-attr.c                 |   2 +-
 libpager/pager-memcpy.c               |  26 +-
 libpipe/pipe.c                        |   4 +-
 libports/claim-right.c                |   4 +-
 libports/complete-deallocate.c        |   6 +-
 libports/create-internal.c            |   6 +-
 libports/destroy-right.c              |   4 +-
 libports/get-right.c                  |   4 +-
 libports/get-send-right.c             |   4 +-
 libports/import-port.c                |   4 +-
 libports/interrupt-on-notify.c        |   4 +-
 libports/manage-multithread.c         |   4 +-
 libports/manage-one-thread.c          |   2 +-
 libports/port-deref-deferred.c        |  12 +-
 libports/port-deref-weak.c            |   2 +-
 libports/port-deref.c                 |   2 +-
 libports/port-ref-weak.c              |   2 +-
 libports/port-ref.c                   |   2 +-
 libports/reallocate-from-external.c   |  14 +-
 libports/reallocate-port.c            |  14 +-
 libports/resume-all-rpcs.c            |   4 +-
 libports/resume-bucket-rpcs.c         |   4 +-
 libports/resume-class-rpcs.c          |   4 +-
 libports/resume-port-rpcs.c           |   4 +-
 libports/transfer-right.c             |  10 +-
 libps/context.c                       |   2 +-
 libps/filters.c                       |   2 +-
 libps/fmt.c                           |  11 +-
 libps/host.c                          |   2 +-
 libps/proclist.c                      |  10 +-
 libps/procstat.c                      |  12 +-
 libps/spec.c                          |   5 +-
 libps/tty.c                           |   2 +-
 libps/user.c                          |   2 +-
 libshouldbeinlibc/assert-backtrace.h  |   2 +
 libshouldbeinlibc/cacheq.c            |   2 +-
 libshouldbeinlibc/idvec-verify.c      |   4 +-
 libshouldbeinlibc/idvec.c             |   6 +-
 libshouldbeinlibc/timefmt.c           |   2 +-
 libshouldbeinlibc/wire.c              | 144 ++++--
 libshouldbeinlibc/wire.h              |   4 +-
 libstore/argp.c                       |   4 +-
 libstore/derive.c                     |   6 +-
 libstore/device.c                     |   6 +-
 libstore/memobj.c                     |   4 +-
 libstore/mvol.c                       |   3 +-
 libstore/part.c                       |   8 +-
 libthreads/cancel-cond.c              |   4 +-
 libthreads/cprocs.c                   |   4 +-
 libthreads/rwlock.h                   |   6 +-
 libtreefs/dir-lookup.c                |   2 +-
 libtreefs/fsys-startup.c              |   2 +-
 libtreefs/treefs.h                    |  10 +-
 libtrivfs/dir-lookup.c                |   2 +-
 libtrivfs/file-get-source.c           |   2 +-
 libtrivfs/file-set-size.c             |   4 +-
 libtrivfs/fsys-getroot.c              |   2 +-
 libtrivfs/get-source.c                |   2 +-
 libtrivfs/io-async-icky.c             |   2 +-
 libtrivfs/io-async.c                  |   2 +-
 libtrivfs/io-map.c                    |   2 +-
 libtrivfs/io-modes-get.c              |   2 +-
 libtrivfs/io-modes-off.c              |   4 +-
 libtrivfs/io-modes-on.c               |   4 +-
 libtrivfs/io-modes-set.c              |   4 +-
 libtrivfs/io-owner-get.c              |   2 +-
 libtrivfs/io-owner-mod.c              |   2 +-
 libtrivfs/io-read.c                   |   4 +-
 libtrivfs/io-readable.c               |   4 +-
 libtrivfs/io-reauthenticate.c         |   4 +-
 libtrivfs/io-seek.c                   |   4 +-
 libtrivfs/io-select.c                 |   6 +-
 libtrivfs/io-write.c                  |   4 +-
 libtrivfs/startup.c                   |   2 +-
 libtrivfs/trivfs.h                    |  11 +-
 login/utmp.c                          |   2 +-
 m4/libgcrypt.m4                       | 143 ++++++
 mach-defpager/Makefile                |   2 +-
 mach-defpager/default_pager.c         |  42 +-
 mach-defpager/setup.c                 |  16 +-
 nfs/cache.c                           |   4 +-
 nfs/main.c                            |  11 +-
 nfs/ops.c                             |  13 +-
 nfs/rpc.c                             |  12 +-
 nfs/storage-info.c                    |   6 +-
 nfsd/cache.c                          |   9 +-
 pfinet/dummy.c                        |   2 +-
 pfinet/ethernet.c                     |  18 +-
 pfinet/glue-include/linux/interrupt.h |   6 +-
 pfinet/glue-include/linux/kernel.h    |   8 +-
 pfinet/glue-include/linux/sched.h     |  14 +-
 pfinet/glue-include/linux/socket.h    |   6 +-
 pfinet/glue-include/linux/types.h     |   2 +-
 pfinet/io-ops.c                       |   4 +-
 pfinet/linux-src/include/net/tcp.h    |   1 -
 pfinet/linux-src/include/net/udp.h    |   2 -
 pfinet/linux-src/net/ipv4/tcp_ipv4.c  |   4 +-
 pfinet/linux-src/net/ipv4/udp.c       |  12 +-
 pfinet/linux-src/net/ipv6/tcp_ipv6.c  |   3 +-
 pfinet/linux-src/net/ipv6/udp_ipv6.c  |   9 +-
 pfinet/main.c                         |   4 +-
 pfinet/socket.c                       |   6 +-
 pfinet/tunnel.c                       |  12 +-
 pflocal/connq.c                       |  20 +-
 pflocal/io.c                          |   2 +-
 pflocal/sock.c                        |   8 +-
 pflocal/sock.h                        |   6 +-
 proc/host.c                           |  19 +-
 proc/info.c                           |   8 +-
 proc/main.c                           |  10 +-
 proc/mgt.c                            |  20 +-
 proc/msg.c                            |   2 +-
 proc/pgrp.c                           |   4 +-
 proc/stubs.c                          |   6 +-
 proc/wait.c                           |   3 +-
 procfs/main.c                         |  12 +-
 procfs/netfs.c                        |   4 +-
 procfs/procfs.c                       |   2 +-
 procfs/proclist.c                     |   4 +-
 procfs/rootdir.c                      |  72 ++-
 random/Makefile                       |  30 --
 random/TODO                           |  11 -
 random/gnupg-bithelp.h                |  41 --
 random/gnupg-glue.h                   |  40 --
 random/gnupg-random.c                 | 809 ----------------------------------
 random/gnupg-random.h                 |  47 --
 random/gnupg-rmd.h                    |  38 --
 random/gnupg-rmd160.c                 | 655 ---------------------------
 random/random.h                       |  32 --
 startup/startup.c                     |  83 ++--
 storeio/dev.c                         |  15 +-
 storeio/pager.c                       |   4 +-
 storeio/storeio.c                     |   2 +-
 sutils/MAKEDEV.sh                     |   8 +-
 sutils/bless.c                        |   4 +-
 sutils/fsck.c                         |   6 +-
 sutils/fstab.c                        |   2 +-
 sutils/swapon.c                       |   2 +-
 term/devio.c                          |  20 +-
 term/hurdio.c                         |   2 +-
 term/main.c                           |   2 +-
 term/munge.c                          |   6 +-
 term/term.h                           |   6 +-
 term/users.c                          |   6 +-
 tmpfs/dir.c                           |  18 +-
 tmpfs/node.c                          |  28 +-
 tmpfs/tmpfs.c                         |   2 +-
 trans/Makefile                        |  16 +-
 trans/crash.c                         |   6 +-
 trans/fakeroot.c                      |  76 +++-
 trans/firmlink.c                      |   3 +-
 trans/magic.c                         |   8 +-
 trans/mtab.c                          |  36 +-
 trans/new-fifo.c                      |  10 +-
 trans/password.c                      |   6 +-
 {random => trans}/random.c            | 500 ++++++++++++---------
 trans/streamio.c                      |  14 +-
 trans/symlink.c                       |  59 ---
 usermux/leaf.c                        |   2 +-
 utils/Makefile                        |   2 +
 utils/fakeauth.c                      |   6 +-
 utils/login.c                         |   6 +-
 utils/ps.c                            |   2 +-
 utils/rpctrace.c                      |  82 ++--
 utils/settrans.c                      |   4 +-
 utils/shd.c                           |   8 +-
 utils/vmallocate.c                    |   4 +-
 290 files changed, 1929 insertions(+), 3158 deletions(-)

diff --git a/Makeconf b/Makeconf
index 02594c6..f718164 100644
--- a/Makeconf
+++ b/Makeconf
@@ -548,7 +548,7 @@ MIGCOMFLAGS := -subrprefix __
          -DHURD_SERVER=1 \
          -MD -MF $*.sdefs.d.new \
          $< -o $*.sdefsi
-       sed -e 's/[^:]*:/$*Server.c $(mig-sheader-prefix)$*_S.h:/' \
+       sed -e 's#[^:]*:#$*Server.c $(mig-sheader-prefix)$*_S.h:#' \
          < $*.sdefs.d.new > $*.sdefs.d
        rm $*.sdefs.d.new
 
@@ -561,7 +561,7 @@ $(mig-sheader-prefix)%_S.h %Server.c: %.sdefsi
        $(CPP) $(CPPFLAGS) $(MIGUFLAGS) $($*-MIGUFLAGS) \
          -MD -MF $*.udefs.d.new \
          $< -o $*.udefsi
-       sed -e 's/[^:]*:/$*User.c $*_U.h:/' \
+       sed -e 's#[^:]*:#$*User.c $*_U.h:#' \
          < $*.udefs.d.new > $*.udefs.d
        rm $*.udefs.d.new
 
diff --git a/Makefile b/Makefile
index 9de4fa8..119f130 100644
--- a/Makefile
+++ b/Makefile
@@ -40,7 +40,6 @@ prog-subdirs = auth proc exec term \
               hostmux usermux ftpfs trans \
               console-client utils sutils \
               benchmarks fstests \
-              random \
               procfs \
               startup \
               init \
diff --git a/NEWS b/NEWS
index 1b500be..009e4e4 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,13 @@ Subhurd's processes are now properly embedded in the 
Motherhurds
 process hierarchy.  They can be inspected and debugged just like any
 other process.
 
+The random translator has been reimplemented using the SHAKE128
+algorithm from the SHA-3 family as the underlying cryptographic
+primitive.
+
+The Hurd now uses its own variant of 'assert' that prints a stack
+trace on failures.
+
 Version 0.9 (2016-12-18)
 
 The 'boot' program can now be run as unprivileged user, allowing any
diff --git a/aclocal.m4 b/aclocal.m4
index 4f091fb..911dca2 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -239,3 +239,7 @@ else
        $3
 fi[]dnl
 ])# PKG_CHECK_MODULES
+
+
+# Include files from m4/.
+m4_include([m4/libgcrypt.m4])
diff --git a/auth/auth.c b/auth/auth.c
index d5ef587..bc5e87a 100644
--- a/auth/auth.c
+++ b/auth/auth.c
@@ -29,7 +29,7 @@
 #include <hurd/ports.h>
 #include <hurd/ihash.h>
 #include <idvec.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <argp.h>
 #include <error.h>
 #include <version.h>
@@ -496,7 +496,7 @@ main (int argc, char **argv)
 
   /* Create the initial root auth handle.  */
   err = create_authhandle (&firstauth);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   idvec_add (&firstauth->euids, 0);
   idvec_add (&firstauth->auids, 0);
   idvec_add (&firstauth->auids, 0);
@@ -505,7 +505,7 @@ main (int argc, char **argv)
 
   /* Fetch our bootstrap port and contact the bootstrap filesystem.  */
   err = task_get_bootstrap_port (mach_task_self (), &boot);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   if (boot == MACH_PORT_NULL)
     error (2, 0, "auth server can only be run by init during boot");
   err = startup_authinit (boot, ports_get_right (firstauth),
diff --git a/boot/boot.c b/boot/boot.c
index 978f56e..35577a8 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -66,7 +66,7 @@
 #include <termios.h>
 #include <error.h>
 #include <hurd.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "private.h"
 
@@ -428,7 +428,7 @@ allocate_pseudo_ports (void)
                                  MACH_NOTIFY_NO_SENDERS, 1,
                                  pseudo_privileged_host_port,
                                  MACH_MSG_TYPE_MAKE_SEND_ONCE, &old);
-  assert (old == MACH_PORT_NULL);
+  assert_backtrace (old == MACH_PORT_NULL);
 
   /* Allocate a port that we hand out as the privileged processor set
      port.  */
@@ -684,7 +684,7 @@ main (int argc, char **argv, char **envp)
            char *msg;
            asprintf (&msg, "cannot set boot-script variable %s: %s\n",
                      word, boot_script_error_string (err));
-           assert (msg);
+           assert_backtrace (msg);
            write (2, msg, strlen (msg));
            free (msg);
            host_exit (1);
@@ -1198,7 +1198,7 @@ ds_device_read_inband (device_t device,
        {
          if (returned != data)
            {
-             bcopy (returned, (void *)data, *datalen);
+             memcpy ((void *)data, returned, *datalen);
              munmap ((caddr_t) returned, *datalen);
            }
          return D_SUCCESS;
@@ -1652,7 +1652,7 @@ S_io_reauthenticate (mach_port_t object,
 
   err = mach_port_insert_right (mach_task_self (), object, object,
                                MACH_MSG_TYPE_MAKE_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   do
     err = auth_server_authenticate (authserver,
@@ -2043,7 +2043,7 @@ S_mach_notify_new_task (mach_port_t notify,
                                         &previous);
   if (err)
     goto fail;
-  assert (! MACH_PORT_VALID (previous));
+  assert_backtrace (! MACH_PORT_VALID (previous));
 
   mach_port_mod_refs (mach_task_self (), task, MACH_PORT_RIGHT_SEND, +1);
   err = hurd_ihash_add (&task_ihash,
diff --git a/config.make.in b/config.make.in
index 0f1390a..dfbf0c1 100644
--- a/config.make.in
+++ b/config.make.in
@@ -80,7 +80,6 @@ XKB_BASE = @XKB_BASE@
 X11_KEYSYMDEF_H = @X11_KEYSYMDEF_H@
 
 # How to compile and link against libdaemon.
-HAVE_DAEMON = @HAVE_DAEMON@
 libdaemon_CFLAGS = @libdaemon_CFLAGS@
 libdaemon_LIBS = @libdaemon_LIBS@
 
@@ -91,13 +90,15 @@ HAVE_LIBBZ2 = @HAVE_LIBBZ2@
 HAVE_LIBZ = @HAVE_LIBZ@
 
 # How to compile and link against libblkid.
-HAVE_BLKID = @HAVE_BLKID@
 libblkid_CFLAGS = @libblkid_CFLAGS@
 libblkid_LIBS = @libblkid_LIBS@
 
 # Whether Sun RPC support is available.
 HAVE_SUN_RPC = @HAVE_SUN_RPC@
 
+# Whether we found libgcrypt.
+HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@
+
 # Installation tools.
 INSTALL = @INSTALL@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/configure.ac b/configure.ac
index 30a1367..54aa72b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -341,6 +341,9 @@ PKG_CHECK_MODULES([libblkid], [blkid],
 AC_SUBST([libblkid_LIBS])
 AC_SUBST([libblkid_CFLAGS])
 
+AM_PATH_LIBGCRYPT("1:1.6.0",[HAVE_LIBGCRYPT=yes], [HAVE_LIBGCRYPT=no])
+AC_SUBST([HAVE_LIBGCRYPT])
+
 AC_CONFIG_FILES([config.make ${makefiles}])
 AC_OUTPUT
 
diff --git a/console-client/console.c b/console-client/console.c
index 2fa0533..3b31611 100644
--- a/console-client/console.c
+++ b/console-client/console.c
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <wchar.h>
 #include <error.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include <pthread.h>
 #if HAVE_DAEMON
@@ -563,8 +563,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
        char *s;
        char *d;
 
-       if (driver_path)
-         free (driver_path);
+       free (driver_path);
        driver_path = malloc (strlen (arg) + 2);
        if (!driver_path)
          {
diff --git a/console-client/driver.c b/console-client/driver.c
index 7a55bbe..b4a03ab 100644
--- a/console-client/driver.c
+++ b/console-client/driver.c
@@ -117,8 +117,7 @@ error_t driver_add (const char *const name, const char 
*const driver,
 
   while (dir)
     {
-      if (filename)
-       free (filename);
+      free (filename);
       if (asprintf (&filename,
                    "%s/%s%s", dir, driver, CONSOLE_SONAME_SUFFIX) < 0)
        {
@@ -156,8 +155,7 @@ error_t driver_add (const char *const name, const char 
*const driver,
 
   if (!shobj)
     {
-      if (filename)
-       free (filename);
+      free (filename);
       pthread_mutex_unlock (&driver_list_lock);
       return ENOENT;
     }
diff --git a/console-client/ncursesw.c b/console-client/ncursesw.c
index 881acad..8e8962f 100644
--- a/console-client/ncursesw.c
+++ b/console-client/ncursesw.c
@@ -16,7 +16,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <unistd.h>
 #include <string.h>
@@ -324,7 +324,7 @@ input_loop (void *unused)
                      console_exit ();
                      break;
                    case 23:    /* ^W */
-                     assert (size < 100);
+                     assert_backtrace (size < 100);
                      buf[size++] = ret;
                      break;
                    case '1':
@@ -397,7 +397,7 @@ input_loop (void *unused)
                          {     
                            if (keycodes[i].cons)
                              {
-                               assert (size 
+                               assert_backtrace (size 
                                        < 101 - strlen (keycodes[i].cons));
                                strcpy (&buf[size], keycodes[i].cons);
                                size += strlen (keycodes[i].cons);
@@ -408,7 +408,7 @@ input_loop (void *unused)
                      }
                    if (!found)
                      {
-                       assert (size < 100);
+                       assert_backtrace (size < 100);
                        buf[size++] = ret;
                      }
                    break;
@@ -472,7 +472,7 @@ mvwputsn (conchar_t *str, size_t len, off_t x, off_t y)
            {
              printf ("setcchar failed: %s\n", strerror (errno));
              printf ("[%lc]\n", wch[0]);
-             assert (!"Do something if setcchar fails.");
+             assert_backtrace (!"Do something if setcchar fails.");
            }
 #endif
          ret = wadd_wch (conspad, &chr);
@@ -481,7 +481,7 @@ mvwputsn (conchar_t *str, size_t len, off_t x, off_t y)
            {
              printf ("add_wch failed: %i, %s\n", ret, strerror (errno));
              printf ("[%lc]\n", wch[0]);
-             assert (!"Do something if add_wchr fails.");
+             assert_backtrace (!"Do something if add_wchr fails.");
            }
 #endif
        }
@@ -505,7 +505,7 @@ static error_t
 ncursesw_set_cursor_pos (void *handle, uint32_t col, uint32_t row)
 {
   pthread_mutex_lock (&ncurses_lock);
-  assert (current_width && current_height);
+  assert_backtrace (current_width && current_height);
   if (autoscroll)
     {
       /* Autoscroll to the right.  */
@@ -569,7 +569,7 @@ static error_t
 ncursesw_scroll (void *handle, int delta)
 {
   /* XXX We don't support scrollback for now.  */
-  assert (delta >= 0);
+  assert_backtrace (delta >= 0);
 
   pthread_mutex_lock (&ncurses_lock);
   idlok (conspad, TRUE);
diff --git a/console-client/pc-kbd.c b/console-client/pc-kbd.c
index 2fc7608..85f3a5c 100644
--- a/console-client/pc-kbd.c
+++ b/console-client/pc-kbd.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <iconv.h>
 #include <sys/mman.h>
@@ -1084,12 +1084,12 @@ input_loop (void *unused)
                      if (!sc_to_kc[sc][modifier][0])
                        {
                          /* Special meaning, emit NUL.  */
-                         assert (size < 100);
+                         assert_backtrace (size < 100);
                          buf[size++] = '\0';
                        }
                      else
                        {
-                         assert (size
+                         assert_backtrace (size
                                  < 101 - strlen(sc_to_kc[sc][modifier]));
                          strcpy (&buf[size], sc_to_kc[sc][modifier]);
                          size += strlen (sc_to_kc[sc][modifier]);
@@ -1162,7 +1162,7 @@ input_loop (void *unused)
            {
              if (modifier >= 0 && sc_x1_to_kc[sc][modifier])
                {
-                 assert (size < 101 - strlen(sc_x1_to_kc[sc][modifier]));
+                 assert_backtrace (size < 101 - 
strlen(sc_x1_to_kc[sc][modifier]));
                  strcpy (&buf[size], sc_x1_to_kc[sc][modifier]);
                  size += strlen (sc_x1_to_kc[sc][modifier]);
                }
diff --git a/console-client/vga-dynacolor.c b/console-client/vga-dynacolor.c
index 9289e1e..ef95247 100644
--- a/console-client/vga-dynacolor.c
+++ b/console-client/vga-dynacolor.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include <hurd/console.h>
 
@@ -290,18 +290,18 @@ dynacolor_replace_colors (dynacolor_t *dc,
            }
        }
 
-      assert (res_bgcol >= 0);
+      assert_backtrace (res_bgcol >= 0);
       new_bgcol = pref[bgcol][i];
     }
 
   if (fgcol == bgcol)
     {
-      assert (res_fgcol == -1);
+      assert_backtrace (res_fgcol == -1);
       /* Acquire another reference.  */
       res_fgcol = dynacolor_lookup (*dc, new_bgcol);
     }
   else
-    assert (res_fgcol != res_bgcol);
+    assert_backtrace (res_fgcol != res_bgcol);
       
   if (res_fgcol == -1)
     {
@@ -315,7 +315,7 @@ dynacolor_replace_colors (dynacolor_t *dc,
                break;
            }
        }
-      assert (res_fgcol >= 0);
+      assert_backtrace (res_fgcol >= 0);
     }
   *r_fgcol = res_fgcol;
   *r_bgcol = res_bgcol;
diff --git a/console-client/vga-dynafont.c b/console-client/vga-dynafont.c
index 2cee47e..c662772 100644
--- a/console-client/vga-dynafont.c
+++ b/console-client/vga-dynafont.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <stddef.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <malloc.h>
 #include <wchar.h>
 #include <stdlib.h>
@@ -848,7 +848,7 @@ dynafont_lookup_internal (dynafont_t df, bdf_font_t font,
        }
       while (pos != start_pos);
 
-      assert (found);
+      assert_backtrace (found);
       df->vga_font_free_indices_lgc--;
       df->vga_font_last_free_index_lgc = pos;
     }
@@ -872,7 +872,7 @@ dynafont_lookup_internal (dynafont_t df, bdf_font_t font,
        }
       while (pos != start_pos);
 
-      assert (found);
+      assert_backtrace (found);
       df->vga_font_free_indices--;
       df->vga_font_last_free_index = pos;
     }
diff --git a/console-client/vga-support.c b/console-client/vga-support.c
index 3a2d758..32ede46 100644
--- a/console-client/vga-support.c
+++ b/console-client/vga-support.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/io.h>
@@ -225,7 +225,7 @@ vga_read_write_font_buffer (int write, int buffer, int 
index,
   char saved_gfx_misc;
 
   int offset = buffer * VGA_FONT_SIZE + index * VGA_FONT_HEIGHT;
-  assert (offset >= 0 && offset + datalen <= VGA_VIDEO_MEM_LENGTH);
+  assert_backtrace (offset >= 0 && offset + datalen <= VGA_VIDEO_MEM_LENGTH);
 
   /* Select plane 2 for sequential writing.  You might think it is not
      necessary for reading, but it is.  Likewise for read settings
diff --git a/console-client/vga.c b/console-client/vga.c
index 2d74aae..e954013 100644
--- a/console-client/vga.c
+++ b/console-client/vga.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <error.h>
 #include <fcntl.h>
@@ -385,14 +385,10 @@ vga_display_fini (void *handle, int force)
   free (disp);
   dynacolor_fini ();
   vga_fini ();
-  if (vga_display_font)
-    free (vga_display_font);
-  if (vga_display_font_italic)
-    free (vga_display_font_italic);
-  if (vga_display_font_bold)
-    free (vga_display_font_bold);
-  if (vga_display_font_bold_italic)
-    free (vga_display_font_bold_italic);
+  free (vga_display_font);
+  free (vga_display_font_italic);
+  free (vga_display_font_bold);
+  free (vga_display_font_bold_italic);
 
   return 0;
 }
diff --git a/console-client/xkb/compose.c b/console-client/xkb/compose.c
index fb3f07c..17f3001 100644
--- a/console-client/xkb/compose.c
+++ b/console-client/xkb/compose.c
@@ -28,7 +28,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <locale.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 /* Tokens that can be recognised by the scanner.  */
 enum tokentype
@@ -427,8 +427,8 @@ map_iterate(const char *map_path, map_callback action, void 
*context)
   size_t buffer_size = 0;
   size_t line_length = 0;
 
-  assert (map_path != NULL);
-  assert (action != NULL);
+  assert_backtrace (map_path != NULL);
+  assert_backtrace (action != NULL);
 
   map = fopen (map_path, "r");
 
diff --git a/console-client/xkb/kstoucs.c b/console-client/xkb/kstoucs.c
index eb47bde..59af1e9 100644
--- a/console-client/xkb/kstoucs.c
+++ b/console-client/xkb/kstoucs.c
@@ -1,4 +1,4 @@
-#include <assert.h>
+#include <assert-backtrace.h>
 
 struct ksmap {
   int keysym;
@@ -13,7 +13,7 @@ find_ucs (int keysym, struct ksmap *first, struct ksmap *last)
 {
   struct ksmap *middle = first + (last - first) / 2;
 
-  assert (first <= last);
+  assert_backtrace (first <= last);
 
   if (middle->keysym == keysym)
     return middle->ucs; /* base case: needle found. */
diff --git a/console-client/xkb/xkbtimer.c b/console-client/xkb/xkbtimer.c
index 24791e9..28e1c68 100644
--- a/console-client/xkb/xkbtimer.c
+++ b/console-client/xkb/xkbtimer.c
@@ -19,7 +19,7 @@
 
 #include <mach.h>
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "xkb.h"
 #include <timer.h>
@@ -123,7 +123,7 @@ key_timing (void *handle)
   switch (per_key_timers[current_key].enable_status)
     {
     case timer_stopped:
-      assert ("Stopped timer triggered timer event\n");
+      assert_backtrace ("Stopped timer triggered timer event\n");
       break;
     case timer_slowkeys:
       per_key_timers[current_key].enable_timer.expires
diff --git a/console/console.c b/console/console.c
index 9c5869d..94de004 100644
--- a/console/console.c
+++ b/console/console.c
@@ -459,7 +459,7 @@ void
 netfs_node_norefs (struct node *np)
 {
   /* The root node does never go away.  */
-  assert (!np->nn->cons && np->nn->vcons);
+  assert_backtrace (!np->nn->cons && np->nn->vcons);
 
   free (np->nn);
   free (np);
@@ -654,7 +654,7 @@ netfs_attempt_lookup (struct iouser *user, struct node *dir,
       /* This is a virtual console directory node.  */
       vcons_t vcons = dir->nn->vcons;
       int ref_vcons = 0;
-      assert (dir == vcons->dir_node);
+      assert_backtrace (dir == vcons->dir_node);
 
       if (!strcmp (name, "console"))
        {
@@ -1057,7 +1057,7 @@ netfs_attempt_set_size (struct iouser *cred, struct node 
*np, off_t size)
       || np == vcons->disp_node)
     return EOPNOTSUPP;
 
-  assert (np == vcons->cons_node || np == vcons->inpt_node);
+  assert_backtrace (np == vcons->cons_node || np == vcons->inpt_node);
   return 0;
 }
 
@@ -1140,7 +1140,7 @@ netfs_attempt_read (struct iouser *cred, struct node *np,
     {
       /* Pass display content to caller.  */
       ssize_t amt = *len;
-      assert (np == vcons->disp_node);
+      assert_backtrace (np == vcons->disp_node);
 
       if (offset + amt > np->nn_stat.st_size)
        amt = np->nn_stat.st_size - offset;
@@ -1187,7 +1187,7 @@ netfs_attempt_write (struct iouser *cred, struct node *np,
       int amt;
       /* The input driver is writing to the input device.  Feed the
         data into the input queue.  */
-      assert (np == vcons->inpt_node);
+      assert_backtrace (np == vcons->inpt_node);
 
       amt = input_enqueue (vcons->input,
                           /* cred->po->openstat & O_NONBLOCK */ 1,
diff --git a/console/display.c b/console/display.c
index ed5571e..ec1462d 100644
--- a/console/display.c
+++ b/console/display.c
@@ -26,7 +26,7 @@
 #include <iconv.h>
 #include <argp.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <error.h>
 
 #include <pthread.h>
@@ -226,7 +226,7 @@ nowait_file_changed (mach_port_t notify_port, natural_t 
tickno,
   {
     Request In;
   } Mess;
-  register Request *InP = &Mess.In;
+  Request *InP = &Mess.In;
 
   static const mach_msg_type_t ticknoType = {
     /* msgt_name = */           2,
@@ -325,7 +325,7 @@ do_mach_notify_port_deleted (struct port_info *pi, 
mach_port_t name)
 {
   /* As we cancel the dead-name notification before deallocating the
      port, this should not happen.  */
-  assert (0);
+  assert_backtrace (0);
 }
 
 /* We request dead name notifications for the user ports.  */
@@ -376,7 +376,7 @@ do_mach_notify_dead_name (struct port_info *pi, mach_port_t 
dead_name)
 error_t
 do_mach_notify_port_destroyed (struct port_info *pi, mach_port_t rights)
 {
-  assert (0);
+  assert_backtrace (0);
 }
 
 error_t
@@ -409,7 +409,7 @@ do_mach_notify_msg_accepted (struct port_info *pi, 
mach_port_t send)
      case.  */
   if (!send)
     {
-      assert(0);
+      assert_backtrace (0);
       return 0;
     }
 
@@ -424,7 +424,7 @@ do_mach_notify_msg_accepted (struct port_info *pi, 
mach_port_t send)
      here.  */
   if (! *preq)
     {
-      assert(0);
+      assert_backtrace (0);
       pthread_mutex_unlock (&display->lock);
       return 0;
     }
@@ -526,7 +526,7 @@ display_notice_changes (display_t display, mach_port_t 
notify)
       pthread_mutex_unlock (&display->lock);
       return err;
     }
-  assert (old == MACH_PORT_NULL);
+  assert_backtrace (old == MACH_PORT_NULL);
 
   req->port = notify;
   req->pending = 0;
@@ -1820,7 +1820,7 @@ display_output_some (display_t display, char **buffer, 
size_t *length)
 #define UNICODE_REPLACEMENT_CHARACTER ((wchar_t) 0xfffd)
          if (saved_err == EILSEQ)
            {
-             assert (*length);
+             assert_backtrace (*length);
              (*length)--;
              (*buffer)++;
              display_output_one (display, UNICODE_REPLACEMENT_CHARACTER);
diff --git a/console/pager.c b/console/pager.c
index d60935a..a18d4d1 100644
--- a/console/pager.c
+++ b/console/pager.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <error.h>
 #include <stdio.h>
 
@@ -80,7 +80,7 @@ error_t
 pager_write_page (struct user_pager_info *upi, vm_offset_t page,
                   vm_address_t buf)
 {
-  assert (upi->memobj_pages[page / vm_page_size] == (vm_address_t) NULL);
+  assert_backtrace (upi->memobj_pages[page / vm_page_size] == (vm_address_t) 
NULL);
   upi->memobj_pages[page / vm_page_size] = buf;
   return 0;
 }
@@ -90,7 +90,7 @@ error_t
 pager_unlock_page (struct user_pager_info *pager,
                    vm_offset_t address)
 {
-  assert (!"unlocking requested on unlocked page");
+  assert_backtrace (!"unlocking requested on unlocked page");
   return 0;
 }
 
@@ -99,7 +99,7 @@ void
 pager_notify_evict (struct user_pager_info *pager,
                    vm_offset_t page)
 {
-  assert (!"unrequested notification on eviction");
+  assert_backtrace (!"unrequested notification on eviction");
 }
 
 
@@ -207,7 +207,7 @@ user_pager_get_filemap (struct user_pager *user_pager, 
vm_prot_t prot)
   /* Add a reference for each call, the caller will deallocate it.  */
   err = mach_port_mod_refs (mach_task_self (), user_pager->memobj,
                             MACH_PORT_RIGHT_SEND, +1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   return user_pager->memobj;
 }
diff --git a/daemons/Makefile b/daemons/Makefile
index 289fbf6..6d03071 100644
--- a/daemons/Makefile
+++ b/daemons/Makefile
@@ -41,7 +41,7 @@ mail.local: lmail.o ../libshouldbeinlibc/libshouldbeinlibc.a
 console-run: console-run.o ../libfshelp/libfshelp.a ../libports/libports.a \
        ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a
 
-runttys: runttys.o
+runttys: runttys.o ../libshouldbeinlibc/libshouldbeinlibc.a
 runttys-LDLIBS = -lutil
 
 runsystem: runsystem.sh
diff --git a/daemons/runttys.c b/daemons/runttys.c
index 7efb7b7..baefdbe 100644
--- a/daemons/runttys.c
+++ b/daemons/runttys.c
@@ -17,7 +17,7 @@
    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <argz.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <error.h>
 #include <fcntl.h>
@@ -239,8 +239,8 @@ static int
 startup_terminal (struct terminal *t)
 {
   pid_t pid;
-  assert (t->on);
-  assert (t->getty_argv);
+  assert_backtrace (t->on);
+  assert_backtrace (t->getty_argv);
 
   if (t->window_argv)
     {
@@ -494,7 +494,7 @@ main ()
          error (1, waiterr, "waitpid");
        }
 
-      assert (pid > 0);
+      assert_backtrace (pid > 0);
 
       /* We have reaped a dead child.  Restart that tty line.  */
       restart_terminal (pid);
diff --git a/defpager/backing.c b/defpager/backing.c
index 7383c91..aa9810c 100644
--- a/defpager/backing.c
+++ b/defpager/backing.c
@@ -92,7 +92,7 @@ allocate_backing_page ()
   
   /* Find which bit */
   bit = ffs (*bmap_rotor);
-  assert (bit);
+  assert_backtrace (bit);
   bit--;
   
   /* Mark it */
@@ -123,7 +123,7 @@ return_backing_pages (off_t *map, int maplen)
       b = bmap + pfn & ~7;
       bit = pfn & 7;
       
-      assert ((*b & (1 << bit)) == 0);
+      assert_backtrace ((*b & (1 << bit)) == 0);
       *b |= 1 << bit;
     }
   pthread_mutex_unlock (&bmap_lock);
diff --git a/eth-multiplexer/dev_stat.c b/eth-multiplexer/dev_stat.c
index bfbb433..2e12cff 100644
--- a/eth-multiplexer/dev_stat.c
+++ b/eth-multiplexer/dev_stat.c
@@ -41,15 +41,21 @@
 #include <mach.h>
 
 #include "vdev.h"
+#include "ethernet.h"
 
 io_return_t
 dev_getstat(struct vether_device *ifp, dev_flavor_t flavor,
                dev_status_t status, natural_t *count)
 {
        switch (flavor) {
+               case NET_FLAGS:
+                       if (*count != 1)
+                               return D_INVALID_SIZE;
+                       status[0] = ifp->if_flags;
+                       break;
                case NET_STATUS:
                        {
-                               register struct net_status *ns = (struct 
net_status *)status;
+                               struct net_status *ns = (struct net_status 
*)status;
 
                                if (*count < NET_STATUS_COUNT)
                                        return (D_INVALID_OPERATION);
@@ -67,9 +73,9 @@ dev_getstat(struct vether_device *ifp, dev_flavor_t flavor,
                        }
                case NET_ADDRESS:
                        {
-                               register int    addr_byte_count;
-                               register int    addr_int_count;
-                               register int    i;
+                               int     addr_byte_count;
+                               int     addr_int_count;
+                               int     i;
 
                                addr_byte_count = ifp->if_address_size;
                                addr_int_count = (addr_byte_count + 
(sizeof(int)-1))
@@ -86,7 +92,7 @@ dev_getstat(struct vether_device *ifp, dev_flavor_t flavor,
                                                         - addr_byte_count));
 
                                for (i = 0; i < addr_int_count; i++) {
-                                       register int word;
+                                       int word;
 
                                        word = status[i];
                                        status[i] = htonl(word);
@@ -99,3 +105,108 @@ dev_getstat(struct vether_device *ifp, dev_flavor_t flavor,
        }
        return (D_SUCCESS);
 }
+
+static
+int wants_all_multi_p (struct vether_device *v)
+{
+  return !! (v->if_flags & IFF_ALLMULTI);
+}
+
+io_return_t
+vdev_setstat (struct vether_device *ifp, dev_flavor_t flavor,
+             dev_status_t status, size_t count)
+{
+  error_t err = 0;
+  short flags;
+  short delta;
+
+  switch (flavor) {
+  case NET_STATUS:
+    {
+      struct net_status *ns = (struct net_status *) status;
+
+      if (count != NET_STATUS_COUNT)
+       return D_INVALID_SIZE;
+
+      /* We allow only the flags to change.  */
+      if (ns->min_packet_size != ifp->if_header_size
+          || ns->max_packet_size != ifp->if_header_size + ifp->if_mtu
+          || ns->header_format != ifp->if_header_format
+          || ns->header_size != ifp->if_header_size
+          || ns->address_size != ifp->if_address_size
+          || ns->mapped_size != 0)
+       return D_INVALID_OPERATION;
+
+      flags = ns->flags;
+      goto change_flags;
+    }
+
+  case NET_FLAGS:
+    if (count != 1)
+      return D_INVALID_SIZE;
+    flags = status[0];
+
+  change_flags:
+    /* What needs to change?  */
+    delta = flags ^ ifp->if_flags;
+
+    /* Only allow specific flag changes.  */
+    if ((delta
+        /* AIUI IFF_RUNNING shouldn't be toggle-able, but we let this slip.  */
+        & ~(IFF_UP | IFF_RUNNING | IFF_DEBUG | IFF_PROMISC | IFF_ALLMULTI))
+       != 0)
+      return D_INVALID_OPERATION;
+
+
+    if (! err && (delta & IFF_PROMISC))
+      {
+       /* The ethernet device is always in promiscuous mode, and we
+          forward all packets.  If this flag is cleared for a virtual
+          device, we should filter traffic based on observed MAC
+          addresses from this interface.  */
+       /* XXX: Implement this.  */
+      }
+
+    if (! err && (delta & IFF_ALLMULTI))
+      {
+       /* We activate IFF_ALLMULTI if at least one virtual device
+          wants it, and deactivate it otherwise.  */
+       if ((flags & IFF_ALLMULTI)
+           || foreach_dev_do (wants_all_multi_p))
+         err = eth_set_clear_flags (IFF_ALLMULTI, 0);
+       else
+         err = eth_set_clear_flags (0, IFF_ALLMULTI);
+      }
+
+    if (! err)
+      ifp->if_flags = flags;
+    break;
+
+  case NET_ADDRESS:
+    {
+      int addr_byte_count;
+      int addr_int_count;
+      int i;
+
+      addr_byte_count = ifp->if_address_size;
+      addr_int_count = (addr_byte_count + (sizeof(int)-1)) / sizeof(int);
+
+      if (count != addr_int_count)
+       return D_INVALID_SIZE;
+
+      memcpy(ifp->if_address, status, addr_byte_count);
+      for (i = 0; i < addr_int_count; i++) {
+       int word;
+
+       word = status[i];
+       status[i] = htonl(word);
+      }
+      break;
+    }
+
+  default:
+    return D_INVALID_OPERATION;
+  }
+
+  return err;
+}
diff --git a/eth-multiplexer/device_impl.c b/eth-multiplexer/device_impl.c
index 4796d5b..d7c8bee 100644
--- a/eth-multiplexer/device_impl.c
+++ b/eth-multiplexer/device_impl.c
@@ -51,7 +51,8 @@ ds_device_open (mach_port_t master_port, mach_port_t 
reply_port,
                mach_msg_type_name_t *devicetype)
 {
   struct vether_device *dev;
-  struct protid *pi = ports_lookup_port (netfs_port_bucket, master_port, 0);
+  struct protid *pi = ports_lookup_port (netfs_port_bucket, master_port,
+                                         netfs_protid_class);
   if (pi == NULL)
     return D_NO_SUCH_DEVICE;
 
@@ -106,10 +107,11 @@ ds_device_write (struct vether_device *vdev, mach_port_t 
reply_port,
 {
   kern_return_t ret = 0;
   if (vdev == NULL)
-    {
-      vm_deallocate (mach_task_self (), (vm_address_t) data, datalen);
-      return D_NO_SUCH_DEVICE;
-    }
+    return D_NO_SUCH_DEVICE;
+
+  if ((vdev->if_flags & IFF_UP) == 0)
+    return D_DEVICE_DOWN;
+
   /* The packet is forwarded to all virtual interfaces and
    * the interface which the multiplexer connects to. */
   broadcast_pack (data, datalen, vdev);
@@ -171,7 +173,7 @@ ds_device_set_status (struct vether_device *vdev, 
dev_flavor_t flavor,
 {
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  return D_INVALID_OPERATION;
+  return vdev_setstat (vdev, flavor, status, statuslen);
 }
 
 kern_return_t
diff --git a/eth-multiplexer/ethernet.c b/eth-multiplexer/ethernet.c
index 1f3a57c..c8849aa 100644
--- a/eth-multiplexer/ethernet.c
+++ b/eth-multiplexer/ethernet.c
@@ -24,7 +24,7 @@
 
 #include <string.h>
 #include <error.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <net/if.h>
 #include <sys/ioctl.h>
 
@@ -75,34 +75,32 @@ int ethernet_demuxer (mach_msg_header_t *inp,
   return 1;
 }
 
-int set_promisc (char *dev_name, mach_port_t ether_port, int is_promisc)
+error_t
+eth_set_clear_flags (int set_flags, int clear_flags)
 {
-#ifndef NET_FLAGS
-#define NET_FLAGS (('n'<<16) + 4)
-#endif
+  error_t err;
   int flags;
-  int ret;
   size_t count;
 
-  debug ("set_promisc is called, is_promisc: %d\n", is_promisc);
   count = 1;
-  ret = device_get_status (ether_port, NET_FLAGS, (dev_status_t) &flags,
+  err = device_get_status (ether_port, NET_FLAGS, (dev_status_t) &flags,
                            &count);
-  if (ret)
+  if (err)
     {
-      error (0, ret, "device_get_status");
-      return -1;
+      error (0, err, "device_get_status");
+      return err;
     }
-  if (is_promisc)
-    flags |= IFF_PROMISC;
-  else
-    flags &= ~IFF_PROMISC;
-  ret = device_set_status(ether_port, NET_FLAGS, (dev_status_t) &flags, 1);
-  if (ret)
+
+  flags |= set_flags;
+  flags &= ~clear_flags;
+
+  err = device_set_status(ether_port, NET_FLAGS, (dev_status_t) &flags, 1);
+  if (err)
     {
-      error (0, ret, "device_set_status");
-      return -1;
+      error (0, err, "device_set_status");
+      return err;
     }
+
   return 0;
 }
 
@@ -112,7 +110,7 @@ get_ethernet_address (mach_port_t port, char *address)
   error_t err;
   int net_address[2];
   size_t count = 2;
-  assert (count * sizeof (int) >= ETH_ALEN);
+  assert_backtrace (count * sizeof (int) >= ETH_ALEN);
 
   err = device_get_status (port, NET_ADDRESS, net_address, &count);
   if (err)
@@ -130,7 +128,7 @@ int ethernet_open (char *dev_name, device_t master_device,
 {
   error_t err;
 
-  assert (ether_port == MACH_PORT_NULL);
+  assert_backtrace (ether_port == MACH_PORT_NULL);
 
   err = ports_create_port (etherreadclass, etherport_bucket,
                           sizeof (struct port_info), &readpt);
@@ -153,7 +151,9 @@ int ethernet_open (char *dev_name, device_t master_device,
   if (err)
     error (2, err, "device_set_filter: %s", dev_name);
 
-  set_promisc (dev_name, ether_port, 1);
+  err = eth_set_clear_flags (IFF_PROMISC, 0);
+  if (err)
+    error (2, err, "eth_set_clear_flags");
 
   err = get_ethernet_address (ether_port, ether_address);
   if (err)
@@ -164,7 +164,12 @@ int ethernet_open (char *dev_name, device_t master_device,
 
 int ethernet_close (char *dev_name)
 {
-  set_promisc (dev_name, ether_port, 0);
+  error_t err;
+
+  err = eth_set_clear_flags (0, IFF_PROMISC);
+  if (err)
+    error (2, err, "eth_set_clear_flags");
+
   return 0;
 }
 
diff --git a/eth-multiplexer/ethernet.h b/eth-multiplexer/ethernet.h
index a2b2f5e..e8b766f 100644
--- a/eth-multiplexer/ethernet.h
+++ b/eth-multiplexer/ethernet.h
@@ -36,6 +36,7 @@ int ethernet_open (char *dev_name, device_t master_device,
 int ethernet_close (char *dev_name);
 int ethernet_demuxer (mach_msg_header_t *inp,
                      mach_msg_header_t *outp);
+error_t eth_set_clear_flags (int set_flags, int clear_flags);
 
 #endif
 
diff --git a/eth-multiplexer/vdev.c b/eth-multiplexer/vdev.c
index 47dc8d2..9a1f7b2 100644
--- a/eth-multiplexer/vdev.c
+++ b/eth-multiplexer/vdev.c
@@ -145,7 +145,12 @@ add_vdev (char *name, int size,
   vdev->if_mtu = ETH_MTU;
   vdev->if_header_format = HDR_ETHERNET;
   vdev->if_address_size = ETH_ALEN;
-  vdev->if_flags = 0;
+  vdev->if_flags = (/* The interface is 'UP' on creation.  */
+                    IFF_UP
+                    /* We have allocated resources for it.  */
+                    | IFF_RUNNING
+                    /* Advertise ethernet-style capabilities.  */
+                    | IFF_BROADCAST | IFF_MULTICAST);
 
   /* Compute a pseudo-random but stable ethernet address.  */
   vdev->if_address[0] = 0x52;
@@ -203,8 +208,12 @@ broadcast_pack (char *data, int datalen, struct 
vether_device *from_vdev)
 {
   int internal_deliver_pack (struct vether_device *vdev)
     {
+      /* Skip current interface.  */
       if (from_vdev == vdev)
        return 0;
+      /* Skip interfaces that are down.  */
+      if ((vdev->if_flags & IFF_UP) == 0)
+        return 0;
       return deliver_pack (data, datalen, vdev);
     }
 
@@ -247,6 +256,9 @@ broadcast_msg (struct net_rcv_msg *msg)
 
   int internal_deliver_msg (struct vether_device *vdev)
     {
+      /* Skip interfaces that are down.  */
+      if ((vdev->if_flags & IFF_UP) == 0)
+        return 0;
       return deliver_msg (msg, vdev);
     }
 
diff --git a/eth-multiplexer/vdev.h b/eth-multiplexer/vdev.h
index c98c441..3c3c320 100644
--- a/eth-multiplexer/vdev.h
+++ b/eth-multiplexer/vdev.h
@@ -79,6 +79,8 @@ int foreach_dev_do (dev_act_func func);
 /* dev_stat.c */
 io_return_t dev_getstat (struct vether_device *, dev_flavor_t,
                          dev_status_t, natural_t *);
+io_return_t vdev_setstat (struct vether_device *, dev_flavor_t,
+                          dev_status_t, size_t);
 
 
 #endif
diff --git a/exec/elfcore.c b/exec/elfcore.c
index 3e4551e..12ecf34 100644
--- a/exec/elfcore.c
+++ b/exec/elfcore.c
@@ -40,7 +40,7 @@
 #endif
 
 #include <mach/thread_status.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #ifdef i386_THREAD_STATE
 # define ELF_MACHINE           EM_386
@@ -56,9 +56,9 @@ fetch_thread_regset (thread_t thread, prgregset_t *gregs)
     prgregset_t gregs;
   } *u = (void *) gregs;
   mach_msg_type_number_t count = i386_THREAD_STATE_COUNT;
-  assert (sizeof (struct i386_thread_state) < sizeof (prgregset_t));
-  assert (offsetof (struct i386_thread_state, gs) == REG_GS * 4);
-  assert (offsetof (struct i386_thread_state, eax) == REG_EAX * 4);
+  assert_backtrace (sizeof (struct i386_thread_state) < sizeof (prgregset_t));
+  assert_backtrace (offsetof (struct i386_thread_state, gs) == REG_GS * 4);
+  assert_backtrace (offsetof (struct i386_thread_state, eax) == REG_EAX * 4);
 
   (void) thread_get_state (thread, i386_THREAD_STATE,
                           (thread_state_t) &u->state, &count);
@@ -82,7 +82,7 @@ fetch_thread_fpregset (thread_t thread, prfpregset_t *fpregs)
                                  (thread_state_t) &st, &count);
   if (err == 0 && st.initialized)
     {
-      assert (sizeof *fpregs >= sizeof st.hw_state);
+      assert_backtrace (sizeof *fpregs >= sizeof st.hw_state);
       memcpy (fpregs, st.hw_state, sizeof st.hw_state);
     }
 }
@@ -96,7 +96,7 @@ static inline void
 fetch_thread_regset (thread_t thread, prgregset_t *gregs)
 {
   mach_msg_type_number_t count = ALPHA_THREAD_STATE_COUNT;
-  assert (sizeof (struct alpha_thread_state) <= sizeof (prgregset_t));
+  assert_backtrace (sizeof (struct alpha_thread_state) <= sizeof 
(prgregset_t));
   (void) thread_get_state (thread, ALPHA_THREAD_STATE,
                           (thread_state_t) gregs, &count);
   /* XXX
@@ -110,7 +110,7 @@ static inline void
 fetch_thread_fpregset (thread_t thread, prfpregset_t *fpregs)
 {
   mach_msg_type_number_t count = ALPHA_FLOAT_STATE_COUNT;
-  assert (sizeof (struct alpha_float_state) == sizeof *fpregs);
+  assert_backtrace (sizeof (struct alpha_float_state) == sizeof *fpregs);
   (void) thread_get_state (thread, ALPHA_FLOAT_STATE,
                           (thread_state_t) fpregs, &count);
 }
diff --git a/exec/exec.c b/exec/exec.c
index d6dd5d8..d78c54c 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -368,7 +368,7 @@ map (struct execdata *e, off_t posn, size_t len)
       char *buffer = map_buffer (e);
       mach_msg_type_number_t nread = map_vsize (e);
 
-      assert (e->file_data == NULL); /* Must be first or second case.  */
+      assert_backtrace (e->file_data == NULL); /* Must be first or second 
case.  */
 
       /* Read as much as we can get into the buffer right now.  */
       e->error = io_read (e->file, &buffer, &nread, posn, round_page (len));
@@ -773,6 +773,8 @@ servercopy (void *arg, mach_msg_type_number_t argsize, 
boolean_t argcopy,
 {
   if (! argcopy)
     return arg;
+  if (! argsize)
+    return NULL;
 
   /* ARG came in-line, so we must copy it.  */
   void *copy;
diff --git a/exec/hashexec.c b/exec/hashexec.c
index 6337f0a..68b4881 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -274,7 +274,7 @@ check_hashbang (struct execdata *e,
              if (memchr (argv, '\0', argvlen) == NULL)
                {
                  name = alloca (argvlen + 1);
-                 bcopy (argv, name, argvlen);
+                 memcpy (name, argv, argvlen);
                  name[argvlen] = '\0';
                }
              else
diff --git a/exec/hostarch.c b/exec/hostarch.c
index a565027..363fda6 100644
--- a/exec/hostarch.c
+++ b/exec/hostarch.c
@@ -42,7 +42,7 @@ elf_machine_matches_host (ElfW(Half) e_machine)
                       (host_info_t) &hostinfo, &hostinfocnt);
       if (err)
        return err;
-      assert (hostinfocnt == HOST_BASIC_INFO_COUNT);
+      assert_backtrace (hostinfocnt == HOST_BASIC_INFO_COUNT);
     }
 
 #define CACHE(test) ({ __label__ here; host_type = &&here; \
diff --git a/exec/main.c b/exec/main.c
index 2658df5..30b20da 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -199,7 +199,7 @@ main (int argc, char **argv)
   if (MACH_PORT_VALID (opt_device_master))
     {
       err = open_console (opt_device_master);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       mach_port_deallocate (mach_task_self (), opt_device_master);
     }
 
@@ -322,9 +322,9 @@ S_exec_init (struct trivfs_protid *protid,
     mach_port_t right;
 
     err = iohelp_create_empty_iouser (&user);
-    assert_perror (err);
+    assert_perror_backtrace (err);
     err = trivfs_open (fsys, user, 0, MACH_PORT_NULL, &cred);
-    assert_perror (err);
+    assert_perror_backtrace (err);
 
     right = ports_get_send_right (cred);
     proc_execdata_notify (procserver, right, MACH_MSG_TYPE_COPY_SEND);
@@ -332,10 +332,10 @@ S_exec_init (struct trivfs_protid *protid,
   }
 
   err = get_privileged_ports (&host_priv, &device_master);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   err = open_console (device_master);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   mach_port_deallocate (mach_task_self (), device_master);
 
   proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION);
@@ -347,7 +347,7 @@ S_exec_init (struct trivfs_protid *protid,
 
       /* Fall back to abusing the message port lookup.  */
       err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
   mach_port_deallocate (mach_task_self (), procserver);
 
@@ -355,7 +355,7 @@ S_exec_init (struct trivfs_protid *protid,
      run once we call it. */
   err = startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL,
                                "exec", host_priv);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   mach_port_deallocate (mach_task_self (), startup);
 
   mach_port_deallocate (mach_task_self (), host_priv);
diff --git a/exec/priv.h b/exec/priv.h
index 733f35c..be08580 100644
--- a/exec/priv.h
+++ b/exec/priv.h
@@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public 
License
 along with the GNU Hurd; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/ext2fs/balloc.c b/ext2fs/balloc.c
index 0b9e5a5..8ebd11c 100644
--- a/ext2fs/balloc.c
+++ b/ext2fs/balloc.c
@@ -166,7 +166,7 @@ ext2_new_block (block_t goal,
   ext2_debug ("goal=%u", goal);
 
 repeat:
-  assert (bh == NULL);
+  assert_backtrace (bh == NULL);
   /*
      * First, test whether the goal block is free.
    */
@@ -272,7 +272,7 @@ repeat:
       pthread_spin_unlock (&global_lock);
       return 0;
     }
-  assert (bh == NULL);
+  assert_backtrace (bh == NULL);
   bh = disk_cache_block_ref (gdp->bg_block_bitmap);
   r = memscan (bh, 0, sblock->s_blocks_per_group >> 3);
   j = (r - bh) << 3;
@@ -291,7 +291,7 @@ repeat:
     }
 
 search_back:
-  assert (bh != NULL);
+  assert_backtrace (bh != NULL);
   /*
      * We have succeeded in finding a free byte in the block
      * bitmap.  Now search backwards up to 7 bits to find the
@@ -300,7 +300,7 @@ search_back:
   for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh); k++, j--);
 
 got_block:
-  assert (bh != NULL);
+  assert_backtrace (bh != NULL);
 
   ext2_debug ("using block group %d (%d)", i, gdp->bg_free_blocks_count);
 
@@ -383,7 +383,7 @@ got_block:
   sblock_dirty = 1;
 
  sync_out:
-  assert (bh == NULL);
+  assert_backtrace (bh == NULL);
   pthread_spin_unlock (&global_lock);
   alloc_sync (0);
 
diff --git a/ext2fs/dir.c b/ext2fs/dir.c
index 87a8a04..bcf9046 100644
--- a/ext2fs/dir.c
+++ b/ext2fs/dir.c
@@ -153,7 +153,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
   int looped;
 
   if ((type == REMOVE) || (type == RENAME))
-    assert (npp);
+    assert_backtrace (npp);
 
   if (npp)
     *npp = 0;
@@ -318,7 +318,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
            goto out;
        }
       else
-       assert (0);
+       assert_backtrace (0);
     }
 
   if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING)
@@ -349,7 +349,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
 
   if (np)
     {
-      assert (npp);
+      assert_backtrace (npp);
       if (err)
        {
          if (!spec_dotdot)
@@ -494,7 +494,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int 
idx,
            diskfs_node_disknode (dp)->dirents[i] = -1;
        }
       /* Make sure the count is correct if there is one now. */
-      assert (diskfs_node_disknode (dp)->dirents[idx] == -1
+      assert_backtrace (diskfs_node_disknode (dp)->dirents[idx] == -1
              || diskfs_node_disknode (dp)->dirents[idx] == nentries);
       diskfs_node_disknode (dp)->dirents[idx] = nentries;
 
@@ -537,9 +537,9 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
   error_t err;
   size_t oldsize = 0;
 
-  assert (ds->type == CREATE);
+  assert_backtrace (ds->type == CREATE);
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   dp->dn_set_mtime = 1;
 
@@ -551,7 +551,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
     {
     case TAKE:
       /* We are supposed to consume this slot. */
-      assert (ds->entry->inode == 0 && ds->entry->rec_len >= needed);
+      assert_backtrace (ds->entry->inode == 0 && ds->entry->rec_len >= needed);
 
       new = ds->entry;
       break;
@@ -560,7 +560,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
       /* We are supposed to take the extra space at the end
         of this slot. */
       oldneeded = EXT2_DIR_REC_LEN (ds->entry->name_len);
-      assert (ds->entry->rec_len - oldneeded >= needed);
+      assert_backtrace (ds->entry->rec_len - oldneeded >= needed);
 
       new = (struct ext2_dir_entry_2 *) ((vm_address_t) ds->entry + oldneeded);
 
@@ -583,7 +583,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
 
          if (from->inode != 0)
            {
-             assert (fromoff >= tooff);
+             assert_backtrace (fromoff >= tooff);
 
              memmove (to, from, fromreclen);
              to->rec_len = EXT2_DIR_REC_LEN (to->name_len);
@@ -594,7 +594,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
        }
 
       totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff;
-      assert (totfreed >= needed);
+      assert_backtrace (totfreed >= needed);
 
       new = (struct ext2_dir_entry_2 *) tooff;
       new->rec_len = totfreed;
@@ -602,7 +602,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
 
     case EXTEND:
       /* Extend the file. */
-      assert (needed <= DIRBLKSIZ);
+      assert_backtrace (needed <= DIRBLKSIZ);
 
       oldsize = dp->dn_stat.st_size;
       if ((off_t)(oldsize + DIRBLKSIZ) != (dp->dn_stat.st_size + DIRBLKSIZ))
@@ -639,7 +639,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
 
     default:
       new = 0;
-      assert (! "impossible: bogus status field in dirstat");
+      assert_backtrace (! "impossible: bogus status field in dirstat");
     }
 
   /* NEW points to the directory entry being written, and its
@@ -716,16 +716,16 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
 error_t
 diskfs_dirremove_hard (struct node *dp, struct dirstat *ds)
 {
-  assert (ds->type == REMOVE);
-  assert (ds->stat == HERE_TIS);
+  assert_backtrace (ds->type == REMOVE);
+  assert_backtrace (ds->stat == HERE_TIS);
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   if (ds->preventry == 0)
     ds->entry->inode = 0;
   else
     {
-      assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry
+      assert_backtrace ((vm_address_t) ds->entry - (vm_address_t) ds->preventry
              == ds->preventry->rec_len);
       ds->preventry->rec_len += ds->entry->rec_len;
     }
@@ -756,10 +756,10 @@ diskfs_dirremove_hard (struct node *dp, struct dirstat 
*ds)
 error_t
 diskfs_dirrewrite_hard (struct node *dp, struct node *np, struct dirstat *ds)
 {
-  assert (ds->type == RENAME);
-  assert (ds->stat == HERE_TIS);
+  assert_backtrace (ds->type == RENAME);
+  assert_backtrace (ds->stat == HERE_TIS);
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   ds->entry->inode = np->cache_id;
   dp->dn_set_mtime = 1;
@@ -790,7 +790,7 @@ diskfs_dirempty (struct node *dp, struct protid *cred)
   err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0,
                1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0);
   mach_port_deallocate (mach_task_self (), memobj);
-  assert (!err);
+  assert_backtrace (!err);
 
   diskfs_set_node_atime (dp);
 
@@ -823,7 +823,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds)
 {
   if (ds->type != LOOKUP)
     {
-      assert (ds->mapbuf);
+      assert_backtrace (ds->mapbuf);
       munmap ((caddr_t) ds->mapbuf, ds->mapextent);
       ds->type = LOOKUP;
     }
@@ -843,13 +843,13 @@ count_dirents (struct node *dp, block_t nb, char *buf)
   int count = 0;
   error_t err;
 
-  assert (diskfs_node_disknode (dp)->dirents);
-  assert ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size);
+  assert_backtrace (diskfs_node_disknode (dp)->dirents);
+  assert_backtrace ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size);
 
   err = diskfs_node_rdwr (dp, buf, nb * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &amt);
   if (err)
     return err;
-  assert (amt == DIRBLKSIZ);
+  assert_backtrace (amt == DIRBLKSIZ);
 
   for (offinblk = buf;
        offinblk < buf + DIRBLKSIZ;
@@ -860,7 +860,7 @@ count_dirents (struct node *dp, block_t nb, char *buf)
        count++;
     }
 
-  assert (diskfs_node_disknode (dp)->dirents[nb] == -1
+  assert_backtrace (diskfs_node_disknode (dp)->dirents[nb] == -1
          || diskfs_node_disknode (dp)->dirents[nb] == count);
   diskfs_node_disknode (dp)->dirents[nb] = count;
   return 0;
@@ -977,7 +977,7 @@ diskfs_get_directs (struct node *dp,
                                  0, 0, &checklen);
          if (err)
            return err;
-         assert (checklen == DIRBLKSIZ);
+         assert_backtrace (checklen == DIRBLKSIZ);
          bufvalid = 1;
        }
       for (i = 0, bufp = buf;
@@ -985,7 +985,7 @@ diskfs_get_directs (struct node *dp,
           bufp += ((struct ext2_dir_entry_2 *)bufp)->rec_len, i++)
        ;
       /* Make sure we didn't run off the end. */
-      assert (bufp - buf < DIRBLKSIZ);
+      assert_backtrace (bufp - buf < DIRBLKSIZ);
     }
 
   i = 0;
@@ -1002,7 +1002,7 @@ diskfs_get_directs (struct node *dp,
                                  0, 0, &checklen);
          if (err)
            return err;
-         assert (checklen == DIRBLKSIZ);
+         assert_backtrace (checklen == DIRBLKSIZ);
          bufvalid = 1;
          bufp = buf;
        }
@@ -1027,7 +1027,7 @@ diskfs_get_directs (struct node *dp,
          /* See if this record would run over the end of the return buffer. */
          if (bufsiz == 0)
            /* It shouldn't ever, as we calculated the worst case size.  */
-           assert (datap + rec_len <= *data + allocsize);
+           assert_backtrace (datap + rec_len <= *data + allocsize);
          else
            /* It's ok if it does, just leave off returning this entry.  */
            if (datap + rec_len > *data + allocsize)
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index 2104dba..83a6c90 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -29,7 +29,7 @@
 #include <hurd/store.h>
 #include <hurd/diskfs.h>
 #include <hurd/ihash.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 #include <sys/mman.h>
 
@@ -119,9 +119,13 @@ void pokel_inherit (struct pokel *pokel, struct pokel 
*from);
 
 #include <stdint.h>
 
+/* Forward declarations for the following functions that are usually
+   inlined.  In case inlining is disabled, or inlining is not
+   applicable, or a reference is taken to one of these functions, an
+   implementation is provided in 'xinl.c'.  */
 extern int test_bit (unsigned num, unsigned char *bitmap);
-
 extern int set_bit (unsigned num, unsigned char *bitmap);
+extern int clear_bit (unsigned num, unsigned char *bitmap);
 
 #if defined(__USE_EXTERN_INLINES) || defined(EXT2FS_DEFINE_EI)
 /* Returns TRUE if bit NUM is set in BITMAP.  */
@@ -354,6 +358,15 @@ unsigned long next_generation;
 /* pointer to in-memory block -> index in disk_cache_info */
 #define bptr_index(ptr) (((char *)ptr - (char *)disk_cache) >> log2_block_size)
 
+/* Forward declarations for the following functions that are usually
+   inlined.  In case inlining is disabled, or inlining is not
+   applicable, or a reference is taken to one of these functions, an
+   implementation is provided in 'xinl.c'.  */
+extern char *boffs_ptr (off_t offset);
+extern off_t bptr_offs (void *ptr);
+
+#if defined(__USE_EXTERN_INLINES) || defined(EXT2FS_DEFINE_EI)
+
 /* byte offset on disk --> pointer to in-memory block */
 EXT2FS_EI char *
 boffs_ptr (off_t offset)
@@ -362,7 +375,7 @@ boffs_ptr (off_t offset)
   pthread_mutex_lock (&disk_cache_lock);
   char *ptr = hurd_ihash_find (disk_cache_bptr, block);
   pthread_mutex_unlock (&disk_cache_lock);
-  assert (ptr);
+  assert_backtrace (ptr);
   ptr += offset % block_size;
   ext2_debug ("(%lld) = %p", offset, ptr);
   return ptr;
@@ -374,17 +387,19 @@ bptr_offs (void *ptr)
 {
   vm_offset_t mem_offset = (char *)ptr - (char *)disk_cache;
   off_t offset;
-  assert (mem_offset < disk_cache_size);
+  assert_backtrace (mem_offset < disk_cache_size);
   pthread_mutex_lock (&disk_cache_lock);
   offset = (off_t) disk_cache_info[boffs_block (mem_offset)].block
     << log2_block_size;
-  assert (offset || mem_offset < block_size);
+  assert_backtrace (offset || mem_offset < block_size);
   offset += mem_offset % block_size;
   pthread_mutex_unlock (&disk_cache_lock);
   ext2_debug ("(%p) = %lld", ptr, offset);
   return offset;
 }
 
+#endif /* Use extern inlines.  */
+
 /* block num --> pointer to in-memory block */
 #define bptr(block) boffs_ptr(boffs(block))
 /* pointer to in-memory block --> block num */
@@ -398,7 +413,12 @@ struct ext2_group_desc *group_desc_image;
 
 #define inode_group_num(inum) (((inum) - 1) / sblock->s_inodes_per_group)
 
-extern struct ext2_inode *dino (ino_t inum);
+/* Forward declarations for the following functions that are usually
+   inlined.  In case inlining is disabled, or inlining is not
+   applicable, or a reference is taken to one of these functions, an
+   implementation is provided in 'xinl.c'.  */
+extern struct ext2_inode * dino_ref (ino_t inum);
+extern void _dino_deref (struct ext2_inode *inode);
 
 #if defined(__USE_EXTERN_INLINES) || defined(EXT2FS_DEFINE_EI)
 /* Convert an inode number to the dinode on disk. */
@@ -447,6 +467,10 @@ struct pokel global_pokel;
 unsigned char *modified_global_blocks;
 extern pthread_spinlock_t modified_global_blocks_lock;
 
+/* Forward declarations for the following functions that are usually
+   inlined.  In case inlining is disabled, or inlining is not
+   applicable, or a reference is taken to one of these functions, an
+   implementation is provided in 'xinl.c'.  */
 extern int global_block_modified (block_t block);
 extern void record_global_poke (void *ptr);
 extern void sync_global_ptr (void *bptr, int wait);
@@ -481,7 +505,7 @@ record_global_poke (void *ptr)
   block_t block = boffs_block (bptr_offs (ptr));
   void *block_ptr = bptr (block);
   ext2_debug ("(%p = %p)", ptr, block_ptr);
-  assert (disk_cache_block_is_ref (block));
+  assert_backtrace (disk_cache_block_is_ref (block));
   global_block_modified (block);
   pokel_add (&global_pokel, block_ptr, block_size);
 }
@@ -507,7 +531,7 @@ record_indir_poke (struct node *node, void *ptr)
   block_t block = boffs_block (bptr_offs (ptr));
   void *block_ptr = bptr (block);
   ext2_debug ("(%llu, %p)", node->cache_id, ptr);
-  assert (disk_cache_block_is_ref (block));
+  assert_backtrace (disk_cache_block_is_ref (block));
   global_block_modified (block);
   pokel_add (&diskfs_node_disknode (node)->indir_pokel, block_ptr, block_size);
 }
diff --git a/ext2fs/getblk.c b/ext2fs/getblk.c
index 0d0fab1..43daf6c 100644
--- a/ext2fs/getblk.c
+++ b/ext2fs/getblk.c
@@ -122,7 +122,7 @@ inode_getblk (struct node *node, int nr, int create, int 
zero,
   block_t hint;
 #endif
 
-  assert (0 <= nr && nr < EXT2_N_BLOCKS);
+  assert_backtrace (0 <= nr && nr < EXT2_N_BLOCKS);
 
   *result = diskfs_node_disknode (node)->info.i_data[nr];
   if (*result)
diff --git a/ext2fs/hyper.c b/ext2fs/hyper.c
index 91d9d12..6ef2b8c 100644
--- a/ext2fs/hyper.c
+++ b/ext2fs/hyper.c
@@ -45,7 +45,7 @@ allocate_mod_map (void)
       mod_map_size = sblock->s_blocks_count >> 3;
       modified_global_blocks = mmap (0, mod_map_size, PROT_READ|PROT_WRITE,
                                     MAP_ANON, 0, 0);
-      assert (modified_global_blocks != (void *) -1);
+      assert_backtrace (modified_global_blocks != (void *) -1);
     }
   else
     modified_global_blocks = 0;
@@ -161,7 +161,7 @@ get_hypermetadata (void)
   if (zeroblock == 0)
     {
       zeroblock = (vm_address_t) mmap (0, block_size, PROT_READ, MAP_ANON, 0, 
0);
-      assert (zeroblock != (vm_address_t) MAP_FAILED);
+      assert_backtrace (zeroblock != (vm_address_t) MAP_FAILED);
     }
 }
 
diff --git a/ext2fs/ialloc.c b/ext2fs/ialloc.c
index 71bfb8c..b14ddee 100644
--- a/ext2fs/ialloc.c
+++ b/ext2fs/ialloc.c
@@ -58,7 +58,7 @@ diskfs_free_node (struct node *np, mode_t old_mode)
   struct ext2_group_desc *gdp;
   ino_t inum = np->cache_id;
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   ext2_debug ("freeing inode %u", inum);
 
@@ -125,7 +125,7 @@ ext2_alloc_inode (ino_t dir_inum, mode_t mode)
   pthread_spin_lock (&global_lock);
 
 repeat:
-  assert (bh == NULL);
+  assert_backtrace (bh == NULL);
   gdp = NULL;
   i = 0;
 
@@ -267,7 +267,7 @@ repeat:
   sblock_dirty = 1;
 
  sync_out:
-  assert (bh == NULL);
+  assert_backtrace (bh == NULL);
   pthread_spin_unlock (&global_lock);
   alloc_sync (0);
 
@@ -298,7 +298,7 @@ diskfs_alloc_node (struct node *dir, mode_t mode, struct 
node **node)
   struct stat *st;
   ino_t inum;
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   inum = ext2_alloc_inode (dir->cache_id, mode);
 
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index 17dded6..472c1b4 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -74,7 +74,7 @@ diskfs_node_norefs (struct node *np)
 {
   if (diskfs_node_disknode (np)->dirents)
     free (diskfs_node_disknode (np)->dirents);
-  assert (!diskfs_node_disknode (np)->pager);
+  assert_backtrace (!diskfs_node_disknode (np)->pager);
 
   /* Move any pending writes of indirect blocks.  */
   pokel_inherit (&global_pokel, &diskfs_node_disknode (np)->indir_pokel);
@@ -362,7 +362,7 @@ write_node (struct node *np)
     {
       struct ext2_inode_info *info = &diskfs_node_disknode (np)->info;
 
-      assert (!diskfs_readonly);
+      assert_backtrace (!diskfs_readonly);
 
       ext2_debug ("writing inode %d to disk", np->cache_id);
 
@@ -395,10 +395,10 @@ write_node (struct node *np)
       else
        /* No hurd extensions should be turned on.  */
        {
-         assert ((st->st_uid & ~0xFFFF) == 0);
-         assert ((st->st_gid & ~0xFFFF) == 0);
-         assert ((st->st_mode & ~0xFFFF) == 0);
-         assert (np->author_tracks_uid && st->st_author == st->st_uid);
+         assert_backtrace ((st->st_uid & ~0xFFFF) == 0);
+         assert_backtrace ((st->st_gid & ~0xFFFF) == 0);
+         assert_backtrace ((st->st_mode & ~0xFFFF) == 0);
+         assert_backtrace (np->author_tracks_uid && st->st_author == 
st->st_uid);
        }
 
       di->i_links_count = st->st_nlink;
@@ -551,7 +551,7 @@ diskfs_set_translator (struct node *np, const char *name, 
unsigned namelen,
 {
   error_t err;
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   if (sblock->s_creator_os != EXT2_OS_HURD)
     return EOPNOTSUPP;
@@ -769,7 +769,7 @@ write_symlink (struct node *node, const char *target)
   if (len > MAX_INODE_SYMLINK)
     return EINVAL;
 
-  assert (node->dn_stat.st_blocks == 0);
+  assert_backtrace (node->dn_stat.st_blocks == 0);
 
   memcpy (diskfs_node_disknode (node)->info.i_data, target, len);
   node->dn_stat.st_size = len - 1;
@@ -786,7 +786,7 @@ read_symlink (struct node *node, char *target)
   if (node->dn_stat.st_blocks)
     return EINVAL;
 
-  assert (node->dn_stat.st_size < MAX_INODE_SYMLINK);
+  assert_backtrace (node->dn_stat.st_size < MAX_INODE_SYMLINK);
 
   memcpy (target, diskfs_node_disknode (node)->info.i_data,
           node->dn_stat.st_size);
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index fd93dcb..a47c53c 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -108,7 +108,7 @@ get_page_buf ()
     }
   else
     {
-      assert (free_page_bufs == 0);
+      assert_backtrace (free_page_bufs == 0);
       buf = mmap (0, vm_page_size * FREE_PAGE_BUFS,
                  PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
       if (buf == MAP_FAILED)
@@ -409,7 +409,7 @@ file_pager_write_page (struct node *node, vm_offset_t 
offset, void *buf)
       err = find_block (node, offset, &block, &lock);
       if (err)
        break;
-      assert (block);
+      assert_backtrace (block);
       pending_blocks_add (&pb, block);
       offset += block_size;
       left -= block_size;
@@ -469,13 +469,13 @@ disk_pager_write_page (vm_offset_t page, void *buf)
   int index = offset >> log2_block_size;
 
   pthread_mutex_lock (&disk_cache_lock);
-  assert (disk_cache_info[index].block != DC_NO_BLOCK);
+  assert_backtrace (disk_cache_info[index].block != DC_NO_BLOCK);
   offset = ((store_offset_t) disk_cache_info[index].block << log2_block_size)
     + offset % block_size;
 #ifdef DEBUG_DISK_CACHE                        /* Not strictly needed.  */
-  assert ((disk_cache_info[index].last_read ^ DISK_CACHE_LAST_READ_XOR)
+  assert_backtrace ((disk_cache_info[index].last_read ^ 
DISK_CACHE_LAST_READ_XOR)
          == disk_cache_info[index].last_read_xor);
-  assert (disk_cache_info[index].last_read
+  assert_backtrace (disk_cache_info[index].last_read
          == disk_cache_info[index].block);
 #endif
   pthread_mutex_unlock (&disk_cache_lock);
@@ -657,7 +657,7 @@ error_t
 diskfs_grow (struct node *node, off_t size, struct protid *cred)
 {
   diskfs_check_readonly ();
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   if (size > node->allocsize)
     {
@@ -794,7 +794,7 @@ inline error_t
 pager_report_extent (struct user_pager_info *pager,
                     vm_address_t *offset, vm_size_t *size)
 {
-  assert (pager->type == DISK || pager->type == FILE_DATA);
+  assert_backtrace (pager->type == DISK || pager->type == FILE_DATA);
 
   *offset = 0;
 
@@ -817,7 +817,7 @@ pager_clear_user_data (struct user_pager_info *upi)
 
       pthread_spin_lock (&node_to_page_lock);
       pager = diskfs_node_disknode (upi->node)->pager;
-      assert (!pager || pager_get_upi (pager) != upi);
+      assert_backtrace (!pager || pager_get_upi (pager) != upi);
       pthread_spin_unlock (&node_to_page_lock);
 
       diskfs_nrele_light (upi->node);
@@ -944,11 +944,11 @@ disk_cache_init (void)
     + (round_block ((sizeof *group_desc_image) * groups_count)
        >> log2_block_size);
   ext2_debug ("%u-%u\n", fixed_first, fixed_last);
-  assert (fixed_last - fixed_first + 1 <= (block_t)disk_cache_blocks + 3);
+  assert_backtrace (fixed_last - fixed_first + 1 <= (block_t)disk_cache_blocks 
+ 3);
   for (block_t i = fixed_first; i <= fixed_last; i++)
     {
       disk_cache_block_ref (i);
-      assert (disk_cache_info[i-fixed_first].block == i);
+      assert_backtrace (disk_cache_info[i-fixed_first].block == i);
       disk_cache_info[i-fixed_first].flags |= DC_FIXED;
     }
 }
@@ -1020,7 +1020,7 @@ disk_cache_block_ref (block_t block)
   void *bptr;
   hurd_ihash_locp_t slot;
 
-  assert (block < store->size >> log2_block_size);
+  assert_backtrace (block < store->size >> log2_block_size);
 
   ext2_debug ("(%u)", block);
 
@@ -1048,7 +1048,7 @@ retry_ref:
        }
 
       /* Just increment reference and return.  */
-      assert (disk_cache_info[index].ref_count + 1
+      assert_backtrace (disk_cache_info[index].ref_count + 1
              > disk_cache_info[index].ref_count);
       disk_cache_info[index].ref_count++;
 
@@ -1113,7 +1113,7 @@ retry_ref:
 
   pthread_mutex_lock (&diskfs_disk_pager->interlock);
   int page = (bptr - disk_cache) / vm_page_size;
-  assert (page >= 0);
+  assert_backtrace (page >= 0);
   int is_incore = (page < diskfs_disk_pager->pagemapsize
                   && (diskfs_disk_pager->pagemap[page] & PM_INCORE));
   pthread_mutex_unlock (&diskfs_disk_pager->interlock);
@@ -1134,9 +1134,9 @@ retry_ref:
   if (disk_cache_info[index].block != DC_NO_BLOCK)
     /* Remove old association.  */
     hurd_ihash_remove (disk_cache_bptr, disk_cache_info[index].block);
-  assert (! (disk_cache_info[index].flags & DC_DONT_REUSE & ~DC_UNTOUCHED));
+  assert_backtrace (! (disk_cache_info[index].flags & DC_DONT_REUSE & 
~DC_UNTOUCHED));
   disk_cache_info[index].block = block;
-  assert (! disk_cache_info[index].ref_count);
+  assert_backtrace (! disk_cache_info[index].ref_count);
   disk_cache_info[index].ref_count = 1;
 
   /* All data structures are set up.  */
@@ -1184,11 +1184,11 @@ disk_cache_block_ref_ptr (void *ptr)
 
   pthread_mutex_lock (&disk_cache_lock);
   index = bptr_index (ptr);
-  assert (disk_cache_info[index].ref_count >= 1);
-  assert (disk_cache_info[index].ref_count + 1
+  assert_backtrace (disk_cache_info[index].ref_count >= 1);
+  assert_backtrace (disk_cache_info[index].ref_count + 1
          > disk_cache_info[index].ref_count);
   disk_cache_info[index].ref_count++;
-  assert (! (disk_cache_info[index].flags & DC_UNTOUCHED));
+  assert_backtrace (! (disk_cache_info[index].flags & DC_UNTOUCHED));
   ext2_debug ("(%p) (ref_count = %hu, flags = %#hx)",
              ptr,
              disk_cache_info[index].ref_count,
@@ -1201,7 +1201,7 @@ _disk_cache_block_deref (void *ptr)
 {
   int index;
 
-  assert (disk_cache <= ptr && ptr <= disk_cache + disk_cache_size);
+  assert_backtrace (disk_cache <= ptr && ptr <= disk_cache + disk_cache_size);
 
   pthread_mutex_lock (&disk_cache_lock);
   index = bptr_index (ptr);
@@ -1209,8 +1209,8 @@ _disk_cache_block_deref (void *ptr)
              ptr,
              disk_cache_info[index].ref_count - 1,
              disk_cache_info[index].flags);
-  assert (! (disk_cache_info[index].flags & DC_UNTOUCHED));
-  assert (disk_cache_info[index].ref_count >= 1);
+  assert_backtrace (! (disk_cache_info[index].flags & DC_UNTOUCHED));
+  assert_backtrace (disk_cache_info[index].ref_count >= 1);
   disk_cache_info[index].ref_count--;
   if (disk_cache_info[index].ref_count == 0 &&
       !(disk_cache_info[index].flags & DC_DONT_REUSE))
@@ -1298,7 +1298,7 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
 {
   mach_port_t right;
 
-  assert (S_ISDIR (node->dn_stat.st_mode)
+  assert_backtrace (S_ISDIR (node->dn_stat.st_mode)
          || S_ISREG (node->dn_stat.st_mode)
          || (S_ISLNK (node->dn_stat.st_mode)));
 
@@ -1309,7 +1309,7 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
       if (pager)
        {
          right = pager_get_port (pager);
-         assert (MACH_PORT_VALID (right));
+         assert_backtrace (MACH_PORT_VALID (right));
          pager_get_upi (pager)->max_prot |= prot;
        }
       else
diff --git a/ext2fs/pokel.c b/ext2fs/pokel.c
index 53dc513..3820942 100644
--- a/ext2fs/pokel.c
+++ b/ext2fs/pokel.c
@@ -102,7 +102,7 @@ pokel_add (struct pokel *pokel, void *loc, vm_size_t length)
       if (pl == NULL)
        {
          pl = malloc (sizeof (struct poke));
-         assert (pl);
+         assert_backtrace (pl);
        }
       else
        pokel->free_pokes = pl->next;
@@ -173,8 +173,8 @@ pokel_inherit (struct pokel *pokel, struct pokel *from)
 {
   struct poke *pokes, *last;
   
-  assert (pokel->pager == from->pager);
-  assert (pokel->image == from->image);
+  assert_backtrace (pokel->pager == from->pager);
+  assert_backtrace (pokel->image == from->image);
 
   /* Take all pokes from FROM...  */
   pthread_spin_lock (&from->lock);
diff --git a/ext2fs/truncate.c b/ext2fs/truncate.c
index 15e5541..265f7f2 100644
--- a/ext2fs/truncate.c
+++ b/ext2fs/truncate.c
@@ -223,7 +223,7 @@ poke_pages (memory_object_t obj, vm_offset_t start, 
vm_offset_t end)
 /* Flush all the data past the new size from the kernel.  Also force any
    delayed copies of this data to take place immediately.  (We are implicitly
    changing the data to zeros and doing it without the kernel's immediate
-   knowledge; accordingl we must help out the kernel thusly.) */
+   knowledge; accordingly we must help out the kernel thusly.) */
 static void
 force_delayed_copies (struct node *node, off_t length)
 {
@@ -286,7 +286,7 @@ diskfs_truncate (struct node *node, off_t length)
   off_t offset;
 
   diskfs_check_readonly ();
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   if (length >= node->dn_stat.st_size)
     return 0;
diff --git a/ext2fs/xattr.c b/ext2fs/xattr.c
index c703717..f6ea0f3 100644
--- a/ext2fs/xattr.c
+++ b/ext2fs/xattr.c
@@ -429,7 +429,7 @@ ext2_free_xattr_block (struct node *np)
 
   if (!EXT2_HAS_COMPAT_FEATURE (sblock, EXT2_FEATURE_COMPAT_EXT_ATTR))
     {
-      ext2_warning ("Filesystem has no support for extended attributes.");
+      ext2_debug ("Filesystem has no support for extended attributes.");
       return EOPNOTSUPP;
     }
 
@@ -445,7 +445,7 @@ ext2_free_xattr_block (struct node *np)
       goto cleanup;
     }
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   block = disk_cache_block_ref (blkno);
   header = EXT2_XATTR_HEADER (block);
@@ -663,7 +663,7 @@ ext2_set_xattr (struct node *np, const char *name, const 
char *value,
   size_t rest;
   error_t err;
   block_t blkno;
-  void *block;
+  void *block = NULL;
   struct ext2_inode *ei;
   struct ext2_xattr_header *header;
   struct ext2_xattr_entry *entry;
@@ -697,7 +697,7 @@ ext2_set_xattr (struct node *np, const char *name, const 
char *value,
       /* Allocate and initialize new block */
       block_t goal;
 
-      assert (!diskfs_readonly);
+      assert_backtrace (!diskfs_readonly);
 
       goal = sblock->s_first_data_block + np->dn->info.i_block_group *
        EXT2_BLOCKS_PER_GROUP (sblock);
diff --git a/fatfs/dir.c b/fatfs/dir.c
index b9b7ae5..2679a0c 100644
--- a/fatfs/dir.c
+++ b/fatfs/dir.c
@@ -191,7 +191,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
   int looped;
 
   if ((type == REMOVE) || (type == RENAME))
-    assert (npp);
+    assert_backtrace (npp);
 
   if (npp)
     *npp = 0;
@@ -352,7 +352,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
             goto out;
         }
       else
-        assert (0);
+        assert_backtrace (0);
     }
 
   if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING)
@@ -383,7 +383,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
 
   if (np)
     {
-      assert (npp);
+      assert_backtrace (npp);
       if (err)
         {
           if (!spec_dotdot)
@@ -590,9 +590,9 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
   error_t err;
   loff_t oldsize = 0;
 
-  assert (ds->type == CREATE);
+  assert_backtrace (ds->type == CREATE);
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   dp->dn_set_mtime = 1;
 
@@ -604,7 +604,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
     {
     case TAKE:
       /* We are supposed to consume this slot.  */
-      assert ((char)ds->entry->name[0] == FAT_DIR_NAME_LAST
+      assert_backtrace ((char)ds->entry->name[0] == FAT_DIR_NAME_LAST
              || (char)ds->entry->name[0] == FAT_DIR_NAME_DELETED);
 
       new = ds->entry;
@@ -612,7 +612,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
 
     case EXTEND:
       /* Extend the file.  */
-      assert (needed <= bytes_per_cluster);
+      assert_backtrace (needed <= bytes_per_cluster);
 
       oldsize = dp->dn_stat.st_size;
       while (oldsize + bytes_per_cluster > dp->allocsize)
@@ -636,7 +636,7 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
     case SHRINK:
     case COMPRESS:
     default:
-      assert(0);
+      assert_backtrace (0);
 
       /* COMPRESS will be used later, with long filenames, but shrink
         does not make sense on fat, as all entries have fixed
@@ -689,10 +689,10 @@ diskfs_direnter_hard (struct node *dp, const char *name, 
struct node *np,
 error_t
 diskfs_dirremove_hard (struct node *dp, struct dirstat *ds)
 {
-  assert (ds->type == REMOVE);
-  assert (ds->stat == HERE_TIS);
+  assert_backtrace (ds->type == REMOVE);
+  assert_backtrace (ds->stat == HERE_TIS);
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   dp->dn_set_mtime = 1;
 
@@ -729,22 +729,22 @@ diskfs_dirrewrite_hard (struct node *dp, struct node *np, 
struct dirstat *ds)
   entry_key.dir_inode = dp->cache_id;
   entry_key.dir_offset = ((int) ds->entry) - ((int) ds->mapbuf);
   err = vi_rlookup (entry_key, &inode, &vinode, 0);
-  assert (err != EINVAL);
+  assert_backtrace (err != EINVAL);
   if (err)
     return err;
 
   /*  Lookup the node, we already have a reference.  */
   oldnp = diskfs_cached_ifind (inode);
 
-  assert (ds->type == RENAME);
-  assert (ds->stat == HERE_TIS);
+  assert_backtrace (ds->type == RENAME);
+  assert_backtrace (ds->stat == HERE_TIS);
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   /*  The link count must be 0 so the file will be removed and
       the node will be dropped.  */
   oldnp->dn_stat.st_nlink--;
-  assert (!oldnp->dn_stat.st_nlink);
+  assert_backtrace (!oldnp->dn_stat.st_nlink);
   
   /* Close the file, free the referenced held by clients.  */
   fshelp_fetch_control (&oldnp->transbox, &control);
@@ -784,7 +784,7 @@ diskfs_dirempty (struct node *dp, struct protid *cred)
   err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0,
                 1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0);
   mach_port_deallocate (mach_task_self (), memobj);
-  assert (!err);
+  assert_backtrace (!err);
 
   diskfs_set_node_atime (dp);
 
@@ -817,7 +817,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds)
 {
   if (ds->type != LOOKUP)
     {
-      assert (ds->mapbuf);
+      assert_backtrace (ds->mapbuf);
       munmap ((caddr_t) ds->mapbuf, ds->mapextent);
       ds->type = LOOKUP;
     }
diff --git a/fatfs/fat.c b/fatfs/fat.c
index 4c98f62..e191cfc 100644
--- a/fatfs/fat.c
+++ b/fatfs/fat.c
@@ -22,7 +22,7 @@
 #include <error.h>
 #include <limits.h>
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <ctype.h>
 #include <time.h>
 
@@ -214,7 +214,7 @@ fat_write_next_cluster(cluster_t cluster, cluster_t 
next_cluster)
   cluster_t data;
 
   /* First data cluster is cluster 2.  */
-  assert (cluster >= 2 && cluster < nr_of_clusters + 2); 
+  assert_backtrace (cluster >= 2 && cluster < nr_of_clusters + 2); 
 
   switch (fat_type)
     {
@@ -267,7 +267,7 @@ fat_get_next_cluster(cluster_t cluster, cluster_t 
*next_cluster)
   loff_t fat_entry_offset;
 
   /* First data cluster is cluster 2.  */
-  assert (cluster >= 2 && cluster < nr_of_clusters + 2); 
+  assert_backtrace (cluster >= 2 && cluster < nr_of_clusters + 2); 
 
   switch (fat_type)
     {
@@ -321,7 +321,7 @@ fat_allocate_cluster (cluster_t content, cluster_t *cluster)
   int wrapped = 0;
   cluster_t found_cluster = FAT_FREE_CLUSTER;
 
-  assert (content != FAT_FREE_CLUSTER);
+  assert_backtrace (content != FAT_FREE_CLUSTER);
 
   pthread_spin_lock (&allocate_free_cluster_lock);
   old_next_free_cluster = next_free_cluster;
@@ -483,17 +483,17 @@ fat_getcluster (struct node *node, cluster_t cluster, int 
create,
        return err;
       if (cluster >= node->dn->length_of_chain)
        {
-         assert (!create);
+         assert_backtrace (!create);
          return EINVAL;
        }
     }
   chain = node->dn->first;
   while (chains_to_go--)
     {
-      assert (chain);
+      assert_backtrace (chain);
       chain = chain->next;
     }
-  assert (chain);
+  assert_backtrace (chain);
   *disk_cluster = chain->cluster[offs];
   return 0;
 }
@@ -508,14 +508,14 @@ fat_truncate_node (struct node *node, cluster_t 
clusters_to_keep)
 
   /* The root dir of a FAT12/16 fs is of fixed size, while the root
      dir of a FAT32 fs must never decease to exist.  */
-  assert (! (((fat_type == FAT12 || fat_type == FAT16) && node == 
diskfs_root_node)
+  assert_backtrace (! (((fat_type == FAT12 || fat_type == FAT16) && node == 
diskfs_root_node)
             || (fat_type == FAT32 && node == diskfs_root_node && 
clusters_to_keep == 0)));
 
   /* Expand the cluster chain, because we have to know the complete tail.  */
   fat_extend_chain (node, FAT_EOC, 0);
   if (clusters_to_keep == node->dn->length_of_chain)
     return;
-  assert (clusters_to_keep < node->dn->length_of_chain);
+  assert_backtrace (clusters_to_keep < node->dn->length_of_chain);
 
   /* Truncation happens here.  */
   next = node->dn->first;
@@ -532,7 +532,7 @@ fat_truncate_node (struct node *node, cluster_t 
clusters_to_keep)
       offs = (clusters_to_keep - 1) & (CLUSTERS_PER_TABLE - 1);
       while (count-- > 0)
        {
-         assert (next);
+         assert_backtrace (next);
 
          /* This cluster is now the last cluster in the chain.  */
          if (count == 0)
@@ -540,7 +540,7 @@ fat_truncate_node (struct node *node, cluster_t 
clusters_to_keep)
 
          next = next->next;
        }
-      assert (next);
+      assert_backtrace (next);
       fat_write_next_cluster (next->cluster[offs++], FAT_EOC);
       pos = clusters_to_keep;
     }
@@ -553,7 +553,7 @@ fat_truncate_node (struct node *node, cluster_t 
clusters_to_keep)
        {
          offs = 0;
          next = next->next;
-         assert(next);
+         assert_backtrace (next);
        }
       fat_write_next_cluster(next->cluster[offs++], 0);
       pos++;
@@ -567,10 +567,10 @@ fat_truncate_node (struct node *node, cluster_t 
clusters_to_keep)
       offs = (clusters_to_keep - 1) & (CLUSTERS_PER_TABLE - 1);
       while (count-- > 0)
        {
-         assert (next);
+         assert_backtrace (next);
          next = next->next;
        }
-      assert (next);
+      assert_backtrace (next);
       next = next->next;
     }
   while (next)
diff --git a/fatfs/inode.c b/fatfs/inode.c
index 4f28d14..e92922f 100644
--- a/fatfs/inode.c
+++ b/fatfs/inode.c
@@ -98,7 +98,7 @@ diskfs_node_norefs (struct node *np)
   if (np->dn->dirnode)
     diskfs_nrele (np->dn->dirnode);
 
-  assert (!np->dn->pager);
+  assert_backtrace (!np->dn->pager);
 
   free (np);
 }
@@ -178,7 +178,7 @@ diskfs_user_read_node (struct node *np, struct 
lookup_context *ctx)
             by libdiskfs.  The only case it is not locked is for NFS
             (fsys_getfile) and we disabled that.  */
          dp = diskfs_cached_ifind (vk.dir_inode);
-         assert (dp);
+         assert_backtrace (dp);
       
          /* Map in the directory contents. */
          memobj = diskfs_get_filemap (dp, prot);
@@ -339,13 +339,13 @@ write_node (struct node *np)
   if (vk.dir_inode == 0 || np == diskfs_root_node)
     return;
 
-  assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime);
+  assert_backtrace (!np->dn_set_ctime && !np->dn_set_atime && 
!np->dn_set_mtime);
   if (np->dn_stat_dirty)
     {
-      assert (!diskfs_readonly);
+      assert_backtrace (!diskfs_readonly);
 
       dp = np->dn->dirnode;
-      assert (dp);
+      assert_backtrace (dp);
 
       pthread_mutex_lock (&dp->lock);
 
@@ -474,14 +474,14 @@ diskfs_set_translator (struct node *node,
                       const char *name, u_int namelen,
                       struct protid *cred)
 {
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
   return EOPNOTSUPP;
 }
 
 error_t
 diskfs_get_translator (struct node *node, char **namep, u_int *namelen)
 {
-  assert(0);
+  assert_backtrace (0);
 }
 
 void
@@ -503,7 +503,7 @@ diskfs_truncate (struct node *node, loff_t length)
   loff_t offset;
 
   diskfs_check_readonly ();
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   if (length >= node->dn_stat.st_size)
     return 0;
@@ -565,7 +565,7 @@ diskfs_S_file_get_storage_info (struct protid *cred,
 void
 diskfs_free_node (struct node *np, mode_t old_mode)
 {
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   vi_free(np->dn->inode);
 }
@@ -584,7 +584,7 @@ diskfs_alloc_node (struct node *dir, mode_t mode, struct 
node **node)
   struct node *np;
   struct lookup_context ctx = { dir: dir };
 
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
 
   /* FIXME: We use a magic key here that signals read_node that we are
      not entered in any directory yet.  */
diff --git a/fatfs/main.c b/fatfs/main.c
index 00c56bc..f0b3aa8 100644
--- a/fatfs/main.c
+++ b/fatfs/main.c
@@ -189,7 +189,7 @@ fetch_root ()
       break;
 
     default:
-      assert(!"don't know how to set size of root dir");
+      assert_backtrace (!"don't know how to set size of root dir");
     };
 
   /* The magic vi_key {0, 1} for the root directory is distinguished
@@ -197,14 +197,14 @@ fetch_root ()
      normal virtual inode keys (in the dir_inode value).  Enter the
      disknode into the inode table.  */
   err = vi_new ((struct vi_key) {0, 1}, &inum, &ctx.inode);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* Allocate a node for the root directory disknode in
      diskfs_root_node.  */
   if (!err)
     err = diskfs_cached_lookup_context (inum, &diskfs_root_node, &ctx);
 
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   pthread_mutex_unlock (&diskfs_root_node->lock);
 }
diff --git a/fatfs/pager.c b/fatfs/pager.c
index bef8dbe..53b5bbc 100644
--- a/fatfs/pager.c
+++ b/fatfs/pager.c
@@ -608,7 +608,7 @@ void
 pager_notify_evict (struct user_pager_info *pager,
                    vm_offset_t page)
 {
-  assert (!"unrequested notification on eviction");
+  assert_backtrace (!"unrequested notification on eviction");
 }
 
 /* Grow the disk allocated to locked node NODE to be at least SIZE
@@ -621,7 +621,7 @@ error_t
 diskfs_grow (struct node *node, loff_t size, struct protid *cred)
 {
   diskfs_check_readonly ();
-  assert (!diskfs_readonly);
+  assert_backtrace (!diskfs_readonly);
   
   if (size > node->allocsize)
     {
@@ -718,7 +718,7 @@ inline error_t
 pager_report_extent (struct user_pager_info *pager,
                      vm_address_t *offset, vm_size_t *size)
 {
-  assert (pager->type == FAT || pager->type == FILE_DATA);
+  assert_backtrace (pager->type == FAT || pager->type == FILE_DATA);
 
   *offset = 0;
 
@@ -815,7 +815,7 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
 {
   mach_port_t right;
   
-  assert (S_ISDIR (node->dn_stat.st_mode)
+  assert_backtrace (S_ISDIR (node->dn_stat.st_mode)
          || S_ISREG (node->dn_stat.st_mode)
          || (S_ISLNK (node->dn_stat.st_mode)));
   
diff --git a/fatfs/virt-inode.c b/fatfs/virt-inode.c
index 7138169..7267cbe 100644
--- a/fatfs/virt-inode.c
+++ b/fatfs/virt-inode.c
@@ -25,7 +25,7 @@
    up-to-date. When a table page can be freed, do so.  */
 
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <pthread.h>
 #include "virt-inode.h"
@@ -117,7 +117,7 @@ vi_new(vi_key_t key, ino_t *inode, inode_t *v_inode)
 {
   error_t err;
 
-  assert (memcmp(&vi_zero_key, &key, sizeof (vi_key_t)));
+  assert_backtrace (memcmp(&vi_zero_key, &key, sizeof (vi_key_t)));
 
   pthread_spin_lock (&inode_table_lock);
   err = _vi_new(key, inode, v_inode);
@@ -171,7 +171,7 @@ vi_rlookup(vi_key_t key, ino_t *inode, inode_t *v_inode, 
int create)
   int page = 0;
   int offset = 0;
 
-  assert (memcmp(&vi_zero_key, &key, sizeof (vi_key_t)));
+  assert_backtrace (memcmp(&vi_zero_key, &key, sizeof (vi_key_t)));
 
   pthread_spin_lock (&inode_table_lock);
 
@@ -211,7 +211,7 @@ vi_key_t vi_change(inode_t v_inode, vi_key_t key)
 {
   vi_key_t okey = v_inode->key;
 
-  assert (memcmp(&vi_zero_key, &key, sizeof (vi_key_t)));
+  assert_backtrace (memcmp(&vi_zero_key, &key, sizeof (vi_key_t)));
   v_inode->key = key;
   return okey;
 }
diff --git a/ftpfs/conn.c b/ftpfs/conn.c
index 0f1b097..2cd1384 100644
--- a/ftpfs/conn.c
+++ b/ftpfs/conn.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdint.h>
 
 #include "ftpfs.h"
@@ -101,6 +101,6 @@ ftpfs_release_ftp_conn (struct ftpfs *fs, struct ftp_conn 
*conn)
        fs->free_conns = fsc;
        break;
       }
-  assert (fsc);
+  assert_backtrace (fsc);
   pthread_spin_unlock (&fs->conn_lock);
 }
diff --git a/ftpfs/dir.c b/ftpfs/dir.c
index 2ea29b5..72b1a46 100644
--- a/ftpfs/dir.c
+++ b/ftpfs/dir.c
@@ -30,7 +30,7 @@
 void
 free_entry (struct ftpfs_dir_entry *e)
 {
-  assert (e->deleted);
+  assert_backtrace (e->deleted);
   free (e->name);
   if (e->symlink_target)
     free (e->symlink_target);
@@ -705,8 +705,7 @@ ftpfs_dir_lookup (struct ftpfs_dir *dir, const char *name,
       pthread_mutex_unlock (&dir->node->lock);
     }
 
-  if (rmt_path)
-    free (rmt_path);
+  free (rmt_path);
 
   return err;
 }
diff --git a/ftpfs/node.c b/ftpfs/node.c
index cc9bf43..fb85fe5 100644
--- a/ftpfs/node.c
+++ b/ftpfs/node.c
@@ -91,7 +91,7 @@ netfs_node_norefs (struct node *node)
 
   if (nn->dir)
     {
-      assert (nn->dir->num_live_entries == 0);
+      assert_backtrace (nn->dir->num_live_entries == 0);
       ftpfs_dir_free (nn->dir);
     }
 
diff --git a/hostmux/leaf.c b/hostmux/leaf.c
index fb53622..ebe9190 100644
--- a/hostmux/leaf.c
+++ b/hostmux/leaf.c
@@ -27,7 +27,7 @@
 error_t
 netfs_attempt_readlink (struct iouser *user, struct node *node, char *buf)
 {
-  assert (node->nn->name);
+  assert_backtrace (node->nn->name);
   memcpy (buf, node->nn->name->canon, node->nn_stat.st_size);
   fshelp_touch (&node->nn_stat, TOUCH_ATIME, hostmux_maptime);
   return 0;
diff --git a/hurd/process.defs b/hurd/process.defs
index df70eb9..d724e20 100644
--- a/hurd/process.defs
+++ b/hurd/process.defs
@@ -156,7 +156,7 @@ routine proc_getmsgport (
        process: process_t;
        sreplyport reply_port: sreply_port_t;
        pid: pid_t;
-       out msgport: mach_port_poly_t);
+       out msgport: mach_port_send_t);
 
 /* Wait for a child process to exit.  If pid is zero, it waits for any
    child in the same pgrp as the parent.  If pid is -1, it waits for
@@ -246,7 +246,7 @@ routine proc_task2pid (
 routine proc_task2proc (
        process: process_t;
        task: task_t;
-       out proc: mach_port_poly_t);
+       out proc: mach_port_send_t);
 
 routine proc_proc2task (
        process: process_t;
@@ -255,7 +255,7 @@ routine proc_proc2task (
 routine proc_pid2proc (
        process: process_t;
        pid: pid_t;
-       out proc: mach_port_poly_t);
+       out proc: mach_port_send_t);
 
 routine proc_getprocinfo (
        process: process_t;
diff --git a/isofs/inode.c b/isofs/inode.c
index eef2a6a..0783385 100644
--- a/isofs/inode.c
+++ b/isofs/inode.c
@@ -328,7 +328,7 @@ diskfs_node_norefs (struct node *np)
   if (np->dn->translator)
     free (np->dn->translator);
 
-  assert (!np->dn->fileinfo);
+  assert_backtrace (!np->dn->fileinfo);
   free (np);
 }
 
diff --git a/isofs/lookup.c b/isofs/lookup.c
index f375212..3590f2d 100644
--- a/isofs/lookup.c
+++ b/isofs/lookup.c
@@ -78,7 +78,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
   ino_t id;
 
   if ((type == REMOVE) || (type == RENAME))
-    assert (npp);
+    assert_backtrace (npp);
 
   if (npp)
     *npp = 0;
@@ -127,7 +127,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum 
lookup_type type,
       else if (spec_dotdot)
        {
          /* renames and removes can't get this far. */
-         assert (type == LOOKUP);
+         assert_backtrace (type == LOOKUP);
          diskfs_nput (dp);
          err = diskfs_cached_lookup_context (id, npp, &ctx);
        }
diff --git a/isofs/main.c b/isofs/main.c
index c07cf3f..db16e2a 100644
--- a/isofs/main.c
+++ b/isofs/main.c
@@ -57,11 +57,11 @@ fetch_root ()
   rrip_lookup (ctx.dr, &ctx.rr, 1);
 
   err = cache_id (ctx.dr, &ctx.rr, &id);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* And fetch the node. */
   err = diskfs_cached_lookup_context (id, &diskfs_root_node, &ctx);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   pthread_mutex_unlock (&diskfs_root_node->lock);
 }
diff --git a/isofs/pager.c b/isofs/pager.c
index 42cad8d..259581e 100644
--- a/isofs/pager.c
+++ b/isofs/pager.c
@@ -64,7 +64,7 @@ pager_read_page (struct user_pager_info *upi,
     }
   else
     {
-      assert (upi->type == DISK);
+      assert_backtrace (upi->type == DISK);
       addr = page >> store->log2_block_size;
     }
 
@@ -87,7 +87,7 @@ pager_write_page (struct user_pager_info *pager,
                  vm_offset_t page,
                  vm_address_t buf)
 {
-  assert (0);
+  assert_backtrace (0);
 }
 
 /* Never permit unlocks to succeed. */
@@ -102,7 +102,7 @@ void
 pager_notify_evict (struct user_pager_info *pager,
                    vm_offset_t page)
 {
-  assert (!"unrequested notification on eviction");
+  assert_backtrace (!"unrequested notification on eviction");
 }
 
 /* Tell how big the file is. */
@@ -166,7 +166,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
   struct user_pager_info *upi;
   mach_port_t right;
   
-  assert (S_ISDIR (np->dn_stat.st_mode)
+  assert_backtrace (S_ISDIR (np->dn_stat.st_mode)
          || S_ISREG (np->dn_stat.st_mode)
          || S_ISLNK (np->dn_stat.st_mode));
   
diff --git a/isofs/rr.c b/isofs/rr.c
index 59205da..85aa569 100644
--- a/isofs/rr.c
+++ b/isofs/rr.c
@@ -280,7 +280,7 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr,
            nmbuf = malloc ((nmbufsize = nmlen) + 1);
          else
            nmbuf = realloc (nmbuf, (nmbufsize += nmlen) + 1);
-         assert (nmbuf);
+         assert_backtrace (nmbuf);
 
          memcpy (nmbuf + nmbufsize - nmlen, nm->name, nmlen);
 
@@ -307,7 +307,7 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr,
          if (name != nmbuf)
            {
              rr->name = strdup (name);
-             assert (rr->name);
+             assert_backtrace (rr->name);
            }
          else
            {
@@ -373,7 +373,7 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr,
                }
              else while (targused + cnamelen > targalloced)
                rr->target = realloc (rr->target, targalloced *= 2);
-             assert (rr->target);
+             assert_backtrace (rr->target);
 
              memcpy (rr->target + targused, cname, cnamelen);
              targused += cnamelen;
@@ -389,7 +389,7 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr,
            slbuf = malloc (slbufsize = crlen);
          else
            slbuf = realloc (slbuf, slbufsize += crlen);
-         assert (slbuf);
+         assert_backtrace (slbuf);
 
          memcpy (slbuf + slbufsize - crlen, sl->data, crlen);
 
@@ -572,7 +572,7 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr,
 
          rr->translen = tr->len;
          rr->trans = malloc (rr->translen);
-         assert (rr->trans);
+         assert_backtrace (rr->trans);
          memcpy (tr->data, rr->trans, rr->translen);
          rr->valid |= VALID_TR;
 
diff --git a/libbpf/bpf_impl.c b/libbpf/bpf_impl.c
index 03a2a53..a419123 100644
--- a/libbpf/bpf_impl.c
+++ b/libbpf/bpf_impl.c
@@ -62,11 +62,11 @@ bpf_do_filter(net_rcv_port_t infp, char *p, unsigned int 
wirelen,
                char *header, unsigned int hlen, net_hash_entry_t **hash_headpp,
                net_hash_entry_t *entpp)
 {
-       register bpf_insn_t pc, pc_end;
-       register unsigned int buflen;
+       bpf_insn_t pc, pc_end;
+       unsigned int buflen;
 
-       register unsigned long A, X;
-       register int k;
+       unsigned long A, X;
+       int k;
        unsigned int mem[BPF_MEMWORDS];
 
        /* Generic pointer to either HEADER or P according to the specified 
offset. */
@@ -350,8 +350,8 @@ load_byte:
 int
 bpf_validate(bpf_insn_t f, int bytes, bpf_insn_t *match)
 {
-       register int i, j, len;
-       register bpf_insn_t p;
+       int i, j, len;
+       bpf_insn_t p;
 
        len = BPF_BYTES2LEN(bytes);
 
@@ -367,7 +367,7 @@ bpf_validate(bpf_insn_t f, int bytes, bpf_insn_t *match)
                 */
                p = &f[i];
                if (BPF_CLASS(p->code) == BPF_JMP) {
-                       register int from = i + 1;
+                       int from = i + 1;
 
                        if (BPF_OP(p->code) == BPF_JA) {
                                if (from + p->k >= len)
@@ -421,7 +421,7 @@ bpf_validate(bpf_insn_t f, int bytes, bpf_insn_t *match)
 int
 bpf_eq (bpf_insn_t f1, bpf_insn_t f2, int bytes)
 {
-       register int count;
+       int count;
 
        count = BPF_BYTES2LEN(bytes);
        for (; count--; f1++, f2++) {
@@ -438,7 +438,7 @@ bpf_eq (bpf_insn_t f1, bpf_insn_t f2, int bytes)
 unsigned int
 bpf_hash (int n, unsigned int *keys)
 {
-       register unsigned int hval = 0;
+       unsigned int hval = 0;
 
        while (n--) {
                hval += *keys++;
@@ -451,8 +451,8 @@ int
 bpf_match (net_hash_header_t hash, int n_keys, unsigned int *keys,
        net_hash_entry_t **hash_headpp, net_hash_entry_t *entpp)
 {
-       register net_hash_entry_t head, entp;
-       register int i;
+       net_hash_entry_t head, entp;
+       int i;
 
        if (n_keys != hash->n_keys)
                return FALSE;
@@ -527,7 +527,7 @@ hash_ent_remove (if_filter_list_t *ifp, net_hash_header_t 
hp, int used,
 void
 net_free_dead_infp (queue_entry_t dead_infp)
 {
-       register net_rcv_port_t infp, nextfp;
+       net_rcv_port_t infp, nextfp;
 
        for (infp = (net_rcv_port_t) dead_infp; infp != 0; infp = nextfp) {
                nextfp = (net_rcv_port_t) queue_next(&infp->input);
@@ -547,7 +547,7 @@ net_free_dead_infp (queue_entry_t dead_infp)
 void
 net_free_dead_entp (queue_entry_t dead_entp)
 {
-       register net_hash_entry_t entp, nextentp;
+       net_hash_entry_t entp, nextentp;
 
        for (entp = (net_hash_entry_t)dead_entp; entp != 0; entp = nextentp) {
                nextentp = (net_hash_entry_t) queue_next(&entp->chain);
@@ -570,10 +570,10 @@ net_set_filter(if_filter_list_t *ifp, mach_port_t 
rcv_port, int priority,
 {
        int               filter_bytes;
        bpf_insn_t            match;
-       register net_rcv_port_t   infp, my_infp;
+       net_rcv_port_t   infp, my_infp;
        net_rcv_port_t        nextfp;
        net_hash_header_t     hhp;
-       register net_hash_entry_t entp, hash_entp=NULL;
+       net_hash_entry_t entp, hash_entp=NULL;
        net_hash_entry_t      *head, nextentp;
        queue_entry_t     dead_infp, dead_entp;
        int               i;
diff --git a/libbpf/queue.c b/libbpf/queue.c
index 3323434..1288a0b 100644
--- a/libbpf/queue.c
+++ b/libbpf/queue.c
@@ -35,8 +35,8 @@
  *     Insert element at head of queue.
  */
 void enqueue_head(
-       register queue_t        que,
-       register queue_entry_t  elt)
+       queue_t que,
+       queue_entry_t   elt)
 {
        elt->next = que->next;
        elt->prev = que;
@@ -48,8 +48,8 @@ void enqueue_head(
  *     Insert element at tail of queue.
  */
 void enqueue_tail(
-       register queue_t        que,
-       register queue_entry_t  elt)
+       queue_t que,
+       queue_entry_t   elt)
 {
        elt->next = que;
        elt->prev = que->prev;
@@ -61,9 +61,9 @@ void enqueue_tail(
  *     Remove and return element at head of queue.
  */
 queue_entry_t dequeue_head(
-       register queue_t        que)
+       queue_t que)
 {
-       register queue_entry_t  elt;
+       queue_entry_t   elt;
 
        if (que->next == que)
                return((queue_entry_t)0);
@@ -78,9 +78,9 @@ queue_entry_t dequeue_head(
  *     Remove and return element at tail of queue.
  */
 queue_entry_t dequeue_tail(
-       register queue_t        que)
+       queue_t que)
 {
-       register queue_entry_t  elt;
+       queue_entry_t   elt;
 
        if (que->prev == que)
                return((queue_entry_t)0);
@@ -100,7 +100,7 @@ queue_entry_t dequeue_tail(
 /*ARGSUSED*/
 void remqueue(
        queue_t                 que,
-       register queue_entry_t  elt)
+       queue_entry_t   elt)
 {
        elt->next->prev = elt->prev;
        elt->prev->next = elt->next;
@@ -111,8 +111,8 @@ void remqueue(
  *     package.
  */
 void insque(
-       register struct queue_entry *entry,
-       register struct queue_entry *pred)
+       struct queue_entry *entry,
+       struct queue_entry *pred)
 {
        entry->next = pred->next;
        entry->prev = pred;
@@ -122,7 +122,7 @@ void insque(
 
 struct queue_entry
 *remque(
-       register struct queue_entry *elt)
+       struct queue_entry *elt)
 {
        (elt->next)->prev = elt->prev;
        (elt->prev)->next = elt->next;
diff --git a/libcons/cons-switch.c b/libcons/cons-switch.c
index d8af50a..c46dfb4 100644
--- a/libcons/cons-switch.c
+++ b/libcons/cons-switch.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 
 #include "cons.h"
@@ -56,7 +56,7 @@ cons_switch (vcons_t vcons, int id, int delta, vcons_t 
*r_vcons)
     }
   else
     {
-      assert (delta < 0);
+      assert_backtrace (delta < 0);
       vcons_entry = vcons->vcons_entry;
       while (delta++ < 0)
         {
diff --git a/libcons/dir-changed.c b/libcons/dir-changed.c
index 8498649..06c2970 100644
--- a/libcons/dir-changed.c
+++ b/libcons/dir-changed.c
@@ -20,7 +20,7 @@
 
 #include <errno.h>
 #include <dirent.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <mach.h>
 #include <pthread.h>
 
@@ -88,14 +88,14 @@ cons_S_dir_changed (cons_notify_t notify, natural_t tickno,
          }
        while (dent && !err);
        if (err)
-         assert ("Unexpected error");  /* XXX */
+         assert_backtrace ("Unexpected error");        /* XXX */
       }
       break;
     case DIR_CHANGED_NEW:
       {
        err = add_one (cons, name);
        if (err)
-         assert ("Unexpected error");  /* XXX */
+         assert_backtrace ("Unexpected error");        /* XXX */
       }
       break;
     case DIR_CHANGED_UNLINK:
@@ -120,7 +120,7 @@ cons_S_dir_changed (cons_notify_t notify, natural_t tickno,
       break;
     case DIR_CHANGED_RENUMBER:
     default:
-      assert ("Unexpected dir-changed type.");
+      assert_backtrace ("Unexpected dir-changed type.");
       pthread_mutex_unlock (&cons->lock);
       return EINVAL;
     }
diff --git a/libcons/file-changed.c b/libcons/file-changed.c
index fa5cebd..e3e3563 100644
--- a/libcons/file-changed.c
+++ b/libcons/file-changed.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 
 #include <mach.h>
@@ -198,7 +198,7 @@ cons_S_file_changed (cons_notify_t notify, natural_t tickno,
                  vcons->state.screen.scr_lines
                    = vcons->display->screen.scr_lines;
                  if (vcons->state.screen.scr_lines < vcons->scrolling)
-                   assert (!"Implement shrinking scrollback buffer! XXX");
+                   assert_backtrace (!"Implement shrinking scrollback buffer! 
XXX");
                }
              if (change.what.bell_audible)
                {
diff --git a/libcons/vcons-close.c b/libcons/vcons-close.c
index 554bfa8..1a2a602 100644
--- a/libcons/vcons-close.c
+++ b/libcons/vcons-close.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include <hurd.h>
 #include <hurd/ports.h>
@@ -35,7 +35,7 @@ cons_vcons_close (vcons_t vcons)
 
   pthread_mutex_lock (&cons->lock);
   /* The same virtual console should never be opened twice.  */
-  assert (vcons_entry->vcons == vcons);
+  assert_backtrace (vcons_entry->vcons == vcons);
   vcons_entry->vcons = NULL;
   pthread_mutex_unlock (&cons->lock);
 
diff --git a/libcons/vcons-refresh.c b/libcons/vcons-refresh.c
index ce6807f..beb36d8 100644
--- a/libcons/vcons-refresh.c
+++ b/libcons/vcons-refresh.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "cons.h"
 #include "priv.h"
diff --git a/libcons/vcons-remove.c b/libcons/vcons-remove.c
index 273c5a0..39df86a 100644
--- a/libcons/vcons-remove.c
+++ b/libcons/vcons-remove.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "cons.h"
 
@@ -27,5 +27,5 @@
 void __attribute__ ((weak))
 cons_vcons_remove (cons_t cons, vcons_list_t vcons_entry)
 {
-  assert (!vcons_entry->vcons);
+  assert_backtrace (!vcons_entry->vcons);
 }
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index f048bad..1b76ebd 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -38,6 +38,10 @@
 #include "fsys_S.h"
 #include "fsys_reply_U.h"
 
+/* We use this port to communicate with startup.  It is the only
+   object that fsys_getpriv and fsys_init may be invoked upon.  */
+static struct port_info *bootinfo;
+
 static mach_port_t diskfs_exec_ctl;
 extern task_t diskfs_exec_server_task;
 extern task_t diskfs_kernel_task;
@@ -73,18 +77,18 @@ get_console ()
 void
 _diskfs_boot_privports (void)
 {
-  assert (diskfs_boot_filesystem ());
+  assert_backtrace (diskfs_boot_filesystem ());
   if (_hurd_host_priv == MACH_PORT_NULL)
     {
       /* We are the boot command run by the real bootstrap filesystem.
         We get the privileged ports from it as init would.  */
       mach_port_t bootstrap;
       error_t err = task_get_bootstrap_port (mach_task_self (), &bootstrap);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       err = fsys_getpriv (bootstrap, &_hurd_host_priv, &_hurd_device_master,
                          &parent_task);
       mach_port_deallocate (mach_task_self (), bootstrap);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
 }
 
@@ -104,7 +108,6 @@ diskfs_start_bootstrap ()
   char *exec_argv, *exec_env;
   const char *initname;
   size_t exec_argvlen, exec_envlen;
-  struct port_info *bootinfo;
   struct protid *rootpi;
   struct peropen *rootpo;
   mach_port_t diskfs_exec;
@@ -113,10 +116,10 @@ diskfs_start_bootstrap ()
   /* Create the port for current and root directory.  */
   err = diskfs_make_peropen (diskfs_root_node, O_READ | O_EXEC, 0,
                             &rootpo);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   err = diskfs_create_protid (rootpo, 0, &rootpi);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* Get us a send right to copy around.  */
   root_pt = ports_get_send_right (rootpi);
@@ -128,8 +131,8 @@ diskfs_start_bootstrap ()
         Our parent (the real bootstrap filesystem) provides us a root
         directory where we look up /servers/exec like any non-bootstrap
         filesystem would.  */
-      assert (_hurd_ports);
-      assert (_hurd_ports[INIT_PORT_CRDIR].port != MACH_PORT_NULL);
+      assert_backtrace (_hurd_ports);
+      assert_backtrace (_hurd_ports[INIT_PORT_CRDIR].port != MACH_PORT_NULL);
       diskfs_exec = file_name_lookup (_SERVERS_EXEC, 0, 0);
       if (diskfs_exec == MACH_PORT_NULL)
        error (1, errno, "%s", _SERVERS_EXEC);
@@ -139,7 +142,7 @@ diskfs_start_bootstrap ()
          /* Make sure this is really a port to another server.  */
          struct port_info *pi = ports_lookup_port (diskfs_port_bucket,
                                                    diskfs_exec, 0);
-         assert (!pi);
+         assert_backtrace (!pi);
 #endif
        }
 
@@ -165,16 +168,16 @@ diskfs_start_bootstrap ()
       start_execserver ();
       pthread_cond_wait (&execstarted, &execstartlock);
       pthread_mutex_unlock (&execstartlock);
-      assert (diskfs_exec_ctl != MACH_PORT_NULL);
+      assert_backtrace (diskfs_exec_ctl != MACH_PORT_NULL);
 
       /* Contact the exec server.  */
       err = fsys_getroot (diskfs_exec_ctl, root_pt, MACH_MSG_TYPE_COPY_SEND,
                          idlist, 3, idlist, 3, 0,
                          &retry, retry_name, &diskfs_exec);
-      assert_perror (err);
-      assert (retry == FS_RETRY_NORMAL);
-      assert (retry_name[0] == '\0');
-      assert (diskfs_exec != MACH_PORT_NULL);
+      assert_perror_backtrace (err);
+      assert_backtrace (retry == FS_RETRY_NORMAL);
+      assert_backtrace (retry_name[0] == '\0');
+      assert_backtrace (diskfs_exec != MACH_PORT_NULL);
 
       /* Attempt to set the active translator for the exec server so that
         filesystems other than the bootstrap can find it.  */
@@ -187,14 +190,14 @@ diskfs_start_bootstrap ()
        }
       else
        {
-         assert (retry == FS_RETRY_NORMAL);
-         assert (retry_name[0] == '\0');
-         assert (execnode != MACH_PORT_NULL);
+         assert_backtrace (retry == FS_RETRY_NORMAL);
+         assert_backtrace (retry_name[0] == '\0');
+         assert_backtrace (execnode != MACH_PORT_NULL);
          err = file_set_translator (execnode, 0, FS_TRANS_SET, 0, 0, 0,
                                     diskfs_exec_ctl, MACH_MSG_TYPE_COPY_SEND);
          mach_port_deallocate (mach_task_self (), diskfs_exec_ctl);
          mach_port_deallocate (mach_task_self (), execnode);
-         assert_perror (err);
+         assert_perror_backtrace (err);
        }
       diskfs_exec_ctl = MACH_PORT_NULL;        /* Not used after this.  */
     }
@@ -206,7 +209,7 @@ diskfs_start_bootstrap ()
     {
       /* We have a boot command line to run instead of init.  */
       err = argz_create (_diskfs_boot_command, &exec_argv, &exec_argvlen);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
   else
     {
@@ -216,11 +219,11 @@ diskfs_start_bootstrap ()
        initname++;
 
       int len = asprintf (&exec_argv, "/%s%c", initname, '\0');
-      assert (len != -1);
+      assert_backtrace (len != -1);
       exec_argvlen = (size_t) len;
       err = argz_add_sep (&exec_argv, &exec_argvlen,
                          diskfs_boot_command_line, ' ');
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
 
   err = task_create (mach_task_self (),
@@ -228,7 +231,7 @@ diskfs_start_bootstrap ()
                     NULL, 0,   /* OSF Mach */
 #endif
                     0, &newt);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (MACH_PORT_VALID (diskfs_kernel_task))
     {
@@ -246,11 +249,11 @@ diskfs_start_bootstrap ()
       diskfs_kernel_task = MACH_PORT_NULL;
 
       len = snprintf (buf, sizeof buf, "--kernel-task=%d", kernel_task_name);
-      assert (len < sizeof buf);
+      assert_backtrace (len < sizeof buf);
       /* Insert as second argument.  */
       err = argz_insert (&exec_argv, &exec_argvlen,
                          argz_next (exec_argv, exec_argvlen, exec_argv), buf);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
 
   initname = exec_argv;
@@ -267,11 +270,11 @@ diskfs_start_bootstrap ()
              initname, strerror (err));
       fflush (stdout);
       free (exec_argv);
-      assert_perror (err);     /* XXX this won't reboot properly */
+      assert_perror_backtrace (err);   /* XXX this won't reboot properly */
     }
   else if (retry == FS_RETRY_MAGICAL && pathbuf[0] == '/')
     {
-      assert (sysconf (_SC_SYMLOOP_MAX) < 0 ||
+      assert_backtrace (sysconf (_SC_SYMLOOP_MAX) < 0 ||
              init_lookups < sysconf (_SC_SYMLOOP_MAX));
 
       /* INITNAME is a symlink with an absolute target, so try again.  */
@@ -279,14 +282,13 @@ diskfs_start_bootstrap ()
       goto lookup_init;
     }
 
-  assert (retry == FS_RETRY_NORMAL);
-  assert (pathbuf[0] == '\0');
+  assert_backtrace (retry == FS_RETRY_NORMAL);
+  assert_backtrace (pathbuf[0] == '\0');
 
-  err = ports_create_port (diskfs_initboot_class, diskfs_port_bucket,
+  err = ports_create_port (diskfs_control_class, diskfs_port_bucket,
                           sizeof (struct port_info), &bootinfo);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   bootpt = ports_get_send_right (bootinfo);
-  ports_port_deref (bootinfo);
 
   portarray[INIT_PORT_CRDIR] = root_pt;
   portarray[INIT_PORT_CWDIR] = root_pt;
@@ -298,7 +300,7 @@ diskfs_start_bootstrap ()
   fdarray[0] = fdarray[1] = fdarray[2] = get_console (); /* XXX */
 
   err = argz_create (environ, &exec_env, &exec_envlen);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (_diskfs_boot_pause)
     {
@@ -383,10 +385,10 @@ diskfs_S_exec_startup_get_info (struct bootinfo *upt,
   *intarraylen = 0;
 
   err = diskfs_make_peropen (diskfs_root_node, O_READ | O_EXEC, 0, &rootpo);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   err = diskfs_create_protid (rootpo, 0, &rootpi);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   rootport = ports_get_right (rootpi);
   ports_port_deref (rootpi);
@@ -425,17 +427,17 @@ diskfs_execboot_fsys_startup (mach_port_t port, int flags,
     return EOPNOTSUPP;
 
   err = diskfs_make_peropen (diskfs_root_node, flags, 0, &rootpo);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = diskfs_create_protid (rootpo, 0, &rootpi);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   rootport = ports_get_send_right (rootpi);
   ports_port_deref (rootpi);
 
   err = dir_lookup (rootport, _SERVERS_EXEC, flags|O_NOTRANS, 0,
                    &retry, pathbuf, real);
-  assert_perror (err);
-  assert (retry == FS_RETRY_NORMAL);
-  assert (pathbuf[0] == '\0');
+  assert_perror_backtrace (err);
+  assert_backtrace (retry == FS_RETRY_NORMAL);
+  assert_backtrace (pathbuf[0] == '\0');
   *realpoly = MACH_MSG_TYPE_MOVE_SEND;
 
   mach_port_deallocate (mach_task_self (), rootport);
@@ -461,7 +463,7 @@ diskfs_S_fsys_getpriv (struct diskfs_control 
*init_bootstrap_port,
   error_t err;
 
   if (!init_bootstrap_port
-      || init_bootstrap_port->pi.class != diskfs_initboot_class)
+      || init_bootstrap_port != bootinfo)
     return EOPNOTSUPP;
 
   err = get_privileged_ports (host_priv, dev_master);
@@ -490,10 +492,9 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
   struct protid *rootpi;
   struct peropen *rootpo;
 
-  if (!pt
-      || pt->pi.class != diskfs_initboot_class)
+  if (!pt)
     return EOPNOTSUPP;
-  
+
   if (initdone)
     return EOPNOTSUPP;
   initdone = 1;
@@ -506,10 +507,10 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
      for the library itself. */
   err = mach_port_mod_refs (mach_task_self (),
                            procserver, MACH_PORT_RIGHT_SEND, +1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = mach_port_mod_refs (mach_task_self (),
                            authhandle, MACH_PORT_RIGHT_SEND, +1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (diskfs_auth_server_port != MACH_PORT_NULL)
     mach_port_deallocate (mach_task_self (), diskfs_auth_server_port);
@@ -519,7 +520,7 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
     {
       process_t execprocess;
       err = proc_task2proc (procserver, diskfs_exec_server_task, &execprocess);
-      assert_perror (err);
+      assert_perror_backtrace (err);
 
       /* Declare that the exec server is our child. */
       proc_child (procserver, diskfs_exec_server_task);
@@ -541,7 +542,7 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
       mach_port_t bootstrap;
       process_t parent_proc;
 
-      assert (parent_task != MACH_PORT_NULL);
+      assert_backtrace (parent_task != MACH_PORT_NULL);
 
       /* Tell the proc server that our parent task is our child.  This
         makes the process hierarchy fail to represent the real order of
@@ -553,12 +554,12 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
         we send it fsys_init (below).  */
 
       err = proc_child (procserver, parent_task);
-      assert_perror (err);
+      assert_perror_backtrace (err);
 
       /* Get the parent's proc server port so we can send it in the fsys_init
         RPC just as init would.  */
       err = proc_task2proc (procserver, parent_task, &parent_proc);
-      assert_perror (err);
+      assert_perror_backtrace (err);
 
       /* We don't need this anymore. */
       mach_port_deallocate (mach_task_self (), parent_task);
@@ -569,20 +570,20 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
       /* Give our parent (the real bootstrap filesystem) an fsys_init
         RPC of its own, as init would have sent it.  */
       err = task_get_bootstrap_port (mach_task_self (), &bootstrap);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       err = fsys_init (bootstrap, parent_proc, MACH_MSG_TYPE_COPY_SEND,
                       authhandle);
       mach_port_deallocate (mach_task_self (), parent_proc);
       mach_port_deallocate (mach_task_self (), bootstrap);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
 
   /* Get a port to the root directory to put in the library's
      data structures.  */
   err = diskfs_make_peropen (diskfs_root_node, O_READ|O_EXEC, 0, &rootpo);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = diskfs_create_protid (rootpo, 0, &rootpi);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   root_pt = ports_get_send_right (rootpi);
   ports_port_deref (rootpi);
 
@@ -656,17 +657,17 @@ start_execserver (void)
   extern task_t diskfs_exec_server_task; /* Set in opts-std-startup.c.  */
   struct port_info *execboot_info;
 
-  assert (diskfs_exec_server_task != MACH_PORT_NULL);
+  assert_backtrace (diskfs_exec_server_task != MACH_PORT_NULL);
 
   err = ports_create_port (diskfs_execboot_class, diskfs_port_bucket,
                           sizeof (struct port_info), &execboot_info);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   right = ports_get_send_right (execboot_info);
   ports_port_deref (execboot_info);
   err = task_set_special_port (diskfs_exec_server_task, TASK_BOOTSTRAP_PORT, 
right);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = mach_port_deallocate (mach_task_self (), right);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (_diskfs_boot_pause)
     {
@@ -675,7 +676,7 @@ start_execserver (void)
       getc (stdin);
     }
   err = task_resume (diskfs_exec_server_task);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   printf (" exec");
   fflush (stdout);
diff --git a/libdiskfs/console.c b/libdiskfs/console.c
index a4c3a1a..74715b8 100644
--- a/libdiskfs/console.c
+++ b/libdiskfs/console.c
@@ -24,7 +24,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include <mach/mach.h>
 #include <device/device.h>
@@ -60,10 +60,10 @@ diskfs_console_stdio ()
       if (diskfs_boot_filesystem ())
        _diskfs_boot_privports ();
       err = get_privileged_ports (NULL, &dev);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       err = device_open (dev, D_READ|D_WRITE, "console", &cons);
       mach_port_deallocate (mach_task_self (), dev);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       stdin = mach_open_devstream (cons, "r");
       stdout = stderr = mach_open_devstream (cons, "w");
       mach_port_deallocate (mach_task_self (), cons);
diff --git a/libdiskfs/dir-clear.c b/libdiskfs/dir-clear.c
index 7cf3235..02a800e 100644
--- a/libdiskfs/dir-clear.c
+++ b/libdiskfs/dir-clear.c
@@ -31,10 +31,10 @@ diskfs_clear_directory (struct node *dp,
 
   /* Find and remove the `.' entry. */
   err = diskfs_lookup (dp, ".", REMOVE, &np, ds, cred);
-  assert (err != ENOENT);
+  assert_backtrace (err != ENOENT);
   if (!err)
     {
-      assert (np == dp);
+      assert_backtrace (np == dp);
       err = diskfs_dirremove (dp, np, ".", ds);
       diskfs_nrele (np);
     }
@@ -49,10 +49,10 @@ diskfs_clear_directory (struct node *dp,
 
   /* Find and remove the `..' entry. */
   err = diskfs_lookup (dp, "..", REMOVE | SPEC_DOTDOT, &np, ds, cred);
-  assert (err != ENOENT);
+  assert_backtrace (err != ENOENT);
   if (!err)
     {
-      assert (np == pdp);
+      assert_backtrace (np == pdp);
       err = diskfs_dirremove (dp, np, "..", ds);
     }
   else
diff --git a/libdiskfs/dir-init.c b/libdiskfs/dir-init.c
index 8301ca1..a085a00 100644
--- a/libdiskfs/dir-init.c
+++ b/libdiskfs/dir-init.c
@@ -43,7 +43,7 @@ diskfs_init_dir (struct node *dp, struct node *pdp, struct 
protid *cred)
   dp->dn_stat.st_nlink++;      /* for `.' */
   dp->dn_set_ctime = 1;
   err = diskfs_lookup (dp, ".", CREATE, &foo, ds, &lookupcred);
-  assert (err == ENOENT);
+  assert_backtrace (err == ENOENT);
   err = diskfs_direnter (dp, ".", dp, ds, cred);
   if (err)
     {
@@ -55,7 +55,7 @@ diskfs_init_dir (struct node *dp, struct node *pdp, struct 
protid *cred)
   pdp->dn_stat.st_nlink++;     /* for `..' */
   pdp->dn_set_ctime = 1;
   err = diskfs_lookup (dp, "..", CREATE, &foo, ds, &lookupcred);
-  assert (err == ENOENT);
+  assert_backtrace (err == ENOENT);
   err = diskfs_direnter (dp, "..", pdp, ds, cred);
   if (err)
     {
diff --git a/libdiskfs/dir-link.c b/libdiskfs/dir-link.c
index ca5dd56..403e9d5 100644
--- a/libdiskfs/dir-link.c
+++ b/libdiskfs/dir-link.c
@@ -106,7 +106,7 @@ diskfs_S_dir_link (struct protid *dircred,
   /* Attach it */
   if (tnp)
     {
-      assert (!excl);
+      assert_backtrace (!excl);
       err = diskfs_dirrewrite (dnp, tnp, np, name, ds);
       if (!err)
        {
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index 8b43e27..3c7198f 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -100,7 +100,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
 
   do
     {
-      assert (!lastcomp);
+      assert_backtrace (!lastcomp);
 
       /* Find the name of the next pathname component */
       nextname = index (filename, '/');
@@ -377,7 +377,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
                                        0, np->dn_stat.st_size, 0,
                                        dircred, &amt);
              if (!err)
-               assert (amt == np->dn_stat.st_size);
+               assert_backtrace (amt == np->dn_stat.st_size);
            }
          if (err)
            goto out;
diff --git a/libdiskfs/dir-renamed.c b/libdiskfs/dir-renamed.c
index a4878f3..772258d 100644
--- a/libdiskfs/dir-renamed.c
+++ b/libdiskfs/dir-renamed.c
@@ -93,7 +93,7 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, const 
char *fromname,
   /* 1: Lookup target; if it exists, make sure it's an empty directory. */
   ds = buf;
   err = diskfs_lookup (tdp, toname, RENAME, &tnp, ds, tocred);
-  assert (err != EAGAIN);      /* <-> assert (TONAME != "..") */
+  assert_backtrace (err != EAGAIN);    /* <-> assert_backtrace (TONAME != 
"..") */
   if (err && err != ENOENT)
     goto out;
 
@@ -110,7 +110,7 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, 
const char *fromname,
   /* Check permissions to remove FROMNAME and lock FNP.  */
   tmpds = alloca (diskfs_dirstat_size);
   err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, tmpds, fromcred);
-  assert (!tmpnp || tmpnp == fnp);
+  assert_backtrace (!tmpnp || tmpnp == fnp);
   if (tmpnp)
     diskfs_nrele (tmpnp);
   diskfs_drop_dirstat (fdp, tmpds);
@@ -144,13 +144,13 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, 
const char *fromname,
       tmpds = alloca (diskfs_dirstat_size);
       err = diskfs_lookup (fnp, "..", RENAME | SPEC_DOTDOT,
                           &tmpnp, tmpds, fromcred);
-      assert (err != ENOENT);
+      assert_backtrace (err != ENOENT);
       if (err)
        {
          diskfs_drop_dirstat (fnp, tmpds);
          goto out;
        }
-      assert (tmpnp == fdp);
+      assert_backtrace (tmpnp == fdp);
 
       err = diskfs_dirrewrite (fnp, fdp, tdp, "..", tmpds);
       if (diskfs_synchronous)
@@ -207,12 +207,12 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, 
const char *fromname,
   ds = buf;
   pthread_mutex_unlock (&fnp->lock);
   err = diskfs_lookup (fdp, fromname, REMOVE, &tmpnp, ds, fromcred);
-  assert (!tmpnp || tmpnp == fnp);
+  assert_backtrace (!tmpnp || tmpnp == fnp);
   if (tmpnp)
     diskfs_nrele (tmpnp);
   if (err)
     {
-      assert (!tmpnp);
+      assert_backtrace (!tmpnp);
       /* diskfs_lookup has not locked fnp then, do not unlock it. */
       fnp = NULL;
       goto out;
diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c
index 434ceed..1a5d8bf 100644
--- a/libdiskfs/disk-pager.c
+++ b/libdiskfs/disk-pager.c
@@ -93,10 +93,10 @@ fault_handler (int sig, long int sigcode, struct sigcontext 
*scp)
             sig, sigcode,
             preemptor.first, preemptor.last,
             scp->sc_pc, scp->sc_error);
-      assert (scp->sc_error == EKERN_MEMORY_ERROR);
+      assert_backtrace (scp->sc_error == EKERN_MEMORY_ERROR);
       err = pager_get_error (diskfs_disk_pager, sigcode);
-      assert (err);
-      assert_perror (err);
+      assert_backtrace (err);
+      assert_perror_backtrace (err);
     }
 #endif
 
@@ -104,9 +104,9 @@ fault_handler (int sig, long int sigcode, struct sigcontext 
*scp)
   diskfs_exception_diu = NULL;
 
   /* Fetch the error code from the pager.  */
-  assert (scp->sc_error == EKERN_MEMORY_ERROR);
+  assert_backtrace (scp->sc_error == EKERN_MEMORY_ERROR);
   err = pager_get_error (diskfs_disk_pager, sigcode);
-  assert (err);
+  assert_backtrace (err);
 
   /* Make `diskfault_catch' return the error code.  */
   longjmp (diskfs_exception_diu->env, err);
diff --git a/libdiskfs/diskfs-pager.h b/libdiskfs/diskfs-pager.h
index 550ca64..e822741 100644
--- a/libdiskfs/diskfs-pager.h
+++ b/libdiskfs/diskfs-pager.h
@@ -24,7 +24,7 @@
 #include <setjmp.h>
 #include <pthread.h>
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdlib.h>
 
 extern __thread struct disk_image_user *diskfs_exception_diu;
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index 106aeb0..40af37a 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -20,7 +20,7 @@
 #ifndef _HURD_DISKFS
 #define _HURD_DISKFS
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <hurd/ports.h>
@@ -216,7 +216,6 @@ struct pager;
 extern struct port_class *diskfs_protid_class;
 extern struct port_class *diskfs_control_class;
 extern struct port_class *diskfs_execboot_class;
-extern struct port_class *diskfs_initboot_class;
 extern struct port_class *diskfs_shutdown_notification_class;
 
 extern struct port_bucket *diskfs_port_bucket;
@@ -587,11 +586,11 @@ error_t (*diskfs_create_symlink_hook)(struct node *np, 
const char *target);
 error_t (*diskfs_read_symlink_hook)(struct node *np, char *target);
 
 /* The user may define this function.  The function must set source to
-   the source of CRED. The function may return an EOPNOTSUPP to
-   indicate that the concept of a source device is not applicable. The
-   default function always returns EOPNOTSUPP. */
-error_t diskfs_get_source (struct protid *cred,
-                           char *source, size_t source_len);
+   the source of the translator. The function may return an EOPNOTSUPP
+   to indicate that the concept of a source device is not
+   applicable. The default function always returns diskfs_disk_name,
+   or EOPNOTSUPP if it is NULL. */
+error_t diskfs_get_source (char *source, size_t source_len);
 
 /* Libdiskfs contains a node cache.
 
@@ -926,7 +925,7 @@ diskfs_begin_using_protid_payload (unsigned long payload)
 DISKFS_EXTERN_INLINE struct diskfs_control *
 diskfs_begin_using_control_port (fsys_t port)
 {
-  return ports_lookup_port (diskfs_port_bucket, port, NULL);
+  return ports_lookup_port (diskfs_port_bucket, port, diskfs_control_class);
 }
 
 DISKFS_EXTERN_INLINE struct diskfs_control *
@@ -934,7 +933,7 @@ diskfs_begin_using_control_port_payload (unsigned long 
payload)
 {
   return ports_lookup_payload (diskfs_port_bucket,
                               payload,
-                              NULL);
+                              diskfs_control_class);
 }
 
 /* And for the exec_startup interface. */
diff --git a/libdiskfs/file-get-source.c b/libdiskfs/file-get-source.c
index b5c3184..d983a82 100644
--- a/libdiskfs/file-get-source.c
+++ b/libdiskfs/file-get-source.c
@@ -33,5 +33,5 @@ diskfs_S_file_get_source (struct protid *cred,
       || cred->pi.class != diskfs_protid_class)
     return EOPNOTSUPP;
 
-  return diskfs_get_source (cred, source, 1024 /* XXX */);
+  return diskfs_get_source (source, 1024 /* XXX */);
 }
diff --git a/libdiskfs/file-get-trans.c b/libdiskfs/file-get-trans.c
index e6e994d..be07605 100644
--- a/libdiskfs/file-get-trans.c
+++ b/libdiskfs/file-get-trans.c
@@ -42,7 +42,7 @@ diskfs_S_file_get_translator (struct protid *cred,
     {
       unsigned int len = sizeof _HURD_SYMLINK + np->dn_stat.st_size + 1;
       size_t amt;
-      assert (diskfs_shortcut_symlink);
+      assert_backtrace (diskfs_shortcut_symlink);
       if (len > *translen)
        *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
       memcpy (*trans, _HURD_SYMLINK, sizeof _HURD_SYMLINK);
@@ -55,7 +55,7 @@ diskfs_S_file_get_translator (struct protid *cred,
          err = diskfs_node_rdwr (np, *trans + sizeof _HURD_SYMLINK,
                                    0, np->dn_stat.st_size, 0, cred, &amt);
          if (!err)
-           assert (amt == np->dn_stat.st_size);
+           assert_backtrace (amt == np->dn_stat.st_size);
        }
       if (!err)
        {
@@ -71,9 +71,9 @@ diskfs_S_file_get_translator (struct protid *cred,
       unsigned int buflen;
 
       if (S_ISCHR (np->dn_stat.st_mode))
-       assert (diskfs_shortcut_chrdev);
+       assert_backtrace (diskfs_shortcut_chrdev);
       else
-       assert (diskfs_shortcut_blkdev);
+       assert_backtrace (diskfs_shortcut_blkdev);
 
       buflen = asprintf (&buf, "%s%c%d%c%d",
                         (S_ISCHR (np->dn_stat.st_mode)
diff --git a/libdiskfs/file-getfh.c b/libdiskfs/file-getfh.c
index e4bc892..ce5c199 100644
--- a/libdiskfs/file-getfh.c
+++ b/libdiskfs/file-getfh.c
@@ -37,7 +37,7 @@ diskfs_S_file_getfh (struct protid *cred, char **fh, size_t 
*fh_len)
   if (! idvec_contains (cred->user->uids, 0))
     return EPERM;
 
-  assert (sizeof *f == sizeof f->bytes);
+  assert_backtrace (sizeof *f == sizeof f->bytes);
 
   node = cred->po->np;
 
diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c
index 3238037..6a73e23 100644
--- a/libdiskfs/file-set-trans.c
+++ b/libdiskfs/file-set-trans.c
@@ -141,7 +141,7 @@ diskfs_S_file_set_translator (struct protid *cred,
                  char *arg;
 
                  arg = passive + strlen (passive) + 1;
-                 assert (arg <= passive + passivelen);
+                 assert_backtrace (arg <= passive + passivelen);
                  if (arg == passive + passivelen)
                    {
                      pthread_mutex_unlock (&np->lock);
@@ -150,7 +150,7 @@ diskfs_S_file_set_translator (struct protid *cred,
                  major = strtol (arg, 0, 0);
 
                  arg = arg + strlen (arg) + 1;
-                 assert (arg < passive + passivelen);
+                 assert_backtrace (arg < passive + passivelen);
                  if (arg == passive + passivelen)
                    {
                      pthread_mutex_unlock (&np->lock);
@@ -185,7 +185,7 @@ diskfs_S_file_set_translator (struct protid *cred,
              if (newmode == S_IFLNK)
                {
                  char *arg = passive + strlen (passive) + 1;
-                 assert (arg <= passive + passivelen);
+                 assert_backtrace (arg <= passive + passivelen);
                  if (arg == passive + passivelen)
                    {
                      pthread_mutex_unlock (&np->lock);
diff --git a/libdiskfs/fsys-getfile.c b/libdiskfs/fsys-getfile.c
index 9dd5d73..e4dbe36 100644
--- a/libdiskfs/fsys-getfile.c
+++ b/libdiskfs/fsys-getfile.c
@@ -42,8 +42,7 @@ diskfs_S_fsys_getfile (struct diskfs_control *pt,
   struct peropen *new_po;
   struct iouser *user;
 
-  if (!pt
-      || pt->pi.class != diskfs_control_class)
+  if (!pt)
     return EOPNOTSUPP;
 
   if (handle_len != sizeof *f)
diff --git a/libdiskfs/fsys-getroot.c b/libdiskfs/fsys-getroot.c
index 6f93888..735f359 100644
--- a/libdiskfs/fsys-getroot.c
+++ b/libdiskfs/fsys-getroot.c
@@ -54,8 +54,7 @@ diskfs_S_fsys_getroot (struct diskfs_control *pt,
     path: NULL,
   };
 
-  if (!pt
-      || pt->pi.class != diskfs_control_class)
+  if (!pt)
     return EOPNOTSUPP;
 
   flags &= O_HURD;
diff --git a/libdiskfs/fsys-goaway.c b/libdiskfs/fsys-goaway.c
index 9b64195..f716970 100644
--- a/libdiskfs/fsys-goaway.c
+++ b/libdiskfs/fsys-goaway.c
@@ -31,13 +31,12 @@ diskfs_S_fsys_goaway (struct diskfs_control *pt,
                      int flags)
 {
   error_t ret;
-  
-  if (!pt
-      || pt->pi.class != diskfs_control_class)
+
+  if (!pt)
     return EOPNOTSUPP;
-  
+
   /* XXX FSYS_GOAWAY_NOWAIT not implemented. */
-  
+
   ret = diskfs_shutdown (flags);
 
   if (ret == 0)
diff --git a/libdiskfs/fsys-options.c b/libdiskfs/fsys-options.c
index b366d14..f676ed0 100644
--- a/libdiskfs/fsys-options.c
+++ b/libdiskfs/fsys-options.c
@@ -58,8 +58,7 @@ diskfs_S_fsys_set_options (struct diskfs_control *pt,
        return error;
       }
 
-  if (!pt
-      || pt->pi.class != diskfs_control_class)
+  if (!pt)
     return EOPNOTSUPP;
 
   if (do_children)
@@ -90,8 +89,7 @@ diskfs_S_fsys_get_options (struct diskfs_control *port,
   size_t argz_len = 0;
   error_t err;
 
-  if (!port
-      || port->pi.class != diskfs_control_class)
+  if (!port)
     return EOPNOTSUPP;
 
   err = argz_add (&argz, &argz_len, program_invocation_name);
diff --git a/libdiskfs/fsys-syncfs.c b/libdiskfs/fsys-syncfs.c
index 4dceed7..17b83ee 100644
--- a/libdiskfs/fsys-syncfs.c
+++ b/libdiskfs/fsys-syncfs.c
@@ -46,11 +46,10 @@ diskfs_S_fsys_syncfs (struct diskfs_control *pi,
        pthread_mutex_lock (&np->lock);
        return 0;
       }
-  
-  if (!pi
-      || pi->pi.class != diskfs_control_class)
+
+  if (!pi)
     return EOPNOTSUPP;
-  
+
   pthread_rwlock_rdlock (&diskfs_fsys_lock);
 
   if (children)
diff --git a/libdiskfs/get-source.c b/libdiskfs/get-source.c
index 2ef8ebc..9962ee9 100644
--- a/libdiskfs/get-source.c
+++ b/libdiskfs/get-source.c
@@ -22,7 +22,7 @@
 #include "priv.h"
 
 error_t __attribute__ ((weak))
-diskfs_get_source (struct protid *cred, char *source, size_t source_len)
+diskfs_get_source (char *source, size_t source_len)
 {
   if (diskfs_disk_name == NULL)
     return EOPNOTSUPP;
diff --git a/libdiskfs/init-init.c b/libdiskfs/init-init.c
index 357960b..b9a714f 100644
--- a/libdiskfs/init-init.c
+++ b/libdiskfs/init-init.c
@@ -46,7 +46,6 @@ int _diskfs_ncontrol_ports;
 
 struct port_class *diskfs_protid_class;
 struct port_class *diskfs_control_class;
-struct port_class *diskfs_initboot_class;
 struct port_class *diskfs_execboot_class;
 struct port_class *diskfs_shutdown_notification_class;
 
@@ -69,14 +68,16 @@ diskfs_init_diskfs (void)
          diskfs_default_pager = MACH_PORT_NULL;
          err = vm_set_default_memory_manager (host, &diskfs_default_pager);
          mach_port_deallocate (mach_task_self (), host);
-
-         if (!err)
-           err = maptime_map (1, 0, &diskfs_mtime);
        }
+      if (err)
+       return err;
     }
-  else
-    err = maptime_map (0, 0, &diskfs_mtime);
 
+  /* First try to use /dev/time...  */
+  err = maptime_map (0, NULL, &diskfs_mtime);
+  if (err)
+    /* ... and fall back to the Mach time device.  */
+    err = maptime_map (1, NULL, &diskfs_mtime);
   if (err)
     return err;
 
@@ -89,7 +90,6 @@ diskfs_init_diskfs (void)
 
   diskfs_protid_class = ports_create_class (diskfs_protid_rele, 0);
   diskfs_control_class = ports_create_class (_diskfs_control_clean, 0);
-  diskfs_initboot_class = ports_create_class (0, 0);
   diskfs_execboot_class = ports_create_class (0, 0);
   diskfs_shutdown_notification_class = ports_create_class (0, 0);
 
diff --git a/libdiskfs/init-main.c b/libdiskfs/init-main.c
index 3e03ae4..5c29b7b 100644
--- a/libdiskfs/init-main.c
+++ b/libdiskfs/init-main.c
@@ -19,7 +19,7 @@
 
 #include "diskfs.h"
 #include <argp.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <error.h>
 #include <hurd/store.h>
 
@@ -37,7 +37,7 @@ diskfs_init_main (struct argp *startup_argp,
   err = argp_parse (startup_argp ?: &diskfs_store_startup_argp,
                    argc, argv, ARGP_IN_ORDER, NULL,
                    &store_params);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   *store_parsed = store_params.result;
 
   err = store_parsed_name (*store_parsed, &diskfs_disk_name);
diff --git a/libdiskfs/init-startup.c b/libdiskfs/init-startup.c
index c1407ed..a2e3638 100644
--- a/libdiskfs/init-startup.c
+++ b/libdiskfs/init-startup.c
@@ -56,9 +56,9 @@ diskfs_startup_diskfs (mach_port_t bootstrap, int flags)
       /* Create a protid we can use in diskfs_lookup.  */
       err = diskfs_make_peropen (diskfs_root_node, O_READ|O_EXEC,
                                 0, &rootpo);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       err = diskfs_create_protid (rootpo, 0, &rootpi);
-      assert_perror (err);
+      assert_perror_backtrace (err);
 
       /* Look up the directory name.  */
       err = diskfs_lookup (diskfs_root_node, _diskfs_chroot_directory,
@@ -185,7 +185,7 @@ _diskfs_init_completed ()
      If we get an error, print an informational message. */
 
   proc = getproc ();
-  assert (proc);
+  assert_backtrace (proc);
 
   err = ports_create_port (diskfs_shutdown_notification_class,
                           diskfs_port_bucket, sizeof (struct port_info),
diff --git a/libdiskfs/io-map-cntl.c b/libdiskfs/io-map-cntl.c
index 2e9b9e9..4a9b1f6 100644
--- a/libdiskfs/io-map-cntl.c
+++ b/libdiskfs/io-map-cntl.c
@@ -28,7 +28,7 @@ diskfs_S_io_map_cntl (struct protid *cred,
   if (!cred)
     return EOPNOTSUPP;
 
-  assert (__vm_page_size >= sizeof (struct shared_io));
+  assert_backtrace (__vm_page_size >= sizeof (struct shared_io));
   pthread_mutex_lock (&cred->po->np->lock);
   if (!cred->mapped)
     {
diff --git a/libdiskfs/io-reauthenticate.c b/libdiskfs/io-reauthenticate.c
index 985db49..1b88a3b 100644
--- a/libdiskfs/io-reauthenticate.c
+++ b/libdiskfs/io-reauthenticate.c
@@ -47,7 +47,7 @@ diskfs_S_io_reauthenticate (struct protid *cred,
     }
 
   newright = ports_get_send_right (newcred);
-  assert (newright != MACH_PORT_NULL);
+  assert_backtrace (newright != MACH_PORT_NULL);
 
   /* Release the node lock while blocking on the auth server and client.  */
   pthread_mutex_unlock (&cred->po->np->lock);
diff --git a/libdiskfs/io-write.c b/libdiskfs/io-write.c
index 2967c4c..f3e191b 100644
--- a/libdiskfs/io-write.c
+++ b/libdiskfs/io-write.c
@@ -40,7 +40,7 @@ diskfs_S_io_write (struct protid *cred,
 
   pthread_mutex_lock (&np->lock);
 
-  assert (!S_ISDIR(np->dn_stat.st_mode));
+  assert_backtrace (!S_ISDIR(np->dn_stat.st_mode));
 
   iohelp_get_conch (&np->conch);
 
diff --git a/libdiskfs/lookup.c b/libdiskfs/lookup.c
index 486fedc..b619365 100644
--- a/libdiskfs/lookup.c
+++ b/libdiskfs/lookup.c
@@ -78,7 +78,7 @@ diskfs_lookup (struct node *dp, const char *name, enum 
lookup_type type,
   struct node *cached;
 
   if (type == REMOVE || type == RENAME)
-    assert (np);
+    assert_backtrace (np);
 
   if (!S_ISDIR (dp->dn_stat.st_mode))
     {
diff --git a/libdiskfs/name-cache.c b/libdiskfs/name-cache.c
index 53935ab..9959175 100644
--- a/libdiskfs/name-cache.c
+++ b/libdiskfs/name-cache.c
@@ -20,7 +20,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include "priv.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/ihash.h>
 #include <string.h>
 
@@ -93,7 +93,7 @@ add_entry (struct cache_bucket *b, int i,
     free (charp (b->name[i]));
 
   b->name[i] = (unsigned long) strdup (name);
-  assert ((b->name[i] & 3) == 0);
+  assert_backtrace ((b->name[i] & 3) == 0);
   if (b->name[i] == 0)
     return;
 
diff --git a/libdiskfs/node-cache.c b/libdiskfs/node-cache.c
index ee7e6fd..d281588 100644
--- a/libdiskfs/node-cache.c
+++ b/libdiskfs/node-cache.c
@@ -105,7 +105,7 @@ diskfs_cached_lookup_context (ino_t inum, struct node **npp,
 
   err = hurd_ihash_locp_add (&nodecache, slot,
                             (hurd_ihash_key_t) &np->cache_id, np);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   diskfs_nref_light (np);
   pthread_rwlock_unlock (&nodecache_lock);
 
@@ -138,7 +138,7 @@ diskfs_cached_ifind (ino_t inum)
   np = hurd_ihash_find (&nodecache, (hurd_ihash_key_t) &inum);
   pthread_rwlock_unlock (&nodecache_lock);
 
-  assert (np);
+  assert_backtrace (np);
   return np;
 }
 
@@ -233,7 +233,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *))
 error_t __attribute__ ((weak))
 diskfs_user_make_node (struct node **npp, struct lookup_context *ctx)
 {
-  assert (! "diskfs_user_make_node not implemented");
+  assert_backtrace (! "diskfs_user_make_node not implemented");
 }
 
 /* The user must define this function if she wants to use the node
@@ -241,7 +241,7 @@ diskfs_user_make_node (struct node **npp, struct 
lookup_context *ctx)
 error_t __attribute__ ((weak))
 diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
 {
-  assert (! "diskfs_user_read_node not implemented");
+  assert_backtrace (! "diskfs_user_read_node not implemented");
 }
 
 /* The user must define this function if she wants to use the node
@@ -250,5 +250,5 @@ diskfs_user_read_node (struct node *np, struct 
lookup_context *ctx)
 void __attribute__ ((weak))
 diskfs_user_try_dropping_softrefs (struct node *np)
 {
-  assert (! "diskfs_user_try_dropping_softrefs not implemented");
+  assert_backtrace (! "diskfs_user_try_dropping_softrefs not implemented");
 }
diff --git a/libdiskfs/node-drop.c b/libdiskfs/node-drop.c
index 455031b..aa00cf0 100644
--- a/libdiskfs/node-drop.c
+++ b/libdiskfs/node-drop.c
@@ -41,7 +41,7 @@ diskfs_drop_node (struct node *np)
   if (np->dn_stat.st_nlink == 0)
     {
       diskfs_check_readonly ();
-      assert (!diskfs_readonly);
+      assert_backtrace (!diskfs_readonly);
 
       if (np->dn_stat.st_mode & S_IPTRANS)
        diskfs_set_translator (np, 0, 0, 0);
@@ -70,7 +70,7 @@ diskfs_drop_node (struct node *np)
          return;
        }
 
-      assert (np->dn_stat.st_size == 0);
+      assert_backtrace (np->dn_stat.st_size == 0);
 
       savemode = np->dn_stat.st_mode;
       np->dn_stat.st_mode = 0;
@@ -89,7 +89,7 @@ diskfs_drop_node (struct node *np)
   if (np->filemod_reqs)
     free_modreqs (np->filemod_reqs);
 
-  assert (!np->sockaddr);
+  assert_backtrace (!np->sockaddr);
 
   pthread_mutex_unlock(&np->lock);
   pthread_mutex_destroy(&np->lock);
diff --git a/libdiskfs/priv.h b/libdiskfs/priv.h
index 276d093..bece45a 100644
--- a/libdiskfs/priv.h
+++ b/libdiskfs/priv.h
@@ -27,7 +27,7 @@
 #include <hurd/fshelp.h>
 #include <hurd/iohelp.h>
 #include <hurd/port.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <argp.h>
 
 #include "diskfs.h"
diff --git a/libdiskfs/protid-make.c b/libdiskfs/protid-make.c
index 0b09299..f8b5dcb 100644
--- a/libdiskfs/protid-make.c
+++ b/libdiskfs/protid-make.c
@@ -17,7 +17,7 @@
 
 #include "priv.h"
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 /* Build and return in CRED a protid which has no user identification, for
    peropen PO.  On success, consume a reference to PO.  */
@@ -48,11 +48,11 @@ diskfs_finish_protid (struct protid *cred, struct iouser 
*user)
     err = iohelp_create_simple_iouser (&cred->user, 0, 0);
   else
     err = iohelp_dup_iouser (&cred->user, user);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   err = mach_port_move_member (mach_task_self (), cred->pi.port_right, 
                               diskfs_port_bucket->portset);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 }
 
 /* Create and return a protid for an existing peropen PO in CRED for
diff --git a/libdiskfs/rdwr-internal.c b/libdiskfs/rdwr-internal.c
index 0d40551..eec0d6a 100644
--- a/libdiskfs/rdwr-internal.c
+++ b/libdiskfs/rdwr-internal.c
@@ -39,7 +39,7 @@ _diskfs_rdwr_internal (struct node *np,
   error_t err = 0;
 
   if (dir)
-    assert (!diskfs_readonly);
+    assert_backtrace (!diskfs_readonly);
 
   if (*amt == 0)
     /* Zero-length writes do not update mtime or anything else, by POSIX.  */
diff --git a/libdiskfs/trans-callback.c b/libdiskfs/trans-callback.c
index 15e8f9a..d08f91c 100644
--- a/libdiskfs/trans-callback.c
+++ b/libdiskfs/trans-callback.c
@@ -38,7 +38,7 @@ _diskfs_translator_callback1_fn (void *cookie1, void *cookie2,
   err = diskfs_get_translator (np, argz, (u_int *) argz_len);
   if (err)
     {
-      assert (err != EOPNOTSUPP);
+      assert_backtrace (err != EOPNOTSUPP);
       return err;
     }
 
diff --git a/libfshelp/fetch-control.c b/libfshelp/fetch-control.c
index 91c65bb..0a11197 100644
--- a/libfshelp/fetch-control.c
+++ b/libfshelp/fetch-control.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "fshelp.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 error_t
 fshelp_fetch_control (struct transbox *box,
@@ -34,7 +34,7 @@ fshelp_fetch_control (struct transbox *box,
   if (err == KERN_INVALID_RIGHT)
     {
       err = mach_port_deallocate (mach_task_self (), *control);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       *control = box->active = MACH_PORT_NULL;
     }
 
diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c
index 75aa2d3..0248f11 100644
--- a/libfshelp/fetch-root.c
+++ b/libfshelp/fetch-root.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/fsys.h>
 #include <hurd/paths.h>
 #include <hurd/ports.h>
@@ -47,7 +47,7 @@ fshelp_fetch_root (struct transbox *box, void *cookie,
  start_over:
 
   if (box->active != MACH_PORT_NULL)
-    assert ((box->flags & TRANSBOX_STARTING) == 0);
+    assert_backtrace ((box->flags & TRANSBOX_STARTING) == 0);
   else
     {
       uid_t uid, gid;
diff --git a/libfshelp/get-identity.c b/libfshelp/get-identity.c
index 2dbd254..17244de 100644
--- a/libfshelp/get-identity.c
+++ b/libfshelp/get-identity.c
@@ -23,7 +23,7 @@
 #include <hurd/ports.h>
 #include <hurd/ihash.h>
 #include <stddef.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 static struct port_class *idclass = 0;
 static pthread_mutex_t idlock = PTHREAD_MUTEX_INITIALIZER;
@@ -49,7 +49,7 @@ id_clean (void *cookie)
 static void
 id_initialize ()
 {
-  assert (!idclass);
+  assert_backtrace (!idclass);
   idclass = ports_create_class (id_clean, NULL);
 }
 
diff --git a/libfshelp/lock-acquire.c b/libfshelp/lock-acquire.c
index 07df428..47a63da 100644
--- a/libfshelp/lock-acquire.c
+++ b/libfshelp/lock-acquire.c
@@ -19,7 +19,7 @@
 
 /* Written by Michael I. Bushnell.  */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <sys/file.h>
 
 #include "fshelp.h"
@@ -60,9 +60,9 @@ fshelp_acquire_lock (struct lock_box *box, int *user, 
pthread_mutex_t *mut,
       if (*user & LOCK_UN)
        return 0;
 
-      assert (*user == box->type ||
+      assert_backtrace (*user == box->type ||
              (*user == LOCK_SH && box->type == (LOCK_SH | LOCK_EX)));
-      assert (*user == LOCK_SH || *user == LOCK_EX ||
+      assert_backtrace (*user == LOCK_SH || *user == LOCK_EX ||
              *user == (LOCK_SH | LOCK_EX));
 
       if (*user == LOCK_SH)
@@ -153,10 +153,10 @@ fshelp_acquire_lock (struct lock_box *box, int *user, 
pthread_mutex_t *mut,
            return EINTR;
        }
 
-      assert ((flags & LOCK_SH) || (flags & LOCK_EX));
+      assert_backtrace ((flags & LOCK_SH) || (flags & LOCK_EX));
       if (flags & LOCK_SH)
        {
-         assert (!(box->type & LOCK_EX));
+         assert_backtrace (!(box->type & LOCK_EX));
          *user = LOCK_SH;
          box->type = LOCK_SH;
          box->shcount++;
@@ -182,7 +182,7 @@ fshelp_acquire_lock (struct lock_box *box, int *user, 
pthread_mutex_t *mut,
            }
          if (*user == LOCK_SH)
            {
-             assert (box->shcount == 1);
+             assert_backtrace (box->shcount == 1);
              box->shcount = 0;
            }
          box->type = LOCK_EX;
diff --git a/libfshelp/start-translator-long.c 
b/libfshelp/start-translator-long.c
index da6f52e..e1aea3c 100644
--- a/libfshelp/start-translator-long.c
+++ b/libfshelp/start-translator-long.c
@@ -26,7 +26,7 @@
 #include <fcntl.h>
 #include <stdint.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include "fshelp.h"
 
 
@@ -247,7 +247,7 @@ fshelp_start_translator_long (fshelp_open_fn_t 
underlying_open_fn,
   if (err)
     goto lose_task;
 
-  assert (ports_len > INIT_PORT_BOOTSTRAP);
+  assert_backtrace (ports_len > INIT_PORT_BOOTSTRAP);
   switch (ports_type)
     {
     case MACH_MSG_TYPE_MAKE_SEND:
diff --git a/libftpconn/unix.c b/libftpconn/unix.c
index 882fee8..2804e7c 100644
--- a/libftpconn/unix.c
+++ b/libftpconn/unix.c
@@ -252,14 +252,11 @@ ftp_conn_unix_start_get_stats (struct ftp_conn *conn,
 
  out:
 
-  if (req)
-    free (req);
+  free (req);
   if (err)
     {
-      if (s)
-       free (s);
-      if (searched_name)
-       free (searched_name);
+      free (s);
+      free (searched_name);
     }
   else
     {
diff --git a/libhurd-slab/slab.c b/libhurd-slab/slab.c
index 5a12a43..f66bfdd 100644
--- a/libhurd-slab/slab.c
+++ b/libhurd-slab/slab.c
@@ -25,7 +25,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <sys/mman.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <unistd.h>
 #include <pthread.h>
@@ -107,7 +107,7 @@ deallocate_buffer (struct hurd_slab_space *space, void 
*buffer, size_t size)
 static void
 insert_slab (struct hurd_slab_space *space, struct hurd_slab *slab)
 {
-  assert (slab->refcount == 0);
+  assert_backtrace (slab->refcount == 0);
   if (space->slab_first == 0)
     space->slab_first = space->slab_last = slab;
   else
@@ -214,7 +214,7 @@ init_space (hurd_slab_space_t space)
   /* If SIZE is so big that one object can not fit into a page
      something gotta be really wrong.  */ 
   size = (size + alignment - 1) & ~(alignment - 1);
-  assert (size <= (space->slab_size 
+  assert_backtrace (size <= (space->slab_size 
                   - sizeof (struct hurd_slab) 
                   - sizeof (union hurd_bufctl)));
 
@@ -488,7 +488,7 @@ put_on_slab_list (struct hurd_slab *slab, union hurd_bufctl 
*bufctl)
   bufctl->next = slab->free_list;
   slab->free_list = bufctl;
   slab->refcount--;
-  assert (slab->refcount >= 0);
+  assert_backtrace (slab->refcount >= 0);
 }
 
 
@@ -499,7 +499,7 @@ hurd_slab_dealloc (hurd_slab_space_t space, void *buffer)
   struct hurd_slab *slab;
   union hurd_bufctl *bufctl;
 
-  assert (space->initialized);
+  assert_backtrace (space->initialized);
 
   pthread_mutex_lock (&space->lock);
 
diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c
index 731e53c..c24a498 100644
--- a/libnetfs/dir-lookup.c
+++ b/libnetfs/dir-lookup.c
@@ -20,7 +20,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <fcntl.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <stdio.h>
 #include <hurd/paths.h>
@@ -92,7 +92,7 @@ netfs_S_dir_lookup (struct protid *dircred,
 
   do
     {
-      assert (!lastcomp);
+      assert_backtrace (!lastcomp);
 
       /* Find the name of the next pathname component */
       nextname = index (filename, '/');
diff --git a/libnetfs/file-get-children.c b/libnetfs/file-get-children.c
index e8ceddf..5a0ddf0 100644
--- a/libnetfs/file-get-children.c
+++ b/libnetfs/file-get-children.c
@@ -33,9 +33,7 @@ netfs_S_file_get_children (struct protid *cred,
                           mach_msg_type_number_t *children_len)
 {
   error_t err;
-  if (! cred
-      || cred->pi.bucket != netfs_port_bucket
-      || cred->pi.class != netfs_protid_class)
+  if (! cred)
     return EOPNOTSUPP;
 
   /* check_access performs the same permission check as is normally
diff --git a/libnetfs/file-get-source.c b/libnetfs/file-get-source.c
index 8b73d5a..acd3230 100644
--- a/libnetfs/file-get-source.c
+++ b/libnetfs/file-get-source.c
@@ -28,10 +28,8 @@ error_t
 netfs_S_file_get_source (struct protid *cred,
                         char *source)
 {
-  if (! cred
-      || cred->pi.bucket != netfs_port_bucket
-      || cred->pi.class != netfs_protid_class)
+  if (! cred)
     return EOPNOTSUPP;
 
-  return netfs_get_source (cred, source, 1024 /* XXX */);
+  return netfs_get_source (source, 1024 /* XXX */);
 }
diff --git a/libnetfs/file-set-translator.c b/libnetfs/file-set-translator.c
index 02c5583..bac950e 100644
--- a/libnetfs/file-set-translator.c
+++ b/libnetfs/file-set-translator.c
@@ -122,7 +122,7 @@ netfs_S_file_set_translator (struct protid *user,
          /* Find the device number from the arguments
             of the translator. */
          arg = passive + strlen (passive) + 1;
-         assert (arg <= passive + passivelen);
+         assert_backtrace (arg <= passive + passivelen);
          if (arg == passive + passivelen)
            {
              pthread_mutex_unlock (&np->lock);
@@ -131,7 +131,7 @@ netfs_S_file_set_translator (struct protid *user,
          major = strtol (arg, 0, 0);
 
          arg = arg + strlen (arg) + 1;
-         assert (arg < passive + passivelen);
+         assert_backtrace (arg < passive + passivelen);
          if (arg == passive + passivelen)
            {
              pthread_mutex_unlock (&np->lock);
@@ -147,7 +147,7 @@ netfs_S_file_set_translator (struct protid *user,
 
        case S_IFLNK:
          arg = passive + strlen (passive) + 1;
-         assert (arg <= passive + passivelen);
+         assert_backtrace (arg <= passive + passivelen);
          if (arg == passive + passivelen)
            {
              pthread_mutex_unlock (&np->lock);
diff --git a/libnetfs/get-source.c b/libnetfs/get-source.c
index 5a234bc..cf23744 100644
--- a/libnetfs/get-source.c
+++ b/libnetfs/get-source.c
@@ -22,7 +22,7 @@
 #include "priv.h"
 
 error_t __attribute__ ((weak))
-netfs_get_source (struct protid *cred, char *source, size_t source_len)
+netfs_get_source (char *source, size_t source_len)
 {
   return EOPNOTSUPP;
 }
diff --git a/libnetfs/io-reauthenticate.c b/libnetfs/io-reauthenticate.c
index b2d4a44..4351545 100644
--- a/libnetfs/io-reauthenticate.c
+++ b/libnetfs/io-reauthenticate.c
@@ -47,7 +47,7 @@ netfs_S_io_reauthenticate (struct protid *user, mach_port_t 
rend_port)
     }
 
   newright = ports_get_send_right (newpi);
-  assert (newright != MACH_PORT_NULL);
+  assert_backtrace (newright != MACH_PORT_NULL);
 
   /* Release the node lock while blocking on the auth server and client.  */
   pthread_mutex_unlock (&user->po->np->lock);
diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h
index e988d90..5b5ca93 100644
--- a/libnetfs/netfs.h
+++ b/libnetfs/netfs.h
@@ -22,7 +22,7 @@
 #include <hurd/ports.h>
 #include <hurd/fshelp.h>
 #include <hurd/iohelp.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 
 /* This library supports client-side network file system
@@ -320,11 +320,10 @@ error_t netfs_file_get_storage_info (struct iouser *cred,
                                     mach_msg_type_number_t *data_len);
 
 /* The user may define this function.  The function must set source to
-   the source of CRED. The function may return an EOPNOTSUPP to
-   indicate that the concept of a source device is not applicable. The
-   default function always returns EOPNOTSUPP. */
-error_t netfs_get_source (struct protid *cred,
-                          char *source, size_t source_len);
+   the source of the translator. The function may return an EOPNOTSUPP
+   to indicate that the concept of a source device is not
+   applicable. The default function always returns EOPNOTSUPP.  */
+error_t netfs_get_source (char *source, size_t source_len);
 
 /* Option parsing */
 
diff --git a/libnetfs/trans-callback.c b/libnetfs/trans-callback.c
index 99f4dc0..de43699 100644
--- a/libnetfs/trans-callback.c
+++ b/libnetfs/trans-callback.c
@@ -38,7 +38,7 @@ _netfs_translator_callback1_fn (void *cookie1, void *cookie2,
   err = netfs_get_translator (np, argz, argz_len);
   if (err)
     {
-      assert (err != EOPNOTSUPP);
+      assert_backtrace (err != EOPNOTSUPP);
       return err;
     }
 
diff --git a/libpager/data-return.c b/libpager/data-return.c
index 01f3db2..c0f5aaf 100644
--- a/libpager/data-return.c
+++ b/libpager/data-return.c
@@ -19,7 +19,7 @@
 #include "memory_object_S.h"
 #include <stdio.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 /* Worker function used by _pager_S_memory_object_data_return
    and _pager_S_memory_object_data_initialize.  All args are
@@ -125,7 +125,7 @@ _pager_do_write_request (struct pager *p,
   /* Mark these pages as being paged out.  */
   if (initializing)
     {
-      assert (npages <= 32);
+      assert_backtrace (npages <= 32);
       for (i = 0; i < npages; i++)
        {
          if (pm_entries[i] & PM_INIT)
@@ -228,7 +228,7 @@ _pager_do_write_request (struct pager *p,
 
   for (i = 0; i < npages; i++)
     {
-      assert (notified[i] == 0 || notified[i] == 1);
+      assert_backtrace (notified[i] == 0 || notified[i] == 1);
       if (notified[i])
        {
          short *pm_entry = &pm_entries[i];
diff --git a/libpager/demuxer.c b/libpager/demuxer.c
index 3fd0516..fcea629 100644
--- a/libpager/demuxer.c
+++ b/libpager/demuxer.c
@@ -15,7 +15,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <error.h>
 #include <mach/mig_errors.h>
 #include <pthread.h>
@@ -315,7 +315,7 @@ pager_start_workers (struct port_bucket *pager_bucket,
   pthread_t t;
   struct pager_requests *requests;
 
-  assert (out_requests != NULL);
+  assert_backtrace (out_requests != NULL);
 
   requests = malloc (sizeof *requests);
   if (requests == NULL)
@@ -376,7 +376,7 @@ pager_inhibit_workers (struct pager_requests *requests)
   pthread_mutex_lock (&requests->lock);
 
   /* Check the workers are not already inhibited.  */
-  assert (requests->queue_out == requests->queue_in);
+  assert_backtrace (requests->queue_out == requests->queue_in);
 
   /* Any new paging requests will go into a new queue.  */
   struct queue *new_queue = malloc (sizeof *new_queue);
@@ -409,9 +409,9 @@ pager_resume_workers (struct pager_requests *requests)
   pthread_mutex_lock (&requests->lock);
 
   /* Check the workers are inhibited.  */
-  assert (requests->queue_out != requests->queue_in);
-  assert (requests->asleep == WORKER_COUNT);
-  assert (queue_empty(requests->queue_out));
+  assert_backtrace (requests->queue_out != requests->queue_in);
+  assert_backtrace (requests->asleep == WORKER_COUNT);
+  assert_backtrace (queue_empty(requests->queue_out));
 
   /* The queue has been drained and will no longer be used.  */
   free (requests->queue_out);
diff --git a/libpager/pager-attr.c b/libpager/pager-attr.c
index cf16d9d..4280e26 100644
--- a/libpager/pager-attr.c
+++ b/libpager/pager-attr.c
@@ -16,7 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 /* Change the attributes of the memory object underlying pager P.
    Arguments MAY_CACHE and COPY_STRATEGY are as for
diff --git a/libpager/pager-memcpy.c b/libpager/pager-memcpy.c
index f98b049..1251593 100644
--- a/libpager/pager-memcpy.c
+++ b/libpager/pager-memcpy.c
@@ -20,7 +20,7 @@
 #include "pager.h"
 #include <sys/mman.h>
 #include <hurd/sigpreempt.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 
 /* Start using vm_copy over memcpy when we have that many page. This is
@@ -50,9 +50,9 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
 
   error_t do_vm_copy (void)
     {
-      assert ((offset & (vm_page_size - 1)) == 0);
-      assert (((vm_address_t) other & (vm_page_size - 1)) == 0);
-      assert (n >= vm_page_size);
+      assert_backtrace ((offset & (vm_page_size - 1)) == 0);
+      assert_backtrace (((vm_address_t) other & (vm_page_size - 1)) == 0);
+      assert_backtrace (n >= vm_page_size);
 
       do
        {
@@ -61,8 +61,8 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
            ? (n - (n & (vm_page_size - 1)))
            : VMCOPY_WINDOW_DEFAULT_SIZE;
 
-         assert (window_size >= VMCOPY_BETTER_THAN_MEMCPY);
-         assert ((window_size & (vm_page_size - 1)) == 0);
+         assert_backtrace (window_size >= VMCOPY_BETTER_THAN_MEMCPY);
+         assert_backtrace ((window_size & (vm_page_size - 1)) == 0);
          
          window = 0;
          err = vm_map (mach_task_self (), &window, window_size, 0, 1,
@@ -135,8 +135,8 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
              to_copy -= copy_count;
              n -= copy_count;
 
-             assert (n >= 0);
-             assert (to_copy >= 0);
+             assert_backtrace (n >= 0);
+             assert_backtrace (to_copy >= 0);
            }
          while (to_copy > 0);
          
@@ -157,14 +157,14 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
          if (err)
            return err;
    
-         assert (n >= VMCOPY_BETTER_THAN_MEMCPY);
+         assert_backtrace (n >= VMCOPY_BETTER_THAN_MEMCPY);
 
          err = do_vm_copy ();
          if (err || n == 0)
            /* We failed or we finished.  */
            return err;
 
-         assert (n < VMCOPY_BETTER_THAN_MEMCPY);
+         assert_backtrace (n < VMCOPY_BETTER_THAN_MEMCPY);
        }
 
       return do_memcpy (n);
@@ -173,7 +173,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
   jmp_buf buf;
   void fault (int signo, long int sigcode, struct sigcontext *scp)
     {
-      assert (scp->sc_error == EKERN_MEMORY_ERROR);
+      assert_backtrace (scp->sc_error == EKERN_MEMORY_ERROR);
       err = pager_get_error (pager, sigcode - window + offset);
       n -= sigcode - window;
       vm_deallocate (mach_task_self (), window, window_size);
@@ -199,7 +199,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
          return err;
        }
 
-      assert (n < VMCOPY_BETTER_THAN_MEMCPY);
+      assert_backtrace (n < VMCOPY_BETTER_THAN_MEMCPY);
     }
 
   /* Need to do it the hard way.  */
@@ -213,7 +213,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
                       &do_copy, (sighandler_t) &fault);
 
   if (! err)
-    assert (n == 0);
+    assert_backtrace (n == 0);
 
   *size -= n;
 
diff --git a/libpipe/pipe.c b/libpipe/pipe.c
index 0b53921..1d4f5cc 100644
--- a/libpipe/pipe.c
+++ b/libpipe/pipe.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include <string.h>            /* For memset() */
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdlib.h>
 
 #include <mach/time_value.h>
@@ -438,7 +438,7 @@ pipe_recv (struct pipe *pipe, int noblock, unsigned *flags, 
void **source,
        packet_read_ports (packet, ports, num_ports);
 
       packet = pq_next (pq, PACKET_TYPE_DATA, NULL);
-      assert (packet);         /* pipe_write always writes a data packet.  */
+      assert_backtrace (packet);               /* pipe_write always writes a 
data packet.  */
     }
   else
     /* No control data... */
diff --git a/libports/claim-right.c b/libports/claim-right.c
index 85592ff..2ead717 100644
--- a/libports/claim-right.c
+++ b/libports/claim-right.c
@@ -20,7 +20,7 @@
 
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <hurd/ihash.h>
 
@@ -39,7 +39,7 @@ ports_claim_right (void *portstruct)
   hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry);
   pthread_rwlock_unlock (&_ports_htable_lock);
   err = mach_port_move_member (mach_task_self (), ret, MACH_PORT_NULL);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   pthread_mutex_lock (&_ports_lock);
   pi->port_right = MACH_PORT_NULL;
   if (pi->flags & PORT_HAS_SENDRIGHTS)
diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c
index e3123b2..5c548a3 100644
--- a/libports/complete-deallocate.c
+++ b/libports/complete-deallocate.c
@@ -19,13 +19,13 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/ihash.h>
 
 void
 _ports_complete_deallocate (struct port_info *pi)
 {
-  assert ((pi->flags & PORT_HAS_SENDRIGHTS) == 0);
+  assert_backtrace ((pi->flags & PORT_HAS_SENDRIGHTS) == 0);
 
   if (MACH_PORT_VALID (pi->port_right))
     {
@@ -38,7 +38,7 @@ _ports_complete_deallocate (struct port_info *pi)
           /* A reference was reacquired through a hash table lookup.
              It's fine, we didn't touch anything yet. */
           /* XXX: This really shouldn't happen.  */
-          assert (! "reacquired reference w/o send rights");
+          assert_backtrace (! "reacquired reference w/o send rights");
           pthread_rwlock_unlock (&_ports_htable_lock);
           return;
         }
diff --git a/libports/create-internal.c b/libports/create-internal.c
index d79dc78..853d541 100644
--- a/libports/create-internal.c
+++ b/libports/create-internal.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/ihash.h>
 #include "ports.h"
 
@@ -49,7 +49,7 @@ _ports_create_port_internal (struct port_class *class,
     {
       err = mach_port_mod_refs (mach_task_self (), port,
                                MACH_PORT_RIGHT_RECEIVE, -1);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       return ENOMEM;
     }
 
@@ -123,7 +123,7 @@ _ports_create_port_internal (struct port_class *class,
   error_t e;
   e = mach_port_mod_refs (mach_task_self (), port,
                          MACH_PORT_RIGHT_RECEIVE, -1);
-  assert_perror (e);
+  assert_perror_backtrace (e);
   free (pi);
 
   return err;
diff --git a/libports/destroy-right.c b/libports/destroy-right.c
index 276255f..1afa80d 100644
--- a/libports/destroy-right.c
+++ b/libports/destroy-right.c
@@ -20,7 +20,7 @@
 
 #include "ports.h"
 #include <hurd/ihash.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include <pthread.h>
 #include <error.h>
@@ -73,7 +73,7 @@ ports_destroy_right (void *portstruct)
     {
       err = mach_port_mod_refs (mach_task_self (), port_right,
                                 MACH_PORT_RIGHT_RECEIVE, -1);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
 
   if (defer)
diff --git a/libports/get-right.c b/libports/get-right.c
index 8681f46..8b58d72 100644
--- a/libports/get-right.c
+++ b/libports/get-right.c
@@ -20,7 +20,7 @@
 
 #include "ports.h"
 #include <mach/notify.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 mach_port_t
 ports_get_right (void *port)
@@ -49,7 +49,7 @@ ports_get_right (void *port)
                                            pi->port_right,
                                            MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                            &foo);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       if (foo != MACH_PORT_NULL)
        mach_port_deallocate (mach_task_self (), foo);
     }
diff --git a/libports/get-send-right.c b/libports/get-send-right.c
index 3e00276..524cb8e 100644
--- a/libports/get-send-right.c
+++ b/libports/get-send-right.c
@@ -18,7 +18,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 mach_port_t
 ports_get_send_right (void *port)
@@ -32,7 +32,7 @@ ports_get_send_right (void *port)
 
   err = mach_port_insert_right (mach_task_self (),
                                right, right, MACH_MSG_TYPE_MAKE_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   return right;
 }
diff --git a/libports/import-port.c b/libports/import-port.c
index 2c638e1..3a13876 100644
--- a/libports/import-port.c
+++ b/libports/import-port.c
@@ -21,7 +21,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/ihash.h>
 #include <mach/notify.h>
 
@@ -107,7 +107,7 @@ ports_import_port (struct port_class *class, struct 
port_bucket *bucket,
                                            stat.mps_mscount, 
                                            port, MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                            &foo);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       if (foo != MACH_PORT_NULL)
        mach_port_deallocate (mach_task_self (), foo);
     }
diff --git a/libports/interrupt-on-notify.c b/libports/interrupt-on-notify.c
index b358e84..2feff63 100644
--- a/libports/interrupt-on-notify.c
+++ b/libports/interrupt-on-notify.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 /* Arrange for hurd_cancel to be called on RPC's thread if OBJECT gets notified
    that any of the things in COND have happened to PORT.  RPC should be an
@@ -176,7 +176,7 @@ ports_interrupt_self_on_notification (void *object,
       break;
   pthread_mutex_unlock (&_ports_lock);
 
-  assert (rpc);
+  assert_backtrace (rpc);
 
   /* We don't have to worry about RPC going away after we dropped the lock
      because we're that thread, and we're still here.  */
diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c
index 576e767..d42cf97 100644
--- a/libports/manage-multithread.c
+++ b/libports/manage-multithread.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <error.h>
 #include <stdio.h>
 #include <mach/message.h>
@@ -126,7 +126,7 @@ ports_manage_port_operations_multithread (struct 
port_bucket *bucket,
       int status;
       struct port_info *pi;
       struct rpc_info link;
-      register mig_reply_header_t *outp = (mig_reply_header_t *) outheadp;
+      mig_reply_header_t *outp = (mig_reply_header_t *) outheadp;
       static const mach_msg_type_t RetCodeType = {
                /* msgt_name = */               MACH_MSG_TYPE_INTEGER_32,
                /* msgt_size = */               32,
diff --git a/libports/manage-one-thread.c b/libports/manage-one-thread.c
index 313838c..4b92148 100644
--- a/libports/manage-one-thread.c
+++ b/libports/manage-one-thread.c
@@ -36,7 +36,7 @@ ports_manage_port_operations_one_thread (struct port_bucket 
*bucket,
       struct rpc_info link;
       int status;
       error_t err;
-      register mig_reply_header_t *outp = (mig_reply_header_t *) outheadp;
+      mig_reply_header_t *outp = (mig_reply_header_t *) outheadp;
       static const mach_msg_type_t RetCodeType = {
                /* msgt_name = */               MACH_MSG_TYPE_INTEGER_32,
                /* msgt_size = */               32,
diff --git a/libports/port-deref-deferred.c b/libports/port-deref-deferred.c
index 2580e91..76373eb 100644
--- a/libports/port-deref-deferred.c
+++ b/libports/port-deref-deferred.c
@@ -19,7 +19,7 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 #include "ports.h"
 
@@ -40,7 +40,7 @@ valid_color (unsigned int c)
 static inline unsigned int
 flip_color (unsigned int c)
 {
-  assert (valid_color (c));
+  assert_backtrace (valid_color (c));
   return ! c;
 }
 
@@ -60,7 +60,7 @@ _ports_threadpool_init (struct ports_threadpool *pool)
 static inline void
 flip_generations (struct ports_threadpool *pool)
 {
-  assert (pool->old_threads == 0);
+  assert_backtrace (pool->old_threads == 0);
   pool->old_threads = pool->young_threads;
   pool->old_objects = pool->young_objects;
   pool->young_threads = 0;
@@ -91,7 +91,7 @@ _ports_thread_quiescent (struct ports_threadpool *pool,
                         struct ports_thread *thread)
 {
   struct pi_list *free_list = NULL, *p;
-  assert (valid_color (thread->color));
+  assert_backtrace (valid_color (thread->color));
 
   pthread_spin_lock (&pool->lock);
   if (thread->color == pool->color)
@@ -123,7 +123,7 @@ void
 _ports_thread_offline (struct ports_threadpool *pool,
                       struct ports_thread *thread)
 {
-  assert (valid_color (thread->color));
+  assert_backtrace (valid_color (thread->color));
 
  retry:
   pthread_spin_lock (&pool->lock);
@@ -154,7 +154,7 @@ _ports_port_deref_deferred (struct port_info *pi)
   pool->young_objects = pl;
   if (pool->old_threads == 0)
     {
-      assert (pool->old_objects == NULL);
+      assert_backtrace (pool->old_objects == NULL);
       flip_generations (pool);
     }
   pthread_spin_unlock (&pool->lock);
diff --git a/libports/port-deref-weak.c b/libports/port-deref-weak.c
index 8432660..cb3f435 100644
--- a/libports/port-deref-weak.c
+++ b/libports/port-deref-weak.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_port_deref_weak (void *portstruct)
diff --git a/libports/port-deref.c b/libports/port-deref.c
index b97dd13..34fa6f4 100644
--- a/libports/port-deref.c
+++ b/libports/port-deref.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_port_deref (void *portstruct)
diff --git a/libports/port-ref-weak.c b/libports/port-ref-weak.c
index 3f62dfe..de75999 100644
--- a/libports/port-ref-weak.c
+++ b/libports/port-ref-weak.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_port_ref_weak (void *portstruct)
diff --git a/libports/port-ref.c b/libports/port-ref.c
index 9a1c71e..0088f09 100644
--- a/libports/port-ref.c
+++ b/libports/port-ref.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_port_ref (void *portstruct)
diff --git a/libports/reallocate-from-external.c 
b/libports/reallocate-from-external.c
index d0fae1a..7392aa8 100644
--- a/libports/reallocate-from-external.c
+++ b/libports/reallocate-from-external.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/ihash.h>
 #include <mach/notify.h>
 
@@ -33,15 +33,15 @@ ports_reallocate_from_external (void *portstruct, 
mach_port_t receive)
   error_t err;
 
   err = mach_port_get_receive_status (mach_task_self (), receive, &stat);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   
   pthread_mutex_lock (&_ports_lock);
   
-  assert (pi->port_right);
+  assert_backtrace (pi->port_right);
   
   err = mach_port_mod_refs (mach_task_self (), pi->port_right,
                            MACH_PORT_RIGHT_RECEIVE, -1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   pthread_rwlock_wrlock (&_ports_htable_lock);
   hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry);
@@ -65,11 +65,11 @@ ports_reallocate_from_external (void *portstruct, 
mach_port_t receive)
 
   pthread_rwlock_wrlock (&_ports_htable_lock);
   err = hurd_ihash_add (&_ports_htable, receive, pi);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = hurd_ihash_add (&pi->bucket->htable, receive, pi);
   pthread_rwlock_unlock (&_ports_htable_lock);
   pthread_mutex_unlock (&_ports_lock);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* This is an optimization.  It may fail.  */
   mach_port_set_protected_payload (mach_task_self (), pi->port_right,
@@ -84,7 +84,7 @@ ports_reallocate_from_external (void *portstruct, mach_port_t 
receive)
                                            stat.mps_mscount, receive,
                                            MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                            &foo);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       if (foo != MACH_PORT_NULL)
        mach_port_deallocate (mach_task_self (), foo);
     }
diff --git a/libports/reallocate-port.c b/libports/reallocate-port.c
index 4e859a1..8a9d360 100644
--- a/libports/reallocate-port.c
+++ b/libports/reallocate-port.c
@@ -20,7 +20,7 @@
 
 #include "ports.h"
 #include <hurd/ihash.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_reallocate_port (void *portstruct)
@@ -30,11 +30,11 @@ ports_reallocate_port (void *portstruct)
   int dropref = 0;
 
   pthread_mutex_lock (&_ports_lock);
-  assert (pi->port_right);
+  assert_backtrace (pi->port_right);
 
   err = mach_port_mod_refs (mach_task_self (), pi->port_right, 
                            MACH_PORT_RIGHT_RECEIVE, -1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   pthread_rwlock_wrlock (&_ports_htable_lock);
   hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry);
@@ -43,7 +43,7 @@ ports_reallocate_port (void *portstruct)
 
   err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
                            &pi->port_right);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   if (pi->flags & PORT_HAS_SENDRIGHTS)
     {
       pi->flags &= ~PORT_HAS_SENDRIGHTS;
@@ -53,11 +53,11 @@ ports_reallocate_port (void *portstruct)
   pi->mscount = 0;
   pthread_rwlock_wrlock (&_ports_htable_lock);
   err = hurd_ihash_add (&_ports_htable, pi->port_right, pi);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = hurd_ihash_add (&pi->bucket->htable, pi->port_right, pi);
   pthread_rwlock_unlock (&_ports_htable_lock);
   pthread_mutex_unlock (&_ports_lock);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* This is an optimization.  It may fail.  */
   mach_port_set_protected_payload (mach_task_self (), pi->port_right,
@@ -65,7 +65,7 @@ ports_reallocate_port (void *portstruct)
 
   err = mach_port_move_member (mach_task_self (), pi->port_right, 
                               pi->bucket->portset);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (dropref)
     ports_port_deref (pi);
diff --git a/libports/resume-all-rpcs.c b/libports/resume-all-rpcs.c
index e4befff..0b78c92 100644
--- a/libports/resume-all-rpcs.c
+++ b/libports/resume-all-rpcs.c
@@ -19,13 +19,13 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_resume_all_rpcs ()
 {
   pthread_mutex_lock (&_ports_lock);
-  assert (_ports_flags & _PORTS_INHIBITED);
+  assert_backtrace (_ports_flags & _PORTS_INHIBITED);
   _ports_flags &= ~_PORTS_INHIBITED;
   if (_ports_flags & _PORTS_BLOCKED)
     {
diff --git a/libports/resume-bucket-rpcs.c b/libports/resume-bucket-rpcs.c
index cf4db91..ad129f4 100644
--- a/libports/resume-bucket-rpcs.c
+++ b/libports/resume-bucket-rpcs.c
@@ -19,13 +19,13 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_resume_bucket_rpcs (struct port_bucket *bucket)
 {
   pthread_mutex_lock (&_ports_lock);
-  assert (bucket->flags & PORT_BUCKET_INHIBITED);
+  assert_backtrace (bucket->flags & PORT_BUCKET_INHIBITED);
   bucket->flags &= ~PORT_BUCKET_INHIBITED;
   if (bucket->flags & PORT_BUCKET_BLOCKED)
     {
diff --git a/libports/resume-class-rpcs.c b/libports/resume-class-rpcs.c
index 60a2b12..806108b 100644
--- a/libports/resume-class-rpcs.c
+++ b/libports/resume-class-rpcs.c
@@ -19,13 +19,13 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_resume_class_rpcs (struct port_class *class)
 {
   pthread_mutex_lock (&_ports_lock);
-  assert (class->flags & PORT_CLASS_INHIBITED);
+  assert_backtrace (class->flags & PORT_CLASS_INHIBITED);
   class->flags &= ~PORT_CLASS_INHIBITED;
   if (class->flags & PORT_CLASS_BLOCKED)
     {
diff --git a/libports/resume-port-rpcs.c b/libports/resume-port-rpcs.c
index 6d71ab5..1894bce 100644
--- a/libports/resume-port-rpcs.c
+++ b/libports/resume-port-rpcs.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 void
 ports_resume_port_rpcs (void *portstruct)
@@ -28,7 +28,7 @@ ports_resume_port_rpcs (void *portstruct)
   
   pthread_mutex_lock (&_ports_lock);
   
-  assert (pi->flags & PORT_INHIBITED);
+  assert_backtrace (pi->flags & PORT_INHIBITED);
   pi->flags &= ~PORT_INHIBITED;
   if (pi->flags & PORT_BLOCKED)
     {
diff --git a/libports/transfer-right.c b/libports/transfer-right.c
index 64de7f7..6e05dc6 100644
--- a/libports/transfer-right.c
+++ b/libports/transfer-right.c
@@ -20,7 +20,7 @@
 
 
 #include "ports.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/ihash.h>
 
 error_t
@@ -63,7 +63,7 @@ ports_transfer_right (void *tostruct,
       pthread_rwlock_unlock (&_ports_htable_lock);
       err = mach_port_mod_refs (mach_task_self (), topi->port_right,
                                MACH_PORT_RIGHT_RECEIVE, -1);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       if ((topi->flags & PORT_HAS_SENDRIGHTS) && !hassendrights)
        {
          dereftopi = 1;
@@ -87,10 +87,10 @@ ports_transfer_right (void *tostruct,
     {
       pthread_rwlock_wrlock (&_ports_htable_lock);
       err = hurd_ihash_add (&_ports_htable, port, topi);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       err = hurd_ihash_add (&topi->bucket->htable, port, topi);
       pthread_rwlock_unlock (&_ports_htable_lock);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       /* This is an optimization.  It may fail.  */
       mach_port_set_protected_payload (mach_task_self (), port,
                                       (unsigned long) topi);
@@ -98,7 +98,7 @@ ports_transfer_right (void *tostruct,
         {
          err = mach_port_move_member (mach_task_self (), port,
                                       topi->bucket->portset);
-         assert_perror (err);
+         assert_perror_backtrace (err);
        }
     }
 
diff --git a/libps/context.c b/libps/context.c
index 3082d83..8ed1594 100644
--- a/libps/context.c
+++ b/libps/context.c
@@ -21,7 +21,7 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/term.h>
 
 #include "ps.h"
diff --git a/libps/filters.c b/libps/filters.c
index 6663e61..1bc5a0e 100644
--- a/libps/filters.c
+++ b/libps/filters.c
@@ -21,7 +21,7 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pwd.h>
 #include <unistd.h>
 
diff --git a/libps/fmt.c b/libps/fmt.c
index f914212..4641663 100644
--- a/libps/fmt.c
+++ b/libps/fmt.c
@@ -21,7 +21,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <ctype.h>
 
@@ -362,12 +362,9 @@ ps_fmt_clone (struct ps_fmt *fmt, struct ps_fmt **copy)
 
   if (!new || !fields || !src)
     {
-      if (new)
-       free (new);
-      if (fields)
-       free (fields);
-      if (src)
-       free (src);
+      free (new);
+      free (fields);
+      free (src);
       return ENOMEM;
     }
 
diff --git a/libps/host.c b/libps/host.c
index 9a46e00..120e5c4 100644
--- a/libps/host.c
+++ b/libps/host.c
@@ -21,7 +21,7 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "ps.h"
 #include "common.h"
diff --git a/libps/proclist.c b/libps/proclist.c
index 9a4d6ed..4e2174a 100644
--- a/libps/proclist.c
+++ b/libps/proclist.c
@@ -21,7 +21,7 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 
 #include "ps.h"
@@ -63,14 +63,12 @@ proc_stat_list_clone (struct proc_stat_list *pp, struct 
proc_stat_list **copy)
 
   if (!new || !procs)
     {
-      if (new)
-       free (new);
-      if (procs)
-       free (procs);
+      free (new);
+      free (procs);
       return ENOMEM;
     }
 
-  bcopy (pp->proc_stats, procs, pp->num_procs);
+  memcpy (procs, pp->proc_stats, sizeof *procs * pp->num_procs);
 
   new->proc_stats = procs;
   new->num_procs = pp->num_procs;
diff --git a/libps/procstat.c b/libps/procstat.c
index 9f488cd..f6420ee 100644
--- a/libps/procstat.c
+++ b/libps/procstat.c
@@ -20,7 +20,7 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 
 #include "ps.h"
@@ -224,12 +224,12 @@ merge_procinfo (struct proc_stat *ps, ps_flags_t need, 
ps_flags_t have)
   /* There was old information, try merging it. */
   if (have & PSTAT_TASK_BASIC)
     /* Task info.  */
-    bcopy (&old_pi_hdr.taskinfo, &new_pi->taskinfo,
-          sizeof (struct task_basic_info));
+    memcpy (&new_pi->taskinfo, &old_pi_hdr.taskinfo,
+           sizeof (struct task_basic_info));
   if (have & PSTAT_TASK_EVENTS)
     /* Event info. */
-    bcopy (&old_pi_hdr.taskevents, &new_pi->taskevents,
-          sizeof (struct task_events_info));
+    memcpy (&new_pi->taskevents, &old_pi_hdr.taskevents,
+           sizeof (struct task_events_info));
   /* That's it for now.  */
 
   if (new_pi != ps->proc_info)
@@ -604,7 +604,7 @@ clone (void *src, size_t size)
 {
   void *dst = malloc (size);
   if (dst)
-    bcopy (src, dst, size);
+    memcpy (dst, src, size);
   return dst;
 }
 
diff --git a/libps/spec.c b/libps/spec.c
index bfee34e..5e540f8 100644
--- a/libps/spec.c
+++ b/libps/spec.c
@@ -21,7 +21,8 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
+#define assert assert_backtrace
 #include <pwd.h>
 #include <hurd/resource.h>
 #include <unistd.h>
@@ -1022,7 +1023,7 @@ specs_add_alias (struct ps_fmt_specs *specs,
   exp->name = malloc (name_len + 1);
   if (! exp->name)
     return 0;
-  bcopy ((char *)alias->name, (char *)exp->name, name_len);
+  memcpy ((char *)exp->name, (char *)alias->name, name_len);
   ((char *)exp->name)[name_len] = '\0';
 
   /* Copy the rest of the fields from ALIAS, but defaulting to SRC.  */
diff --git a/libps/tty.c b/libps/tty.c
index 3ab72ee..92f8f3e 100644
--- a/libps/tty.c
+++ b/libps/tty.c
@@ -22,7 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/term.h>
 
 #include "ps.h"
diff --git a/libps/user.c b/libps/user.c
index 0b87ace..f5b7edc 100644
--- a/libps/user.c
+++ b/libps/user.c
@@ -22,7 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "ps.h"
 #include "common.h"
diff --git a/libshouldbeinlibc/assert-backtrace.h 
b/libshouldbeinlibc/assert-backtrace.h
index af1d590..f49a537 100644
--- a/libshouldbeinlibc/assert-backtrace.h
+++ b/libshouldbeinlibc/assert-backtrace.h
@@ -27,6 +27,8 @@
 
 #else /* NDEBUG */
 
+#include <sys/cdefs.h>
+
 /* This prints an "Assertion failed" message, prints a stack trace,
    and aborts. */
 void __assert_fail_backtrace (const char *assertion,
diff --git a/libshouldbeinlibc/cacheq.c b/libshouldbeinlibc/cacheq.c
index 5912f84..d3a7591 100644
--- a/libshouldbeinlibc/cacheq.c
+++ b/libshouldbeinlibc/cacheq.c
@@ -95,7 +95,7 @@ cacheq_set_length (struct cacheq *cq, int length)
            (!th || th >= end) ? 0 : (void *)th + esz;
 
          if (fh && th)
-           bcopy (fh, th, esz); /* Copy the bits in a moved entry.  */
+           memcpy (th, fh, esz);       /* Copy the bits in a moved entry.  */
          else if (th)
            memset (th, 0, esz);        /* Zero the bits in a new entry.  */
 
diff --git a/libshouldbeinlibc/idvec-verify.c b/libshouldbeinlibc/idvec-verify.c
index 4019a04..a7d9576 100644
--- a/libshouldbeinlibc/idvec-verify.c
+++ b/libshouldbeinlibc/idvec-verify.c
@@ -22,7 +22,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
-#include <assert.h>
+#include "assert-backtrace.h"
 #include <idvec.h>
 #include <grp.h>
 #include <pwd.h>
@@ -258,7 +258,7 @@ verify_id (uid_t id, int is_group, int multiple,
   char sp_lookup_buf[1024];
 
   /* VERIFY_FN should have been defaulted in idvec_verify if necessary.  */
-  assert (verify_fn);
+  assert_backtrace (verify_fn);
 
   if (id != (uid_t) -1)
     do
diff --git a/libshouldbeinlibc/idvec.c b/libshouldbeinlibc/idvec.c
index c60fc9f..63f59f6 100644
--- a/libshouldbeinlibc/idvec.c
+++ b/libshouldbeinlibc/idvec.c
@@ -113,7 +113,7 @@ idvec_insert (struct idvec *idvec, unsigned pos, uid_t id)
     {
       uid_t *ids = idvec->ids;
       if (pos < num)
-       bcopy (ids + pos, ids + pos + 1, (num - pos) * sizeof (uid_t));
+       memmove (ids + pos + 1, ids + pos, (num - pos) * sizeof (uid_t));
       else if (pos > num)
        memset (ids + num, 0, (pos - num) * sizeof(uid_t));
       ids[pos] = id;
@@ -163,7 +163,7 @@ idvec_set_ids (struct idvec *idvec, const uid_t *ids, 
unsigned num)
   err = idvec_ensure (idvec, num);
   if (!err)
     {
-      bcopy (ids, idvec->ids, num * sizeof (uid_t));
+      memcpy (idvec->ids, ids, num * sizeof (uid_t));
       idvec->num = num;
     }
   return err;
@@ -279,7 +279,7 @@ idvec_delete (struct idvec *idvec, unsigned pos)
       uid_t *ids = idvec->ids;
       idvec->num = --num;
       if (num > pos)
-       bcopy (ids + pos + 1, ids + pos, (num - pos) * sizeof (uid_t));
+       memmove (ids + pos, ids + pos + 1, (num - pos) * sizeof (uid_t));
     }
 }
 
diff --git a/libshouldbeinlibc/timefmt.c b/libshouldbeinlibc/timefmt.c
index cef72e0..2bbeffc 100644
--- a/libshouldbeinlibc/timefmt.c
+++ b/libshouldbeinlibc/timefmt.c
@@ -296,7 +296,7 @@ fmt_past_time (struct timeval *tv, struct timeval *now,
   if (diff < 0)
     diff = -diff;              /* XXX */
 
-  bcopy (localtime ((time_t *) &tv->tv_sec), &tm, sizeof tm);
+  memcpy (&tm, localtime ((time_t *) &tv->tv_sec), sizeof tm);
 
   if (width <= 0 || width >= buf_len)
     width = buf_len - 1;
diff --git a/libshouldbeinlibc/wire.c b/libshouldbeinlibc/wire.c
index ca5d32b..5b41555 100644
--- a/libshouldbeinlibc/wire.c
+++ b/libshouldbeinlibc/wire.c
@@ -24,6 +24,7 @@
 #include <hurd.h>
 #include <error.h>
 #include <elf.h>
+#include <mach/gnumach.h>
 
 #pragma weak _DYNAMIC
 #pragma weak dlopen
@@ -34,15 +35,18 @@
 #define RTLD_NOLOAD 0
 #endif
 
+static int
+statically_linked (void)
+{
+  return &_DYNAMIC == 0;       /* statically linked */
+}
+
 /* Find the list of shared objects */
 static struct link_map *
 loaded (void)
 {
   ElfW(Dyn) *d;
 
-  if (&_DYNAMIC == 0)          /* statically linked */
-    return 0;
-
   for (d = _DYNAMIC; d->d_tag != DT_NULL; ++d)
     if (d->d_tag == DT_DEBUG)
       {
@@ -79,7 +83,7 @@ map_extent (struct link_map *map)
 
 /* Wire down all memory currently allocated at START for LEN bytes;
    host_priv is the privileged host port. */
-static void
+static error_t
 wire_segment_internal (vm_address_t start,
                       vm_size_t len,
                       host_priv_t host_priv)
@@ -101,40 +105,63 @@ wire_segment_internal (vm_address_t start,
       err = vm_region (mach_task_self (), &addr, &size, &protection,
                       &max_protection, &inheritance, &shared, &object_name,
                       &offset);
+      if (err == KERN_NO_SPACE)
+        return 0;      /* We're done.  */
       if (err)
-       return;
-
-      /* The current region begins at ADDR and is SIZE long.  If it
-        extends beyond the LEN, prune it. */
-      if (addr + size > start + len)
-       size = len - (addr - start);
-
-      /* Set protection to allow all access possible */
-      vm_protect (mach_task_self (), addr, size, 0, max_protection);
-
-      /* Generate write faults */
-      for (poke = (char *) addr;
-          (vm_address_t) poke < addr + size;
-          poke += vm_page_size)
-       *poke = *poke;
-
-      /* Wire pages */
-      vm_wire (host_priv, mach_task_self (), addr, size, max_protection);
-
-      /* Set protection back to what it was */
-      vm_protect (mach_task_self (), addr, size, 0, protection);
-
-
+       return err;
       mach_port_deallocate (mach_task_self (), object_name);
 
+      if (protection != VM_PROT_NONE)
+        {
+          /* The VM system cannot cope with a COW fault on another
+             unrelated virtual copy happening later when we have
+             wired down the original page.  So we must touch all our
+             pages before wiring to make sure that only we will ever
+             use them.  */
+
+          /* The current region begins at ADDR and is SIZE long.  If it
+             extends beyond the LEN, prune it. */
+          if (addr + size > start + len)
+            size = len - (addr - start);
+
+          /* Set protection to allow all access possible */
+          if (!(protection & VM_PROT_WRITE))
+            {
+              err = vm_protect (mach_task_self (), addr, size, 0, 
max_protection);
+              if (err)
+                return err;
+            }
+
+          /* Generate write faults */
+          for (poke = (char *) addr;
+               (vm_address_t) poke < addr + size;
+               poke += vm_page_size)
+            *poke = *poke;
+
+          /* Wire pages */
+          err = vm_wire (host_priv, mach_task_self (), addr, size, protection);
+          if (err)
+            return err;
+
+          /* Set protection back to what it was */
+          if (!(protection & VM_PROT_WRITE))
+            {
+              err = vm_protect (mach_task_self (), addr, size, 0, protection);
+              if (err)
+                return err;
+            }
+        }
+
       len -= (addr - start) + size;
       start = addr + size;
     }
   while (len);
+
+  return err;
 }
 
 /* Wire down all memory currently allocated at START for LEN bytes. */
-void
+error_t
 wire_segment (vm_address_t start,
              vm_size_t len)
 {
@@ -142,45 +169,64 @@ wire_segment (vm_address_t start,
   error_t err;
 
   err = get_privileged_ports (&host, &device);
-  if (!err)
-    {
-      wire_segment_internal (start, len, host);
-      mach_port_deallocate (mach_task_self (), host);
-      mach_port_deallocate (mach_task_self (), device);
-    }
-}
+  if (err)
+    return err;
 
+  err = wire_segment_internal (start, len, host);
+  mach_port_deallocate (mach_task_self (), host);
+  mach_port_deallocate (mach_task_self (), device);
+  return err;
+}
 
 /* Wire down all the text and data (including from shared libraries)
    for the current program. */
-void
+error_t
 wire_task_self ()
 {
-  struct link_map *map;
   mach_port_t host, device;
   error_t err;
-  extern char _edata, _etext, __data_start;
 
   err = get_privileged_ports (&host, &device);
   if (err)
-    return;
+    return err;
 
-  map = loaded ();
-  if (!map)
+  if (statically_linked ())
     {
       extern void _start ();
+      extern char _edata, _etext, __data_start;
       vm_address_t text_start = (vm_address_t) &_start;
-      wire_segment_internal (text_start,
-                            (vm_size_t) (&_etext - text_start),
-                            host);
-      wire_segment_internal ((vm_address_t) &__data_start,
-                            (vm_size_t) (&_edata - &__data_start),
-                            host);
+      err = wire_segment_internal (text_start,
+                                   (vm_size_t) (&_etext - text_start),
+                                   host);
+      if (err)
+        goto out;
+
+      err = wire_segment_internal ((vm_address_t) &__data_start,
+                                   (vm_size_t) (&_edata - &__data_start),
+                                   host);
     }
   else
-    while (map)
-      wire_segment ((vm_address_t) map->l_addr, map_extent (map));
+    {
+      struct link_map *map;
+
+      map = loaded ();
+      if (map)
+        for (err = 0; ! err && map; map = map->l_next)
+          err = wire_segment_internal ((vm_address_t) map->l_addr,
+                                       map_extent (map), host);
+      else
+        err = wire_segment_internal (VM_MIN_ADDRESS, VM_MAX_ADDRESS, host);
+    }
+
+  if (err)
+    goto out;
+
+  /* Automatically wire down future mappings, including those that are
+     currently PROT_NONE but become accessible.  */
+  err = vm_wire_all (host, mach_task_self (), VM_WIRE_ALL);
 
+ out:
   mach_port_deallocate (mach_task_self (), host);
   mach_port_deallocate (mach_task_self (), device);
+  return err;
 }
diff --git a/libshouldbeinlibc/wire.h b/libshouldbeinlibc/wire.h
index 6783cc5..2f310cf 100644
--- a/libshouldbeinlibc/wire.h
+++ b/libshouldbeinlibc/wire.h
@@ -20,7 +20,7 @@
 
 /* Wire down all the text and data (including from shared libraries)
    for the current program. */
-void wire_task_self (void);
+error_t wire_task_self (void);
 
 /* Wire down all memory currently allocated at START for LEN bytes. */
-void wire_segment (vm_address_t start, vm_size_t len);
+error_t wire_segment (vm_address_t start, vm_size_t len);
diff --git a/libstore/argp.c b/libstore/argp.c
index 73146a8..a9c7fbd 100644
--- a/libstore/argp.c
+++ b/libstore/argp.c
@@ -19,7 +19,7 @@
    59 Temple Place - Suite 330, Boston, MA 02111, USA. */
 
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd.h>
 #include <argp.h>
 #include <argz.h>
@@ -217,7 +217,7 @@ store_parsed_open (const struct store_parsed *parsed, int 
flags,
              store_ileave_create (stores, num, parsed->interleave,
                                   flags, store);
          else if (parsed->layer)
-           assert (! parsed->layer);
+           assert_backtrace (! parsed->layer);
          else
            err = store_concat_create (stores, num, flags, store);
        }
diff --git a/libstore/derive.c b/libstore/derive.c
index a76fbe1..be615b6 100644
--- a/libstore/derive.c
+++ b/libstore/derive.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <sys/types.h>
 #include <mach.h>
 
@@ -78,10 +78,10 @@ _store_derive (struct store *store)
     {
       while ((1 << store->log2_block_size) < bsize)
        store->log2_block_size++;
-      assert ((1 << store->log2_block_size) == bsize);
+      assert_backtrace ((1 << store->log2_block_size) == bsize);
 
       while ((bsize << store->log2_blocks_per_page) < vm_page_size)
        store->log2_blocks_per_page++;
-      assert ((bsize << store->log2_blocks_per_page) == vm_page_size);
+      assert_backtrace ((bsize << store->log2_blocks_per_page) == 
vm_page_size);
     }
 }
diff --git a/libstore/device.c b/libstore/device.c
index 3a72df4..b350bc7 100644
--- a/libstore/device.c
+++ b/libstore/device.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -146,7 +146,7 @@ enforced (struct store *store)
 
       if (!err)
        {
-         assert (sizes_len == DEV_GET_RECORDS_COUNT);
+         assert_backtrace (sizes_len == DEV_GET_RECORDS_COUNT);
 
          if (sizes[DEV_GET_RECORDS_RECORD_SIZE] != store->block_size
              || (store->runs[0].length !=
@@ -165,7 +165,7 @@ enforced (struct store *store)
          if (err)
            return EINVAL;
 
-         assert (sizes_len == DEV_GET_SIZE_COUNT);
+         assert_backtrace (sizes_len == DEV_GET_SIZE_COUNT);
 
          if (sizes[DEV_GET_SIZE_RECORD_SIZE] != store->block_size
              || (store->runs[0].length !=
diff --git a/libstore/memobj.c b/libstore/memobj.c
index 0849151..ea2d7b9 100644
--- a/libstore/memobj.c
+++ b/libstore/memobj.c
@@ -22,7 +22,7 @@
 #include <hurd/sigpreempt.h>
 #include <sys/mman.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 
 /* Return a new store in STORE referring to the memory object MEMOBJ.
@@ -101,7 +101,7 @@ memobj_memcpy (memory_object_t memobj,
   jmp_buf buf;
   void fault (int signo, long int sigcode, struct sigcontext *scp)
     {
-      assert (scp->sc_error == EKERN_MEMORY_ERROR);
+      assert_backtrace (scp->sc_error == EKERN_MEMORY_ERROR);
       err = EIO;
       to_copy -= sigcode - window;
       siglongjmp (buf, 1);
diff --git a/libstore/mvol.c b/libstore/mvol.c
index d243cc8..ee1526b 100644
--- a/libstore/mvol.c
+++ b/libstore/mvol.c
@@ -148,8 +148,7 @@ store_mvol_create (struct store *phys,
 
       if (err)
        {
-         if (mv)
-           free (mv);
+         free (mv);
          store_free (*store);
        }
     }
diff --git a/libstore/part.c b/libstore/part.c
index 0ef2bd4..349d90f 100644
--- a/libstore/part.c
+++ b/libstore/part.c
@@ -21,7 +21,7 @@
 #include "store.h"
 #include <stdlib.h>
 #include <errno.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 
 #include <parted/parted.h>
@@ -99,7 +99,7 @@ store_part_create (struct store *source, int index, int flags,
       goto out;
     }
 
-  assert (ped_device_open (dev) != 0);
+  assert_backtrace (ped_device_open (dev) != 0);
 
   disk = ped_disk_new (dev);
   if (! disk)
@@ -116,7 +116,7 @@ store_part_create (struct store *source, int index, int 
flags,
          && part->type != 0 /* PED_PARTITION_PRIMARY */)
        continue;
 
-      assert (part->num);
+      assert_backtrace (part->num);
       if (part->num == index)
         break;
     }
@@ -155,7 +155,7 @@ store_part_create (struct store *source, int index, int 
flags,
     }
 
 out_with_disk:
-  assert (ped_device_close (dev) != 0);
+  assert_backtrace (ped_device_close (dev) != 0);
   ped_disk_destroy (disk);
 out_with_dev:
   ped_device_destroy (dev);
diff --git a/libthreads/cancel-cond.c b/libthreads/cancel-cond.c
index 0cd5f0f..3aa33f6 100644
--- a/libthreads/cancel-cond.c
+++ b/libthreads/cancel-cond.c
@@ -20,7 +20,7 @@
 #include <hurd/signal.h>
 #include <cthreads.h>
 #include "cthread_internals.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 /* Just like condition_wait, but cancellable.  Returns true if cancelled.  */
 int
@@ -37,7 +37,7 @@ hurd_condition_wait (condition_t c, mutex_t m)
   cproc_t p = cproc_self ();
   int cancel;
 
-  assert (ss->intr_port == MACH_PORT_NULL); /* Sanity check for signal bugs. */
+  assert_backtrace (ss->intr_port == MACH_PORT_NULL); /* Sanity check for 
signal bugs. */
 
   p->state = CPROC_CONDWAIT | CPROC_SWITCHING;
 
diff --git a/libthreads/cprocs.c b/libthreads/cprocs.c
index 5459d7d..5fb138d 100644
--- a/libthreads/cprocs.c
+++ b/libthreads/cprocs.c
@@ -233,7 +233,7 @@
 #include "cthread_internals.h"
 #include <mach/message.h>
 #include <hurd/threadvar.h>    /* GNU */
-#include <assert.h>
+#include <assert-backtrace.h>
 
 /*
  * Port_entry's are used by cthread_mach_msg to store information
@@ -343,7 +343,7 @@ cthread_wire(void)
        register cproc_t p = cproc_self();
 
        /* In GNU, we wire all threads on creation (in cproc_alloc).  */
-       assert (p->wired != MACH_PORT_NULL);
+       assert_backtrace (p->wired != MACH_PORT_NULL);
 }
 
 /*
diff --git a/libthreads/rwlock.h b/libthreads/rwlock.h
index 44d9a35..cbe56d7 100644
--- a/libthreads/rwlock.h
+++ b/libthreads/rwlock.h
@@ -20,7 +20,7 @@
 #define _RWLOCK_H 1
 
 #include <cthreads.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <features.h>
 
 #ifdef RWLOCK_DEFINE_EI
@@ -89,7 +89,7 @@ RWLOCK_EI void
 rwlock_reader_unlock (struct rwlock *lock)
 {
   mutex_lock (&lock->master);
-  assert (lock->readers);
+  assert_backtrace (lock->readers);
   lock->readers--;
   if (lock->readers_waiting || lock->writers_waiting)
     condition_broadcast (&lock->wakeup);
@@ -101,7 +101,7 @@ RWLOCK_EI void
 rwlock_writer_unlock (struct rwlock *lock)
 {
   mutex_lock (&lock->master);
-  assert (lock->readers == -1);
+  assert_backtrace (lock->readers == -1);
   lock->readers = 0;
   if (lock->readers_waiting || lock->writers_waiting)
     condition_broadcast (&lock->wakeup);
diff --git a/libtreefs/dir-lookup.c b/libtreefs/dir-lookup.c
index 80b5538..33fefe6 100644
--- a/libtreefs/dir-lookup.c
+++ b/libtreefs/dir-lookup.c
@@ -73,7 +73,7 @@ _treefs_s_dir_lookup (struct treefs_handle *h,
     {
       char *nextname;
 
-      assert (!lastcomp);
+      assert_backtrace (!lastcomp);
       
       /* Find the name of the next pathname component */
       nextname = index (path, '/');
diff --git a/libtreefs/fsys-startup.c b/libtreefs/fsys-startup.c
index fcee353..e2d138b 100644
--- a/libtreefs/fsys-startup.c
+++ b/libtreefs/fsys-startup.c
@@ -28,7 +28,7 @@ treefs_S_fsys_startup (mach_port_t child_boot_port, 
mach_port_t control_port,
   struct port_info *child_boot =
     ports_check_port_type (child_boot_port, PT_TRANSBOOT);
 
-  assert (child_boot);                 /* XXX deal with exec server boot */
+  assert_backtrace (child_boot);                       /* XXX deal with exec 
server boot */
   err = fshelp_handle_fsys_startup (child_boot, control_port, real, real_type);
   ports_done_with_port (child_boot);
 
diff --git a/libtreefs/treefs.h b/libtreefs/treefs.h
index 0e49ef5..50cf91f 100644
--- a/libtreefs/treefs.h
+++ b/libtreefs/treefs.h
@@ -25,7 +25,7 @@
 
 #include <errno.h>
 #include <pthread.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <features.h>
 
 #include <sys/stat.h>
@@ -281,7 +281,7 @@ treefs_node_release (struct treefs_node *node)
 
  loop:
   pthread_spin_lock (&treefs_node_refcnt_lock);
-  assert (node->refs);
+  assert_backtrace (node->refs);
   node->refs--;
   if (node->refs + node->weak_refs == 0)
     treefs_node_drop (node);
@@ -328,7 +328,7 @@ treefs_node_unref (struct treefs_node *node)
 
  loop:
   pthread_spin_lock (&treefs_node_refcnt_lock);
-  assert (node->refs);
+  assert_backtrace (node->refs);
   node->refs--;
   if (node->refs + node->weak_refs == 0)
     {
@@ -374,7 +374,7 @@ TREEFS_EI void
 treefs_node_release_weak (struct treefs_node *node)
 {
   pthread_spin_lock (&treefs_node_refcnt_lock);
-  assert (node->weak_refs);
+  assert_backtrace (node->weak_refs);
   node->weak_refs--;
   if (node->refs + node->weak_refs == 0)
     treefs_node_drop (node);
@@ -392,7 +392,7 @@ TREEFS_EI void
 treefs_node_unref_weak (struct treefs_node *node)
 {
   pthread_spin_lock (&treefs_node_refcnt_lock);
-  assert (node->weak_refs);
+  assert_backtrace (node->weak_refs);
   node->weak_refs--;
   if (node->refs + node->weak_refs == 0)
     {
diff --git a/libtrivfs/dir-lookup.c b/libtrivfs/dir-lookup.c
index 66afac1..73aff5c 100644
--- a/libtrivfs/dir-lookup.c
+++ b/libtrivfs/dir-lookup.c
@@ -16,7 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <fcntl.h>
 #include <string.h>
 
diff --git a/libtrivfs/file-get-source.c b/libtrivfs/file-get-source.c
index f6637d8..c2420fb 100644
--- a/libtrivfs/file-get-source.c
+++ b/libtrivfs/file-get-source.c
@@ -30,5 +30,5 @@ trivfs_S_file_get_source (struct trivfs_protid *cred,
                          mach_msg_type_name_t replyPoly,
                          char *source)
 {
-  return cred? trivfs_get_source (cred, source, 1024 /* XXX */): EOPNOTSUPP;
+  return cred ? trivfs_get_source (source, 1024 /* XXX */) : EOPNOTSUPP;
 }
diff --git a/libtrivfs/file-set-size.c b/libtrivfs/file-set-size.c
index f90ceec..a2691c8 100644
--- a/libtrivfs/file-set-size.c
+++ b/libtrivfs/file-set-size.c
@@ -17,13 +17,13 @@
 
 #include "priv.h"
 #include "trivfs_fs_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_file_set_size (struct trivfs_protid *cred,
                        mach_port_t reply, mach_msg_type_name_t reply_type,
                        off_t size)
 {
-  assert (!trivfs_support_write);
+  assert_backtrace (!trivfs_support_write);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/fsys-getroot.c b/libtrivfs/fsys-getroot.c
index c9b8261..eac1328 100644
--- a/libtrivfs/fsys-getroot.c
+++ b/libtrivfs/fsys-getroot.c
@@ -22,7 +22,7 @@
 #include "priv.h"
 #include "fsys_reply_U.h"
 #include "trivfs_fsys_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <fcntl.h>
 #include <string.h>
 
diff --git a/libtrivfs/get-source.c b/libtrivfs/get-source.c
index 1b3ce11..1f77200 100644
--- a/libtrivfs/get-source.c
+++ b/libtrivfs/get-source.c
@@ -22,7 +22,7 @@
 #include "priv.h"
 
 error_t __attribute__ ((weak))
-trivfs_get_source (struct trivfs_protid *cred, char *source, size_t source_len)
+trivfs_get_source (char *source, size_t source_len)
 {
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/io-async-icky.c b/libtrivfs/io-async-icky.c
index d6313d1..7256942 100644
--- a/libtrivfs/io-async-icky.c
+++ b/libtrivfs/io-async-icky.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_get_icky_async_id (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-async.c b/libtrivfs/io-async.c
index 5f60956..01a809c 100644
--- a/libtrivfs/io-async.c
+++ b/libtrivfs/io-async.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_async (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-map.c b/libtrivfs/io-map.c
index 3bf8dab..958627f 100644
--- a/libtrivfs/io-map.c
+++ b/libtrivfs/io-map.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_map (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-modes-get.c b/libtrivfs/io-modes-get.c
index b70d94b..c536732 100644
--- a/libtrivfs/io-modes-get.c
+++ b/libtrivfs/io-modes-get.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_get_openmodes (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-modes-off.c b/libtrivfs/io-modes-off.c
index 85d18e7..3717470 100644
--- a/libtrivfs/io-modes-off.c
+++ b/libtrivfs/io-modes-off.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_clear_some_openmodes (struct trivfs_protid *cred,
@@ -29,6 +29,6 @@ trivfs_S_io_clear_some_openmodes (struct trivfs_protid *cred,
                                  mach_msg_type_name_t replytype,
                                  int bits)
 {
-  assert (!trivfs_support_read && !trivfs_support_write);
+  assert_backtrace (!trivfs_support_read && !trivfs_support_write);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/io-modes-on.c b/libtrivfs/io-modes-on.c
index f1c6ffb..b71d21b 100644
--- a/libtrivfs/io-modes-on.c
+++ b/libtrivfs/io-modes-on.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_set_some_openmodes (struct trivfs_protid *cred,
@@ -29,6 +29,6 @@ trivfs_S_io_set_some_openmodes (struct trivfs_protid *cred,
                                mach_msg_type_name_t replytype,
                                int bits)
 {
-  assert (!trivfs_support_read && !trivfs_support_write);
+  assert_backtrace (!trivfs_support_read && !trivfs_support_write);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/io-modes-set.c b/libtrivfs/io-modes-set.c
index 1d01b9b..4484642 100644
--- a/libtrivfs/io-modes-set.c
+++ b/libtrivfs/io-modes-set.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 error_t
 trivfs_S_io_set_all_openmodes (struct trivfs_protid *cred,
@@ -29,6 +29,6 @@ trivfs_S_io_set_all_openmodes (struct trivfs_protid *cred,
                               mach_msg_type_name_t replytype,
                               int mode)
 {
-  assert (!trivfs_support_read && !trivfs_support_write);
+  assert_backtrace (!trivfs_support_read && !trivfs_support_write);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/io-owner-get.c b/libtrivfs/io-owner-get.c
index bd49046..8b4791b 100644
--- a/libtrivfs/io-owner-get.c
+++ b/libtrivfs/io-owner-get.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_get_owner (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-owner-mod.c b/libtrivfs/io-owner-mod.c
index bed9000..58deb4d 100644
--- a/libtrivfs/io-owner-mod.c
+++ b/libtrivfs/io-owner-mod.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_mod_owner (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-read.c b/libtrivfs/io-read.c
index 7dfdc19..cd8e2d8 100644
--- a/libtrivfs/io-read.c
+++ b/libtrivfs/io-read.c
@@ -17,7 +17,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_read (struct trivfs_protid *cred,
@@ -28,6 +28,6 @@ trivfs_S_io_read (struct trivfs_protid *cred,
                  off_t off,
                  mach_msg_type_number_t amt)
 {
-  assert (!trivfs_support_read);
+  assert_backtrace (!trivfs_support_read);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/io-readable.c b/libtrivfs/io-readable.c
index 90e66c7..de4d32b 100644
--- a/libtrivfs/io-readable.c
+++ b/libtrivfs/io-readable.c
@@ -17,7 +17,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_readable (struct trivfs_protid *cred,
@@ -25,6 +25,6 @@ trivfs_S_io_readable (struct trivfs_protid *cred,
                      mach_msg_type_name_t replytype,
                      mach_msg_type_number_t *amount)
 {
-  assert (!trivfs_support_read);
+  assert_backtrace (!trivfs_support_read);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/io-reauthenticate.c b/libtrivfs/io-reauthenticate.c
index 72684e3..db8272f 100644
--- a/libtrivfs/io-reauthenticate.c
+++ b/libtrivfs/io-reauthenticate.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 
 kern_return_t
@@ -49,7 +49,7 @@ trivfs_S_io_reauthenticate (struct trivfs_protid *cred,
 
   auth = getauth ();
   newright = ports_get_send_right (newcred);
-  assert (newright != MACH_PORT_NULL);
+  assert_backtrace (newright != MACH_PORT_NULL);
 
   err = iohelp_reauth (&newcred->user, auth, rendport, newright, 1);
   if (!err)
diff --git a/libtrivfs/io-seek.c b/libtrivfs/io-seek.c
index cfb7f53..b2ec8f4 100644
--- a/libtrivfs/io-seek.c
+++ b/libtrivfs/io-seek.c
@@ -17,7 +17,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_seek (struct trivfs_protid *cred,
@@ -27,6 +27,6 @@ trivfs_S_io_seek (struct trivfs_protid *cred,
                  int whence,
                  off_t *newp)
 {
-  assert (!trivfs_support_read && !trivfs_support_write);
+  assert_backtrace (!trivfs_support_read && !trivfs_support_write);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/io-select.c b/libtrivfs/io-select.c
index 0682b2d..668b7a5 100644
--- a/libtrivfs/io-select.c
+++ b/libtrivfs/io-select.c
@@ -21,7 +21,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 
 kern_return_t
 trivfs_S_io_select (struct trivfs_protid *cred,
@@ -32,9 +32,9 @@ trivfs_S_io_select (struct trivfs_protid *cred,
   if (!cred)
     return EOPNOTSUPP;
   if (*seltype & (SELECT_READ|SELECT_URG))
-    assert (!trivfs_support_read);
+    assert_backtrace (!trivfs_support_read);
   if (*seltype & (SELECT_WRITE|SELECT_URG))
-    assert (!trivfs_support_write);
+    assert_backtrace (!trivfs_support_write);
   return EOPNOTSUPP;
 }
 
diff --git a/libtrivfs/io-write.c b/libtrivfs/io-write.c
index c479c55..d5b3252 100644
--- a/libtrivfs/io-write.c
+++ b/libtrivfs/io-write.c
@@ -17,7 +17,7 @@
 
 #include "priv.h"
 #include "trivfs_io_S.h"
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <fcntl.h>
 
 kern_return_t
@@ -32,6 +32,6 @@ trivfs_S_io_write (struct trivfs_protid *cred,
   if (!(trivfs_allow_open & O_WRITE))
     return EBADF;
 
-  assert (!trivfs_support_write);
+  assert_backtrace (!trivfs_support_write);
   return EOPNOTSUPP;
 }
diff --git a/libtrivfs/startup.c b/libtrivfs/startup.c
index 4d76d47..56ef02c 100644
--- a/libtrivfs/startup.c
+++ b/libtrivfs/startup.c
@@ -20,7 +20,7 @@
 
 #include <hurd.h>
 #include <hurd/fsys.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "priv.h"
 
diff --git a/libtrivfs/trivfs.h b/libtrivfs/trivfs.h
index 49cc765..ddeb29a 100644
--- a/libtrivfs/trivfs.h
+++ b/libtrivfs/trivfs.h
@@ -215,12 +215,11 @@ error_t trivfs_set_options (struct trivfs_control *fsys,
 error_t trivfs_append_args (struct trivfs_control *fsys,
                            char **argz, size_t *argz_len);
 
-/* The user may define this function.  The function must set source to
-   the source device of CRED. The function may return an EOPNOTSUPP to
-   indicate that the concept of a source device is not applicable. The
-   default function always returns EOPNOTSUPP. */
-error_t trivfs_get_source (struct trivfs_protid *cred,
-                           char *source, size_t source_len);
+/* The user may define this function.  The function must set SOURCE to
+   the source of the translator. The function may return an EOPNOTSUPP
+   to indicate that the concept of a source device is not
+   applicable. The default function always returns EOPNOTSUPP. */
+error_t trivfs_get_source (char *source, size_t source_len);
 
 /* Add the port class *CLASS to the list of control port classes recognized
    by trivfs; if *CLASS is 0, an attempt is made to allocate a new port
diff --git a/login/utmp.c b/login/utmp.c
index f366d44..41e244a 100644
--- a/login/utmp.c
+++ b/login/utmp.c
@@ -32,7 +32,7 @@
 #include <hurd/fsys.h>
 #include <mach/notify.h>
 #include <stdio.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <fcntl.h>
 #include <getopt.h>
 
diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4
new file mode 100644
index 0000000..d89fe11
--- /dev/null
+++ b/m4/libgcrypt.m4
@@ -0,0 +1,143 @@
+# libgcrypt.m4 - Autoconf macros to detect libgcrypt
+# Copyright (C) 2002, 2003, 2004, 2011, 2014 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Last-changed: 2014-10-02
+
+
+dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
+dnl                   [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
+dnl MINIMUM-VERSION is a string with the version number optionalliy prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUM-VERSION of 1:1.2.5 won't pass the test unless the installed
+dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1.  Using
+dnl this feature prevents building against newer versions of libgcrypt
+dnl with a changed API.
+dnl
+dnl If a prefix option is not used, the config script is first
+dnl searched in $SYSROOT/bin and then along $PATH.  If the used
+dnl config script does not match the host specification the script
+dnl is added to the gpg_config_script_warn variable.
+dnl
+AC_DEFUN([AM_PATH_LIBGCRYPT],
+[ AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_ARG_WITH(libgcrypt-prefix,
+            AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
+                           [prefix where LIBGCRYPT is installed (optional)]),
+     libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
+  if test x"${LIBGCRYPT_CONFIG}" = x ; then
+     if test x"${libgcrypt_config_prefix}" != x ; then
+        LIBGCRYPT_CONFIG="${libgcrypt_config_prefix}/bin/libgcrypt-config"
+     else
+       case "${SYSROOT}" in
+         /*)
+           if test -x "${SYSROOT}/bin/libgcrypt-config" ; then
+             LIBGCRYPT_CONFIG="${SYSROOT}/bin/libgcrypt-config"
+           fi
+           ;;
+         '')
+           ;;
+          *)
+           AC_MSG_WARN([Ignoring \$SYSROOT as it is not an absolute path.])
+           ;;
+       esac
+     fi
+  fi
+
+  AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
+  tmp=ifelse([$1], ,1:1.2.0,$1)
+  if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+     req_libgcrypt_api=`echo "$tmp"     | sed 's/\(.*\):\(.*\)/\1/'`
+     min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+  else
+     req_libgcrypt_api=0
+     min_libgcrypt_version="$tmp"
+  fi
+
+  AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
+  ok=no
+  if test "$LIBGCRYPT_CONFIG" != "no" ; then
+    req_major=`echo $min_libgcrypt_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+    req_minor=`echo $min_libgcrypt_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+    req_micro=`echo $min_libgcrypt_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+    libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
+    major=`echo $libgcrypt_config_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+    minor=`echo $libgcrypt_config_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+    micro=`echo $libgcrypt_config_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
+    if test "$major" -gt "$req_major"; then
+        ok=yes
+    else
+        if test "$major" -eq "$req_major"; then
+            if test "$minor" -gt "$req_minor"; then
+               ok=yes
+            else
+               if test "$minor" -eq "$req_minor"; then
+                   if test "$micro" -ge "$req_micro"; then
+                     ok=yes
+                   fi
+               fi
+            fi
+        fi
+    fi
+  fi
+  if test $ok = yes; then
+    AC_MSG_RESULT([yes ($libgcrypt_config_version)])
+  else
+    AC_MSG_RESULT(no)
+  fi
+  if test $ok = yes; then
+     # If we have a recent libgcrypt, we should also check that the
+     # API is compatible
+     if test "$req_libgcrypt_api" -gt 0 ; then
+        tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+        if test "$tmp" -gt 0 ; then
+           AC_MSG_CHECKING([LIBGCRYPT API version])
+           if test "$req_libgcrypt_api" -eq "$tmp" ; then
+             AC_MSG_RESULT([okay])
+           else
+             ok=no
+             AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
+           fi
+        fi
+     fi
+  fi
+  if test $ok = yes; then
+    LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
+    LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
+    ifelse([$2], , :, [$2])
+    libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+    if test x"$libgcrypt_config_host" != xnone ; then
+      if test x"$libgcrypt_config_host" != x"$host" ; then
+  AC_MSG_WARN([[
+***
+*** The config script $LIBGCRYPT_CONFIG was
+*** built for $libgcrypt_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgcrypt-prefix
+*** to specify a matching config script or use \$SYSROOT.
+***]])
+        gpg_config_script_warn="$gpg_config_script_warn libgcrypt"
+      fi
+    fi
+  else
+    LIBGCRYPT_CFLAGS=""
+    LIBGCRYPT_LIBS=""
+    ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(LIBGCRYPT_CFLAGS)
+  AC_SUBST(LIBGCRYPT_LIBS)
+])
diff --git a/mach-defpager/Makefile b/mach-defpager/Makefile
index 3b8ce58..9bf394e 100644
--- a/mach-defpager/Makefile
+++ b/mach-defpager/Makefile
@@ -29,7 +29,7 @@ OBJS  := $(SRCS:.c=.o) \
                       memory_object default_pager memory_object_default exc) \
           default_pager_replyUser.o
 
-HURDLIBS:= ihash
+HURDLIBS:= ihash shouldbeinlibc
 LDLIBS:= -lpthread
 
 include ../Makeconf
diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c
index aafa2cf..d2220c5 100644
--- a/mach-defpager/default_pager.c
+++ b/mach-defpager/default_pager.c
@@ -50,7 +50,7 @@
 #include "kalloc.h"
 #include "default_pager.h"
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
@@ -1137,7 +1137,7 @@ void pager_release_offset(pager, offset)
 
        pthread_mutex_lock(&pager->lock);       /* XXX lock_read */
 
-       assert (pager->map);
+       assert_backtrace (pager->map);
        if (INDIRECT_PAGEMAP(pager->size)) {
                dp_map_t        mapptr;
 
@@ -2164,7 +2164,7 @@ void pager_port_check_request(ds, pager_request)
        mach_port_delta_t delta;
        kern_return_t kr;
 
-       assert(ds->pager_request == pager_request);
+       assert_backtrace (ds->pager_request == pager_request);
 
        if (++ds->request_refs > default_pager_max_urefs) {
                delta = 1 - ds->request_refs;
@@ -2249,10 +2249,10 @@ seqnos_memory_object_create(old_pager, seqno, 
new_pager, new_size,
 {
        default_pager_t ds;
 
-       assert(old_pager == default_pager_default_port);
-       assert(MACH_PORT_VALID(new_pager_request));
-       assert(MACH_PORT_VALID(new_pager_name));
-       assert(new_page_size == vm_page_size);
+       assert_backtrace (old_pager == default_pager_default_port);
+       assert_backtrace (MACH_PORT_VALID(new_pager_request));
+       assert_backtrace (MACH_PORT_VALID(new_pager_name));
+       assert_backtrace (new_page_size == vm_page_size);
 
        ds = pager_port_alloc(new_size);
 
@@ -2293,9 +2293,9 @@ seqnos_memory_object_init(ds, seqno, pager_request, 
pager_name,
        kern_return_t            kr;
        static char              here[] = "%sinit";
 
-       assert(MACH_PORT_VALID(pager_request));
-       assert(MACH_PORT_VALID(pager_name));
-       assert(pager_page_size == vm_page_size);
+       assert_backtrace (MACH_PORT_VALID(pager_request));
+       assert_backtrace (MACH_PORT_VALID(pager_name));
+       assert_backtrace (pager_page_size == vm_page_size);
 
        if (ds == DEFAULT_PAGER_NULL)
            panic(here, my_name);
@@ -2371,7 +2371,7 @@ ddprintf ("seqnos_memory_object_terminate <%p>: 
pager_port_lock: <%p>[s:%d,r:%d,
                pager_request = ds->pager_request;
        ds->pager_request = MACH_PORT_NULL;
        ds->request_refs = 0;
-       assert(ds->pager_name == pager_name);
+       assert_backtrace (ds->pager_name == pager_name);
        ds->pager_name = MACH_PORT_NULL;
        ds->name_refs = 0;
 ddprintf ("seqnos_memory_object_terminate <%p>: pager_port_unlock: 
<%p>[s:%d,r:%d,w:%d,l:%d]\n",
@@ -2660,8 +2660,8 @@ seqnos_memory_object_data_return(ds, seqno, pager_request,
        vm_size_t limit = ds->dpager.byte_limit;
        pager_port_unlock(ds);
        if ((limit != round_page(limit)) && (trunc_page(limit) == offset)) {
-           assert(trunc_page(limit) == offset);
-           assert(data_cnt == vm_page_size);
+           assert_backtrace (trunc_page(limit) == offset);
+           assert_backtrace (data_cnt == vm_page_size);
 
            vm_offset_t tail = addr + limit - trunc_page(limit);
            vm_size_t tail_size = round_page(limit) - limit;
@@ -2807,16 +2807,16 @@ boolean_t default_pager_notify_server(in, out)
                return FALSE;
        }
 
-       assert(ds != DEFAULT_PAGER_NULL);
+       assert_backtrace (ds != DEFAULT_PAGER_NULL);
 
-       assert(n->not_header.msgh_size == sizeof *n);
-       assert(n->not_header.msgh_remote_port == MACH_PORT_NULL);
+       assert_backtrace (n->not_header.msgh_size == sizeof *n);
+       assert_backtrace (n->not_header.msgh_remote_port == MACH_PORT_NULL);
 
-       assert(n->not_type.msgt_name == MACH_MSG_TYPE_INTEGER_32);
-       assert(n->not_type.msgt_size == 32);
-       assert(n->not_type.msgt_number == 1);
-       assert(n->not_type.msgt_inline);
-       assert(! n->not_type.msgt_longform);
+       assert_backtrace (n->not_type.msgt_name == MACH_MSG_TYPE_INTEGER_32);
+       assert_backtrace (n->not_type.msgt_size == 32);
+       assert_backtrace (n->not_type.msgt_number == 1);
+       assert_backtrace (n->not_type.msgt_inline);
+       assert_backtrace (! n->not_type.msgt_longform);
 
        default_pager_no_senders(ds, n->not_header.msgh_seqno, n->not_count);
 
diff --git a/mach-defpager/setup.c b/mach-defpager/setup.c
index e4ec8d9..94685c0 100644
--- a/mach-defpager/setup.c
+++ b/mach-defpager/setup.c
@@ -20,7 +20,7 @@
 
 #include <errno.h>
 #include <stddef.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <mach.h>
 #include <string.h>
 #include <strings.h>
@@ -115,12 +115,12 @@ page_read_file_direct (struct file_direct *fdp,
   char *page;
   mach_msg_type_number_t nread;
 
-  assert (page_aligned (offset));
-  assert (size == vm_page_size);
+  assert_backtrace (page_aligned (offset));
+  assert_backtrace (size == vm_page_size);
 
   offset >>= fdp->bshift;
 
-  assert (offset + (size >> fdp->bshift) <= fdp->fd_size);
+  assert_backtrace (offset + (size >> fdp->bshift) <= fdp->fd_size);
 
   /* Find the run containing the beginning of the page.  */
   for (r = fdp->runs; offset > r->length; ++r)
@@ -179,12 +179,12 @@ page_write_file_direct(struct file_direct *fdp,
   error_t err;
   int wrote;
 
-  assert (page_aligned (offset));
-  assert (size == vm_page_size);
+  assert_backtrace (page_aligned (offset));
+  assert_backtrace (size == vm_page_size);
 
   offset >>= fdp->bshift;
 
-  assert (offset + (size >> fdp->bshift) <= fdp->fd_size);
+  assert_backtrace (offset + (size >> fdp->bshift) <= fdp->fd_size);
 
   /* Find the run containing the beginning of the page.  */
   for (r = fdp->runs; offset > r->length; ++r)
@@ -251,7 +251,7 @@ add_paging_file(master_device_port, file_name, 
linux_signature)
   natural_t count;
   char *devname = file_name;
 
-  assert (linux_signature == 0);
+  assert_backtrace (linux_signature == 0);
 
   if (!strncmp (file_name, "/dev/", 5))
     devname += 5;
diff --git a/nfs/cache.c b/nfs/cache.c
index ecf3b11..883cb96 100644
--- a/nfs/cache.c
+++ b/nfs/cache.c
@@ -75,7 +75,7 @@ lookup_fhandle (struct fhandle *handle, struct node **npp)
   
   /* Could not find it */
   np = netfs_make_node_alloc (sizeof (struct netnode));
-  assert (np);
+  assert_backtrace (np);
   nn = netfs_node_netnode (np);
 
   nn->handle.size = handle->size;
@@ -127,7 +127,7 @@ netfs_node_norefs (struct node *np)
       error_t err;
 
       args = malloc (sizeof (struct fnd));
-      assert (args);
+      assert_backtrace (args);
 
       args->dir = np->nn->dead_dir;
       args->name = np->nn->dead_name;
diff --git a/nfs/main.c b/nfs/main.c
index cd1c29a..c98eb56 100644
--- a/nfs/main.c
+++ b/nfs/main.c
@@ -270,15 +270,12 @@ netfs_append_args (char **argz, size_t *argz_len)
 }
 
 /* The user may define this function.  The function must set source to
-   the source of CRED. The function may return an EOPNOTSUPP to
-   indicate that the concept of a source device is not applicable. The
-   default function always returns EOPNOTSUPP. */
+   the source of the translator. The function may return an EOPNOTSUPP
+   to indicate that the concept of a source device is not
+   applicable. The default function always returns EOPNOTSUPP.  */
 error_t
-netfs_get_source (struct protid *cred, char *source, size_t source_len)
+netfs_get_source (char *source, size_t source_len)
 {
-  if (! cred)
-    return EOPNOTSUPP;
-
   snprintf (source, source_len, "%s:%s", host, remote_fs);
   return 0;
 }
diff --git a/nfs/ops.c b/nfs/ops.c
index 33ab38b..e0daae3 100644
--- a/nfs/ops.c
+++ b/nfs/ops.c
@@ -251,8 +251,7 @@ netfs_attempt_chmod (struct iouser *cred, struct node *np,
              np->nn->dtrans = SOCK;
              np->nn->stat_updated = 0;
            }
-         if (f)
-           free (f);
+         free (f);
          return 0;
        }
     }
@@ -608,7 +607,7 @@ verify_nonexistent (struct iouser *cred, struct node *dir,
   /* Don't use the lookup cache for this; we want a full sync to
      get as close to real exclusive create behavior as possible. */
 
-  assert (protocol_version == 2);
+  assert_backtrace (protocol_version == 2);
 
   p = nfs_initialize_rpc (NFSPROC_LOOKUP (protocol_version),
                          cred, 0, &rpcbuf, dir, -1);
@@ -1134,8 +1133,8 @@ netfs_attempt_mkfile (struct iouser *cred, struct node 
*dir,
       return err;
     }
 
-  assert (!(*newnp)->nn->dead_dir);
-  assert (!(*newnp)->nn->dead_name);
+  assert_backtrace (!(*newnp)->nn->dead_dir);
+  assert_backtrace (!(*newnp)->nn->dead_name);
   netfs_nref (dir);
   (*newnp)->nn->dead_dir = dir;
   (*newnp)->nn->dead_name = name;
@@ -1668,7 +1667,7 @@ netfs_report_access (struct iouser *cred,
   err = netfs_attempt_read (cred, np, 0, &len, &byte);
   if (err)
     return;
-  assert (len == 1 || len == 0);
+  assert_backtrace (len == 1 || len == 0);
 
   *types |= O_READ | O_EXEC;
 
@@ -1777,7 +1776,7 @@ fetch_directory (struct iouser *cred, struct node *dir,
              char *newbuf;
 
              newbuf = realloc (buf, bufmalloced *= 2);
-             assert (newbuf);
+             assert_backtrace (newbuf);
              if (newbuf != buf)
                bp = newbuf + (bp - buf);
              buf = newbuf;
diff --git a/nfs/rpc.c b/nfs/rpc.c
index c0d0290..0d83064 100644
--- a/nfs/rpc.c
+++ b/nfs/rpc.c
@@ -31,7 +31,7 @@
 #undef malloc                  /* Get rid of the sun block.  */
 
 #include <netinet/in.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <error.h>
 #include <unistd.h>
@@ -107,7 +107,7 @@ initialize_rpc (int program, int version, int rpc_proc,
   *(p++) = htonl (version);
   *(p++) = htonl (rpc_proc);
   
-  assert ((uid == -1) == (gid == -1));
+  assert_backtrace ((uid == -1) == (gid == -1));
 
   if (uid == -1)
     {
@@ -214,7 +214,7 @@ conduct_rpc (void **rpcbuf, int **pp)
          return errno;
        }
       else 
-       assert (cc == nc);
+       assert_backtrace (cc == nc);
       
       /* Wait for reply.  */
       cancel = 0;
@@ -254,7 +254,7 @@ conduct_rpc (void **rpcbuf, int **pp)
   
   /* If the transmition id does not match that in the message,
      something strange happened in rpc_receive_thread.  */
-  assert (*p == xid);
+  assert_backtrace (*p == xid);
   p++;
   
   switch (ntohl (*p))
@@ -376,7 +376,7 @@ rpc_receive_thread (void *arg)
 
   /* Allocate a receive buffer.  */
   buf = malloc (1024 + read_size);
-  assert (buf);
+  assert_backtrace (buf);
 
   while (1)
     {
@@ -416,7 +416,7 @@ rpc_receive_thread (void *arg)
          if (r)
            {
               buf = malloc (1024 + read_size);
-              assert (buf);
+              assert_backtrace (buf);
            }
         }
     }
diff --git a/nfs/storage-info.c b/nfs/storage-info.c
index 7427b3d..f86f6c0 100644
--- a/nfs/storage-info.c
+++ b/nfs/storage-info.c
@@ -65,7 +65,7 @@ netfs_file_get_storage_info (struct iouser *cred,
       if (*data == MAP_FAILED)
        return errno;
       *data_len = fmt (name_len) + 1;
-      assert (*data_len == name_len);
+      assert_backtrace (*data_len == name_len);
     }
 
   /* Now fill in the file handle data in hexadecimal.  */
@@ -86,12 +86,12 @@ netfs_file_get_storage_info (struct iouser *cred,
   *num_ports = 0;
   *ports_type = MACH_MSG_TYPE_COPY_SEND;
 
-  assert (*num_offsets >= 2);  /* mig always gives us some */
+  assert_backtrace (*num_offsets >= 2);        /* mig always gives us some */
   *num_offsets = 2;
   (*offsets)[0] = 0;
   (*offsets)[1] = np->nn_stat.st_size;
 
-  assert (*num_ints >= 6);     /* mig always gives us some */
+  assert_backtrace (*num_ints >= 6);   /* mig always gives us some */
   *num_ints = 1;
   (*ints)[0] = STORAGE_NETWORK;
   (*ints)[1] = 0;              /* XXX readonly if we supported it */
diff --git a/nfsd/cache.c b/nfsd/cache.c
index 1b2b6ee..45234d8 100644
--- a/nfsd/cache.c
+++ b/nfsd/cache.c
@@ -19,10 +19,11 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 
+#include <stdint.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <hurd/fsys.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <pthread.h>
 #include <hurd/io.h>
@@ -59,7 +60,7 @@ idspec_compare (struct idspec *i, int nuids, int ngids,
       || i->ngids != ngids)
     return 0;
 
-  assert (sizeof (int) == sizeof (uid_t));
+  assert_backtrace (sizeof (int) == sizeof (uid_t));
 
   if (bcmp (i->uids, uids, nuids * sizeof (uid_t))
       || bcmp (i->gids, gids, ngids * sizeof (gid_t)))
@@ -103,7 +104,7 @@ idspec_lookup (int nuids, int ngids, int *uids, int *gids)
        return i;
       }
 
-  assert (sizeof (uid_t) == sizeof (int));
+  assert_backtrace (sizeof (uid_t) == sizeof (int));
   i = malloc (sizeof (struct idspec));
   i->nuids = nuids;
   i->ngids = ngids;
@@ -202,7 +203,7 @@ void
 cred_ref (struct idspec *i)
 {
   pthread_spin_lock (&idhashlock);
-  assert (i->references);
+  assert_backtrace (i->references);
   i->references++;
   pthread_spin_unlock (&idhashlock);
 }
diff --git a/pfinet/dummy.c b/pfinet/dummy.c
index b744f0f..8830149 100644
--- a/pfinet/dummy.c
+++ b/pfinet/dummy.c
@@ -130,5 +130,5 @@ setup_dummy_device (char *name, struct device **device)
      initializes its `ifindex' member (which matters!),
      and tells the protocol stacks about the device.  */
   err = - register_netdevice (dev);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 }
diff --git a/pfinet/ethernet.c b/pfinet/ethernet.c
index e6ae53c..1b3b5d0 100644
--- a/pfinet/ethernet.c
+++ b/pfinet/ethernet.c
@@ -197,11 +197,11 @@ ethernet_open (struct device *dev)
   device_t master_device;
   struct ether_device *edev = (struct ether_device *) dev->priv;
 
-  assert (edev->ether_port == MACH_PORT_NULL);
+  assert_backtrace (edev->ether_port == MACH_PORT_NULL);
 
   err = ports_create_port (etherreadclass, etherport_bucket,
                           sizeof (struct port_info), &edev->readpt);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   edev->readptname = ports_get_right (edev->readpt);
   mach_port_insert_right (mach_task_self (), edev->readptname, 
edev->readptname,
                          MACH_MSG_TYPE_MAKE_SEND);
@@ -291,8 +291,8 @@ ethernet_xmit (struct sk_buff *skb, struct device *dev)
        }
       else
        {
-         assert_perror (err);
-         assert (count == skb->len);
+         assert_perror_backtrace (err);
+         assert_backtrace (count == skb->len);
        }
     }
   while (err);
@@ -378,12 +378,12 @@ setup_ethernet_device (char *name, struct device **device)
   if (err)
     error (2, err, "%s: Cannot get device status", name);
   dev->mtu = netstat.max_packet_size - dev->hard_header_len;
-  assert (netstat.header_format == HDR_ETHERNET);
-  assert (netstat.header_size == ETH_HLEN);
-  assert (netstat.address_size == ETH_ALEN);
+  assert_backtrace (netstat.header_format == HDR_ETHERNET);
+  assert_backtrace (netstat.header_size == ETH_HLEN);
+  assert_backtrace (netstat.address_size == ETH_ALEN);
 
   count = 2;
-  assert (count * sizeof (int) >= ETH_ALEN);
+  assert_backtrace (count * sizeof (int) >= ETH_ALEN);
   err = device_get_status (edev->ether_port, NET_ADDRESS, net_address, &count);
   if (err)
     error (2, err, "%s: Cannot get hardware Ethernet address", name);
@@ -397,5 +397,5 @@ setup_ethernet_device (char *name, struct device **device)
      initializes its `ifindex' member (which matters!),
      and tells the protocol stacks about the device.  */
   err = - register_netdevice (dev);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 }
diff --git a/pfinet/glue-include/linux/interrupt.h 
b/pfinet/glue-include/linux/interrupt.h
index 22312ba..49eb23d 100644
--- a/pfinet/glue-include/linux/interrupt.h
+++ b/pfinet/glue-include/linux/interrupt.h
@@ -30,7 +30,7 @@ extern int net_bh_raised;
 static inline void
 mark_bh (int bh)
 {
-  assert (bh == NET_BH);
+  assert_backtrace (bh == NET_BH);
   net_bh_raised = 1;
   pthread_cond_broadcast (&net_bh_wakeup);
 }
@@ -39,8 +39,8 @@ void net_bh (void);
 static inline void
 init_bh (int bh, void (*fn) (void))
 {
-  assert (bh == NET_BH);
-  assert (fn == &net_bh);
+  assert_backtrace (bh == NET_BH);
+  assert_backtrace (fn == &net_bh);
 }
 
 #endif
diff --git a/pfinet/glue-include/linux/kernel.h 
b/pfinet/glue-include/linux/kernel.h
index de5852f..62ba2ff 100644
--- a/pfinet/glue-include/linux/kernel.h
+++ b/pfinet/glue-include/linux/kernel.h
@@ -3,7 +3,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 
 /* These don't actually matter since our locking protocols are different.  */
@@ -24,7 +24,7 @@
 #define        KERN_INFO
 #define        KERN_DEBUG
 
-#define panic(str...)  (printk (str), assert (!"panic"))
+#define panic(str...)  (printk (str), assert_backtrace (!"panic"))
 
 /*
  *      Display an IP address in readable format.
@@ -63,14 +63,14 @@ putname (char *p)
 static inline int
 kill_proc (int pid, int signo, int priv)
 {
-  assert (signo == SIGURG);
+  assert_backtrace (signo == SIGURG);
   return 0;
 }
 
 static inline int
 kill_pg (int pgrp, int signo, int priv)
 {
-  assert (signo == SIGURG);
+  assert_backtrace (signo == SIGURG);
   return 0;
 }
 
diff --git a/pfinet/glue-include/linux/sched.h 
b/pfinet/glue-include/linux/sched.h
index e39263e..2446e88 100644
--- a/pfinet/glue-include/linux/sched.h
+++ b/pfinet/glue-include/linux/sched.h
@@ -6,7 +6,7 @@
 #include <mach.h>
 #include <hurd/hurd_types.h>
 #include <limits.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 #include <errno.h>
 
@@ -105,7 +105,7 @@ interruptible_sleep_on_timeout (struct wait_queue **p, 
struct timespec *tsp)
   if (c == 0)
     {
       c = malloc (sizeof **condp);
-      assert (c);
+      assert_backtrace (c);
       pthread_cond_init (c, NULL);
       *condp = c;
     }
@@ -134,21 +134,21 @@ wake_up_interruptible (struct wait_queue **p)
 static inline void
 add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
 {
-  assert (current->next_wait == 0);
+  assert_backtrace (current->next_wait == 0);
   current->next_wait = p;
 }
 
 static inline void
 remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
 {
-  assert (current->next_wait == p);
+  assert_backtrace (current->next_wait == p);
   current->next_wait = 0;
 }
 
 static inline void
 schedule (void)
 {
-  assert (current->next_wait);
+  assert_backtrace (current->next_wait);
   interruptible_sleep_on_timeout (current->next_wait, NULL);
 }
 
@@ -201,8 +201,8 @@ schedule_timeout (long timeout)
 static inline int
 send_sig (u_long signo, struct task_struct *task, int priv)
 {
-  assert (signo == SIGPIPE);
-  assert (task == current);
+  assert_backtrace (signo == SIGPIPE);
+  assert_backtrace (task == current);
   return 0;
 }
 
diff --git a/pfinet/glue-include/linux/socket.h 
b/pfinet/glue-include/linux/socket.h
index 057afbd..a7475ea 100644
--- a/pfinet/glue-include/linux/socket.h
+++ b/pfinet/glue-include/linux/socket.h
@@ -111,14 +111,14 @@ extern inline int         /* Does not modify IOV.  */
 memcpy_fromiovecend (unsigned char *kdata, struct iovec *iov,
                     int offset, int len)
 {
-  assert (offset + len <= iov->iov_len);
+  assert_backtrace (offset + len <= iov->iov_len);
   memcpy (kdata, iov->iov_base + offset, len);
   return 0;
 }
 extern inline int              /* Modifies IOV to consume LEN bytes.  */
 memcpy_fromiovec (unsigned char *kdata, struct iovec *iov, int len)
 {
-  assert (len <= iov->iov_len);
+  assert_backtrace (len <= iov->iov_len);
   memcpy (kdata, iov->iov_base, len);
   iov->iov_base += len;
   iov->iov_len -= len;
@@ -127,7 +127,7 @@ memcpy_fromiovec (unsigned char *kdata, struct iovec *iov, 
int len)
 extern inline void             /* Modifies IOV to consume LEN bytes.  */
 memcpy_tokerneliovec (struct iovec *iov, unsigned char *kdata, int len)
 {
-  assert (len <= iov->iov_len);
+  assert_backtrace (len <= iov->iov_len);
   memcpy (iov->iov_base, kdata, len);
   iov->iov_base += len;
   iov->iov_len -= len;
diff --git a/pfinet/glue-include/linux/types.h 
b/pfinet/glue-include/linux/types.h
index 604b8b1..f348ac2 100644
--- a/pfinet/glue-include/linux/types.h
+++ b/pfinet/glue-include/linux/types.h
@@ -4,7 +4,7 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <stdint.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 
 #define        __u8    uint8_t
diff --git a/pfinet/io-ops.c b/pfinet/io-ops.c
index 742d64f..ddda111 100644
--- a/pfinet/io-ops.c
+++ b/pfinet/io-ops.c
@@ -269,7 +269,7 @@ io_select_common (struct sock_user *user,
 
   /* In Linux, this means (supposedly) that I/O will never be possible.
      That's a lose, so prevent it from happening.  */
-  assert (user->sock->ops->poll);
+  assert_backtrace (user->sock->ops->poll);
 
   avail = (*user->sock->ops->poll) ((void *) 0xdeadbeef,
                                    user->sock,
@@ -378,7 +378,7 @@ S_io_reauthenticate (struct sock_user *user,
 
   auth = getauth ();
   newright = ports_get_send_right (newuser);
-  assert (newright != MACH_PORT_NULL);
+  assert_backtrace (newright != MACH_PORT_NULL);
   /* Release the global lock while blocking on the auth server and client.  */
   pthread_mutex_unlock (&global_lock);
   do
diff --git a/pfinet/linux-src/include/net/tcp.h 
b/pfinet/linux-src/include/net/tcp.h
index 96b8071..d6797ea 100644
--- a/pfinet/linux-src/include/net/tcp.h
+++ b/pfinet/linux-src/include/net/tcp.h
@@ -82,7 +82,6 @@ extern struct tcp_bind_bucket **tcp_bhash;
 extern kmem_cache_t *tcp_bucket_cachep;
 extern struct tcp_bind_bucket *tcp_bucket_create(unsigned short snum);
 extern void tcp_bucket_unlock(struct sock *sk);
-extern int tcp_port_rover;
 
 /* Level-1 socket-demux cache. */
 #define TCP_NUM_REGS           32
diff --git a/pfinet/linux-src/include/net/udp.h 
b/pfinet/linux-src/include/net/udp.h
index f3ceadb..daf6702 100644
--- a/pfinet/linux-src/include/net/udp.h
+++ b/pfinet/linux-src/include/net/udp.h
@@ -35,8 +35,6 @@ extern struct sock *udp_hash[UDP_HTABLE_SIZE];
 
 #define UDP_NO_CHECK   0
 
-extern int udp_port_rover;
-
 static inline int udp_lport_inuse(u16 num)
 {
        struct sock *sk = udp_hash[num & (UDP_HTABLE_SIZE - 1)];
diff --git a/pfinet/linux-src/net/ipv4/tcp_ipv4.c 
b/pfinet/linux-src/net/ipv4/tcp_ipv4.c
index df2c8b7..8a5f717 100644
--- a/pfinet/linux-src/net/ipv4/tcp_ipv4.c
+++ b/pfinet/linux-src/net/ipv4/tcp_ipv4.c
@@ -123,7 +123,6 @@ int sysctl_local_port_range[2] = { 1024, 4999 };
 #else
 int sysctl_local_port_range[2] = { 32768, 61000 };
 #endif
-int tcp_port_rover = (1024 - 1);
 
 static __inline__ int tcp_hashfn(__u32 laddr, __u16 lport,
                                 __u32 faddr, __u16 fport)
@@ -223,9 +222,9 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short 
snum)
 
        SOCKHASH_LOCK();
        if (snum == 0) {
-               int rover = tcp_port_rover;
                int low = sysctl_local_port_range[0];
                int high = sysctl_local_port_range[1];
+               int rover = net_random() % (high - low) + low;
                int remaining = (high - low) + 1;
 
                do {    rover++;
@@ -239,7 +238,6 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short 
snum)
                next:
                        ; /* Do nothing.  */
                } while (--remaining > 0);
-               tcp_port_rover = rover;
 
                /* Exhausted local port range during search? */
                if (remaining <= 0)
diff --git a/pfinet/linux-src/net/ipv4/udp.c b/pfinet/linux-src/net/ipv4/udp.c
index f9be2e0..ff5812a 100644
--- a/pfinet/linux-src/net/ipv4/udp.c
+++ b/pfinet/linux-src/net/ipv4/udp.c
@@ -127,20 +127,16 @@ struct udp_mib            udp_statistics;
 
 struct sock *udp_hash[UDP_HTABLE_SIZE];
 
-/* Shared by v4/v6 udp. */
-int udp_port_rover = 0;
-
 static int udp_v4_get_port(struct sock *sk, unsigned short snum)
 {
        SOCKHASH_LOCK();
        if (snum == 0) {
+               int low = sysctl_local_port_range[0];
+               int high = sysctl_local_port_range[1];
                int best_size_so_far, best, result, i;
 
-               if (udp_port_rover > sysctl_local_port_range[1] ||
-                   udp_port_rover < sysctl_local_port_range[0])
-                       udp_port_rover = sysctl_local_port_range[0];
                best_size_so_far = 32767;
-               best = result = udp_port_rover;
+               best = result = net_random() % (high - low) + low;
                for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
                        struct sock *sk;
                        int size;
@@ -173,7 +169,7 @@ static int udp_v4_get_port(struct sock *sk, unsigned short 
snum)
                                break;
                }
 gotit:
-               udp_port_rover = snum = result;
+               snum = result;
        } else {
                struct sock *sk2;
 
diff --git a/pfinet/linux-src/net/ipv6/tcp_ipv6.c 
b/pfinet/linux-src/net/ipv6/tcp_ipv6.c
index 3fba9af..cca5abf 100644
--- a/pfinet/linux-src/net/ipv6/tcp_ipv6.c
+++ b/pfinet/linux-src/net/ipv6/tcp_ipv6.c
@@ -130,9 +130,9 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short 
snum)
 
        SOCKHASH_LOCK();
        if (snum == 0) {
-               int rover = tcp_port_rover;
                int low = sysctl_local_port_range[0];
                int high = sysctl_local_port_range[1];
+               int rover = net_random() % (high - low) + low;
                int remaining = (high - low) + 1;
 
                do {    rover++;
@@ -148,7 +148,6 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short 
snum)
                        (void) 0;
 
                } while (--remaining > 0);
-               tcp_port_rover = rover;
 
                /* Exhausted local port range during search? */
                if (remaining <= 0)
diff --git a/pfinet/linux-src/net/ipv6/udp_ipv6.c 
b/pfinet/linux-src/net/ipv6/udp_ipv6.c
index bbc4f02..f838d25 100644
--- a/pfinet/linux-src/net/ipv6/udp_ipv6.c
+++ b/pfinet/linux-src/net/ipv6/udp_ipv6.c
@@ -92,13 +92,12 @@ static int udp_v6_get_port(struct sock *sk, unsigned short 
snum)
 {
        SOCKHASH_LOCK();
        if (snum == 0) {
+               int low = sysctl_local_port_range[0];
+               int high = sysctl_local_port_range[1];
                int best_size_so_far, best, result, i;
 
-               if (udp_port_rover > sysctl_local_port_range[1] ||
-                   udp_port_rover < sysctl_local_port_range[0])
-                       udp_port_rover = sysctl_local_port_range[0];
                best_size_so_far = 32767;
-               best = result = udp_port_rover;
+               best = result = net_random() % (high - low) + low;
                for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
                        struct sock *sk;
                        int size;
@@ -132,7 +131,7 @@ static int udp_v6_get_port(struct sock *sk, unsigned short 
snum)
                                break;
                }
 gotit:
-               udp_port_rover = snum = result;
+               snum = result;
        } else {
                struct sock *sk2;
                int addr_type = 
ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr);
diff --git a/pfinet/main.c b/pfinet/main.c
index 5e4b749..6b1b723 100644
--- a/pfinet/main.c
+++ b/pfinet/main.c
@@ -197,7 +197,7 @@ find_device (char *name, struct device **device)
   char *base_name;
 
   /* Skip loopback interface. */
-  assert (dev);
+  assert_backtrace (dev);
   dev = dev->next;
 
   if (!name)
@@ -252,7 +252,7 @@ enumerate_devices (error_t (*fun) (struct device *dev))
   struct device *dev = dev_base;
 
   /* Skip loopback device.  */
-  assert (dev);
+  assert_backtrace (dev);
   dev = dev->next;
 
   for (; dev; dev = dev->next)
diff --git a/pfinet/socket.c b/pfinet/socket.c
index 06ce2c7..4a12426 100644
--- a/pfinet/socket.c
+++ b/pfinet/socket.c
@@ -17,7 +17,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include "pfinet.h"
 
 #include <linux/socket.h>
@@ -32,7 +32,7 @@ struct net_proto_family *net_families[NPROTO];
 int
 sock_register (struct net_proto_family *fam)
 {
-  assert (fam->family < NPROTO);
+  assert_backtrace (fam->family < NPROTO);
   net_families[fam->family] = fam;
   return 0;
 }
@@ -72,7 +72,7 @@ make_sock_user (struct socket *sock, int isroot, int 
noinstall, int consume)
   error_t err;
   struct sock_user *user;
 
-  assert (sock->refcnt != 0);
+  assert_backtrace (sock->refcnt != 0);
 
   if (noinstall)
     err = ports_create_port_noinstall (socketport_class, pfinet_bucket,
diff --git a/pfinet/tunnel.c b/pfinet/tunnel.c
index 02e9ee8..b57f8db 100644
--- a/pfinet/tunnel.c
+++ b/pfinet/tunnel.c
@@ -68,7 +68,7 @@ tunnel_get_stats (struct device *dev)
 {
   struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
 
-  assert (tdev);
+  assert_backtrace (tdev);
 
   return &tdev->stats;
 }
@@ -79,7 +79,7 @@ tunnel_stop (struct device *dev)
   struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
   struct sk_buff *skb;
 
-  assert (tdev);
+  assert_backtrace (tdev);
 
   while ((skb = skb_dequeue (&tdev->xq)) != 0)
     dev_kfree_skb(skb);
@@ -105,7 +105,7 @@ tunnel_open (struct device *dev)
 {
   struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
 
-  assert (tdev);
+  assert_backtrace (tdev);
 
   skb_queue_head_init(&tdev->xq);
 
@@ -118,7 +118,7 @@ tunnel_xmit (struct sk_buff *skb, struct device *dev)
 {
   struct tunnel_device *tdev = (struct tunnel_device *) dev->priv;
 
-  assert (tdev);
+  assert_backtrace (tdev);
 
   pthread_mutex_lock (&tdev->lock);
 
@@ -232,7 +232,7 @@ setup_tunnel_device (char *name, struct device **device)
      initializes its `ifindex' member (which matters!),
      and tells the protocol stacks about the device.  */
   err = - register_netdevice (dev);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 }
 
 /* If a new open with read and/or write permissions is requested,
@@ -327,7 +327,7 @@ trivfs_S_io_read (struct trivfs_protid *cred,
     }
 
   skb = skb_dequeue (&tdev->xq);
-  assert(skb);
+  assert_backtrace (skb);
 
   if (skb->len < amount)
     amount = skb->len;
diff --git a/pflocal/connq.c b/pflocal/connq.c
index d86f9a2..b231da7 100644
--- a/pflocal/connq.c
+++ b/pflocal/connq.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include <pthread.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdlib.h>
 
 #include "connq.h"
@@ -66,7 +66,7 @@ connq_request_init (struct connq_request *req, struct sock 
*sock)
 static void
 connq_request_enqueue (struct connq *cq, struct connq_request *req)
 {
-  assert (pthread_mutex_trylock (&cq->lock));
+  assert_backtrace (pthread_mutex_trylock (&cq->lock));
 
   req->next = NULL;
   *cq->tail = req;
@@ -82,8 +82,8 @@ connq_request_dequeue (struct connq *cq)
 {
   struct connq_request *req;
 
-  assert (pthread_mutex_trylock (&cq->lock));
-  assert (cq->head);
+  assert_backtrace (pthread_mutex_trylock (&cq->lock));
+  assert_backtrace (cq->head);
 
   req = cq->head;
   cq->head = req->next;
@@ -132,8 +132,8 @@ connq_destroy (struct connq *cq)
 {
   /* Everybody in the queue should hold a reference to the socket
      containing the queue.  */
-  assert (! cq->head);
-  assert (cq->count == 0);
+  assert_backtrace (! cq->head);
+  assert_backtrace (cq->count == 0);
 
   free (cq);
 }
@@ -171,7 +171,7 @@ connq_listen (struct connq *cq, struct timespec *tsp, 
struct sock **sock)
   if (cq->count == 0)
     /* The request queue is empty.  */
     {
-      assert (! cq->head);
+      assert_backtrace (! cq->head);
 
       if (cq->num_connectors > 0)
        /* Someone is waiting for an acceptor.  Signal that we can
@@ -190,7 +190,7 @@ connq_listen (struct connq *cq, struct timespec *tsp, 
struct sock **sock)
       while (cq->count == 0);
     }
 
-  assert (cq->head);
+  assert_backtrace (cq->head);
 
   if (sock)
     /* Dequeue the next request, if desired.  */
@@ -271,7 +271,7 @@ connq_connect_complete (struct connq *cq, struct sock *sock)
 
   pthread_mutex_lock (&cq->lock);
 
-  assert (cq->num_connectors > 0);
+  assert_backtrace (cq->num_connectors > 0);
   cq->num_connectors --;
 
   connq_request_enqueue (cq, req);
@@ -294,7 +294,7 @@ connq_connect_cancel (struct connq *cq)
 {
   pthread_mutex_lock (&cq->lock);
 
-  assert (cq->num_connectors > 0);
+  assert_backtrace (cq->num_connectors > 0);
   cq->num_connectors --;
 
   if (cq->count + cq->num_connectors >= cq->max + cq->num_listeners)
diff --git a/pflocal/io.c b/pflocal/io.c
index c562274..77e9df6 100644
--- a/pflocal/io.c
+++ b/pflocal/io.c
@@ -442,7 +442,7 @@ S_io_reauthenticate (struct sock_user *user, mach_port_t 
rendezvous)
   auth_server = getauth ();
   err = mach_port_insert_right (mach_task_self (), new_user_port,
                                new_user_port, MACH_MSG_TYPE_MAKE_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   do
     err =
       auth_server_authenticate (auth_server,
diff --git a/pflocal/sock.c b/pflocal/sock.c
index ef70d2c..be64a3d 100644
--- a/pflocal/sock.c
+++ b/pflocal/sock.c
@@ -147,7 +147,7 @@ _sock_norefs (struct sock *sock)
 {
   /* A sock should never have an address when it has 0 refs, as the
      address should hold a reference to the sock!  */
-  assert (sock->addr == NULL);
+  assert_backtrace (sock->addr == NULL);
   pthread_mutex_unlock (&sock->lock);  /* Unlock so sock_free can do stuff.  */
   sock_free (sock);
 }
@@ -249,7 +249,7 @@ addr_clean (void *vaddr)
   /* ADDR should never have a socket bound to it at this point, as it should
      have been removed by addr_unbind dropping the socket's weak reference
      it.  */
-  assert (addr->sock == NULL);
+  assert_backtrace (addr->sock == NULL);
 }
 
 /* Return a new address, not connected to any socket yet, ADDR.  */
@@ -307,7 +307,7 @@ sock_bind (struct sock *sock, struct addr *addr)
             zero because whoever's calling us should be holding a ref.  */
          sock->refs--;
          ports_port_deref_weak (old_addr);
-         assert (sock->refs > 0);      /* But make sure... */
+         assert_backtrace (sock->refs > 0);    /* But make sure... */
        }
     }
 
@@ -394,7 +394,7 @@ sock_connect (struct sock *sock1, struct sock *sock2)
            || (rd->flags & PFLOCAL_SOCK_SHUTDOWN_READ)))
        {
          struct pipe *pipe = rd->read_pipe;
-         assert (pipe);        /* Since PFLOCAL_SOCK_SHUTDOWN_READ isn't set.  
*/
+         assert_backtrace (pipe);      /* Since PFLOCAL_SOCK_SHUTDOWN_READ 
isn't set.  */
          pipe_add_writer (pipe);
          wr->write_pipe = pipe;
        }
diff --git a/pflocal/sock.h b/pflocal/sock.h
index 29f0f1f..011b91a 100644
--- a/pflocal/sock.h
+++ b/pflocal/sock.h
@@ -21,7 +21,7 @@
 #ifndef __SOCK_H__
 #define __SOCK_H__
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>           /* For mutexes */
 #include <sys/mman.h>
 #include <sys/types.h>
@@ -139,12 +139,12 @@ sock_deref (struct sock *sock)
 
       /* Unbind */
       err = sock_bind (sock, NULL);
-      assert (!err);
+      assert_backtrace (!err);
 
       /* And release the ref, and thus kill SOCK.  */
       pthread_mutex_lock (&sock->lock);
       sock->refs--;
-      assert(sock->refs == 0);
+      assert_backtrace (sock->refs == 0);
       _sock_norefs (sock);
     }
   else
diff --git a/proc/host.c b/proc/host.c
index c68ab8a..7d76f7c 100644
--- a/proc/host.c
+++ b/proc/host.c
@@ -32,7 +32,7 @@
 #include <stdio.h>
 #include <hurd/exec.h>
 #include <unistd.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <version.h>
 #include <sys/mman.h>
 
@@ -113,8 +113,7 @@ S_proc_setexecdata (struct proc *p,
        mach_port_deallocate (mach_task_self (), std_port_array[i]);
       free (std_port_array);
     }
-  if (std_int_array)
-    free (std_int_array);
+  free (std_int_array);
 
   std_port_array = std_port_array_new;
   n_std_ports = nports;
@@ -359,7 +358,7 @@ initialize_version_info (void)
 
   err = host_info (mach_host_self (), HOST_BASIC_INFO,
                   (host_info_t) &info, &n);
-  assert (! err);
+  assert_backtrace (! err);
   snprintf (uname_info.machine, sizeof uname_info.machine, "%s-%s",
            mach_cpu_types[info.cpu_type],
            mach_cpu_subtypes[info.cpu_type][info.cpu_subtype]);
@@ -367,11 +366,11 @@ initialize_version_info (void)
   /* Notice Mach's and our own version and initialize server version
      variables. */
   server_versions = malloc (sizeof (struct server_version) * 10);
-  assert (server_versions);
+  assert_backtrace (server_versions);
   server_versions_nalloc = 10;
 
   err = host_kernel_version (mach_host_self (), kv);
-  assert (! err);
+  assert_backtrace (! err);
   /* Make sure the result is null-terminated, as the kernel doesn't
      guarantee it.  */
   kv[sizeof (kv) - 1] = '\0';
@@ -382,14 +381,14 @@ initialize_version_info (void)
   if (p)
     *p = '\0';
   kernel_name = strdup (p ? kv : "mach");
-  assert (kernel_name);
+  assert_backtrace (kernel_name);
   kernel_version = strdup (p ? p + 1 : kv);
-  assert (kernel_version);
+  assert_backtrace (kernel_version);
 
   server_versions[0].name = strdup ("proc");
-  assert (server_versions[0].name);
+  assert_backtrace (server_versions[0].name);
   server_versions[0].version = strdup (HURD_VERSION);
-  assert (server_versions[0].version);
+  assert_backtrace (server_versions[0].version);
 
   nserver_versions = 1;
 
diff --git a/proc/info.c b/proc/info.c
index 79a4c37..3c1bf6d 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -27,7 +27,7 @@
 #include <errno.h>
 #include <string.h>
 #include <sys/resource.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/msg.h>
 
 #include "proc.h"
@@ -71,7 +71,7 @@ S_proc_pid2task (struct proc *callerp,
   if (! check_owner (callerp, p))
     return EPERM;
 
-  assert (MACH_PORT_VALID (p->p_task));
+  assert_backtrace (MACH_PORT_VALID (p->p_task));
   *t = p->p_task;
 
   return 0;
@@ -618,7 +618,7 @@ S_proc_getprocinfo (struct proc *callerp,
   pi->pgrp = p->p_pgrp->pg_pgid;
   pi->session = p->p_pgrp->pg_session->s_sid;
   for (tp = p; !tp->p_loginleader; tp = tp->p_parent)
-    assert (tp);
+    assert_backtrace (tp);
   pi->logincollection = tp->p_pid;
   if (p->p_dead || p->p_stopped)
     {
@@ -837,7 +837,7 @@ S_proc_getloginid (struct proc *callerp,
     }
 
   for (p = proc; !p->p_loginleader; p = p->p_parent)
-    assert (p);
+    assert_backtrace (p);
 
   *leader = p->p_pid;
   return 0;
diff --git a/proc/main.c b/proc/main.c
index e615f36..0a6f991 100644
--- a/proc/main.c
+++ b/proc/main.c
@@ -25,7 +25,7 @@
 #include <hurd/paths.h>
 #include <hurd/startup.h>
 #include <device/device.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <argp.h>
 #include <error.h>
 #include <version.h>
@@ -165,7 +165,7 @@ main (int argc, char **argv, char **envp)
   initialize_version_info ();
 
   err = task_get_bootstrap_port (mach_task_self (), &boot);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   if (boot == MACH_PORT_NULL)
     error (2, 0, "proc server can only be run by startup during boot");
 
@@ -187,14 +187,14 @@ main (int argc, char **argv, char **envp)
 
   /* Create our own proc object.  */
   self_proc = allocate_proc (mach_task_self ());
-  assert (self_proc);
+  assert_backtrace (self_proc);
 
   complete_proc (self_proc, HURD_PID_PROC);
 
   startup_port = ports_get_send_right (startup_proc);
   err = startup_procinit (boot, startup_port, &startup_proc->p_task,
                          &authserver, &_hurd_host_priv, &_hurd_device_master);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   mach_port_deallocate (mach_task_self (), startup_port);
 
   /* Get our stderr set up to print on the console, in case we have
@@ -252,7 +252,7 @@ main (int argc, char **argv, char **envp)
        startup_fallback = 1;
 
       err = mach_port_deallocate (mach_task_self (), startup);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
   else
     /* Fall back to abusing the message port lookup.   */
diff --git a/proc/mgt.c b/proc/mgt.c
index a9015cc..750073a 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -33,7 +33,7 @@
 #include <mach/mig_errors.h>
 #include <sys/resource.h>
 #include <hurd/auth.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pids.h>
 
 #include "proc.h"
@@ -189,7 +189,7 @@ S_proc_child (struct proc *parentp,
   /* Process hierarchy.  Remove from our current location
      and place us under our new parent.  Sanity check to make sure
      parent is currently init. */
-  assert (childp->p_parent == init_proc);
+  assert_backtrace (childp->p_parent == init_proc);
   if (childp->p_sib)
     childp->p_sib->p_prevsib = childp->p_prevsib;
   *childp->p_prevsib = childp->p_sib;
@@ -606,7 +606,7 @@ create_init_proc (void)
   const char *rootsname = "root";
 
   p = allocate_proc (MACH_PORT_NULL);
-  assert (p);
+  assert_backtrace (p);
 
   p->p_pid = HURD_PID_INIT;
 
@@ -622,11 +622,11 @@ create_init_proc (void)
 
   p->p_noowner = 0;
   p->p_id = make_ids (&zero, 1);
-  assert (p->p_id);
+  assert_backtrace (p->p_id);
 
   p->p_loginleader = 1;
   p->p_login = malloc (sizeof (struct login) + strlen (rootsname) + 1);
-  assert (p->p_login);
+  assert_backtrace (p->p_login);
 
   p->p_login->l_refcnt = 1;
   strcpy (p->p_login->l_name, rootsname);
@@ -649,7 +649,7 @@ proc_death_notify (struct proc *p)
                                        p->p_pi.port_right,
                                        MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                        &old);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (old != MACH_PORT_NULL)
     mach_port_deallocate (mach_task_self (), old);
@@ -681,7 +681,7 @@ complete_proc (struct proc *p, pid_t pid)
          HURD_PID_INIT.  */
       static const uid_t zero;
       p->p_id = make_ids (&zero, 1);
-      assert (p->p_id);
+      assert_backtrace (p->p_id);
     }
   else
     {
@@ -930,8 +930,8 @@ process_has_exited (struct proc *p)
 void
 complete_exit (struct proc *p)
 {
-  assert (p->p_dead);
-  assert (p->p_waited);
+  assert_backtrace (p->p_dead);
+  assert_backtrace (p->p_waited);
 
   remove_proc_from_hash (p);
   if (p->p_task != MACH_PORT_NULL)
@@ -1178,7 +1178,7 @@ S_mach_notify_new_task (struct port_info *notify,
         proc_child, so we do it on their behalf.  */
       mach_port_mod_refs (mach_task_self (), task, MACH_PORT_RIGHT_SEND, +1);
       err = S_proc_child (parentp, task);
-      assert_perror (err);
+      assert_perror_backtrace (err);
 
       /* Relay the notification.  This consumes task and parent.  */
       return mach_notify_new_task (childp->p_task_namespace, task, parent);
diff --git a/proc/msg.c b/proc/msg.c
index 8efc993..9c326e2 100644
--- a/proc/msg.c
+++ b/proc/msg.c
@@ -19,7 +19,7 @@
 #include <hurd.h>
 #include "proc.h"
 #include <hurd/startup.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdlib.h>
 #include <stdio.h>
 
diff --git a/proc/pgrp.c b/proc/pgrp.c
index 9db1dba..a787676 100644
--- a/proc/pgrp.c
+++ b/proc/pgrp.c
@@ -25,7 +25,7 @@
 #include <sys/errno.h>
 #include <stdlib.h>
 #include <signal.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "proc.h"
 #include "process_S.h"
@@ -130,7 +130,7 @@ boot_setsid (struct proc *p)
 
   sess = new_session (p);
   p->p_pgrp = new_pgrp (p->p_pid, sess);
-  assert (p->p_pgrp);
+  assert_backtrace (p->p_pgrp);
   join_pgrp (p);
   return;
 }
diff --git a/proc/stubs.c b/proc/stubs.c
index 096e55e..e984f23 100644
--- a/proc/stubs.c
+++ b/proc/stubs.c
@@ -20,7 +20,7 @@
 #include <hurd/hurd_types.h>
 #include <mach/message.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdio.h>
 
 #include "proc.h"
@@ -61,7 +61,7 @@ blocking_message_send (void *arg)
     case MACH_SEND_INVALID_NOTIFY:
     case MACH_SEND_NO_NOTIFY:
     case MACH_SEND_NOTIFY_IN_PROGRESS:
-      assert_perror (err);
+      assert_perror_backtrace (err);
       break;
 
     default:                   /* Other errors are safe to ignore.  */
@@ -169,7 +169,7 @@ send_signal (mach_port_t msgport,
     case MACH_SEND_INVALID_NOTIFY:
     case MACH_SEND_NO_NOTIFY:
     case MACH_SEND_NOTIFY_IN_PROGRESS:
-      assert_perror (err);
+      assert_perror_backtrace (err);
       break;
 
     default:                   /* Other errors are safe to ignore.  */
diff --git a/proc/wait.c b/proc/wait.c
index 824e667..e8c379a 100644
--- a/proc/wait.c
+++ b/proc/wait.c
@@ -29,7 +29,8 @@
 #include <sys/wait.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
+#define assert assert_backtrace
 
 #include "process_S.h"
 #include <mach/mig_errors.h>
diff --git a/procfs/main.c b/procfs/main.c
index 87c726f..e9e2912 100644
--- a/procfs/main.c
+++ b/procfs/main.c
@@ -254,13 +254,11 @@ netfs_append_args (char **argz, size_t *argz_len)
 }
 
 /* The user may define this function.  The function must set source to
-   the source of CRED. The function may return an EOPNOTSUPP to
-   indicate that the concept of a source device is not applicable. The
-   default function always returns EOPNOTSUPP. */
-error_t netfs_get_source (struct protid *cred, char *source, size_t source_len)
+   the source of the translator. The function may return an EOPNOTSUPP
+   to indicate that the concept of a source device is not
+   applicable. The default function always returns EOPNOTSUPP.  */
+error_t netfs_get_source (char *source, size_t source_len)
 {
-  if (! cred)
-    return EOPNOTSUPP;
   snprintf (source, source_len, "proc");
   return 0;
 }
@@ -314,6 +312,6 @@ int main (int argc, char **argv)
   netfs_startup (bootstrap, 0);
   netfs_server_loop ();
 
-  assert (0 /* netfs_server_loop returned after all */);
+  assert_backtrace (0 /* netfs_server_loop returned after all */);
 }
 
diff --git a/procfs/netfs.c b/procfs/netfs.c
index 0b3d31a..9410bdd 100644
--- a/procfs/netfs.c
+++ b/procfs/netfs.c
@@ -110,7 +110,7 @@ error_t netfs_attempt_readlink (struct iouser *user, struct 
node *np,
   if (err)
     return err;
 
-  assert (contents_len == np->nn_stat.st_size);
+  assert_backtrace (contents_len == np->nn_stat.st_size);
   memcpy (buf, contents, contents_len);
   return 0;
 }
@@ -172,7 +172,7 @@ error_t netfs_get_dirents (struct iouser *cred, struct node 
*dir,
     return err;
 
   /* We depend on the fact that CONTENTS is terminated. */
-  assert (contents_len == 0 || contents[contents_len - 1] == '\0');
+  assert_backtrace (contents_len == 0 || contents[contents_len - 1] == '\0');
 
   /* Skip to the first requested entry. */
   while (contents_len && entry--)
diff --git a/procfs/procfs.c b/procfs/procfs.c
index cae4a51..6d6d964 100644
--- a/procfs/procfs.c
+++ b/procfs/procfs.c
@@ -120,7 +120,7 @@ procfs_make_ino (struct node *np, const char *filename)
   if (! strcmp (filename, ".."))
     return np->nn->parent ? np->nn->parent->nn_stat.st_ino : /* FIXME: */ 2;
 
-  assert (sizeof np->nn_stat.st_ino > sizeof x);
+  assert_backtrace (sizeof np->nn_stat.st_ino > sizeof x);
   memcpy (x, &np->nn_stat.st_ino, sizeof x);
 
   while (*filename)
diff --git a/procfs/proclist.c b/procfs/proclist.c
index 58b942d..1ecf75b 100644
--- a/procfs/proclist.c
+++ b/procfs/proclist.c
@@ -49,7 +49,7 @@ proclist_get_contents (void *hook, char **contents, ssize_t 
*contents_len)
       for (i=0; i < num_pids; i++)
        {
          int n = sprintf (*contents + *contents_len, "%d", pids[i]);
-         assert (n >= 0);
+         assert_backtrace (n >= 0);
          *contents_len += (n + 1);
        }
     }
@@ -68,7 +68,7 @@ proclist_lookup (void *hook, const char *name, struct node 
**np)
   pid_t pid;
 
   /* Self-lookups should not end up here. */
-  assert (name[0]);
+  assert_backtrace (name[0]);
 
   /* No leading zeros allowed */
   if (name[0] == '0' && name[1])
diff --git a/procfs/rootdir.c b/procfs/rootdir.c
index 4f4a142..9f860a9 100644
--- a/procfs/rootdir.c
+++ b/procfs/rootdir.c
@@ -1,5 +1,5 @@
 /* Hurd /proc filesystem, permanent files of the root directory.
-   Copyright (C) 2010,13,14 Free Software Foundation, Inc.
+   Copyright (C) 2010,13,14,17 Free Software Foundation, Inc.
 
    This file is part of the GNU Hurd.
 
@@ -254,7 +254,7 @@ rootdir_gc_loadavg (void *hook, char **contents, ssize_t 
*contents_len)
   if (err)
     return err;
 
-  assert (cnt == HOST_LOAD_INFO_COUNT);
+  assert_backtrace (cnt == HOST_LOAD_INFO_COUNT);
   *contents_len = asprintf (contents,
       "%.2f %.2f %.2f 1/0 0\n",
       hli.avenrun[0] / (double) LOAD_SCALE,
@@ -301,7 +301,7 @@ rootdir_gc_meminfo (void *hook, char **contents, ssize_t 
*contents_len)
   if (err)
     goto out;
 
-  assert (cnt == HOST_BASIC_INFO_COUNT);
+  assert_backtrace (cnt == HOST_BASIC_INFO_COUNT);
   fprintf (m,
       "MemTotal: %14lu kB\n"
       "MemFree:  %14lu kB\n"
@@ -339,8 +339,6 @@ rootdir_gc_meminfo (void *hook, char **contents, ssize_t 
*contents_len)
 static error_t
 rootdir_gc_vmstat (void *hook, char **contents, ssize_t *contents_len)
 {
-  host_basic_info_data_t hbi;
-  mach_msg_type_number_t cnt;
   struct vm_statistics vmstats;
   error_t err;
 
@@ -348,12 +346,6 @@ rootdir_gc_vmstat (void *hook, char **contents, ssize_t 
*contents_len)
   if (err)
     return EIO;
 
-  cnt = HOST_BASIC_INFO_COUNT;
-  err = host_info (mach_host_self (), HOST_BASIC_INFO, (host_info_t) &hbi, 
&cnt);
-  if (err)
-    return err;
-
-  assert (cnt == HOST_BASIC_INFO_COUNT);
   *contents_len = asprintf (contents,
       "nr_free_pages %lu\n"
       "nr_inactive_anon %lu\n"
@@ -481,6 +473,57 @@ rootdir_gc_slabinfo (void *hook, char **contents, ssize_t 
*contents_len)
 }
 
 static error_t
+rootdir_gc_hostinfo (void *hook, char **contents, ssize_t *contents_len)
+{
+  error_t err;
+  FILE *m;
+  host_basic_info_t basic;
+  host_sched_info_t sched;
+  host_load_info_t load;
+
+  m = open_memstream (contents, (size_t *) contents_len);
+  if (m == NULL)
+    return ENOMEM;
+
+  err = ps_host_basic_info (&basic);
+  if (! err)
+    fprintf (m, "Basic info:\n"
+             "max_cpus = %10u  /* max number of cpus possible */\n"
+             "avail_cpus       = %10u  /* number of cpus now available */\n"
+             "memory_size      = %10u  /* size of memory in bytes */\n"
+             "cpu_type = %10u  /* cpu type */\n"
+             "cpu_subtype      = %10u  /* cpu subtype */\n",
+             basic->max_cpus,
+             basic->avail_cpus,
+             basic->memory_size,
+             basic->cpu_type,
+             basic->cpu_subtype);
+
+  err = ps_host_sched_info (&sched);
+  if (! err)
+    fprintf (m, "\nScheduling info:\n"
+             "min_timeout      = %10u  /* minimum timeout in milliseconds */\n"
+             "min_quantum      = %10u  /* minimum quantum in milliseconds 
*/\n",
+             sched->min_timeout,
+             sched->min_quantum);
+
+  err = ps_host_load_info (&load);
+  if (! err)
+    fprintf (m, "\nLoad info:\n"
+             "avenrun[3]       = { %.2f, %.2f, %.2f }\n"
+             "mach_factor[3]   = { %.2f, %.2f, %.2f }\n",
+             load->avenrun[0] / (double) LOAD_SCALE,
+             load->avenrun[1] / (double) LOAD_SCALE,
+             load->avenrun[2] / (double) LOAD_SCALE,
+             load->mach_factor[0] / (double) LOAD_SCALE,
+             load->mach_factor[1] / (double) LOAD_SCALE,
+             load->mach_factor[2] / (double) LOAD_SCALE);
+
+  fclose (m);
+  return 0;
+}
+
+static error_t
 rootdir_gc_filesystems (void *hook, char **contents, ssize_t *contents_len)
 {
   error_t err = 0;
@@ -753,6 +796,13 @@ static const struct procfs_dir_entry rootdir_entries[] = {
     },
   },
   {
+    .name = "hostinfo",
+    .hook = & (struct procfs_node_ops) {
+      .get_contents = rootdir_gc_hostinfo,
+      .cleanup_contents = procfs_cleanup_contents_with_free,
+    },
+  },
+  {
     .name = "filesystems",
     .hook = & (struct procfs_node_ops) {
       .get_contents = rootdir_gc_filesystems,
diff --git a/random/Makefile b/random/Makefile
deleted file mode 100644
index 5f8a62c..0000000
--- a/random/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-#   Copyright (C) 1994,95,96,97,99,2000,2001 Free Software Foundation, Inc.
-#
-#   This program is free software; you can redistribute it and/or
-#   modify it under the terms of the GNU General Public License as
-#   published by the Free Software Foundation; either version 2, or (at
-#   your option) any later version.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#   General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with this program; if not, write to the Free Software
-#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-dir := random
-makemode := server
-
-CFLAGS += -D__HURD__
-
-target = random
-SRCS = random.c gnupg-random.c gnupg-rmd160.c
-OBJS = $(SRCS:.c=.o) startup_notifyServer.o
-LCLHDRS = gnupg-random.h gnupg-rmd.h gnupg-bithelp.h random.h
-HURDLIBS = trivfs ports fshelp ihash iohelp shouldbeinlibc
-LDLIBS = -lpthread
-
-include ../Makeconf
diff --git a/random/TODO b/random/TODO
deleted file mode 100644
index 9cc57ab..0000000
--- a/random/TODO
+++ /dev/null
@@ -1,11 +0,0 @@
-* read_poll uses random_poll until the pool is filled.  This is ian
-  issue at first initialization, as this requries POOLSIZE good random (level 
1 from
-  gather_random) even in level 0 and 1.
-  For now, the code is only applied to level 2.  Eventually, readable_pool
-  should be fixed to return 0 if initialization is not done yet and not enough 
bytes
-  are available.  Otherwise it enters an infinite loop.
-
-* Permissions?
-
-* Off by one error in gather_random/io_write?  I can only get GATHERBUFSIZE - 1
-  bytes from it.
diff --git a/random/gnupg-bithelp.h b/random/gnupg-bithelp.h
deleted file mode 100644
index 188db16..0000000
--- a/random/gnupg-bithelp.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* bithelp.h  -  Some bit manipulation helpers
- *     Copyright (C) 1999 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_BITHELP_H
-#define G10_BITHELP_H
-
-
-/****************
- * Rotate a 32 bit integer by n bytes
- */
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-rol( u32 x, int n)
-{
-       __asm__("roll %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
-}
-#else
-  #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
-#endif
-
-
-#endif /*G10_BITHELP_H*/
diff --git a/random/gnupg-glue.h b/random/gnupg-glue.h
deleted file mode 100644
index cbf0a10..0000000
--- a/random/gnupg-glue.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __GNUPG_GLUE_H__
-#define __GNUPG_GLUE_H__
-
-#include <sys/types.h>
-#include <random.h>
-
-#define SIZEOF_UNSIGNED_LONG 4
-typedef unsigned int u32;
-typedef unsigned char byte;
-
-/* GnuPG's config.h  */
-#define HAVE_GETTIMEOFDAY 1
-#define HAVE_GETRUSAGE 1
-#define HAVE_RAND 1
-
-/* GnuPG's memory.h  */
-#define m_alloc malloc
-#define m_alloc_secure malloc
-#define m_alloc_clear(x) calloc(x, 1)
-#define m_alloc_secure_clear(x) calloc(x, 1)
-#define m_free free
-#define m_strdup strdup
-
-/* GnuPG's dynaload.h  */
-#define dynload_getfnc_fast_random_poll() (0)
-#define dynload_getfnc_gather_random() &gather_random
-int
-gather_random( void (*add)(const void*, size_t, int), int requester,
-               size_t length, int level );
-
-/* GnuPG's miscellaneous stuff.  */
-#define BUG() assert(0)
-#define _(x) x
-#define make_timestamp() time(0)
-#define tty_printf printf
-#define log_info(format, args...) printf(format , ## args)
-#define log_fatal(format, args...) { printf(format , ## args) ; exit(2); }
-#define DIM(v) (sizeof(v)/sizeof((v)[0]))
-
-#endif /* __GNUPG_GLUE_H__ */
diff --git a/random/gnupg-random.c b/random/gnupg-random.c
deleted file mode 100644
index a4df694..0000000
--- a/random/gnupg-random.c
+++ /dev/null
@@ -1,809 +0,0 @@
-/* random.c  - random number generator
- *     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-/****************
- * This random number generator is modelled after the one described
- * in Peter Gutmann's Paper: "Software Generation of Practically
- * Strong Random Numbers".
- */
-
-#ifndef __HURD__
-#include <config.h>
-#else
-#include "gnupg-glue.h"
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#ifdef HAVE_GETHRTIME
-  #include <sys/times.h>
-#endif
-#ifdef HAVE_GETTIMEOFDAY
-  #include <sys/times.h>
-#endif
-#ifdef HAVE_GETRUSAGE
-  #include <sys/resource.h>
-#endif
-#ifdef __MINGW32__
-  #include <process.h>
-#endif
-#ifndef __HURD__
-#include "util.h"
-#endif
-#ifndef __HURD__
-#include "rmd.h"
-#include "ttyio.h"
-#include "i18n.h"
-#include "random.h"
-#include "rand-internal.h"
-#include "dynload.h"
-#else
-#include "gnupg-rmd.h"
-#include "gnupg-random.h"
-#endif
-
-#ifndef RAND_MAX   /* for SunOS */
-  #define RAND_MAX 32767
-#endif
-
-
-#if SIZEOF_UNSIGNED_LONG == 8
-  #define ADD_VALUE 0xa5a5a5a5a5a5a5a5
-#elif SIZEOF_UNSIGNED_LONG == 4
-  #define ADD_VALUE 0xa5a5a5a5
-#else
-  #error weird size for an unsigned long
-#endif
-
-#define BLOCKLEN  64   /* hash this amount of bytes */
-#define DIGESTLEN 20   /* into a digest of this length (rmd160) */
-/* poolblocks is the number of digests which make up the pool
- * and poolsize must be a multiple of the digest length
- * to make the AND operations faster, the size should also be
- * a multiple of ulong
- */
-#define POOLBLOCKS 30
-#define POOLSIZE (POOLBLOCKS*DIGESTLEN)
-#if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
-  #error Please make sure that poolsize is a multiple of ulong
-#endif
-#define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
-
-
-static int is_initialized;
-#define MASK_LEVEL(a) do {if( a > 2 ) a = 2; else if( a < 0 ) a = 0; } while(0)
-static byte *rndpool;  /* allocated size is POOLSIZE+BLOCKLEN */
-static byte *keypool;  /* allocated size is POOLSIZE+BLOCKLEN */
-static size_t pool_readpos;
-static size_t pool_writepos;
-static int pool_filled;
-static int pool_balance;
-static int just_mixed;
-static int did_initial_extra_seeding;
-static char *seed_file_name;
-static int allow_seed_file_update;
-
-static int secure_alloc;
-static int quick_test;
-static int faked_rng;
-
-
-#ifndef __HURD__
-static void read_pool( byte *buffer, size_t length, int level );
-#else
-int read_pool( byte *buffer, size_t length, int level );
-#endif
-static void add_randomness( const void *buffer, size_t length, int source );
-static void random_poll(void);
-#ifndef __HURD__
-static void read_random_source( int requester, size_t length, int level);
-#else
-static int read_random_source( int requester, size_t length, int level);
-#endif
-static int gather_faked( void (*add)(const void*, size_t, int), int requester,
-                                                   size_t length, int level );
-
-static struct {
-    ulong mixrnd;
-    ulong mixkey;
-    ulong slowpolls;
-    ulong fastpolls;
-    ulong getbytes1;
-    ulong ngetbytes1;
-    ulong getbytes2;
-    ulong ngetbytes2;
-    ulong addbytes;
-    ulong naddbytes;
-} rndstats;
-
-static void
-initialize(void)
-{
-    /* The data buffer is allocated somewhat larger, so that
-     * we can use this extra space (which is allocated in secure memory)
-     * as a temporary hash buffer */
-    rndpool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
-                          : m_alloc_clear(POOLSIZE+BLOCKLEN);
-    keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
-                          : m_alloc_clear(POOLSIZE+BLOCKLEN);
-    is_initialized = 1;
-#ifndef __HURD__
-    cipher_modules_constructor();
-#endif
-}
-
-static void
-burn_stack (int bytes)
-{
-    char buf[128];
-    
-    memset (buf, 0, sizeof buf);
-    bytes -= sizeof buf;
-    if (bytes > 0)
-        burn_stack (bytes);
-}
-
-void
-random_dump_stats()
-{
-    fprintf(stderr,
-           "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
-           "              outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n",
-       POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
-                 rndstats.naddbytes, rndstats.addbytes,
-       rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
-                   rndstats.ngetbytes2, rndstats.getbytes2 );
-}
-
-void
-secure_random_alloc()
-{
-    secure_alloc = 1;
-}
-
-
-int
-quick_random_gen( int onoff )
-{
-    int last;
-
-    read_random_source(0,0,0); /* init */
-    last = quick_test;
-    if( onoff != -1 )
-       quick_test = onoff;
-    return faked_rng? 1 : last;
-}
-
-
-/****************
- * Fill the buffer with LENGTH bytes of cryptographically strong
- * random bytes. level 0 is not very strong, 1 is strong enough
- * for most usage, 2 is good for key generation stuff but may be very slow.
- */
-void
-randomize_buffer( byte *buffer, size_t length, int level )
-{
-    byte *p = get_random_bits( length*8, level, 1 );
-    memcpy( buffer, p, length );
-    m_free(p);
-}
-
-
-int
-random_is_faked()
-{
-    if( !is_initialized )
-       initialize();
-    return faked_rng || quick_test;
-}
-
-/****************
- * Return a pointer to a randomized buffer of level 0 and LENGTH bits
- * caller must free the buffer.
- * Note: The returned value is rounded up to bytes.
- */
-byte *
-get_random_bits( size_t nbits, int level, int secure )
-{
-    byte *buf, *p;
-    size_t nbytes = (nbits+7)/8;
-
-    if( quick_test && level > 1 )
-       level = 1;
-    MASK_LEVEL(level);
-    if( level == 1 ) {
-       rndstats.getbytes1 += nbytes;
-       rndstats.ngetbytes1++;
-    }
-    else if( level >= 2 ) {
-       rndstats.getbytes2 += nbytes;
-       rndstats.ngetbytes2++;
-    }
-
-    buf = secure && secure_alloc ? m_alloc_secure( nbytes ) : m_alloc( nbytes 
);
-    for( p = buf; nbytes > 0; ) {
-       size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes;
-#ifdef __HURD__
-       n =
-#endif
-       read_pool( p, n, level );
-       nbytes -= n;
-       p += n;
-
-    }
-    return buf;
-}
-
-
-/****************
- * Mix the pool
- */
-static void
-mix_pool(byte *pool)
-{
-    byte *hashbuf = pool + POOLSIZE;
-    byte *p, *pend;
-    int i, n;
-    RMD160_CONTEXT md;
-
-    rmd160_init( &md );
- #if DIGESTLEN != 20
-    #error must have a digest length of 20 for ripe-md-160
- #endif
-    /* pool -> pool' */
-    pend = pool + POOLSIZE;
-    memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
-    memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
-    rmd160_mixblock( &md, hashbuf);
-    memcpy(pool, hashbuf, DIGESTLEN);
-
-    /* Loop for the remaining iterations.  */
-    p = pool;
-    for( n=1; n < POOLBLOCKS; n++ ) {
-       if( p + BLOCKLEN < pend )
-           memcpy(hashbuf, p, BLOCKLEN);
-       else {
-           byte *pp = p;
-           for(i=0; i < BLOCKLEN; i++ ) {
-               if( pp >= pend )
-                   pp = pool;
-               hashbuf[i] = *pp++;
-           }
-       }
-
-       rmd160_mixblock( &md, hashbuf);
-       p += DIGESTLEN;
-       memcpy(p, hashbuf, DIGESTLEN);
-    }
-    burn_stack (200); /* for the rmd160_mixblock() */
-}
-
-
-void
-set_random_seed_file( const char *name )
-{
-    if( seed_file_name )
-       BUG();
-    seed_file_name = m_strdup( name );
-}
-
-/****************
- * Read in a seed form the random_seed file
- * and return true if this was successful
- */
-static int
-read_seed_file()
-{
-    int fd;
-    struct stat sb;
-    byte buffer[POOLSIZE];
-    int n;
-
-    if( !seed_file_name )
-       return 0;
-
-  #ifdef HAVE_DOSISH_SYSTEM
-    fd = open( seed_file_name, O_RDONLY | O_BINARY );
-  #else
-    fd = open( seed_file_name, O_RDONLY );
-  #endif
-    if( fd == -1 && errno == ENOENT) {
-       allow_seed_file_update = 1;
-       return 0;
-    }
-
-    if( fd == -1 ) {
-       log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
-       return 0;
-    }
-    if( fstat( fd, &sb ) ) {
-       log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
-       close(fd);
-       return 0;
-    }
-    if( !S_ISREG(sb.st_mode) ) {
-       log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
-       close(fd);
-       return 0;
-    }
-    if( !sb.st_size ) {
-       log_info(_("note: random_seed file is empty\n") );
-       close(fd);
-       allow_seed_file_update = 1;
-       return 0;
-    }
-    if( sb.st_size != POOLSIZE ) {
-       log_info(_("warning: invalid size of random_seed file - not used\n") );
-       close(fd);
-       return 0;
-    }
-    do {
-       n = read( fd, buffer, POOLSIZE );
-    } while( n == -1 && errno == EINTR );
-    if( n != POOLSIZE ) {
-       log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
-       close(fd);
-       return 0;
-    }
-
-    close(fd);
-
-    add_randomness( buffer, POOLSIZE, 0 );
-    /* add some minor entropy to the pool now (this will also force a mixing) 
*/
-    {  pid_t x = getpid();
-       add_randomness( &x, sizeof(x), 0 );
-    }
-    {  time_t x = time(NULL);
-       add_randomness( &x, sizeof(x), 0 );
-    }
-    {  clock_t x = clock();
-       add_randomness( &x, sizeof(x), 0 );
-    }
-    /* And read a few bytes from our entropy source.  By using
-     * a level of 0 this will not block and might not return anything
-     * with some entropy drivers, however the rndlinux driver will use
-     * /dev/urandom and return some stuff - Do not read to much as we
-     * want to be friendly to the scare system entropy resource. */
-    read_random_source( 0, 16, 0 );
-
-    allow_seed_file_update = 1;
-    return 1;
-}
-
-void
-update_random_seed_file()
-{
-    ulong *sp, *dp;
-    int fd, i;
-
-    if( !seed_file_name || !is_initialized || !pool_filled )
-       return;
-    if( !allow_seed_file_update ) {
-       log_info(_("note: random_seed file not updated\n"));
-       return;
-    }
-
-
-    /* copy the entropy pool to a scratch pool and mix both of them */
-    for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
-                                   i < POOLWORDS; i++, dp++, sp++ ) {
-       *dp = *sp + ADD_VALUE;
-    }
-    mix_pool(rndpool); rndstats.mixrnd++;
-    mix_pool(keypool); rndstats.mixkey++;
-
-  #ifdef HAVE_DOSISH_SYSTEM
-    fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
-                                                       S_IRUSR|S_IWUSR );
-  #else
-    fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
-  #endif
-    if( fd == -1 ) {
-       log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) 
);
-       return;
-    }
-    do {
-       i = write( fd, keypool, POOLSIZE );
-    } while( i == -1 && errno == EINTR );
-    if( i != POOLSIZE ) {
-       log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno) );
-    }
-    if( close(fd) )
-       log_info(_("can't close `%s': %s\n"), seed_file_name, strerror(errno) );
-}
-
-#ifdef __HURD__
-int readable_pool( size_t length, int level )
-{
-  size_t needed = 0;
-  size_t my_balance = pool_balance;
-  size_t available = (gatherwpos - gatherrpos + GATHERBUFSIZE) % GATHERBUFSIZE;
-
-  if (length > POOLSIZE)
-    length = POOLSIZE;
-
-  if (level < 2)
-    return length;
-
-  if( !pool_filled ) {
-    if( read_seed_file() )
-      pool_filled = 1;
-  }
-
-  if (!did_initial_extra_seeding)
-    {
-      /* Take account for initial extra seeding.  */
-      needed = length;
-      if (needed < POOLSIZE/2)
-       needed = POOLSIZE/2;
-      my_balance = needed;
-
-      if (!pool_filled && pool_writepos + needed < POOLSIZE)
-       {
-         /* If the pool is not filled yet, we couldn't read the seed
-            file.  Too bad.  We will now have to take account for so many
-            random_poll()s as fit into the remaining pool.  */
-         
-         needed += (POOLSIZE - pool_writepos + needed + POOLSIZE/5 - 1) / 
(POOLSIZE/5);
-       }
-    }
-  else
-    {
-      if (!pool_filled)
-       needed += (POOLSIZE - pool_writepos + needed + POOLSIZE/5 - 1) / 
(POOLSIZE/5);
-    }
-
-  /* NEEDED contains the bytes needed for initialization, MY_BALANCE the 
resulting
-     available bytes.  */
-  if (available < needed)
-    return 0;
-  return available + my_balance - needed;
-}
-#endif
-
-#ifndef __HURD__
-static void
-#else
-int
-#endif
-read_pool( byte *buffer, size_t length, int level )
-{
-    int i;
-    ulong *sp, *dp;
-
-    if( length > POOLSIZE ) {
-#ifndef __HURD__
-       log_fatal(_("too many random bits requested; the limit is %d\n"),
-                 POOLSIZE*8-1 );
-#else
-       length = POOLSIZE;
-#endif
-    }
-
-    if( !pool_filled ) {
-       if( read_seed_file() )
-           pool_filled = 1;
-    }
-
-    /* For level 2 quality (key generation) we alwas make
-     * sure that the pool has been seeded enough initially */
-    if( level == 2 && !did_initial_extra_seeding ) {
-       size_t needed;
-
-       pool_balance = 0;
-       needed = length - pool_balance;
-       if( needed < POOLSIZE/2 )
-           needed = POOLSIZE/2;
-       else if( needed > POOLSIZE )
-           BUG();
-#ifdef __HURD__
-       needed =
-#endif
-       read_random_source( 3, needed, 2 );
-#ifdef __HURD__
-       if (! needed)
-         return 0;
-       /* XXX This will succeed with needed < POOLSIZE/2 even.  But
-          erroring out will waste the random we already got.  */
-#endif
-       pool_balance += needed;
-       did_initial_extra_seeding=1;
-    }
-
-    /* for level 2 make sure that there is enough random in the pool */
-    if( level == 2 && pool_balance < length ) {
-       size_t needed;
-
-       if( pool_balance < 0 )
-           pool_balance = 0;
-       needed = length - pool_balance;
-       if( needed > POOLSIZE )
-           BUG();
-#ifdef __HURD__
-       needed =
-#endif
-       read_random_source( 3, needed, 2 );
-       pool_balance += needed;
-    }
-
-#ifdef __HURD__
-    /* XXX This makes level 0 and 1 worse than needed at first start up.  */
-    if (level == 2)
-#endif
-    /* make sure the pool is filled */
-    while( !pool_filled )
-       random_poll();
-
-    /* do always a fast random poll */
-    fast_random_poll();
-
-    if( !level ) { /* no need for cryptographic strong random */
-       /* create a new pool */
-       for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
-                                   i < POOLWORDS; i++, dp++, sp++ )
-           *dp = *sp + ADD_VALUE;
-       /* must mix both pools */
-       mix_pool(rndpool); rndstats.mixrnd++;
-       mix_pool(keypool); rndstats.mixkey++;
-       memcpy( buffer, keypool, length );
-       return length;
-    }
-    else {
-#ifdef __HURD__
-      int amount;
-#endif
-       /* mix the pool (if add_randomness() didn't it) */
-       if( !just_mixed ) {
-           mix_pool(rndpool);
-           rndstats.mixrnd++;
-       }
-       /* create a new pool */
-       for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
-                                   i < POOLWORDS; i++, dp++, sp++ )
-           *dp = *sp + ADD_VALUE;
-       /* and mix both pools */
-       mix_pool(rndpool); rndstats.mixrnd++;
-       mix_pool(keypool); rndstats.mixkey++;
-       /* read the required data
-        * we use a readpointer to read from a different position each
-        * time */
-#ifdef __HURD__
-       if (level == 2 && length > pool_balance)
-         length = pool_balance;
-       amount = length;
-#endif
-       while( length-- ) {
-           *buffer++ = keypool[pool_readpos++];
-           if( pool_readpos >= POOLSIZE )
-               pool_readpos = 0;
-           pool_balance--;
-       }
-       if( pool_balance < 0 )
-           pool_balance = 0;
-       /* and clear the keypool */
-       memset( keypool, 0, POOLSIZE );
-#ifdef __HURD__
-       return amount;
-#endif
-    }
-}
-
-
-/****************
- * Add LENGTH bytes of randomness from buffer to the pool.
- * source may be used to specify the randomness source.
- * Source is:
- *     0 - used ony for initialization
- *     1 - fast random poll function
- *     2 - normal poll function
- *     3 - used when level 2 random quality has been requested
- *         to do an extra pool seed.
- */
-static void
-add_randomness( const void *buffer, size_t length, int source )
-{
-    const byte *p = buffer;
-
-    if( !is_initialized )
-       initialize();
-    rndstats.addbytes += length;
-    rndstats.naddbytes++;
-    while( length-- ) {
-       rndpool[pool_writepos++] = *p++;
-       if( pool_writepos >= POOLSIZE ) {
-           if( source > 1 )
-               pool_filled = 1;
-           pool_writepos = 0;
-           mix_pool(rndpool); rndstats.mixrnd++;
-           just_mixed = !length;
-       }
-    }
-}
-
-
-
-static void
-random_poll()
-{
-    rndstats.slowpolls++;
-    read_random_source( 2, POOLSIZE/5, 1 );
-}
-
-
-void
-fast_random_poll()
-{
-    static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
-    static int initialized = 0;
-
-    rndstats.fastpolls++;
-    if( !initialized ) {
-       if( !is_initialized )
-           initialize();
-       initialized = 1;
-       fnc = dynload_getfnc_fast_random_poll();
-    }
-    if( fnc ) {
-       (*fnc)( add_randomness, 1 );
-       return;
-    }
-
-    /* fall back to the generic function */
-  #if HAVE_GETHRTIME
-    {  hrtime_t tv;
-       tv = gethrtime();
-       add_randomness( &tv, sizeof(tv), 1 );
-    }
-  #elif HAVE_GETTIMEOFDAY
-    {  struct timeval tv;
-       if( gettimeofday( &tv, NULL ) )
-           BUG();
-       add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
-       add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
-    }
-  #elif HAVE_CLOCK_GETTIME
-    {  struct timespec tv;
-       if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
-           BUG();
-       add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
-       add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
-    }
-  #else /* use times */
-    #ifndef HAVE_DOSISH_SYSTEM
-    {  struct tms buf;
-       times( &buf );
-       add_randomness( &buf, sizeof buf, 1 );
-    }
-    #endif
-  #endif
-  #ifdef HAVE_GETRUSAGE
-    #ifndef RUSAGE_SELF
-      #ifdef __GCC__
-       #warning There is no RUSAGE_SELF on this system
-      #endif
-    #else
-    {  struct rusage buf;
-        /* QNX/Neutrino does return ENOSYS - so we just ignore it and
-         * add whatever is in buf.  In a chroot environment it might not
-         * work at all (i.e. because /proc/ is not accessible), so we better 
-         * ognore all error codes and hope for the best
-         */
-        getrusage( RUSAGE_SELF, &buf );
-        
-       add_randomness( &buf, sizeof buf, 1 );
-       memset( &buf, 0, sizeof buf );
-    }
-    #endif
-  #endif
-    /* time and clock are available on all systems - so
-     * we better do it just in case one of the above functions
-     * didn't work */
-    {  time_t x = time(NULL);
-       add_randomness( &x, sizeof(x), 1 );
-    }
-    {  clock_t x = clock();
-       add_randomness( &x, sizeof(x), 1 );
-    }
-}
-
-
-#ifndef __HURD__
-static void
-#else
-static int
-#endif
-read_random_source( int requester, size_t length, int level )
-{
-    static int (*fnc)(void (*)(const void*, size_t, int), int,
-                                                   size_t, int) = NULL;
-#ifdef __HURD__
-    int got;
-#endif
-    if( !fnc ) {
-       if( !is_initialized )
-           initialize();
-       fnc = dynload_getfnc_gather_random();
-       if( !fnc ) {
-           faked_rng = 1;
-           fnc = gather_faked;
-       }
-       if( !requester && !length && !level )
-#ifndef __HURD__
-           return; /* init only */
-#else
-           return 0;
-#endif
-    }
-#ifndef __HURD__
-    if( (*fnc)( add_randomness, requester, length, level ) < 0 )
-        log_fatal("No way to gather entropy for the RNG\n");
-#else
-    got = (*fnc)( add_randomness, requester, length, level );
-    if (got < 0)
-        log_fatal("No way to gather entropy for the RNG\n");
-    return got;
-#endif
-}
-
-
-static int
-gather_faked( void (*add)(const void*, size_t, int), int requester,
-             size_t length, int level )
-{
-    static int initialized=0;
-    size_t n;
-    char *buffer, *p;
-
-    if( !initialized ) {
-       log_info(_("WARNING: using insecure random number generator!!\n"));
-       tty_printf(_("The random number generator is only a kludge to let\n"
-                  "it run - it is in no way a strong RNG!\n\n"
-                  "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
-       initialized=1;
-      #ifdef HAVE_RAND
-       srand(make_timestamp()*getpid());
-      #else
-       srandom(make_timestamp()*getpid());
-      #endif
-    }
-    printf("WAITING FOR %i bytes.\n", length);
-    p = buffer = m_alloc( length );
-    n = length;
-  #ifdef HAVE_RAND
-    while( n-- )
-       *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
-  #else
-    while( n-- )
-       *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
-  #endif
-    add_randomness( buffer, length, requester );
-    m_free(buffer);
-    return 0; /* okay */
-}
-
diff --git a/random/gnupg-random.h b/random/gnupg-random.h
deleted file mode 100644
index ee18feb..0000000
--- a/random/gnupg-random.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* random.h - random functions
- *     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_RANDOM_H
-#define G10_RANDOM_H
-
-#ifndef __HURD__
-#include "types.h"
-#else
-#include "gnupg-glue.h"
-int read_pool (byte *, size_t, int);
-int readable_pool (size_t, int);
-#endif
-
-/*-- random.c --*/
-void random_dump_stats(void);
-void secure_random_alloc(void);
-void set_random_seed_file(const char *);
-void update_random_seed_file(void);
-int  quick_random_gen( int onoff );
-int  random_is_faked(void);
-void randomize_buffer( byte *buffer, size_t length, int level );
-byte *get_random_bits( size_t nbits, int level, int secure );
-void fast_random_poll( void );
-
-/*-- rndw32.c --*/
-#ifdef USE_STATIC_RNDW32
-void rndw32_set_dll_name( const char *name );
-#endif
-
-#endif /*G10_RANDOM_H*/
diff --git a/random/gnupg-rmd.h b/random/gnupg-rmd.h
deleted file mode 100644
index 102624a..0000000
--- a/random/gnupg-rmd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* rmd.h - RIPE-MD hash functions
- *     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_RMD_H
-#define G10_RMD_H
-
-#ifdef __HURD__
-#include "gnupg-glue.h"
-#endif
-
-/* we need this here because random.c must have direct access */
-typedef struct {
-    u32  h0,h1,h2,h3,h4;
-    u32  nblocks;
-    byte buf[64];
-    int  count;
-} RMD160_CONTEXT;
-
-void rmd160_init( RMD160_CONTEXT *hd );
-void rmd160_mixblock( RMD160_CONTEXT *hd, byte *buffer );
-
-#endif /*G10_RMD_H*/
diff --git a/random/gnupg-rmd160.c b/random/gnupg-rmd160.c
deleted file mode 100644
index 8f4207b..0000000
--- a/random/gnupg-rmd160.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/* rmd160.c  - RIPE-MD160
- *     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef __HURD__
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#ifndef __HURD__
-#include "util.h"
-#include "memory.h"
-#include "rmd.h"
-#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
-#include "dynload.h"
-
-#include "bithelp.h"
-#else
-#include "gnupg-rmd.h"
-#include "gnupg-bithelp.h"
-#endif
-
-
-/*********************************
- * RIPEMD-160 is not patented, see (as of 25.10.97)
- *   http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
- * Note that the code uses Little Endian byteorder, which is good for
- * 386 etc, but we must add some conversion when used on a big endian box.
- *
- *
- * Pseudo-code for RIPEMD-160
- *
- * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
- * The round function takes as input a 5-word chaining variable and a 16-word
- * message block and maps this to a new chaining variable. All operations are
- * defined on 32-bit words. Padding is identical to that of MD4.
- *
- *
- * RIPEMD-160: definitions
- *
- *
- *   nonlinear functions at bit level: exor, mux, -, mux, -
- *
- *   f(j, x, y, z) = x XOR y XOR z               (0 <= j <= 15)
- *   f(j, x, y, z) = (x AND y) OR (NOT(x) AND z)  (16 <= j <= 31)
- *   f(j, x, y, z) = (x OR NOT(y)) XOR z         (32 <= j <= 47)
- *   f(j, x, y, z) = (x AND z) OR (y AND NOT(z))  (48 <= j <= 63)
- *   f(j, x, y, z) = x XOR (y OR NOT(z))         (64 <= j <= 79)
- *
- *
- *   added constants (hexadecimal)
- *
- *   K(j) = 0x00000000     (0 <= j <= 15)
- *   K(j) = 0x5A827999    (16 <= j <= 31)      int(2**30 x sqrt(2))
- *   K(j) = 0x6ED9EBA1    (32 <= j <= 47)      int(2**30 x sqrt(3))
- *   K(j) = 0x8F1BBCDC    (48 <= j <= 63)      int(2**30 x sqrt(5))
- *   K(j) = 0xA953FD4E    (64 <= j <= 79)      int(2**30 x sqrt(7))
- *   K'(j) = 0x50A28BE6     (0 <= j <= 15)      int(2**30 x cbrt(2))
- *   K'(j) = 0x5C4DD124    (16 <= j <= 31)      int(2**30 x cbrt(3))
- *   K'(j) = 0x6D703EF3    (32 <= j <= 47)      int(2**30 x cbrt(5))
- *   K'(j) = 0x7A6D76E9    (48 <= j <= 63)      int(2**30 x cbrt(7))
- *   K'(j) = 0x00000000    (64 <= j <= 79)
- *
- *
- *   selection of message word
- *
- *   r(j)      = j                   (0 <= j <= 15)
- *   r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
- *   r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
- *   r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
- *   r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
- *   r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
- *   r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
- *   r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
- *   r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
- *   r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
- *
- *
- *   amount for rotate left (rol)
- *
- *   s(0..15)  = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
- *   s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
- *   s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
- *   s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
- *   s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
- *   s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
- *   s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
- *   s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
- *   s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
- *   s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
- *
- *
- *   initial value (hexadecimal)
- *
- *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
- *                                                     h4 = 0xC3D2E1F0;
- *
- *
- * RIPEMD-160: pseudo-code
- *
- *   It is assumed that the message after padding consists of t 16-word blocks
- *   that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
- *   The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
- *   shift (rotate) over s positions.
- *
- *
- *   for i := 0 to t-1 {
- *      A := h0; B := h1; C := h2; D = h3; E = h4;
- *      A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
- *      for j := 0 to 79 {
- *          T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
- *          A := E; E := D; D := rol_10(C); C := B; B := T;
- *          T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
-                                                      [+] K'(j)) [+] E';
- *          A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
- *      }
- *      T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
- *      h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
- *   }
- */
-
-/* Some examples:
- * ""                    9c1185a5c5e9fc54612808977ee8f548b2258d31
- * "a"                   0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
- * "abc"                 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
- * "message digest"      5d0689ef49d2fae572b881b123a85ffa21595f36
- * "a...z"               f71c27109c692c1b56bbdceb5b9d2865b3708dbc
- * "abcdbcde...nopq"     12a053384a9c0c88e405a06c27dcf49ada62eb2b
- * "A...Za...z0...9"     b0e20b6e3116640286ed3a87a5713079b21f5189
- * 8 times "1234567890"  9b752e45573d4b39f4dbd3323cab82bf63326bfb
- * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
- */
-
-static void
-burn_stack (int bytes)
-{
-    char buf[150];
-    
-    memset (buf, 0, sizeof buf);
-    bytes -= sizeof buf;
-    if (bytes > 0)
-        burn_stack (bytes);
-}
-
-
-
-void
-rmd160_init( RMD160_CONTEXT *hd )
-{
-    hd->h0 = 0x67452301;
-    hd->h1 = 0xEFCDAB89;
-    hd->h2 = 0x98BADCFE;
-    hd->h3 = 0x10325476;
-    hd->h4 = 0xC3D2E1F0;
-    hd->nblocks = 0;
-    hd->count = 0;
-}
-
-
-
-/****************
- * Transform the message X which consists of 16 32-bit-words
- */
-static void
-transform( RMD160_CONTEXT *hd, byte *data )
-{
-    u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
-  #ifdef BIG_ENDIAN_HOST
-    u32 x[16];
-    { int i;
-      byte *p2, *p1;
-      for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
-       p2[3] = *p1++;
-       p2[2] = *p1++;
-       p2[1] = *p1++;
-       p2[0] = *p1++;
-      }
-    }
-  #else
-   #if 0
-    u32 *x =(u32*)data;
-   #else
-    /* this version is better because it is always aligned;
-     * The performance penalty on a 586-100 is about 6% which
-     * is acceptable - because the data is more local it might
-     * also be possible that this is faster on some machines.
-     * This function (when compiled with -02 on gcc 2.7.2)
-     * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
-     * [measured with a 4MB data and "gpgm --print-md rmd160"] */
-    u32 x[16];
-    memcpy( x, data, 64 );
-   #endif
-  #endif
-
-
-#define K0  0x00000000
-#define K1  0x5A827999
-#define K2  0x6ED9EBA1
-#define K3  0x8F1BBCDC
-#define K4  0xA953FD4E
-#define KK0 0x50A28BE6
-#define KK1 0x5C4DD124
-#define KK2 0x6D703EF3
-#define KK3 0x7A6D76E9
-#define KK4 0x00000000
-#define F0(x,y,z)   ( (x) ^ (y) ^ (z) )
-#define F1(x,y,z)   ( ((x) & (y)) | (~(x) & (z)) )
-#define F2(x,y,z)   ( ((x) | ~(y)) ^ (z) )
-#define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
-#define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
-#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
-                                 a = rol(t,s) + e;            \
-                                 c = rol(c,10);               \
-                               } while(0)
-
-    /* left lane */
-    a = hd->h0;
-    b = hd->h1;
-    c = hd->h2;
-    d = hd->h3;
-    e = hd->h4;
-    R( a, b, c, d, e, F0, K0,  0, 11 );
-    R( e, a, b, c, d, F0, K0,  1, 14 );
-    R( d, e, a, b, c, F0, K0,  2, 15 );
-    R( c, d, e, a, b, F0, K0,  3, 12 );
-    R( b, c, d, e, a, F0, K0,  4,  5 );
-    R( a, b, c, d, e, F0, K0,  5,  8 );
-    R( e, a, b, c, d, F0, K0,  6,  7 );
-    R( d, e, a, b, c, F0, K0,  7,  9 );
-    R( c, d, e, a, b, F0, K0,  8, 11 );
-    R( b, c, d, e, a, F0, K0,  9, 13 );
-    R( a, b, c, d, e, F0, K0, 10, 14 );
-    R( e, a, b, c, d, F0, K0, 11, 15 );
-    R( d, e, a, b, c, F0, K0, 12,  6 );
-    R( c, d, e, a, b, F0, K0, 13,  7 );
-    R( b, c, d, e, a, F0, K0, 14,  9 );
-    R( a, b, c, d, e, F0, K0, 15,  8 );
-    R( e, a, b, c, d, F1, K1,  7,  7 );
-    R( d, e, a, b, c, F1, K1,  4,  6 );
-    R( c, d, e, a, b, F1, K1, 13,  8 );
-    R( b, c, d, e, a, F1, K1,  1, 13 );
-    R( a, b, c, d, e, F1, K1, 10, 11 );
-    R( e, a, b, c, d, F1, K1,  6,  9 );
-    R( d, e, a, b, c, F1, K1, 15,  7 );
-    R( c, d, e, a, b, F1, K1,  3, 15 );
-    R( b, c, d, e, a, F1, K1, 12,  7 );
-    R( a, b, c, d, e, F1, K1,  0, 12 );
-    R( e, a, b, c, d, F1, K1,  9, 15 );
-    R( d, e, a, b, c, F1, K1,  5,  9 );
-    R( c, d, e, a, b, F1, K1,  2, 11 );
-    R( b, c, d, e, a, F1, K1, 14,  7 );
-    R( a, b, c, d, e, F1, K1, 11, 13 );
-    R( e, a, b, c, d, F1, K1,  8, 12 );
-    R( d, e, a, b, c, F2, K2,  3, 11 );
-    R( c, d, e, a, b, F2, K2, 10, 13 );
-    R( b, c, d, e, a, F2, K2, 14,  6 );
-    R( a, b, c, d, e, F2, K2,  4,  7 );
-    R( e, a, b, c, d, F2, K2,  9, 14 );
-    R( d, e, a, b, c, F2, K2, 15,  9 );
-    R( c, d, e, a, b, F2, K2,  8, 13 );
-    R( b, c, d, e, a, F2, K2,  1, 15 );
-    R( a, b, c, d, e, F2, K2,  2, 14 );
-    R( e, a, b, c, d, F2, K2,  7,  8 );
-    R( d, e, a, b, c, F2, K2,  0, 13 );
-    R( c, d, e, a, b, F2, K2,  6,  6 );
-    R( b, c, d, e, a, F2, K2, 13,  5 );
-    R( a, b, c, d, e, F2, K2, 11, 12 );
-    R( e, a, b, c, d, F2, K2,  5,  7 );
-    R( d, e, a, b, c, F2, K2, 12,  5 );
-    R( c, d, e, a, b, F3, K3,  1, 11 );
-    R( b, c, d, e, a, F3, K3,  9, 12 );
-    R( a, b, c, d, e, F3, K3, 11, 14 );
-    R( e, a, b, c, d, F3, K3, 10, 15 );
-    R( d, e, a, b, c, F3, K3,  0, 14 );
-    R( c, d, e, a, b, F3, K3,  8, 15 );
-    R( b, c, d, e, a, F3, K3, 12,  9 );
-    R( a, b, c, d, e, F3, K3,  4,  8 );
-    R( e, a, b, c, d, F3, K3, 13,  9 );
-    R( d, e, a, b, c, F3, K3,  3, 14 );
-    R( c, d, e, a, b, F3, K3,  7,  5 );
-    R( b, c, d, e, a, F3, K3, 15,  6 );
-    R( a, b, c, d, e, F3, K3, 14,  8 );
-    R( e, a, b, c, d, F3, K3,  5,  6 );
-    R( d, e, a, b, c, F3, K3,  6,  5 );
-    R( c, d, e, a, b, F3, K3,  2, 12 );
-    R( b, c, d, e, a, F4, K4,  4,  9 );
-    R( a, b, c, d, e, F4, K4,  0, 15 );
-    R( e, a, b, c, d, F4, K4,  5,  5 );
-    R( d, e, a, b, c, F4, K4,  9, 11 );
-    R( c, d, e, a, b, F4, K4,  7,  6 );
-    R( b, c, d, e, a, F4, K4, 12,  8 );
-    R( a, b, c, d, e, F4, K4,  2, 13 );
-    R( e, a, b, c, d, F4, K4, 10, 12 );
-    R( d, e, a, b, c, F4, K4, 14,  5 );
-    R( c, d, e, a, b, F4, K4,  1, 12 );
-    R( b, c, d, e, a, F4, K4,  3, 13 );
-    R( a, b, c, d, e, F4, K4,  8, 14 );
-    R( e, a, b, c, d, F4, K4, 11, 11 );
-    R( d, e, a, b, c, F4, K4,  6,  8 );
-    R( c, d, e, a, b, F4, K4, 15,  5 );
-    R( b, c, d, e, a, F4, K4, 13,  6 );
-
-    aa = a; bb = b; cc = c; dd = d; ee = e;
-
-    /* right lane */
-    a = hd->h0;
-    b = hd->h1;
-    c = hd->h2;
-    d = hd->h3;
-    e = hd->h4;
-    R( a, b, c, d, e, F4, KK0, 5,  8);
-    R( e, a, b, c, d, F4, KK0, 14,  9);
-    R( d, e, a, b, c, F4, KK0, 7,  9);
-    R( c, d, e, a, b, F4, KK0, 0, 11);
-    R( b, c, d, e, a, F4, KK0, 9, 13);
-    R( a, b, c, d, e, F4, KK0, 2, 15);
-    R( e, a, b, c, d, F4, KK0, 11, 15);
-    R( d, e, a, b, c, F4, KK0, 4,  5);
-    R( c, d, e, a, b, F4, KK0, 13,  7);
-    R( b, c, d, e, a, F4, KK0, 6,  7);
-    R( a, b, c, d, e, F4, KK0, 15,  8);
-    R( e, a, b, c, d, F4, KK0, 8, 11);
-    R( d, e, a, b, c, F4, KK0, 1, 14);
-    R( c, d, e, a, b, F4, KK0, 10, 14);
-    R( b, c, d, e, a, F4, KK0, 3, 12);
-    R( a, b, c, d, e, F4, KK0, 12,  6);
-    R( e, a, b, c, d, F3, KK1, 6,  9);
-    R( d, e, a, b, c, F3, KK1, 11, 13);
-    R( c, d, e, a, b, F3, KK1, 3, 15);
-    R( b, c, d, e, a, F3, KK1, 7,  7);
-    R( a, b, c, d, e, F3, KK1, 0, 12);
-    R( e, a, b, c, d, F3, KK1, 13,  8);
-    R( d, e, a, b, c, F3, KK1, 5,  9);
-    R( c, d, e, a, b, F3, KK1, 10, 11);
-    R( b, c, d, e, a, F3, KK1, 14,  7);
-    R( a, b, c, d, e, F3, KK1, 15,  7);
-    R( e, a, b, c, d, F3, KK1, 8, 12);
-    R( d, e, a, b, c, F3, KK1, 12,  7);
-    R( c, d, e, a, b, F3, KK1, 4,  6);
-    R( b, c, d, e, a, F3, KK1, 9, 15);
-    R( a, b, c, d, e, F3, KK1, 1, 13);
-    R( e, a, b, c, d, F3, KK1, 2, 11);
-    R( d, e, a, b, c, F2, KK2, 15,  9);
-    R( c, d, e, a, b, F2, KK2, 5,  7);
-    R( b, c, d, e, a, F2, KK2, 1, 15);
-    R( a, b, c, d, e, F2, KK2, 3, 11);
-    R( e, a, b, c, d, F2, KK2, 7,  8);
-    R( d, e, a, b, c, F2, KK2, 14,  6);
-    R( c, d, e, a, b, F2, KK2, 6,  6);
-    R( b, c, d, e, a, F2, KK2, 9, 14);
-    R( a, b, c, d, e, F2, KK2, 11, 12);
-    R( e, a, b, c, d, F2, KK2, 8, 13);
-    R( d, e, a, b, c, F2, KK2, 12,  5);
-    R( c, d, e, a, b, F2, KK2, 2, 14);
-    R( b, c, d, e, a, F2, KK2, 10, 13);
-    R( a, b, c, d, e, F2, KK2, 0, 13);
-    R( e, a, b, c, d, F2, KK2, 4,  7);
-    R( d, e, a, b, c, F2, KK2, 13,  5);
-    R( c, d, e, a, b, F1, KK3, 8, 15);
-    R( b, c, d, e, a, F1, KK3, 6,  5);
-    R( a, b, c, d, e, F1, KK3, 4,  8);
-    R( e, a, b, c, d, F1, KK3, 1, 11);
-    R( d, e, a, b, c, F1, KK3, 3, 14);
-    R( c, d, e, a, b, F1, KK3, 11, 14);
-    R( b, c, d, e, a, F1, KK3, 15,  6);
-    R( a, b, c, d, e, F1, KK3, 0, 14);
-    R( e, a, b, c, d, F1, KK3, 5,  6);
-    R( d, e, a, b, c, F1, KK3, 12,  9);
-    R( c, d, e, a, b, F1, KK3, 2, 12);
-    R( b, c, d, e, a, F1, KK3, 13,  9);
-    R( a, b, c, d, e, F1, KK3, 9, 12);
-    R( e, a, b, c, d, F1, KK3, 7,  5);
-    R( d, e, a, b, c, F1, KK3, 10, 15);
-    R( c, d, e, a, b, F1, KK3, 14,  8);
-    R( b, c, d, e, a, F0, KK4, 12,  8);
-    R( a, b, c, d, e, F0, KK4, 15,  5);
-    R( e, a, b, c, d, F0, KK4, 10, 12);
-    R( d, e, a, b, c, F0, KK4, 4,  9);
-    R( c, d, e, a, b, F0, KK4, 1, 12);
-    R( b, c, d, e, a, F0, KK4, 5,  5);
-    R( a, b, c, d, e, F0, KK4, 8, 14);
-    R( e, a, b, c, d, F0, KK4, 7,  6);
-    R( d, e, a, b, c, F0, KK4, 6,  8);
-    R( c, d, e, a, b, F0, KK4, 2, 13);
-    R( b, c, d, e, a, F0, KK4, 13,  6);
-    R( a, b, c, d, e, F0, KK4, 14,  5);
-    R( e, a, b, c, d, F0, KK4, 0, 15);
-    R( d, e, a, b, c, F0, KK4, 3, 13);
-    R( c, d, e, a, b, F0, KK4, 9, 11);
-    R( b, c, d, e, a, F0, KK4, 11, 11);
-
-
-    t     = hd->h1 + d + cc;
-    hd->h1 = hd->h2 + e + dd;
-    hd->h2 = hd->h3 + a + ee;
-    hd->h3 = hd->h4 + b + aa;
-    hd->h4 = hd->h0 + c + bb;
-    hd->h0 = t;
-}
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
-{
-    if( hd->count == 64 ) { /* flush the buffer */
-       transform( hd, hd->buf );
-        burn_stack (108+5*sizeof(void*));
-       hd->count = 0;
-       hd->nblocks++;
-    }
-    if( !inbuf )
-       return;
-    if( hd->count ) {
-       for( ; inlen && hd->count < 64; inlen-- )
-           hd->buf[hd->count++] = *inbuf++;
-       rmd160_write( hd, NULL, 0 );
-       if( !inlen )
-           return;
-    }
-
-    while( inlen >= 64 ) {
-       transform( hd, inbuf );
-       hd->count = 0;
-       hd->nblocks++;
-       inlen -= 64;
-       inbuf += 64;
-    }
-    burn_stack (108+5*sizeof(void*));
-    for( ; inlen && hd->count < 64; inlen-- )
-       hd->buf[hd->count++] = *inbuf++;
-}
-
-/****************
- * Apply the rmd160 transform function on the buffer which must have
- * a length 64 bytes. Do not use this function together with the
- * other functions, use rmd160_init to initialize internal variables.
- * Returns: 16 bytes in buffer with the mixed contentes of buffer.
- */
-void
-rmd160_mixblock( RMD160_CONTEXT *hd, byte *buffer )
-{
-    byte *p = buffer;
-    transform( hd, buffer );
-  #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-    X(0);
-    X(1);
-    X(2);
-    X(3);
-    X(4);
-  #undef X
-}
-
-
-/* The routine terminates the computation
- */
-
-static void
-rmd160_final( RMD160_CONTEXT *hd )
-{
-    u32 t, msb, lsb;
-    byte *p;
-
-    rmd160_write(hd, NULL, 0); /* flush */;
-
-    t = hd->nblocks;
-    /* multiply by 64 to make a byte count */
-    lsb = t << 6;
-    msb = t >> 26;
-    /* add the count */
-    t = lsb;
-    if( (lsb += hd->count) < t )
-       msb++;
-    /* multiply by 8 to make a bit count */
-    t = lsb;
-    lsb <<= 3;
-    msb <<= 3;
-    msb |= t >> 29;
-
-    if( hd->count < 56 ) { /* enough room */
-       hd->buf[hd->count++] = 0x80; /* pad */
-       while( hd->count < 56 )
-           hd->buf[hd->count++] = 0;  /* pad */
-    }
-    else { /* need one extra block */
-       hd->buf[hd->count++] = 0x80; /* pad character */
-       while( hd->count < 64 )
-           hd->buf[hd->count++] = 0;
-       rmd160_write(hd, NULL, 0);  /* flush */;
-       memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
-    }
-    /* append the 64 bit count */
-    hd->buf[56] = lsb     ;
-    hd->buf[57] = lsb >>  8;
-    hd->buf[58] = lsb >> 16;
-    hd->buf[59] = lsb >> 24;
-    hd->buf[60] = msb     ;
-    hd->buf[61] = msb >>  8;
-    hd->buf[62] = msb >> 16;
-    hd->buf[63] = msb >> 24;
-    transform( hd, hd->buf );
-    burn_stack (108+5*sizeof(void*));
-
-    p = hd->buf;
-  #ifdef BIG_ENDIAN_HOST
-    #define X(a) do { *p++ = hd->h##a     ; *p++ = hd->h##a >> 8;      \
-                     *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
-  #else /* little endian */
-    #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-  #endif
-    X(0);
-    X(1);
-    X(2);
-    X(3);
-    X(4);
-  #undef X
-}
-
-
-
-/****************
- * Shortcut functions which puts the hash value of the supplied buffer
- * into outbuf which must have a size of 20 bytes.
- */
-void
-rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
-{
-    RMD160_CONTEXT hd;
-
-    rmd160_init( &hd );
-    rmd160_write( &hd, (byte*)buffer, length );
-    rmd160_final( &hd );
-    memcpy( outbuf, hd.buf, 20 );
-}
-
-
-#ifndef __HURD__
-
-static byte *
-rmd160_read( RMD160_CONTEXT *hd )
-{
-    return hd->buf;
-}
-
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-static const char *
-rmd160_get_info( int algo, size_t *contextsize,
-              byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-              void (**r_init)( void *c ),
-              void (**r_write)( void *c, byte *buf, size_t nbytes ),
-              void (**r_final)( void *c ),
-              byte *(**r_read)( void *c )
-            )
-{
-    static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
-         { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
-           0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
-
-    if( algo != 3 )
-       return NULL;
-
-    *contextsize = sizeof(RMD160_CONTEXT);
-    *r_asnoid = asn;
-    *r_asnlen = DIM(asn);
-    *r_mdlen = 20;
-    *(void  (**)(RMD160_CONTEXT *))r_init                = rmd160_init;
-    *(void  (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write;
-    *(void  (**)(RMD160_CONTEXT *))r_final               = rmd160_final;
-    *(byte *(**)(RMD160_CONTEXT *))r_read                = rmd160_read;
-
-    return "RIPEMD160";
-}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RMD160 ($Revision: 1.17.2.4 $)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 10, 1, 0, (void(*)(void))rmd160_get_info },
-    { 11, 1, 3 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11:
-         case 21:
-         case 31:
-           ret = &func_table[i].value;
-           break;
-         default:
-           ret = func_table[i].func;
-           break;
-       }
-       i++;
-    } while( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-#ifndef IS_MODULE
-void
-rmd160_constructor(void)
-{
-    register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
-#endif
diff --git a/random/random.h b/random/random.h
deleted file mode 100644
index a38a417..0000000
--- a/random/random.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* random.c - A single-file translator providing random data
-   Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
-#ifndef __RANDOM_H__
-#define __RANDOM_H__
-
-/* How many random bytes to gather at most.
-   XXX: Should be at least POOLSIZE.  */
-#define GATHERBUFSIZE 32768
-
-/* The random bytes we collected.  */
-extern char gatherbuf[GATHERBUFSIZE];
-
-/* The current positions in gatherbuf[].  */
-extern int gatherrpos;
-extern int gatherwpos;
-
-#endif
diff --git a/startup/startup.c b/startup/startup.c
index 3c3ead4..7c3fbf0 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -27,7 +27,7 @@
 #include <hurd/fsys.h>
 #include <device/device.h>
 #include <stdio.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd/paths.h>
 #include <sys/reboot.h>
 #include <sys/file.h>
@@ -117,8 +117,10 @@ static struct ntfy_task *ntfy_tasks;
 /* Our receive right */
 static mach_port_t startup;
 
-/* Ports to the kernel */
-static mach_port_t host_priv, device_master;
+/* Ports to the kernel.  We use alias to the internal glibc locations
+   so that other code can get them using get_privileged_ports.  */
+#define host_priv      _hurd_host_priv
+#define device_master  _hurd_device_master
 
 /* Args to bootstrap, expressed as flags */
 static int bootstrap_args = 0;
@@ -187,9 +189,10 @@ reboot_mach (int flags)
       fprintf (stderr, "%s: %sing Mach (flags %#x)...\n",
                program_invocation_short_name, BOOT (flags), flags);
       sleep (5);
-      while ((err = host_reboot (host_priv, flags)))
-       error (0, err, "reboot");
-      for (;;);
+      err = host_reboot (host_priv, flags);
+      if (err)
+       error (1, err, "reboot");
+      for (;;) sleep (1);
     }
 }
 
@@ -379,19 +382,19 @@ run (const char *server, mach_port_t *ports, task_t *task,
           char *argz = NULL;
           size_t argz_len = 0;
           err = argz_create_sep (prog, ' ', &argz, &argz_len);
-          assert_perror (err);
+          assert_perror_backtrace (err);
 
           err = task_create (mach_task_self (),
 #ifdef KERN_INVALID_LEDGER
                              NULL, 0,  /* OSF Mach */
 #endif
                              0, task);
-          assert_perror (err);
+          assert_perror_backtrace (err);
 
           if (insert_ports)
             {
               err = insert_ports (&argz, &argz_len, *task);
-              assert_perror (err);
+              assert_perror_backtrace (err);
             }
 
          if (bootstrap_args & RB_KDB)
@@ -672,7 +675,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
 int
 main (int argc, char **argv, char **envp)
 {
-  volatile int err;
+  error_t err;
   int i;
   int flags;
   mach_port_t consdev;
@@ -700,8 +703,6 @@ main (int argc, char **argv, char **envp)
       || device_open (device_master, D_READ|D_WRITE, "console", &consdev))
     crash_mach ();
 
-  wire_task_self ();
-
   /* Clear our bootstrap port so our children don't inherit it.  */
   task_set_bootstrap_port (mach_task_self (), MACH_PORT_NULL);
 
@@ -711,16 +712,20 @@ main (int argc, char **argv, char **envp)
     crash_mach ();
   setbuf (stdout, NULL);
 
+  err = wire_task_self ();
+  if (err)
+    error (0, err, "wire_task_self");
+
   err = argz_create (envp, &startup_envz, &startup_envz_len);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* At this point we can use assert to check for errors.  */
   err = mach_port_allocate (mach_task_self (),
                            MACH_PORT_RIGHT_RECEIVE, &startup);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = mach_port_insert_right (mach_task_self (), startup, startup,
                                MACH_MSG_TYPE_MAKE_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* Crash if the boot filesystem task dies.  */
   request_dead_name (fstask);
@@ -765,7 +770,7 @@ main (int argc, char **argv, char **envp)
   while (1)
     {
       err = mach_msg_server (demuxer, 0, startup);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
 }
 
@@ -784,7 +789,7 @@ launch_core_servers (void)
                                mach_task_self (), authserver,
                                host_priv, MACH_MSG_TYPE_COPY_SEND,
                                device_master, MACH_MSG_TYPE_COPY_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   if (!fakeboot)
     {
       mach_port_deallocate (mach_task_self (), device_master);
@@ -796,22 +801,22 @@ launch_core_servers (void)
 
   /* Mark us as important.  */
   err = proc_mark_important (procserver);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = proc_mark_exec (procserver);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* Declare that the filesystem and auth are our children. */
   err = proc_child (procserver, fstask);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = proc_child (procserver, authtask);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   err = proc_task2proc (procserver, authtask, &authproc);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = proc_mark_important (authproc);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = proc_mark_exec (authproc);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   err = install_as_translator ();
   if (err)
@@ -823,7 +828,7 @@ launch_core_servers (void)
 
   err = startup_authinit_reply (authreply, authreplytype, 0, authproc,
                                MACH_MSG_TYPE_MOVE_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (verbose)
     fprintf (stderr, "auth launched\n");
@@ -838,13 +843,13 @@ launch_core_servers (void)
   err = proc_set_arg_locations (procserver,
                                (vm_address_t) global_argv,
                                (vm_address_t) environ);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   default_ports[INIT_PORT_AUTH] = authserver;
 
   /* Declare that the proc server is our child.  */
   err = proc_child (procserver, proctask);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = proc_task2proc (procserver, proctask, &procproc);
   if (!err)
     {
@@ -855,16 +860,16 @@ launch_core_servers (void)
 
   err = proc_register_version (procserver, host_priv,
                               "init", "", HURD_VERSION);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* Get the bootstrap filesystem's proc server port.
      We must do this before calling proc_setmsgport below.  */
   err = proc_task2proc (procserver, fstask, &fsproc);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = proc_mark_important (fsproc);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = proc_mark_exec (fsproc);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   fprintf (stderr, ".\n");
 
@@ -875,7 +880,7 @@ launch_core_servers (void)
      calling fsys_init, because fsys_init blocks on exec_init, and
      exec_init will block waiting on our message port.  */
   err = proc_setmsgport (procserver, startup, &old);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   if (old != MACH_PORT_NULL)
     mach_port_deallocate (mach_task_self (), old);
 
@@ -1010,10 +1015,10 @@ frob_kernel_process (void)
     error (0, err, "cannot mark the kernel as important");
 
   err = record_essential_task ("kernel", task);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   err = task_get_bootstrap_port (task, &kbs);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   if (kbs == MACH_PORT_NULL)
     {
       /* The kernel task has no bootstrap port set, so we are presumably
@@ -1062,16 +1067,16 @@ frob_kernel_process (void)
      canonical argv array and argz of those words.  */
 
   err = argz_create (&global_argv[1], &argz, &argzlen);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = argz_insert (&argz, &argzlen, argz, "gnumach");
-  assert_perror (err);
+  assert_perror_backtrace (err);
   argc = argz_count (argz, argzlen);
 
   windowsz = round_page (((argc + 1) * sizeof (char *)) + argzlen);
 
   mine = (vm_address_t) mmap (0, windowsz, PROT_READ|PROT_WRITE,
                              MAP_ANON, 0, 0);
-  assert (mine != -1);
+  assert_backtrace (mine != -1);
   err = vm_allocate (task, &his, windowsz, 1);
   if (err)
     {
@@ -1211,7 +1216,7 @@ start_child (const char *prog, char **progargs)
        err = argz_create ((char **) argv, &args, &arglen);
       }
     }
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (verbose)
     fprintf (stderr, "Going to execute '%s'\n", args);
@@ -1477,7 +1482,7 @@ do_mach_notify_dead_name (mach_port_t notify,
   struct ntfy_task *nt, *pnt;
   struct ess_task *et;
 
-  assert (notify == startup);
+  assert_backtrace (notify == startup);
 
   /* Deallocate the extra reference the notification carries. */
   mach_port_deallocate (mach_task_self (), name);
diff --git a/storeio/dev.c b/storeio/dev.c
index 614c257..8bdfa11 100644
--- a/storeio/dev.c
+++ b/storeio/dev.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include <hurd.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <hurd/pager.h>
 #include <hurd/store.h>
@@ -106,7 +106,7 @@ dev_buf_rw (struct dev *dev, size_t buf_offs, size_t 
*io_offs, size_t *len,
 {
   size_t block_size = dev->store->block_size;
 
-  assert (dev_buf_is_active (dev));
+  assert_backtrace (dev_buf_is_active (dev));
 
   if (buf_offs + *len >= block_size)
     /* Only part of BUF lies within the buffer (or everything up
@@ -141,7 +141,7 @@ dev_open (struct dev *dev)
   const int flags = ((dev->readonly ? STORE_READONLY : 0)
                     | (dev->no_fileio ? STORE_NO_FILEIO : 0));
 
-  assert (dev->store == 0);
+  assert_backtrace (dev->store == 0);
 
   if (dev->store_name == 0)
     {
@@ -161,8 +161,11 @@ dev_open (struct dev *dev)
      to support this.  */
   store_set_flags (dev->store, STORE_INACTIVE);
 
-  dev->buf = mmap (0, dev->store->block_size, PROT_READ|PROT_WRITE,
-                  MAP_ANON, 0, 0);
+  if (! dev->store->block_size)
+    dev->buf = NULL;
+  else
+    dev->buf = mmap (0, dev->store->block_size, PROT_READ|PROT_WRITE,
+                    MAP_ANON, 0, 0);
   if (dev->buf == MAP_FAILED)
     {
       store_free (dev->store);
@@ -188,7 +191,7 @@ dev_open (struct dev *dev)
 void
 dev_close (struct dev *dev)
 {
-  assert (dev->store);
+  assert_backtrace (dev->store);
 
   if (!dev->inhibit_cache)
     {
diff --git a/storeio/pager.c b/storeio/pager.c
index 54b1714..1238793 100644
--- a/storeio/pager.c
+++ b/storeio/pager.c
@@ -20,7 +20,7 @@
 
 #include <hurd.h>
 #include <hurd/pager.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <strings.h>
 #include <unistd.h>
 #include <errno.h>
@@ -115,7 +115,7 @@ void
 pager_notify_evict (struct user_pager_info *pager,
                    vm_offset_t page)
 {
-  assert (!"unrequested notification on eviction");
+  assert_backtrace (!"unrequested notification on eviction");
 }
 
 /* The user must define this function.  It should report back (in
diff --git a/storeio/storeio.c b/storeio/storeio.c
index fcf2f30..515944e 100644
--- a/storeio/storeio.c
+++ b/storeio/storeio.c
@@ -19,7 +19,7 @@
 
 #include <stdio.h>
 #include <error.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <fcntl.h>
 #include <argp.h>
 #include <argz.h>
diff --git a/sutils/MAKEDEV.sh b/sutils/MAKEDEV.sh
index 1baec15..0730a64 100644
--- a/sutils/MAKEDEV.sh
+++ b/sutils/MAKEDEV.sh
@@ -100,7 +100,7 @@ mkdev() {
        ;;
 
       std)
-       mkdev console tty urandom null zero full fd time mem klog shm
+       mkdev console tty random urandom null zero full fd time mem klog shm
        ;;
       console|com[0-9])
        st $I root 600 /hurd/term ${DEVDIR}/$I device $I;;
@@ -111,8 +111,12 @@ mkdev() {
           ${DEVDIR}/vcs/`echo $I | sed -e s/tty//`/console;;
       lpr[0-9])
         st $I root 660 /hurd/streamio "$I";;
+      random)
+       st $I root 644 /hurd/random --seed-file /var/lib/random-seed;;
       urandom)
-       st $I root 644 /hurd/random --fast --seed-file /var/lib/random-seed;;
+       # Our /dev/random is both secure and non-blocking.  Create a
+       # link for compatibility with Linux.
+       cmd ln -f -s random $I;;
       null)
        st $I root 666 /hurd/null;;
       full)
diff --git a/sutils/bless.c b/sutils/bless.c
index 039320a..4b272ad 100644
--- a/sutils/bless.c
+++ b/sutils/bless.c
@@ -18,7 +18,7 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <argp.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <error.h>
 #include <hurd.h>
 #include <mach.h>
@@ -90,7 +90,7 @@ main (int argc, char **argv)
     error (1, err, "Could not mark process as important");
 
   err = mach_port_deallocate (mach_task_self (), proc);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   return EXIT_SUCCESS;
 }
diff --git a/sutils/fsck.c b/sutils/fsck.c
index 1ab9caa..d864134 100644
--- a/sutils/fsck.c
+++ b/sutils/fsck.c
@@ -50,7 +50,7 @@
 #include <error.h>
 #include <argp.h>
 #include <argz.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <version.h>
 
 #include "fstab.h"
@@ -137,8 +137,8 @@ fs_start_fsck (struct fs *fs, int flags)
   struct fstype *type;
   error_t err = fs_type (fs, &type);
 
-  assert_perror (err);         /* Should already have been checked for. */
-  assert (type->program);
+  assert_perror_backtrace (err);               /* Should already have been 
checked for. */
+  assert_backtrace (type->program);
 
   *argp++ = type->program;
 
diff --git a/sutils/fstab.c b/sutils/fstab.c
index 2e125d8..9748ae9 100644
--- a/sutils/fstab.c
+++ b/sutils/fstab.c
@@ -617,7 +617,7 @@ fstab_add_mntent (struct fstab *const fstab, const struct 
mntent *mntent,
     {
       if (! err)
        _fstab_add (fstab, fs);
-      else if (fs)
+      else
        free (fs);
     }
 
diff --git a/sutils/swapon.c b/sutils/swapon.c
index 40f5a20..78a4590 100644
--- a/sutils/swapon.c
+++ b/sutils/swapon.c
@@ -29,7 +29,7 @@
 #include <argp.h>
 #include <argz.h>
 #include <error.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <sys/mman.h>
 #include <hurd/store.h>
 #include <hurd/paths.h>
diff --git a/term/devio.c b/term/devio.c
index eedd7b8..60ee221 100644
--- a/term/devio.c
+++ b/term/devio.c
@@ -43,7 +43,7 @@
 #undef EXTA
 #undef EXTB
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <error.h>
 #include <string.h>
@@ -459,15 +459,15 @@ initial_open ()
 {
   error_t err;
 
-  assert (open_pending != FAKE);
+  assert_backtrace (open_pending != FAKE);
 
   /* Nothing to do */
   if (open_pending == INITIAL)
     return 0;
 
-  assert (phys_device == MACH_PORT_NULL);
-  assert (phys_reply == MACH_PORT_NULL);
-  assert (phys_reply_pi == 0);
+  assert_backtrace (phys_device == MACH_PORT_NULL);
+  assert_backtrace (phys_reply == MACH_PORT_NULL);
+  assert_backtrace (phys_reply_pi == 0);
 
   err = ports_create_port (phys_reply_class, term_bucket,
                           sizeof (struct port_info), &phys_reply_pi);
@@ -516,7 +516,7 @@ devio_assert_dtr ()
 
   /* Schedule a fake open to wait for DTR, unless one is already
      happening. */
-  assert (open_pending != INITIAL);
+  assert_backtrace (open_pending != INITIAL);
   if (open_pending == FAKE)
     return 0;
 
@@ -544,7 +544,7 @@ device_open_reply (mach_port_t replyport,
 
   pthread_mutex_lock (&global_lock);
 
-  assert (open_pending != NOTPENDING);
+  assert_backtrace (open_pending != NOTPENDING);
 
   if (returncode != 0)
     {
@@ -564,9 +564,9 @@ device_open_reply (mach_port_t replyport,
     {
       /* Special handling for the first open */
 
-      assert (phys_device == MACH_PORT_NULL);
-      assert (phys_reply_writes == MACH_PORT_NULL);
-      assert (phys_reply_writes_pi == 0);
+      assert_backtrace (phys_device == MACH_PORT_NULL);
+      assert_backtrace (phys_reply_writes == MACH_PORT_NULL);
+      assert_backtrace (phys_reply_writes_pi == 0);
       phys_device = device;
       err = ports_create_port (phys_reply_class, term_bucket,
                               sizeof (struct port_info),
diff --git a/term/hurdio.c b/term/hurdio.c
index b34854c..3456ef2 100644
--- a/term/hurdio.c
+++ b/term/hurdio.c
@@ -22,7 +22,7 @@
 
 #include <termios.h>
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <error.h>
 #include <string.h>
diff --git a/term/main.c b/term/main.c
index be014e1..2813d52 100644
--- a/term/main.c
+++ b/term/main.c
@@ -232,7 +232,7 @@ parse_opt (int opt, char *arg, struct argp_state *state)
              bottom = &hurdio_bottom;
              break;
            default:
-             assert (! "impossible type");
+             assert_backtrace (! "impossible type");
              break;
            }
          free (tty_arg);
diff --git a/term/munge.c b/term/munge.c
index 96b0df3..242dd36 100644
--- a/term/munge.c
+++ b/term/munge.c
@@ -306,7 +306,7 @@ erase_1 (char erase_char)
            write_erase_sequence ();
        }
       if (echo_qsize == 0)
-       assert (echo_pstart == output_psize);
+       assert_backtrace (echo_pstart == output_psize);
     }
   else
     reprint_line ();
@@ -712,7 +712,7 @@ create_queue (int size, int lowat, int hiwat)
   struct queue *q;
 
   q = malloc (sizeof (struct queue) + size * sizeof (quoted_char));
-  assert (q);
+  assert_backtrace (q);
 
   q->susp = 0;
   q->lowat = lowat;
@@ -720,7 +720,7 @@ create_queue (int size, int lowat, int hiwat)
   q->cs = q->ce = q->array;
   q->arraylen = size;
   q->wait = malloc (sizeof (pthread_cond_t));
-  assert (q->wait);
+  assert_backtrace (q->wait);
 
   pthread_cond_init (q->wait, NULL);
   return q;
diff --git a/term/term.h b/term/term.h
index 0a42869..9125e99 100644
--- a/term/term.h
+++ b/term/term.h
@@ -22,7 +22,7 @@
 #define __HURD_TERM_H__
 
 #include <pthread.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <hurd/trivfs.h>
 #include <sys/types.h>
@@ -246,7 +246,7 @@ dequeue_quote (struct queue *q)
 {
   int beep = 0;
 
-  assert (qsize (q));
+  assert_backtrace (qsize (q));
   if (q->susp && (qsize (q) < q->lowat))
     {
       q->susp = 0;
@@ -340,7 +340,7 @@ queue_erase (struct queue *q)
   short answer;
   int beep = 0;
 
-  assert (qsize (q));
+  assert_backtrace (qsize (q));
   answer = *--q->ce;
   if (q->susp && (qsize (q) < q->lowat))
     {
diff --git a/term/users.c b/term/users.c
index 193b358..4e8368e 100644
--- a/term/users.c
+++ b/term/users.c
@@ -172,7 +172,7 @@ open_hook (struct trivfs_control *cntl,
     }
   else
     {
-      assert (open_count > 0); /* XXX debugging */
+      assert_backtrace (open_count > 0);       /* XXX debugging */
 
       if (termflags & EXCL_USE)
        {
@@ -254,7 +254,7 @@ pi_destroy_hook (struct trivfs_protid *cred)
   pthread_mutex_lock (&global_lock);
   if (cred->hook)
     {
-      assert (((struct protid_hook *)cred->hook)->refcnt > 0);
+      assert_backtrace (((struct protid_hook *)cred->hook)->refcnt > 0);
       if (--((struct protid_hook *)cred->hook)->refcnt == 0)
        free (cred->hook);
     }
@@ -388,7 +388,7 @@ S_termctty_open_terminal (struct port_info *pi,
   if (!pi)
     return EOPNOTSUPP;
 
-  assert (pi == cttyid);
+  assert_backtrace (pi == cttyid);
 
   err = io_restrict_auth (termctl->underlying, &new_realnode, 0, 0, 0, 0);
 
diff --git a/tmpfs/dir.c b/tmpfs/dir.c
index 37bb7bf..340a63d 100644
--- a/tmpfs/dir.c
+++ b/tmpfs/dir.c
@@ -44,8 +44,8 @@ diskfs_clear_directory (struct node *dp, struct node *pdp,
 {
   if (dp->dn->u.dir.entries != 0)
     return ENOTEMPTY;
-  assert (dp->dn_stat.st_size == 0);
-  assert (dp->dn->u.dir.dotdot == pdp->dn);
+  assert_backtrace (dp->dn_stat.st_size == 0);
+  assert_backtrace (dp->dn->u.dir.dotdot == pdp->dn);
 
   /* Decrease hardlink count for parent directory */
   pdp->dn_stat.st_nlink--;
@@ -97,7 +97,7 @@ diskfs_get_directs (struct node *dp, int entry, int n,
     {
       if (dp->dn->u.dir.dotdot == 0)
        {
-         assert (dp == diskfs_root_node);
+         assert_backtrace (dp == diskfs_root_node);
          /* Use something not zero and not an st_ino value for any node in
             this filesystem.  Since we use pointer values, 2 will never
             be a valid number.  */
@@ -120,7 +120,7 @@ diskfs_get_directs (struct node *dp, int entry, int n,
 
   if (i < entry)
     {
-      assert (d == 0);
+      assert_backtrace (d == 0);
       *datacnt = 0;
       *amt = 0;
       return 0;
@@ -177,7 +177,7 @@ diskfs_lookup_hard (struct node *dp,
   struct tmpfs_dirent *d, **prevp;
 
   if (type == REMOVE || type == RENAME)
-    assert (np);
+    assert_backtrace (np);
 
   if (ds)
     ds->dotdot = type & SPEC_DOTDOT;
@@ -196,16 +196,16 @@ diskfs_lookup_hard (struct node *dp,
       struct disknode *dddn = dp->dn->u.dir.dotdot;
       error_t err;
 
-      assert (np != 0);
+      assert_backtrace (np != 0);
       if (dddn == 0)           /* root directory */
        return EAGAIN;
 
       if (type == (REMOVE|SPEC_DOTDOT) || type == (RENAME|SPEC_DOTDOT))
         {
          *np = *dddn->hprevp;
-         assert (*np);
-         assert ((*np)->dn == dddn);
-         assert (*dddn->hprevp == *np);
+         assert_backtrace (*np);
+         assert_backtrace ((*np)->dn == dddn);
+         assert_backtrace (*dddn->hprevp == *np);
          return 0;
        }
       else
diff --git a/tmpfs/node.c b/tmpfs/node.c
index 2a4489c..e93b879 100644
--- a/tmpfs/node.c
+++ b/tmpfs/node.c
@@ -78,7 +78,7 @@ diskfs_free_node (struct node *np, mode_t mode)
       }        
       break;
     case DT_DIR:
-      assert (np->dn->u.dir.entries == 0);
+      assert_backtrace (np->dn->u.dir.entries == 0);
       break;
     case DT_LNK:
       free (np->dn->u.lnk);
@@ -122,7 +122,7 @@ diskfs_node_norefs (struct node *np)
       switch (np->dn->type)
        {
        case DT_REG:
-         assert (np->allocsize % vm_page_size == 0);
+         assert_backtrace (np->allocsize % vm_page_size == 0);
          np->dn->u.reg.allocpages = np->allocsize / vm_page_size;
          break;
        case DT_CHR:
@@ -170,7 +170,7 @@ diskfs_cached_lookup (ino_t inum, struct node **npp)
   struct disknode *dn = (void *) (uintptr_t) inum;
   struct node *np;
 
-  assert (npp);
+  assert_backtrace (npp);
 
   pthread_rwlock_rdlock (&all_nodes_lock);
   if (dn->hprevp != 0)         /* There is already a node.  */
@@ -232,8 +232,8 @@ diskfs_cached_lookup (ino_t inum, struct node **npp)
 
  gotit:
   np = *dn->hprevp;
-  assert (np->dn == dn);
-  assert (*dn->hprevp == np);
+  assert_backtrace (np->dn == dn);
+  assert_backtrace (*dn->hprevp == np);
   diskfs_nref (np);
   pthread_rwlock_unlock (&all_nodes_lock);
   pthread_mutex_lock (&np->lock);
@@ -379,7 +379,7 @@ diskfs_set_translator (struct node *np,
 static error_t
 create_symlink_hook (struct node *np, const char *target)
 {
-  assert (np->dn->u.lnk == 0);
+  assert_backtrace (np->dn->u.lnk == 0);
   np->dn_stat.st_size = strlen (target);
   if (np->dn_stat.st_size > 0)
     {
@@ -444,7 +444,7 @@ diskfs_truncate (struct node *np, off_t size)
   if (np->allocsize <= size)
     return 0;
 
-  assert (np->dn->type == DT_REG);
+  assert_backtrace (np->dn->type == DT_REG);
 
   if (default_pager == MACH_PORT_NULL)
     return EIO;
@@ -484,7 +484,7 @@ diskfs_truncate (struct node *np, off_t size)
 error_t
 diskfs_grow (struct node *np, off_t size, struct protid *cred)
 {
-  assert (np->dn->type == DT_REG);
+  assert_backtrace (np->dn->type == DT_REG);
 
   if (np->allocsize >= size)
     return 0;
@@ -548,7 +548,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
          errno = err;
          return MACH_PORT_NULL;
        }
-      assert (np->dn->u.reg.memobj != MACH_PORT_NULL);
+      assert_backtrace (np->dn->u.reg.memobj != MACH_PORT_NULL);
       
       /* XXX we need to keep a reference to the object, or GNU Mach
         will terminate it when we release the map. */
@@ -556,7 +556,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
       vm_map (mach_task_self (), &np->dn->u.reg.memref, 4096, 0, 1,
              np->dn->u.reg.memobj, 0, 0, VM_PROT_NONE, VM_PROT_NONE,
              VM_INHERIT_NONE);
-      assert_perror (err);
+      assert_perror_backtrace (err);
     }
 
   /* XXX always writable */
@@ -564,7 +564,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
   /* Add a reference for each call, the caller will deallocate it.  */
   err = mach_port_mod_refs (mach_task_self (), np->dn->u.reg.memobj,
                            MACH_PORT_RIGHT_SEND, +1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   return np->dn->u.reg.memobj;
 }
@@ -613,18 +613,18 @@ diskfs_S_file_get_storage_info (struct protid *cred,
   if (memobj == MACH_PORT_NULL)
     return errno;
 
-  assert (*num_ports >= 1);    /* mig always gives us some */
+  assert_backtrace (*num_ports >= 1);  /* mig always gives us some */
   *num_ports = 1;
   *ports_type = MACH_MSG_TYPE_MOVE_SEND;
   (*ports)[0]
     = (cred->po->openstat & O_RDWR) == O_RDWR ? memobj : MACH_PORT_NULL;
 
-  assert (*num_offsets >= 2);  /* mig always gives us some */
+  assert_backtrace (*num_offsets >= 2);        /* mig always gives us some */
   *num_offsets = 2;
   (*offsets)[0] = 0;
   (*offsets)[1] = cred->po->np->dn_stat.st_size;
 
-  assert (*num_ints >= 6);     /* mig always gives us some */
+  assert_backtrace (*num_ints >= 6);   /* mig always gives us some */
   *num_ints = 6;
   (*ints)[0] = STORAGE_MEMORY;
   (*ints)[1] = (cred->po->openstat & O_WRITE) ? 0 : STORE_READONLY;
diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c
index fd1c9aa..2815199 100644
--- a/tmpfs/tmpfs.c
+++ b/tmpfs/tmpfs.c
@@ -341,7 +341,7 @@ main (int argc, char **argv)
   struct stat st;
 
   err = argp_parse (&startup_argp, argc, argv, ARGP_IN_ORDER, NULL, NULL);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   task_get_bootstrap_port (mach_task_self (), &bootstrap);
   if (bootstrap == MACH_PORT_NULL)
diff --git a/trans/Makefile b/trans/Makefile
index 65b51d1..02718df 100644
--- a/trans/Makefile
+++ b/trans/Makefile
@@ -28,7 +28,7 @@ SRCS = ifsock.c symlink.c magic.c null.c fifo.c new-fifo.c 
fwd.c \
 OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o passwordServer.o \
        crashServer.o crash_replyUser.o msgServer.o \
        default_pagerServer.o default_pagerUser.o \
-       device_replyServer.o elfcore.o
+       device_replyServer.o elfcore.o startup_notifyServer.o
 HURDLIBS = ports netfs trivfs iohelp fshelp pipe ihash shouldbeinlibc
 LDLIBS += -lpthread
 password-LDLIBS = -lcrypt
@@ -52,6 +52,20 @@ device_reply-MIGSFLAGS=\
 # fsysServer is only used by the symlink translator which does not use
 # libports.  Disable the default payload to port conversion.
 fsys-MIGSFLAGS = "-DHURD_DEFAULT_PAYLOAD_TO_PORT=1"
+fsysServer-CFLAGS = "-DMIG_EOPNOTSUPP=EOPNOTSUPP"
+
+# If we have a configured tree, include the configuration so that we
+# can conditionally build translators.
+ifneq (,$(wildcard ../config.make))
+ include ../config.make
+endif
+
+ifeq ($(HAVE_LIBGCRYPT),yes)
+ SRCS += random.c
+ targets += random
+ random-LDLIBS = -lgcrypt
+ random: startup_notifyServer.o mach_debugUser.o ../libtrivfs/libtrivfs.a
+endif
 
 include ../Makeconf
 
diff --git a/trans/crash.c b/trans/crash.c
index f8e1658..3fad499 100644
--- a/trans/crash.c
+++ b/trans/crash.c
@@ -29,7 +29,7 @@
 #include <argp.h>
 #include <argz.h>
 #include <sys/mman.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <pthread.h>
 
 #include <version.h>
@@ -152,7 +152,7 @@ template_make_file_name (const char *template,
              break;
 
            default:
-             assert (!"reached!");
+             assert_backtrace (!"reached!");
            }
          specifier = 0;
        }
@@ -162,7 +162,7 @@ template_make_file_name (const char *template,
        fprintf (stream, "%c", *t);
     }
 
-  assert (! specifier);
+  assert_backtrace (! specifier);
 
   fprintf (stream, "%c", 0);
   fclose (stream);
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index ad7bec9..df47b00 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -76,7 +76,7 @@ new_node (file_t file, mach_port_t idport, int locked, int 
openmodes,
   error_t err;
   struct netnode *nn;
 
-  assert ((openmodes & ~(O_RDWR|O_EXEC)) == 0);
+  assert_backtrace ((openmodes & ~(O_RDWR|O_EXEC)) == 0);
 
   *np = netfs_make_node_alloc (sizeof *nn);
   if (*np == 0)
@@ -97,7 +97,7 @@ new_node (file_t file, mach_port_t idport, int locked, int 
openmodes,
     {
       ino_t fileno;
       mach_port_t fsidport;
-      assert (!locked);
+      assert_backtrace (!locked);
       err = io_identity (file, &nn->idport, &fsidport, &fileno);
       if (err)
        {
@@ -218,7 +218,7 @@ check_openmodes (struct netnode *nn, int newmodes, file_t 
file)
 {
   error_t err = 0;
 
-  assert ((newmodes & ~(O_RDWR|O_EXEC)) == 0);
+  assert_backtrace ((newmodes & ~(O_RDWR|O_EXEC)) == 0);
 
   if (newmodes &~ nn->openmodes)
     {
@@ -302,16 +302,74 @@ netfs_S_dir_lookup (struct protid *diruser,
 
   dnp = diruser->po->np;
 
+  /* See glibc's lookup-retry.c about O_NOFOLLOW.  */
+  if (flags & O_NOFOLLOW)
+    flags |= O_NOTRANS;
+
   mach_port_t dir = netfs_node_netnode (dnp)->file;
  redo_lookup:
   err = dir_lookup (dir, filename,
-                   flags & (O_NOLINK|O_RDWR|O_EXEC|O_CREAT|O_EXCL|O_NONBLOCK),
+                   flags & (O_NOFOLLOW|O_NOTRANS|O_NOLINK
+                            |O_RDWR|O_EXEC|O_CREAT|O_EXCL|O_NONBLOCK),
                    real_from_fake_mode (mode), do_retry, retry_name, &file);
   if (dir != netfs_node_netnode (dnp)->file)
     mach_port_deallocate (mach_task_self (), dir);
   if (err)
     return err;
 
+  /* See glibc's lookup-retry.c about O_NOFOLLOW.  */
+  if (flags & O_NOFOLLOW
+      && (*do_retry == FS_RETRY_NORMAL && *retry_name == 0))
+    {
+      /* In Linux, O_NOFOLLOW means to reject symlinks.  If we
+        did an O_NOLINK lookup above and io_stat here to check
+        for S_IFLNK, a translator like firmlink could easily
+        spoof this check by not showing S_IFLNK, but in fact
+        redirecting the lookup to some other name
+        (i.e. opening the very same holes a symlink would).
+
+        Instead we do an O_NOTRANS lookup above, and stat the
+        underlying node: if it has a translator set, and its
+        owner is not root (st_uid 0) then we reject it.
+        Since the motivation for this feature is security, and
+        that security presumes we trust the containing
+        directory, this check approximates the security of
+        refusing symlinks while accepting mount points.
+        Note that we actually permit something Linux doesn't:
+        we follow root-owned symlinks; if that is deemed
+        undesireable, we can add a final check for that
+        one exception to our general translator-based rule.  */
+      struct stat st;
+      err = io_stat (file, &st);
+      if (!err
+         && (st.st_mode & (S_IPTRANS|S_IATRANS)))
+       {
+         if (st.st_uid != 0)
+           err = ENOENT;
+         else if (st.st_mode & S_IPTRANS)
+           {
+             char buf[1024];   /* XXX */
+             char *trans = buf;
+             size_t translen = sizeof buf;
+             err = file_get_translator (file,
+                                        &trans, &translen);
+             if (!err
+                 && translen > sizeof _HURD_SYMLINK
+                 && !memcmp (trans,
+                             _HURD_SYMLINK, sizeof _HURD_SYMLINK))
+                 err = ENOENT;
+
+             if (trans != buf)
+               vm_deallocate (mach_task_self (), (vm_address_t) trans, 
translen);
+           }
+       }
+      if (err)
+       {
+         mach_port_deallocate (mach_task_self (), file);
+         return err;
+       }
+    }
+
   switch (*do_retry)
     {
     case FS_RETRY_REAUTH:
@@ -426,7 +484,7 @@ netfs_S_dir_lookup (struct protid *diruser,
   if (err)
     goto lose;
 
-  assert (retry_name[0] == '\0' && *do_retry == FS_RETRY_NORMAL);
+  assert_backtrace (retry_name[0] == '\0' && *do_retry == FS_RETRY_NORMAL);
   flags &= ~(O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS|O_NONBLOCK);
 
   err = iohelp_dup_iouser (&user, diruser->user);
@@ -473,7 +531,7 @@ error_t
 netfs_attempt_lookup (struct iouser *user, struct node *dir,
                      char *name, struct node **np)
 {
-  assert (! "should not be here");
+  assert_backtrace (! "should not be here");
   return EIEIO;
 }
 
@@ -481,7 +539,7 @@ error_t
 netfs_attempt_create_file (struct iouser *user, struct node *dir,
                           char *name, mode_t mode, struct node **np)
 {
-  assert (! "should not be here");
+  assert_backtrace (! "should not be here");
   return EIEIO;
 }
 
@@ -754,7 +812,7 @@ netfs_attempt_readlink (struct iouser *user, struct node 
*np, char *buf)
        err = EINVAL;
       else
        {
-         assert (translen <= sizeof _HURD_SYMLINK + np->nn_stat.st_size + 1);
+         assert_backtrace (translen <= sizeof _HURD_SYMLINK + 
np->nn_stat.st_size + 1);
          memcpy (buf, &trans[sizeof _HURD_SYMLINK],
                  translen - sizeof _HURD_SYMLINK);
        }
@@ -1029,7 +1087,7 @@ netfs_demuxer (mach_msg_header_t *inp,
       else
        {
          error_t err;
-         assert (MACH_MSGH_BITS_LOCAL (inp->msgh_bits)
+         assert_backtrace (MACH_MSGH_BITS_LOCAL (inp->msgh_bits)
                  == MACH_MSG_TYPE_MOVE_SEND
                  || MACH_MSGH_BITS_LOCAL (inp->msgh_bits)
                  == MACH_MSG_TYPE_PROTECTED_PAYLOAD);
diff --git a/trans/firmlink.c b/trans/firmlink.c
index 19382f1..ca094ec 100644
--- a/trans/firmlink.c
+++ b/trans/firmlink.c
@@ -287,8 +287,7 @@ trivfs_S_io_select_timeout (struct trivfs_protid *cred,
   return trivfs_S_io_select (cred, reply, reply_type, type);
 }
 
-error_t trivfs_get_source (struct trivfs_protid *cred,
-                          char *source, size_t source_len)
+error_t trivfs_get_source (char *source, size_t source_len)
 {
   strncpy (source, target, source_len - 1);
   source[source_len -1 ] = '\0';
diff --git a/trans/magic.c b/trans/magic.c
index a033db9..e38efca 100644
--- a/trans/magic.c
+++ b/trans/magic.c
@@ -34,7 +34,7 @@
 #include <limits.h>
 #include <argp.h>
 #include <argz.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include "fsys_S.h"
 
@@ -167,7 +167,7 @@ magic_getroot (struct trivfs_control *cntl,
   *node_type = MACH_MSG_TYPE_COPY_SEND;
 
   err = mach_port_deallocate (mach_task_self (), dotdot);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   return 0;
 }
@@ -313,10 +313,10 @@ trivfs_S_dir_lookup (struct trivfs_protid *cred,
     }
   err = mach_port_mod_refs (mach_task_self (), dotdot,
                            MACH_PORT_RIGHT_SEND, +1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = mach_port_mod_refs (mach_task_self (), cred->realnode,
                            MACH_PORT_RIGHT_SEND, +1);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   *retry_type = FS_RETRY_NORMAL;
   *retry_name = '\0';
diff --git a/trans/mtab.c b/trans/mtab.c
index c03749c..a69ede6 100644
--- a/trans/mtab.c
+++ b/trans/mtab.c
@@ -141,31 +141,34 @@ size_t uids_len, gids_len;
 error_t
 get_credentials (void)
 {
+  int len, len_;
   /* Fetch uids...  */
-  uids_len = geteuids (0, 0);
-  if (uids_len < 0)
+  len = geteuids (0, NULL);
+  if (len < 0)
     return errno;
 
-  uids = malloc (uids_len * sizeof (uid_t));
+  uids = malloc (len * sizeof (uid_t));
   if (! uids)
     return ENOMEM;
 
-  uids_len = geteuids (uids_len, uids);
-  if (uids_len < 0)
+  len_ = geteuids (len, uids);
+  if (len_ != len)
     return errno;
+  uids_len = (size_t) len;
 
   /* ... and gids.  */
-  gids_len = getgroups (0, 0);
-  if (gids_len < 0)
+  len = getgroups (0, NULL);
+  if (len < 0)
     return errno;
 
-  gids = malloc (gids_len * sizeof (gid_t));
-  if (! uids)
+  gids = malloc (len * sizeof (gid_t));
+  if (! gids)
     return ENOMEM;
 
-  gids_len = getgroups (gids_len, gids);
-  if (gids_len < 0)
+  len_ = getgroups (len, gids);
+  if (len_ != len)
     return errno;
+  gids_len = (size_t) len;
 
   return 0;
 }
@@ -428,7 +431,7 @@ mtab_populate (struct mtab *mtab, const char *path, int 
insecure)
       goto errout;
     }
 
-  for (int i = 1; i < count - 1; i++)
+  for (size_t i = 1; i < count - 1; i++)
     {
       char *v = argv[i];
 
@@ -775,13 +778,14 @@ trivfs_S_io_seek (struct trivfs_protid *cred,
       goto check;
     case SEEK_END:
       offs += op->contents_len;
+      goto check;
     case SEEK_SET:
     check:
       if (offs >= 0)
-       {
-         *new_offs = op->offs = offs;
-         break;
-       }
+        *new_offs = op->offs = offs;
+      else
+        err = EINVAL;
+      break;
     default:
       err = EINVAL;
     }
diff --git a/trans/new-fifo.c b/trans/new-fifo.c
index f11ceca..efa36c2 100644
--- a/trans/new-fifo.c
+++ b/trans/new-fifo.c
@@ -24,7 +24,7 @@
 #include <error.h>
 #include <string.h>
 #include <fcntl.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 
 #include <pthread.h>
 #include <hurd.h>
@@ -220,7 +220,7 @@ main (int argc, char **argv)
   if (err)
     error (1, 0, "error creating protid port class");
 
-    err = trivfs_add_protid_port_class (&server_port_class);
+  err = trivfs_add_protid_port_class (&server_port_class);
   if (err)
     error (1, 0, "error creating protid port class");
 
@@ -536,7 +536,7 @@ trivfs_S_io_read (struct trivfs_protid *cred,
   else
     {
       struct pipe *pipe = cred->po->hook;
-      assert (pipe);
+      assert_backtrace (pipe);
       pthread_mutex_lock (&pipe->lock);
       err = pipe_read (pipe, cred->po->openmodes & O_NONBLOCK, NULL,
                       data, data_len, amount);
@@ -565,7 +565,7 @@ trivfs_S_io_readable (struct trivfs_protid *cred,
   else
     {
       struct pipe *pipe = cred->po->hook;
-      assert (pipe);
+      assert_backtrace (pipe);
       pthread_mutex_lock (&pipe->lock);
       *amount = pipe_readable (pipe, 1);
       pthread_mutex_unlock (&pipe->lock);
@@ -835,7 +835,7 @@ trivfs_S_fsys_forward (mach_port_t server,
     return EOPNOTSUPP;
 
   server_trans = cred->po->cntl->hook;
-  assert (server_trans->server);
+  assert_backtrace (server_trans->server);
 
   argz_extract (argz, argz_len, argv);
 
diff --git a/trans/password.c b/trans/password.c
index 9ffcaa0..b9f9c5b 100644
--- a/trans/password.c
+++ b/trans/password.c
@@ -17,7 +17,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include <argp.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <errno.h>
 #include <error.h>
 #include <stdlib.h>
@@ -151,7 +151,7 @@ S_password_check_user (struct trivfs_protid *cred, uid_t 
user, char *pw,
   char *getpass (const char *prompt, uid_t id, int is_group,
                 void *pwd_or_group, void *hook)
     {
-      assert (! is_group && id == user);
+      assert_backtrace (! is_group && id == user);
       return strdup (pw);
     }
 
@@ -199,7 +199,7 @@ S_password_check_group (struct trivfs_protid *cred, uid_t 
group, char *pw,
   char *getpass (const char *prompt, uid_t id, int is_group,
                 void *pwd_or_group, void *hook)
     {
-      assert (is_group && id == group);
+      assert_backtrace (is_group && id == group);
       return strdup (pw);
     }
 
diff --git a/random/random.c b/trans/random.c
similarity index 64%
rename from random/random.c
rename to trans/random.c
index 69176b7..f48cea5 100644
--- a/random/random.c
+++ b/trans/random.c
@@ -1,5 +1,5 @@
 /* random.c - A single-file translator providing random data
-   Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2001, 2017 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -15,98 +15,266 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-#define _GNU_SOURCE 1
-
+#include <argp.h>
+#include <argz.h>
+#include <assert-backtrace.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gcrypt.h>
 #include <hurd/paths.h>
-#include <hurd/trivfs.h>
 #include <hurd/startup.h>
+#include <hurd/trivfs.h>
+#include <mach/gnumach.h>
+#include <mach/vm_cache_statistics.h>
+#include <mach/vm_param.h>
+#include <mach/vm_statistics.h>
+#include <mach_debug/mach_debug_types.h>
+#include <maptime.h>
+#include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <argp.h>
-#include <argz.h>
-#include <error.h>
 #include <string.h>
-#include <fcntl.h>
 #include <sys/mman.h>
-#include <pthread.h>
-#include <assert.h>
-
+#include <sys/stat.h>
+#include <unistd.h>
 #include <version.h>
 
-#include "random.h"
-#include "gnupg-random.h"
+#include "mach_debug_U.h"
 
-/* Our control port.  */
-struct trivfs_control *fsys;
+
 
-int read_blocked;              /* For read and select.  */
-pthread_cond_t wait;           /* For read and select.  */
-pthread_cond_t select_alert;   /* For read and select.  */
+/* Entropy pool.  We use one of the SHAKE algorithms from the Keccak
+   family.  Being a sponge construction, it allows the extraction of
+   arbitrary amounts of pseudorandom data.  */
+static gcry_md_hd_t pool;
+enum gcry_md_algos hash_algo = GCRY_MD_SHAKE128;
+
+/* Protected by this lock.  */
+static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* A map of the Mach time device.  Used for quick stirring.  */
+volatile struct mapped_time_value *mtime;
+
+static void
+pool_initialize (void)
+{
+  error_t err;
+  gcry_error_t cerr;
+
+  if (! gcry_check_version (GCRYPT_VERSION))
+    error (1, 0, "libgcrypt version mismatch\n");
+
+  cerr = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+  if (cerr)
+    error (1, 0, "Finalizing gcrypt failed: %s",
+          gcry_strerror (cerr));
+
+  cerr = gcry_md_open (&pool, hash_algo, GCRY_MD_FLAG_SECURE);
+  if (cerr)
+    error (1, 0, "Initializing hash failed: %s",
+          gcry_strerror (cerr));
+
+  err = maptime_map (0, NULL, &mtime);
+  if (err)
+    err = maptime_map (1, NULL, &mtime);
+  if (err)
+    error (1, err, "Failed to map time device");
+}
+
+/* Mix data into the pool.  */
+static void
+pool_add_entropy (const void *buffer, size_t length)
+{
+  pthread_mutex_lock (&pool_lock);
+  gcry_md_write (pool, buffer, length);
+  pthread_mutex_unlock (&pool_lock);
+}
+
+/* Extract data from the pool.  */
+static error_t
+pool_randomize (void *buffer, size_t length)
+{
+  gcry_error_t cerr;
+  pthread_mutex_lock (&pool_lock);
+
+  /* Quickly stir the the time device into the pool.  Do not even
+     bother with synchronization.  */
+  gcry_md_write (pool, (void *) mtime, sizeof *mtime);
+
+  cerr = gcry_md_extract (pool, hash_algo, buffer, length);
+  pthread_mutex_unlock (&pool_lock);
+  return cerr ? EIO : 0;
+}
 
 
-/* The quality of randomness we provide.
-   0: Very weak randomness based on time() and getrusage().
-   No external random data is used.
-   1: Pseudo random numbers based on all available real random
-   numbers.
-   2: Strong random numbers with a somewhat guaranteed entropy.
-*/
-#define DEFAULT_LEVEL 2
-static int level = DEFAULT_LEVEL;
 
 /* Name of file to use as seed.  */
 static char *seed_file;
 
-/* The random bytes we collected.  */
-char gatherbuf[GATHERBUFSIZE];
+/* Size of the seed file.  */
+size_t seed_size = 600;
 
-/* The current positions in gatherbuf[].  */
-int gatherrpos;
-int gatherwpos;
+static error_t
+update_random_seed_file (void)
+{
+  error_t err;
+  int fd;
+  void *map;
 
-/* XXX Yuk Yuk.  */
-#define POOLSIZE 600
+  if (seed_file == NULL)
+    return 0;
 
-/* Take up to length bytes from gather_random if available.  If
-   nothing is available, sleep until something becomes available.
-   Must be called with global_lock held.  */
-int
-gather_random( void (*add)(const void*, size_t, int), int requester,
-               size_t length, int level )
+  fd = open (seed_file, O_RDWR|O_CREAT, 0600);
+  if (fd < 0)
+    return errno;
+
+  if (ftruncate (fd, seed_size))
+    {
+      err = errno;
+      goto out;
+    }
+
+  map = mmap (NULL, seed_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+  if (map == MAP_FAILED)
+    {
+      err = errno;
+      goto out;
+    }
+
+  err = pool_randomize (map, seed_size);
+  munmap (map, seed_size);
+
+ out:
+  close (fd);
+  return err;
+}
+
+static error_t
+read_random_seed_file (void)
 {
-  int avail = (gatherwpos - gatherrpos + GATHERBUFSIZE) % GATHERBUFSIZE;
-  int first = GATHERBUFSIZE - gatherrpos;
-  int second = length - first;
+  error_t err;
+  int fd;
+  struct stat s;
+  void *map;
 
-  /* If level is zero, we should not block and not add anything
-     to the pool.  */
-  if( !level )
+  if (seed_file == NULL)
     return 0;
 
-  /* io_read() should guarantee that there is always data available.  */
-  if (level == 2)
-    assert (avail);
+  fd = open (seed_file, O_RDWR);
+  if (fd < 0)
+    return errno;
+
+  if (fstat (fd, &s))
+    {
+      err = errno;
+      goto out;
+    }
+
+  /* XXX should check file permissions.  */
+
+  map = mmap (NULL, s.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+  if (map == MAP_FAILED)
+    {
+      err = errno;
+      goto out;
+    }
+
+  pool_add_entropy (map, s.st_size);
+  /* Immediately update it, to minimize the chance that the same state
+     is read twice.  */
+  pool_randomize (map, s.st_size);
+  munmap (map, s.st_size);
+
+ out:
+  close (fd);
+  return err;
+}
+
+
+
+static void
+gather_slab_info (void)
+{
+  error_t err;
+  cache_info_array_t cache_info;
+  mach_msg_type_number_t cache_info_count;
+
+  cache_info = NULL;
+  cache_info_count = 0;
+
+  err = host_slab_info (mach_host_self(), &cache_info, &cache_info_count);
+  if (err)
+    return;
+
+  pool_add_entropy (cache_info, cache_info_count * sizeof *cache_info);
+
+  vm_deallocate (mach_task_self (),
+                (vm_address_t) cache_info,
+                cache_info_count * sizeof *cache_info);
+}
+
+static void
+gather_vm_statistics (void)
+{
+  error_t err;
+  struct vm_statistics vmstats;
+
+  err = vm_statistics (mach_task_self (), &vmstats);
+  if (err)
+    return;
+
+  pool_add_entropy (&vmstats, sizeof vmstats);
+}
+
+static void
+gather_vm_cache_statistics (void)
+{
+  error_t err;
+  struct vm_cache_statistics cache_stats;
 
-  if (length > avail)
-    length = avail;
+  err = vm_cache_statistics (mach_task_self (), &cache_stats);
+  if (err)
+    return;
 
-  if (first > length)
-    first = length;
-  (*add) (&gatherbuf[gatherrpos], first, requester);
-  gatherrpos = (gatherrpos + first) % GATHERBUFSIZE;
-  if (second > 0)
+  pool_add_entropy (&cache_stats, sizeof cache_stats);
+}
+
+static void *
+gather_thread (void *args)
+{
+  while (1)
     {
-      (*add) (&gatherbuf[gatherrpos], second, requester);
-      gatherrpos += second;
+      gather_slab_info ();
+      gather_vm_statistics ();
+      gather_vm_cache_statistics ();
+      usleep (
+        (useconds_t) (1000000. * (1.
+                                  + (float) random () / (float) RAND_MAX)));
     }
-  return length;
+
+  assert_backtrace (! "reached");
+}
+
+error_t
+start_gather_thread (void)
+{
+  error_t err;
+  pthread_t thread;
+
+  err = pthread_create (&thread, NULL, gather_thread, NULL);
+  if (err)
+    return err;
+
+  err = pthread_detach (thread);
+  return err;
 }
 
 
+
 const char *argp_program_version = STANDARD_HURD_VERSION (random);
 
-/* This lock protects the GnuPG code.  */
-static pthread_mutex_t global_lock;
+/* Our control port.  */
+struct trivfs_control *fsys;
 
 /* Trivfs hooks. */
 int trivfs_fstype = FSTYPE_MISC;
@@ -122,7 +290,7 @@ void
 trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st)
 {
   /* Mark the node as a read-only plain file. */
-  st->st_mode &= ~S_IFMT;
+  st->st_mode &= ~((unsigned) S_IFMT);
   st->st_mode |= (S_IFCHR);
   st->st_size = 0;
 }
@@ -130,7 +298,10 @@ trivfs_modify_stat (struct trivfs_protid *cred, struct 
stat *st)
 error_t
 trivfs_goaway (struct trivfs_control *cntl, int flags)
 {
-  update_random_seed_file ();
+  error_t err;
+  err = update_random_seed_file ();
+  if (err)
+    error (0, err, "Warning: Failed to save random seed to %s", seed_file);
   exit (0);
 }
 
@@ -144,53 +315,24 @@ trivfs_S_io_read (struct trivfs_protid *cred,
                  loff_t offs, mach_msg_type_number_t amount)
 {
   error_t err;
-  mach_msg_type_number_t read_amount = 0;
   void *buf = NULL;
-  size_t length;
+  size_t length = 0;
 
-  /* Deny access if they have bad credentials. */
   if (! cred)
     return EOPNOTSUPP;
   else if (! (cred->po->openmodes & O_READ))
     return EBADF;
 
-  pthread_mutex_lock (&global_lock);
-
-  while (amount > 0)
+  if (amount > 0)
     {
-      mach_msg_type_number_t new_amount;
-      /* XXX: It would be nice to fix readable_pool to work for sizes
-        greater than the POOLSIZE.  Otherwise we risk detecting too
-        late that we run out of entropy and all that entropy is
-        wasted.  */
-      while (readable_pool (amount, level) == 0)
-       {
-         if (cred->po->openmodes & O_NONBLOCK)
-           {
-             pthread_mutex_unlock (&global_lock);
-             err = EWOULDBLOCK;
-             goto errout;
-           }
-         read_blocked = 1;
-         if (pthread_hurd_cond_wait_np (&wait, &global_lock))
-           {
-             pthread_mutex_unlock (&global_lock);
-             err = EINTR;
-             goto errout;
-           }
-         /* See term/users.c for possible race?  */
-       }
-
       /* Possibly allocate a new buffer. */
       if (*data_len < amount)
        {
-         *data = mmap (0, amount, PROT_READ|PROT_WRITE,
-                                      MAP_ANON, 0, 0);
-
+         *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
          if (*data == MAP_FAILED)
            {
-             pthread_mutex_unlock (&global_lock);
-             return errno;
+              err = errno;
+              goto errout;
            }
 
          /* Keep track of our map in case of errors.  */
@@ -200,15 +342,14 @@ trivfs_S_io_read (struct trivfs_protid *cred,
          *data_len = amount;
        }
 
-      new_amount = read_pool (((byte *) *data) + read_amount, amount, level);
-      read_amount += new_amount;
-      amount -= new_amount;
-    }
+      err = pool_randomize (*data, amount);
+      if (err)
+        goto errout;
 
-  /* Set atime, see term/users.c */
+    }
 
-  pthread_mutex_unlock (&global_lock);
-  *data_len = read_amount;
+  *data_len = amount;
+  trivfs_set_atime (fsys);
   return 0;
 
  errout:
@@ -233,33 +374,15 @@ trivfs_S_io_write (struct trivfs_protid *cred,
                    loff_t offset,
                    mach_msg_type_number_t *amount)
 {
-  int i = 0;
   /* Deny access if they have bad credentials. */
   if (! cred)
     return EOPNOTSUPP;
   else if (! (cred->po->openmodes & O_WRITE))
     return EBADF;
 
-  pthread_mutex_lock (&global_lock);
-
-  while (i < datalen)
-    {
-      gatherbuf[gatherwpos] = data[i++];
-      gatherwpos = (gatherwpos + 1) % GATHERBUFSIZE;
-      if (gatherrpos == gatherwpos)
-       /* Overrun.  */
-       gatherrpos = (gatherrpos + 1) % GATHERBUFSIZE;
-    }
+  pool_add_entropy (data, datalen);
   *amount = datalen;
-
-  if (datalen > 0 && read_blocked)
-    {
-      read_blocked = 0;
-      pthread_cond_broadcast (&wait);
-      pthread_cond_broadcast (&select_alert);
-    }
-
-  pthread_mutex_unlock (&global_lock);
+  trivfs_set_mtime (fsys);
   return 0;
 }
 
@@ -277,14 +400,9 @@ trivfs_S_io_readable (struct trivfs_protid *cred,
   else if (! (cred->po->openmodes & O_READ))
     return EBADF;
 
-  pthread_mutex_lock (&global_lock);
-
-  /* XXX: Before initialization, the amount depends on the amount we
-     want to read.  Assume some medium value.  */
-  *amount = readable_pool (POOLSIZE/2, level);
-
-  pthread_mutex_unlock (&global_lock);
-
+  /* We allow an infinite amount of data to be extracted.  We need to
+     return something here, so just go with the page size.  */
+  *amount = PAGE_SIZE;
   return 0;
 }
 
@@ -306,33 +424,9 @@ trivfs_S_io_select (struct trivfs_protid *cred,
   if (*type & ~(SELECT_READ | SELECT_WRITE))
     return EINVAL;
 
-  if (*type == 0)
-    return 0;
-
-  pthread_mutex_lock (&global_lock);
-
-  while (1)
-    {
-      /* XXX Before initialization, readable_pool depends on length.  */
-      int avail = readable_pool (POOLSIZE/2, level);
-
-      if (avail != 0 || *type & SELECT_WRITE)
-       {
-         *type = (avail ? SELECT_READ : 0) | (*type & SELECT_WRITE);
-         pthread_mutex_unlock (&global_lock);
-         return 0;
-       }
-
-      ports_interrupt_self_on_port_death (cred, reply);
-      read_blocked = 1;
-
-      if (pthread_hurd_cond_wait_np (&select_alert, &global_lock))
-       {
-         *type = 0;
-         pthread_mutex_unlock (&global_lock);
-         return EINTR;
-       }
-    }
+  /* We allow an infinite amount of data to be extracted and stored.
+     Just return success.  */
+  return 0;
 }
 
 
@@ -455,9 +549,8 @@ random_demuxer (mach_msg_header_t *inp,
 
 static const struct argp_option options[] =
 {
-  {"weak",      'w', 0, 0, "Output weak pseudo random data"},
-  {"fast",     'f', 0, 0, "Output cheap random data fast"},
-  {"secure",    's', 0, 0, "Output cryptographically secure random"},
+  {"fast",     'f', 0, 0, "(ignored)"},
+  {"secure",    's', 0, 0, "(ignored)"},
   {"seed-file", 'S', "FILE", 0, "Use FILE to remember the seed"},
   {0}
 };
@@ -474,26 +567,14 @@ parse_opt (int opt, char *arg, struct argp_state *state)
     case ARGP_KEY_ERROR:
       break;
 
-    case 'w':
-      {
-       level = 0;
-       break;
-      }
     case 'f':
-      {
-       level = 1;
-       break;
-      }
     case 's':
-      {
-       level = 2;
-       break;
-      }
+      /* Ignored.  */
+      break;
+
     case 'S':
-      {
-       seed_file = strdup (arg);
-       set_random_seed_file (arg);
-      }
+      seed_file = strdup (arg);
+      break;
     }
   return 0;
 }
@@ -507,24 +588,7 @@ trivfs_append_args (struct trivfs_control *fsys,
   error_t err = 0;
   char *opt;
 
-  pthread_mutex_lock (&global_lock);
-  switch (level)
-    {
-    case 0:
-       opt = "--weak";
-       break;
-
-    case 1:
-       opt = "--fast";
-       break;
-
-    default:
-       opt = "--secure";
-    }
-  if (level != DEFAULT_LEVEL)
-    err = argz_add (argz, argz_len, opt);
-
-  if (!err && seed_file)
+  if (seed_file)
     {
       if (asprintf (&opt, "--seed-file=%s", seed_file) < 0)
        err = ENOMEM;
@@ -534,7 +598,6 @@ trivfs_append_args (struct trivfs_control *fsys,
          free (opt);
        }
     }
-  pthread_mutex_unlock (&global_lock);
 
   return err;
 }
@@ -554,20 +617,26 @@ struct port_class *shutdown_notify_class;
 error_t
 S_startup_dosync (mach_port_t handle)
 {
+  error_t err;
   struct port_info *inpi = ports_lookup_port (fsys->pi.bucket, handle,
                                              shutdown_notify_class);
 
   if (!inpi)
     return EOPNOTSUPP;
 
-  update_random_seed_file ();
+  err = update_random_seed_file ();
+  if (err)
+    error (0, err, "Warning: Failed to save random seed to %s", seed_file);
   return 0;
 }
 
 void
 sigterm_handler (int signo)
 {
-  update_random_seed_file ();
+  error_t err;
+  err = update_random_seed_file ();
+  if (err)
+    error (0, err, "Warning: Failed to save random seed to %s", seed_file);
   signal (SIGTERM, SIG_DFL);
   raise (SIGTERM);
 }
@@ -581,7 +650,8 @@ arrange_shutdown_notification ()
 
   shutdown_notify_class = ports_create_class (0, 0);
 
-  signal (SIGTERM, sigterm_handler);
+  if (signal (SIGTERM, sigterm_handler) == SIG_ERR)
+    return errno;
 
   /* Arrange to get notified when the system goes down,
      but if we fail for some reason, just silently give up.  No big deal. */
@@ -606,27 +676,27 @@ arrange_shutdown_notification ()
   return err;
 }
 
-
 int
 main (int argc, char **argv)
 {
   error_t err;
+  unsigned int seed;
   mach_port_t bootstrap;
 
-  /* Initialize the lock that will protect everything.
-     We must do this before argp_parse, because parse_opt (above) will
-     use the lock.  */
-  pthread_mutex_init (&global_lock, NULL);
-
-  /* The conditions are used to implement proper read/select
-     behaviour.  */
-  pthread_cond_init (&wait, NULL);
-  pthread_cond_init (&select_alert, NULL);
-
   /* We use the same argp for options available at startup
      as for options we'll accept in an fsys_set_options RPC.  */
   argp_parse (&random_argp, argc, argv, 0, 0, 0);
 
+  pool_initialize ();
+
+  err = read_random_seed_file ();
+  if (err)
+    error (0, err, "Warning: Failed to read random seed file %s", seed_file);
+
+  /* Initialize the libcs PRNG.  */
+  pool_randomize (&seed, sizeof seed);
+  srandom (seed);
+
   task_get_bootstrap_port (mach_task_self (), &bootstrap);
   if (bootstrap == MACH_PORT_NULL)
     error (1, 0, "Must be started as a translator");
@@ -639,7 +709,11 @@ main (int argc, char **argv)
 
   err = arrange_shutdown_notification ();
   if (err)
-    error (0, err, "Warning: cannot request shutdown notification");
+    error (0, err, "Warning: Cannot request shutdown notification");
+
+  err = start_gather_thread ();
+  if (err)
+    error (1, err, "Starting gather thread failed");
 
   /* Launch. */
   ports_manage_port_operations_multithread (fsys->pi.bucket, random_demuxer,
diff --git a/trans/streamio.c b/trans/streamio.c
index 5539c8e..f276ad6 100644
--- a/trans/streamio.c
+++ b/trans/streamio.c
@@ -19,7 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <argp.h>
@@ -74,11 +74,11 @@ static inline struct buffer *
 create_buffer (size_t size)
 {
   struct buffer *new = malloc (sizeof (struct buffer) + size);
-  assert (new);
+  assert_backtrace (new);
   new->head = new->tail = new->buf;
   new->size = size;
   new->wait = malloc (sizeof (pthread_cond_t));
-  assert (new->wait);
+  assert_backtrace (new->wait);
   pthread_cond_init (new->wait, NULL);
   return new;
 }
@@ -862,12 +862,12 @@ device_open_reply (mach_port_t reply, int returncode, 
mach_port_t device)
     }
   else if (err == 0)
     {
-      assert (sizes_len == DEV_GET_SIZE_COUNT);
+      assert_backtrace (sizes_len == DEV_GET_SIZE_COUNT);
 
       dev_blksize = sizes[DEV_GET_SIZE_RECORD_SIZE];
       dev_size = sizes[DEV_GET_SIZE_DEVICE_SIZE];
 
-      assert (dev_blksize && dev_blksize <= IO_INBAND_MAX);
+      assert_backtrace (dev_blksize && dev_blksize <= IO_INBAND_MAX);
     }
   else
     {
@@ -990,7 +990,7 @@ dev_read (size_t amount, void **buf, size_t *len, int 
nowait)
     vm_allocate (mach_task_self (), (vm_address_t *)buf, max, 1);
 
   *len = buffer_read (input_buffer, *buf, max);
-  assert (*len == max);
+  assert_backtrace (*len == max);
 
   err = start_input (nowait);
   return err;
@@ -1057,7 +1057,7 @@ start_output (int nowait)
 {
   int size;
 
-  assert (output_buffer);
+  assert_backtrace (output_buffer);
 
   size = buffer_size (output_buffer);
 
diff --git a/trans/symlink.c b/trans/symlink.c
index 845a112..80d60f6 100644
--- a/trans/symlink.c
+++ b/trans/symlink.c
@@ -163,13 +163,6 @@ S_fsys_getroot (mach_port_t fsys_t,
 }
 
 error_t
-S_fsys_startup (mach_port_t bootstrap, int flags, mach_port_t control,
-               mach_port_t *real, mach_msg_type_name_t *realtype)
-{
-  return EOPNOTSUPP;
-}
-
-error_t
 S_fsys_goaway (mach_port_t control, int flags)
 {
   exit (0);
@@ -182,55 +175,3 @@ S_fsys_syncfs (mach_port_t control,
 {
   return 0;
 }
-
-error_t
-S_fsys_set_options (mach_port_t control,
-                   char *data, mach_msg_type_number_t len,
-                   int do_children)
-{
-  return EOPNOTSUPP;
-}
-
-error_t
-S_fsys_get_options (mach_port_t control,
-                   char **data, mach_msg_type_number_t *len)
-{
-  return EOPNOTSUPP;
-}
-
-error_t
-S_fsys_getfile (mach_port_t control,
-               uid_t *uids, size_t nuids,
-               uid_t *gids, size_t ngids,
-               char *handle, size_t handllen,
-               mach_port_t *pt,
-               mach_msg_type_name_t *pttype)
-{
-  return EOPNOTSUPP;
-}
-
-error_t
-S_fsys_getpriv (mach_port_t control,
-               mach_port_t *host_priv, mach_msg_type_name_t *host_priv_type,
-               mach_port_t *dev_master, mach_msg_type_name_t *dev_master_type,
-               task_t *fs_task, mach_msg_type_name_t *fs_task_type)
-{
-  return EOPNOTSUPP;
-}
-
-error_t
-S_fsys_init (mach_port_t control,
-          mach_port_t reply,
-          mach_msg_type_name_t replytype,
-          mach_port_t proc,
-          auth_t auth)
-{
-  return EOPNOTSUPP;
-}
-
-error_t
-S_fsys_forward (mach_port_t server, mach_port_t requestor,
-               char *argz, size_t argz_len)
-{
-  return EOPNOTSUPP;
-}
diff --git a/usermux/leaf.c b/usermux/leaf.c
index 7f41b18..ba7fa27 100644
--- a/usermux/leaf.c
+++ b/usermux/leaf.c
@@ -30,7 +30,7 @@
 error_t
 netfs_attempt_readlink (struct iouser *user, struct node *node, char *buf)
 {
-  assert (node->nn->name);
+  assert_backtrace (node->nn->name);
   /* For symlink nodes, the translator spec just contains the link target. */
   memcpy (buf, node->nn->trans, node->nn->trans_len);
   fshelp_touch (&node->nn_stat, TOUCH_ATIME, usermux_maptime);
diff --git a/utils/Makefile b/utils/Makefile
index d2ef9e8..f3f76e9 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -86,3 +86,5 @@ mount umount: ../sutils/fstab.o ../sutils/clookup.o 
match-options.o \
 ../sutils/fstab.o ../sutils/clookup.o: FORCE
        $(MAKE) -C $(@D) $(@F)
 FORCE:
+
+shd vmallocate: ../libshouldbeinlibc/libshouldbeinlibc.a
diff --git a/utils/fakeauth.c b/utils/fakeauth.c
index 40c898b..5a349a8 100644
--- a/utils/fakeauth.c
+++ b/utils/fakeauth.c
@@ -23,7 +23,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/wait.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <argp.h>
 #include <error.h>
 #include "auth_S.h"
@@ -359,7 +359,7 @@ believe it has restricted them to different identities or 
no identity at all.\
 
   /* Create the initial root auth handle.  */
   err = create_authhandle (&firstauth);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   idvec_add (&firstauth->euids, 0);
   idvec_add (&firstauth->auids, 0);
   idvec_add (&firstauth->auids, 0);
@@ -370,7 +370,7 @@ believe it has restricted them to different identities or 
no identity at all.\
   authport = ports_get_right (firstauth);
   err = mach_port_insert_right (mach_task_self (), authport, authport,
                                MACH_MSG_TYPE_MAKE_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   ports_port_deref (firstauth);
 
   /* Stash our original auth port for later use.  */
diff --git a/utils/login.c b/utils/login.c
index 9ee296a..1a12c3c 100644
--- a/utils/login.c
+++ b/utils/login.c
@@ -30,7 +30,7 @@
 #include <grp.h>
 #include <netdb.h>
 #include <time.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <version.h>
 #include <sys/mman.h>
 
@@ -314,7 +314,7 @@ check_login (process_t proc_server, int lid)
   if (err == ESRCH)
     exit (42);                 /* Nothing left to watch. */
   else
-    assert_perror (err);
+    assert_perror_backtrace (err);
 
   if (owned)
     exit (0);                  /* Our task is done.  */
@@ -648,7 +648,7 @@ main(int argc, char *argv[])
   }
 
   err = proc_getsid (proc_server, pid, &sid);
-  assert_perror (err);         /* This should never fail.  */
+  assert_perror_backtrace (err);               /* This should never fail.  */
 
   if (!no_login
       && (parent_uids.num != 0
diff --git a/utils/ps.c b/utils/ps.c
index 2abb92a..f510323 100644
--- a/utils/ps.c
+++ b/utils/ps.c
@@ -21,7 +21,7 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index cb4df8a..0aecfc4 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -24,7 +24,7 @@
 #include <hurd/ports.h>
 #include <hurd/ihash.h>
 #include <mach/message.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -321,7 +321,7 @@ destroy_receiver_info (struct receiver_info *info)
   while (send_wrapper)
     {
       struct sender_info *next = send_wrapper->next;
-      assert (
+      assert_backtrace (
        refcounts_hard_references (&TRACED_INFO (send_wrapper)->pi.refcounts)
        == 1);
       /* Reset the receive_right of the send wrapper in advance to avoid
@@ -350,7 +350,7 @@ new_send_wrapper (struct receiver_info *receive, task_t 
task,
   /* Create a new wrapper port that forwards to *RIGHT.  */
   err = ports_create_port (traced_class, traced_bucket,
                           sizeof *info, &info);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   TRACED_INFO (info)->name = 0;
   asprintf (&TRACED_INFO (info)->name, "  %lu<--%lu(pid%d)", 
@@ -385,7 +385,7 @@ new_send_once_wrapper (mach_port_t right, mach_port_t 
*wrapper_right)
       /* Create a new wrapper port that forwards to *RIGHT.  */
       err = ports_create_port (traced_class, traced_bucket,
                               sizeof *info, &info);
-      assert_perror (err);
+      assert_perror_backtrace (err);
       TRACED_INFO (info)->name = 0;
     }
 
@@ -422,7 +422,7 @@ unlink_sender_info (void *pi)
       prev = &info->receive_right->next;
       while (*prev != info && *prev)
        prev = &((*prev)->next);
-      assert (*prev);
+      assert_backtrace (*prev);
       *prev = info->next;
 
       info->next = NULL;
@@ -437,7 +437,7 @@ traced_clean (void *pi)
 {
   struct sender_info *info = pi;
 
-  assert (TRACED_INFO (info)->type == MACH_MSG_TYPE_MOVE_SEND);
+  assert_backtrace (TRACED_INFO (info)->type == MACH_MSG_TYPE_MOVE_SEND);
   free (TRACED_INFO (info)->name);
 
   if (info->receive_right)
@@ -493,8 +493,8 @@ discover_receive_right (mach_port_t send, task_t task)
       && !(info->task != unknown_task
          && info->portname == UNKNOWN_NAME))
     return info;
-  
-    {
+
+  {
       int j;
       mach_port_t *portnames = NULL;
       mach_msg_type_number_t nportnames = 0;
@@ -558,7 +558,7 @@ discover_receive_right (mach_port_t send, task_t task)
 
       if (receiver_info)
        return receiver_info;
-    }
+  }
   return NULL;
 }
 
@@ -629,7 +629,7 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t 
*type,
          /* If the send right is moved to the task with the receive right,
           * copy the send right in 'forward' of receiver info to the 
destination.
           * Otherwise, copy the send right to the send wrapper. */
-         assert (send_wrapper->receive_right);
+         assert_backtrace (send_wrapper->receive_right);
          if (dest == send_wrapper->receive_right->task)
            {
              *right = send_wrapper->receive_right->forward;
@@ -678,7 +678,7 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t 
*type,
        return receiver_info->name;
       else
        {
-         assert (*right == receiver_info->forward);
+         assert_backtrace (*right == receiver_info->forward);
          mach_port_deallocate (mach_task_self (), *right);
          send_wrapper = get_send_wrapper (receiver_info, dest, right);
          *type = MACH_MSG_TYPE_MAKE_SEND;
@@ -703,7 +703,7 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t 
*type,
        * We wrap the receive right A in the send wrapper and move the receive
        * right B to the destination task.  */
       {
-       assert (req);
+       assert_backtrace (req);
        receiver_info = hurd_ihash_find (&traced_names, *right);
        if (receiver_info)
          {
@@ -740,7 +740,7 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t 
*type,
            hurd_ihash_locp_remove (&traced_names, receiver_info->locp);
 
            send_wrapper2 = get_send_wrapper (receiver_info, dest, &rr);
-           assert (
+           assert_backtrace (
              refcounts_hard_references (
                &TRACED_INFO (send_wrapper2)->pi.refcounts)
              == 1);
@@ -793,7 +793,7 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t 
*type,
       }
 
     default:
-      assert (!"??? bogus port type from kernel!");
+      assert_backtrace (!"??? bogus port type from kernel!");
     }
   return 0;
 }
@@ -860,8 +860,8 @@ print_contents (mach_msg_header_t *inp,
          mach_msg_type_name_t newtypes[nelt];
          int poly;
 
-         assert (inp->msgh_bits & MACH_MSGH_BITS_COMPLEX);
-         assert (eltsize == sizeof (mach_port_t));
+         assert_backtrace (inp->msgh_bits & MACH_MSGH_BITS_COMPLEX);
+         assert_backtrace (eltsize == sizeof (mach_port_t));
 
          poly = 0;
          for (i = 0; i < nelt; ++i)
@@ -904,10 +904,10 @@ print_contents (mach_msg_header_t *inp,
                                                      portnames[i],
                                                      portnames[i],
                                                      newtypes[i]);
-                       assert_perror (err);
+                       assert_perror_backtrace (err);
                      }
                    else
-                     assert (newtypes[i] == MACH_MSG_TYPE_MOVE_SEND_ONCE);
+                     assert_backtrace (newtypes[i] == 
MACH_MSG_TYPE_MOVE_SEND_ONCE);
                }
              else
                {
@@ -918,17 +918,17 @@ print_contents (mach_msg_header_t *inp,
                        err = mach_port_mod_refs (mach_task_self (),
                                                  portnames[i],
                                                  MACH_PORT_RIGHT_SEND, +1);
-                       assert_perror (err);
+                       assert_perror_backtrace (err);
                        break;
                      case MACH_MSG_TYPE_MAKE_SEND:
                        err = mach_port_insert_right (mach_task_self (),
                                                      portnames[i],
                                                      portnames[i],
                                                      newtypes[i]);
-                       assert_perror (err);
+                       assert_perror_backtrace (err);
                        break;
                      default:
-                       assert (newtypes[i] == MACH_MSG_TYPE_MOVE_SEND);
+                       assert_backtrace (newtypes[i] == 
MACH_MSG_TYPE_MOVE_SEND);
                        break;
                      }
 
@@ -1017,8 +1017,8 @@ wrap_new_thread (mach_msg_header_t *inp, struct req_info 
*req)
   struct sender_info *send_wrapper = ports_lookup_port (traced_bucket,
                                                        reply->child_thread, 0);
 
-  assert (send_wrapper);
-  assert (send_wrapper->receive_right);
+  assert_backtrace (send_wrapper);
+  assert_backtrace (send_wrapper->receive_right);
   thread_port = send_wrapper->receive_right->forward;
 
   err = mach_port_insert_right (mach_task_self (), reply->child_thread,
@@ -1058,8 +1058,8 @@ wrap_new_task (mach_msg_header_t *inp, struct req_info 
*req)
   /* The send wrapper for the new task itself. */
   struct sender_info *task_wrapper2;
 
-  assert (task_wrapper1);
-  assert (task_wrapper1->receive_right);
+  assert_backtrace (task_wrapper1);
+  assert_backtrace (task_wrapper1->receive_right);
 
   task_port = task_wrapper1->receive_right->forward;
   add_task (task_port);
@@ -1138,7 +1138,7 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
   else
     info = ports_lookup_port (traced_bucket, inp->msgh_local_port, NULL);
 
-  assert (info);
+  assert_backtrace (info);
 
   /* A notification message from the kernel appears to have been sent
      with a send-once right, even if there have never really been any.  */
@@ -1156,7 +1156,7 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
           * If not, we destroy it here. */
          if (receiver_info)
            {
-             assert (n->not_port == receiver_info->forward);
+             assert_backtrace (n->not_port == receiver_info->forward);
              destroy_receiver_info (receiver_info);
            }
 
@@ -1190,8 +1190,8 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
        }
     }
 
-  assert (info != (void *) notify_pi);
-  assert (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) == info->type);
+  assert_backtrace (info != (void *) notify_pi);
+  assert_backtrace (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) == info->type);
 
   complex = inp->msgh_bits & MACH_MSGH_BITS_COMPLEX;
 
@@ -1221,7 +1221,7 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
            info = new_send_once_wrapper (inp->msgh_local_port,
                                          &inp->msgh_local_port);
            reply_type = MACH_MSG_TYPE_MAKE_SEND_ONCE;
-           assert (inp->msgh_local_port);
+           assert_backtrace (inp->msgh_local_port);
 
            if (TRACED_INFO (info)->name == 0)
              {
@@ -1245,7 +1245,7 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
       inp->msgh_remote_port = SEND_ONCE_INFO (info)->forward;
     else
       {
-       assert (SEND_INFO (info)->receive_right);
+       assert_backtrace (SEND_INFO (info)->receive_right);
        inp->msgh_remote_port = SEND_INFO (info)->receive_right->forward;
       }
     if (this_type == MACH_MSG_TYPE_MOVE_SEND_ONCE)
@@ -1282,7 +1282,7 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
        {
          struct req_info *req = remove_request (inp->msgh_id - 100,
                                                 inp->msgh_remote_port);
-         assert (req);
+         assert_backtrace (req);
          req->is_req = FALSE;
          /* This sure looks like an RPC reply message.  */
          mig_reply_header_t *rh = (void *) inp;
@@ -1310,10 +1310,10 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
          /* It's a notification message. */
          if (inp->msgh_id <= 72 && inp->msgh_id >= 64)
            {
-             assert (info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE);
+             assert_backtrace (info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE);
              /* mach_notify_port_destroyed message has a port,
               * TODO how do I handle it? */
-             assert (inp->msgh_id != 69);
+             assert_backtrace (inp->msgh_id != 69);
            }
 
          /* If it's mach_port RPC,
@@ -1364,7 +1364,7 @@ trace_and_forward (mach_msg_header_t *inp, 
mach_msg_header_t *outp)
       mach_msg_destroy (inp);
     }
   else
-    assert_perror (err);
+    assert_perror_backtrace (err);
 
   ports_port_deref (info);
 
@@ -1502,7 +1502,7 @@ print_data (mach_msg_type_name_t type,
   switch (type)
     {
     case MACH_MSG_TYPE_PORT_NAME:
-      assert (eltsize == sizeof (mach_port_t));
+      assert_backtrace (eltsize == sizeof (mach_port_t));
       {
        mach_msg_type_number_t i;
        fprintf (ostream, "pn{");
@@ -1631,7 +1631,7 @@ traced_spawn (char **argv, char **envp)
                     NULL, 0,   /* OSF Mach */
 #endif
                     0, &traced_task);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   add_task (traced_task);
   /* Declare the new task to be our child.  This is what a fork does.  */
@@ -1654,9 +1654,9 @@ traced_spawn (char **argv, char **envp)
      own real task port.  */
   err = mach_port_insert_right (mach_task_self (), task_wrapper,
                                task_wrapper, MACH_MSG_TYPE_MAKE_SEND);
-  assert_perror (err);
+  assert_perror_backtrace (err);
   err = task_set_special_port (traced_task, TASK_KERNEL_PORT, task_wrapper);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* Now actually run the command they told us to trace.  We do the exec on
      the actual task, so the RPCs to map in the program itself do not get
@@ -1750,7 +1750,7 @@ main (int argc, char **argv, char **envp)
 
   err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_DEAD_NAME,
                            &unknown_task);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   if (outfile)
     {
@@ -1767,7 +1767,7 @@ main (int argc, char **argv, char **envp)
   other_class = ports_create_class (0, 0);
   err = ports_create_port (other_class, traced_bucket,
                           sizeof (*notify_pi), &notify_pi);
-  assert_perror (err);
+  assert_perror_backtrace (err);
 
   /* Spawn a single thread that will receive intercepted messages, print
      them, and interpose on the ports they carry.  The access to the
diff --git a/utils/settrans.c b/utils/settrans.c
index ee7cba5..9c9f087 100644
--- a/utils/settrans.c
+++ b/utils/settrans.c
@@ -18,7 +18,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <hurd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -450,7 +450,7 @@ main(int argc, char *argv[])
          if (MACH_PORT_VALID (executable))
            {
              err = mach_port_deallocate (mach_task_self (), executable);
-             assert_perror (err);
+             assert_perror_backtrace (err);
              if (prefixed_name)
                chroot_command[0] = prefixed_name;
            }
diff --git a/utils/shd.c b/utils/shd.c
index feff613..09a4790 100644
--- a/utils/shd.c
+++ b/utils/shd.c
@@ -19,7 +19,7 @@
 #include <hurd.h>
 #include <stdio.h>
 #include <string.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <device/device.h>
 #include <unistd.h>
 #include <errno.h>
@@ -230,7 +230,7 @@ main (int argc, char *argv[])
   size_t linebufsize = 0;
 
   proc = getproc ();
-  assert (proc);
+  assert_backtrace (proc);
 
 #if 0
   {
@@ -238,10 +238,10 @@ main (int argc, char *argv[])
     mach_port_t outp;
     mach_port_t hostp, masterd;
     err = proc_getprivports (proc, &hostp, &masterd);
-    assert (!err);
+    assert_backtrace (!err);
 
     err = device_open (masterd, D_WRITE|D_READ, "console", &outp);
-    assert (!err);
+    assert_backtrace (!err);
 
     stdin = mach_open_devstream (outp, "r");
     stdout = stderr = mach_open_devstream (outp, "w+");
diff --git a/utils/vmallocate.c b/utils/vmallocate.c
index 628cfd1..039b3097 100644
--- a/utils/vmallocate.c
+++ b/utils/vmallocate.c
@@ -18,7 +18,7 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <argp.h>
-#include <assert.h>
+#include <assert-backtrace.h>
 #include <error.h>
 #include <hurd.h>
 #include <inttypes.h>
@@ -161,7 +161,7 @@ main (int argc, char **argv)
   process_t proc = getproc ();
 
   /* We must make sure that chunk_size fits into vm_size_t.  */
-  assert (chunk_size <= 1U << (sizeof (vm_size_t) * 8 - 1));
+  assert_backtrace (chunk_size <= 1U << (sizeof (vm_size_t) * 8 - 1));
 
   /* Parse our arguments.  */
   argp_parse (&argp, argc, argv, 0, 0, 0);

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]