[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 01/05: New upstream snapshot
From: |
Samuel Thibault |
Subject: |
[hurd] 01/05: New upstream snapshot |
Date: |
Wed, 16 Nov 2016 08:30:24 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch master
in repository hurd.
commit dd66fe0952d00192e7750a2b8665dca95a5ac0ad
Author: Samuel Thibault <address@hidden>
Date: Tue Nov 15 20:12:16 2016 +0000
New upstream snapshot
---
Makefile | 4 +-
NEWS | 8 +
boot/Makefile | 30 +-
boot/boot.c | 702 ++++++++++++++++++++--------------
boot/frank1.ld | 94 -----
boot/frankemul.ld | 107 ------
boot/mach-crt0.c | 158 --------
proc/mig-mutate.h => boot/mig-decls.h | 24 +-
{proc => boot}/mig-mutate.h | 22 +-
boot/sigvec.S | 23 --
boot/syscall.S | 35 --
boot/userland-boot.c | 226 ++++++++++-
boot/ux.c | 303 ---------------
boot/ux.h | 114 ------
console/display.c | 15 +
eth-multiplexer/ChangeLog | 18 +-
eth-multiplexer/Makefile | 4 +-
eth-multiplexer/README | 2 +-
eth-multiplexer/demuxer.c | 2 +-
eth-multiplexer/dev_stat.c | 18 +-
eth-multiplexer/device_impl.c | 18 +-
eth-multiplexer/ethernet.c | 47 ++-
eth-multiplexer/ethernet.h | 6 +-
eth-multiplexer/multiplexer.c | 6 +-
eth-multiplexer/netfs_impl.c | 8 +-
eth-multiplexer/netfs_impl.h | 2 +-
eth-multiplexer/notify_impl.c | 2 +-
eth-multiplexer/test.c | 2 +-
eth-multiplexer/util.h | 16 +-
eth-multiplexer/vdev.c | 30 +-
eth-multiplexer/vdev.h | 5 +
ext2fs/ext2fs.c | 3 +
ext2fs/ext2fs.h | 4 +-
libbpf/Makefile | 4 +-
libbpf/bpf_impl.c | 32 +-
libbpf/bpf_impl.h | 22 +-
libbpf/queue.c | 12 +-
libbpf/util.h | 8 +-
libdiskfs/Makefile | 4 +-
libdiskfs/file-utimes.c | 3 +
libdiskfs/io-stubs.c | 8 +-
libdiskfs/node-lastref.c | 49 +++
libdiskfs/node-nput.c | 24 +-
libdiskfs/node-nrele.c | 12 +-
libdiskfs/priv.h | 4 +
libnetfs/fsstubs.c | 6 +-
libnetfs/fsysstubs.c | 10 +-
libnetfs/iostubs.c | 20 +-
libpager/data-unlock.c | 2 +-
libpager/stubs.c | 6 +-
libtreefs/xinl.c | 2 +
libtrivfs/fsys-stubs.c | 8 +-
libtrivfs/io-stubs.c | 18 +-
mach-defpager/main.c | 4 +-
proc/mgt.c | 12 +-
proc/mig-mutate.h | 9 +
startup/startup.c | 22 +-
utils/rpctrace.c | 2 +-
58 files changed, 974 insertions(+), 1387 deletions(-)
diff --git a/Makefile b/Makefile
index d48baaa..a9ad3f6 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,8 @@ include ./Makeconf
lib-subdirs = libshouldbeinlibc libihash libiohelp libports libthreads \
libpager libfshelp libdiskfs libtrivfs libps \
libnetfs libpipe libstore libhurdbugaddr libftpconn libcons \
- libhurd-slab
+ libhurd-slab \
+ libbpf \
# Hurd programs
prog-subdirs = auth proc exec term \
@@ -44,6 +45,7 @@ prog-subdirs = auth proc exec term \
startup \
init \
devnode \
+ eth-multiplexer \
ifeq ($(HAVE_SUN_RPC),yes)
prog-subdirs += nfs nfsd
diff --git a/NEWS b/NEWS
index e9c4cb5..d84ae33 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+Version 0.9 (2016-11-XX)
+
+The 'boot' program can now be run as unprivileged user, allowing any
+user to create unprivileged Subhurds.
+
+The Berkeley Packet Filter library and the ethernet multiplexer have
+been merged into this repository.
+
Version 0.8 (2016-05-18)
The netfs library is using the lockless reference-counting primitives
diff --git a/boot/Makefile b/boot/Makefile
index c877295..ac40044 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -22,31 +22,13 @@ SRCS = mach-crt0.c boot.c ux.c sigvec.S syscall.S \
boot_script.c userland-boot.c
COMMON-OBJS = notifyServer.o deviceServer.o \
ioServer.o io_replyUser.o device_replyUser.o \
- termServer.o bootstrapServer.o boot_script.o userland-boot.o
-OBJS = boot.o $(COMMON-OBJS)
-UX-OBJS = mach-crt0.o uxboot.o sigvec.o syscall.o ux.o $(COMMON-OBJS)
+ termServer.o boot_script.o userland-boot.o
+MIGSTUBS = machServer.o mach_hostServer.o gnumachServer.o task_notifyServer.o
+OBJS = boot.o $(COMMON-OBJS) $(MIGSTUBS)
target = boot
-io-MIGSFLAGS=-DREPLY_PORTS
-HURDLIBS = store shouldbeinlibc
+MIGSFLAGS=-imacros $(srcdir)/mig-mutate.h -DHURD_DEFAULT_PAYLOAD_TO_PORT=1
+io-MIGSFLAGS=-DREPLY_PORTS -DHURD_DEFAULT_PAYLOAD_TO_PORT=1
+HURDLIBS = store shouldbeinlibc ihash
LDLIBS += -lpthread
include ../Makeconf
-
-#install: /usr/local/bin/uxboot
-#
-#/usr/local/bin/uxboot: uxboot
-# cp $< $@
-
-MIGSFLAGS = -DHURD_DEFAULT_PAYLOAD_TO_PORT=1
-
-all: boot # uxboot
-
-uxboot.o: boot.c
- $(COMPILE.c) -DUX $< -o $@
-
-uxboot.0: $(UX-OBJS)
- $(LINK.o) -o $@ -static -nostartfiles -Wl,-T -Wl,$(srcdir)/frank1.ld $^
-uxboot.1: frankemul.ld uxboot.0
- $(LD) -o $@ -T $^
-uxboot: uxboot.1
- -$(OBJCOPY) -S --remove-section=.comment -O a.out-mach3 $< $@
diff --git a/boot/boot.c b/boot/boot.c
index 02af068..d0e0207 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -1,6 +1,6 @@
/* Load a task using the single server, and then run it
as if we were the kernel.
- Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,2006
+ Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,2006,14,16
Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -24,20 +24,20 @@
#include <mach.h>
#include <mach/notify.h>
#include <device/device.h>
-#include <a.out.h>
#include <mach/message.h>
#include <mach/mig_errors.h>
+#include <mach/task_notify.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
-#include <elf.h>
#include <mach/mig_support.h>
#include <mach/default_pager.h>
-#include <mach/machine/vm_param.h> /* For VM_XXX_ADDRESS */
#include <argp.h>
#include <hurd/store.h>
+#include <hurd/ihash.h>
+#include <sys/reboot.h>
#include <sys/mman.h>
#include <version.h>
@@ -49,23 +49,15 @@
#include "term_S.h"
#include "bootstrap_S.h"
/* #include "tioctl_S.h" */
+#include "mach_S.h"
+#include "mach_host_S.h"
+#include "gnumach_S.h"
+#include "task_notify_S.h"
#include "boot_script.h"
#include <hurd/auth.h>
-#ifdef UX
-#undef STORE /* We can't use libstore when under UX. */
-#else
-#define STORE
-#endif
-
-#ifdef UX
-
-#include "ux.h"
-
-#else /* !UX */
-
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
@@ -76,6 +68,14 @@
#include <hurd.h>
#include <assert.h>
+/* We support two modes of operation. Traditionally, Subhurds were
+ privileged, i.e. they had the privileged kernel ports. This has a
+ few drawbacks. Privileged subhurds can manipulate all tasks on the
+ system and halt the system. Nowadays we allow an unprivileged
+ mode. */
+static int privileged;
+static int want_privileged;
+
static struct termios orig_tty_state;
static int isig;
static char *kernel_command_line;
@@ -105,14 +105,23 @@ restore_termstate ()
#define host_fstat fstat
typedef struct stat host_stat_t;
-#define host_exit exit
-#endif /* UX */
+void __attribute__ ((__noreturn__))
+host_exit (int status)
+{
+ restore_termstate ();
+ exit (status);
+}
mach_port_t privileged_host_port, master_device_port;
+mach_port_t pseudo_privileged_host_port;
mach_port_t pseudo_master_device_port;
mach_port_t receive_set;
mach_port_t pseudo_console, pseudo_root, pseudo_time;
+mach_port_t pseudo_pset;
+task_t pseudo_kernel;
+mach_port_t task_notification_port;
+mach_port_t dead_task_notification_port;
auth_t authserver;
struct store *root_store;
@@ -145,29 +154,7 @@ void safe_gets (char *buf, int buf_len)
fgets (buf, buf_len, stdin);
}
-char *useropen_dir;
-
-int
-useropen (const char *name, int flags, int mode)
-{
- if (useropen_dir)
- {
- static int dlen;
- if (!dlen) dlen = strlen (useropen_dir);
- {
- int len = strlen (name);
- char try[dlen + 1 + len + 1];
- int fd;
- memcpy (try, useropen_dir, dlen);
- try[dlen] = '/';
- memcpy (&try[dlen + 1], name, len + 1);
- fd = open (try, flags, mode);
- if (fd >= 0)
- return fd;
- }
- }
- return open (name, flags, mode);
-}
+extern char *useropen_dir;
/* XXX: glibc should provide mig_reply_setup but does not. */
/* Fill in default response. */
@@ -210,7 +197,11 @@ boot_demuxer (mach_msg_header_t *inp,
if ((routine = io_server_routine (inp)) ||
(routine = device_server_routine (inp)) ||
(routine = notify_server_routine (inp)) ||
- (routine = term_server_routine (inp))
+ (routine = term_server_routine (inp)) ||
+ (routine = mach_server_routine (inp)) ||
+ (routine = mach_host_server_routine (inp)) ||
+ (routine = gnumach_server_routine (inp)) ||
+ (routine = task_notify_server_routine (inp))
/* (routine = tioctl_server_routine (inp)) */)
{
(*routine) (inp, outp);
@@ -220,189 +211,19 @@ boot_demuxer (mach_msg_header_t *inp,
return FALSE;
}
-vm_address_t
-load_image (task_t t,
- char *file)
-{
- int fd;
- union
- {
- struct exec a;
- Elf32_Ehdr e;
- } hdr;
- char msg[] = ": cannot open bootstrap file\n";
-
- fd = useropen (file, O_RDONLY, 0);
-
- if (fd == -1)
- {
- write (2, file, strlen (file));
- write (2, msg, sizeof msg - 1);
- task_terminate (t);
- host_exit (1);
- }
-
- read (fd, &hdr, sizeof hdr);
- /* File must have magic ELF number. */
- if (hdr.e.e_ident[0] == 0177 && hdr.e.e_ident[1] == 'E' &&
- hdr.e.e_ident[2] == 'L' && hdr.e.e_ident[3] == 'F')
- {
- Elf32_Phdr phdrs[hdr.e.e_phnum], *ph;
- lseek (fd, hdr.e.e_phoff, SEEK_SET);
- read (fd, phdrs, sizeof phdrs);
- for (ph = phdrs; ph < &phdrs[sizeof phdrs/sizeof phdrs[0]]; ++ph)
- if (ph->p_type == PT_LOAD)
- {
- vm_address_t buf;
- vm_size_t offs = ph->p_offset & (ph->p_align - 1);
- vm_size_t bufsz = round_page (ph->p_filesz + offs);
-
- buf = (vm_address_t) mmap (0, bufsz,
- PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
-
- lseek (fd, ph->p_offset, SEEK_SET);
- read (fd, (void *)(buf + offs), ph->p_filesz);
-
- ph->p_memsz = ((ph->p_vaddr + ph->p_memsz + ph->p_align - 1)
- & ~(ph->p_align - 1));
- ph->p_vaddr &= ~(ph->p_align - 1);
- ph->p_memsz -= ph->p_vaddr;
-
- vm_allocate (t, (vm_address_t*)&ph->p_vaddr, ph->p_memsz, 0);
- vm_write (t, ph->p_vaddr, buf, bufsz);
- munmap ((caddr_t) buf, bufsz);
- vm_protect (t, ph->p_vaddr, ph->p_memsz, 0,
- ((ph->p_flags & PF_R) ? VM_PROT_READ : 0) |
- ((ph->p_flags & PF_W) ? VM_PROT_WRITE : 0) |
- ((ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0));
- }
- return hdr.e.e_entry;
- }
- else
- {
- /* a.out */
- int magic = N_MAGIC (hdr.a);
- int headercruft;
- vm_address_t base = 0x10000;
- int rndamount, amount;
- vm_address_t bsspagestart, bssstart;
- char *buf;
-
- headercruft = sizeof (struct exec) * (magic == ZMAGIC);
-
- amount = headercruft + hdr.a.a_text + hdr.a.a_data;
- rndamount = round_page (amount);
- buf = mmap (0, rndamount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
- lseek (fd, sizeof hdr.a - headercruft, SEEK_SET);
- read (fd, buf, amount);
- vm_allocate (t, &base, rndamount, 0);
- vm_write (t, base, (vm_address_t) buf, rndamount);
- if (magic != OMAGIC)
- vm_protect (t, base, trunc_page (headercruft + hdr.a.a_text),
- 0, VM_PROT_READ | VM_PROT_EXECUTE);
- munmap ((caddr_t) buf, rndamount);
-
- bssstart = base + hdr.a.a_text + hdr.a.a_data + headercruft;
- bsspagestart = round_page (bssstart);
- vm_allocate (t, &bsspagestart,
- hdr.a.a_bss - (bsspagestart - bssstart), 0);
-
- return hdr.a.a_entry;
- }
-}
-
-
void read_reply ();
void * msg_thread (void *);
-/* Callbacks for boot_script.c; see boot_script.h. */
-int
-boot_script_exec_cmd (void *hook,
- mach_port_t task, char *path, int argc,
- char **argv, char *strings, int stringlen)
-{
- char *args, *p;
- int arg_len, i;
- size_t reg_size;
- void *arg_pos;
- vm_offset_t stack_start, stack_end;
- vm_address_t startpc, str_start;
- thread_t thread;
-
- write (2, path, strlen (path));
- for (i = 1; i < argc; ++i)
- {
- write (2, " ", 1);
- write (2, argv[i], strlen (argv[i]));
- }
- write (2, "\r\n", 2);
-
- startpc = load_image (task, path);
- arg_len = stringlen + (argc + 2) * sizeof (char *) + sizeof (integer_t);
- arg_len += 5 * sizeof (int);
- stack_end = VM_MAX_ADDRESS;
- stack_start = VM_MAX_ADDRESS - 16 * 1024 * 1024;
- vm_allocate (task, &stack_start, stack_end - stack_start, FALSE);
- arg_pos = (void *) ((stack_end - arg_len) & ~(sizeof (natural_t) - 1));
- args = mmap (0, stack_end - trunc_page ((vm_offset_t) arg_pos),
- PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
- str_start = ((vm_address_t) arg_pos
- + (argc + 2) * sizeof (char *) + sizeof (integer_t));
- p = args + ((vm_address_t) arg_pos & (vm_page_size - 1));
- *(int *) p = argc;
- p = (void *) p + sizeof (int);
- for (i = 0; i < argc; i++)
- {
- *(char **) p = argv[i] - strings + (char *) str_start;
- p = (void *) p + sizeof (char *);
- }
- *(char **) p = 0;
- p = (void *) p + sizeof (char *);
- *(char **) p = 0;
- p = (void *) p + sizeof (char *);
- memcpy (p, strings, stringlen);
- memset (args, 0, (vm_offset_t)arg_pos & (vm_page_size - 1));
- vm_write (task, trunc_page ((vm_offset_t) arg_pos), (vm_address_t) args,
- stack_end - trunc_page ((vm_offset_t) arg_pos));
- munmap ((caddr_t) args,
- stack_end - trunc_page ((vm_offset_t) arg_pos));
-
- thread_create (task, &thread);
-#ifdef i386_THREAD_STATE_COUNT
- {
- struct i386_thread_state regs;
- reg_size = i386_THREAD_STATE_COUNT;
- thread_get_state (thread, i386_THREAD_STATE,
- (thread_state_t) ®s, ®_size);
- regs.eip = (int) startpc;
- regs.uesp = (int) arg_pos;
- thread_set_state (thread, i386_THREAD_STATE,
- (thread_state_t) ®s, reg_size);
- }
-#elif defined(ALPHA_THREAD_STATE_COUNT)
- {
- struct alpha_thread_state regs;
- reg_size = ALPHA_THREAD_STATE_COUNT;
- thread_get_state (thread, ALPHA_THREAD_STATE,
- (thread_state_t) ®s, ®_size);
- regs.r30 = (natural_t) arg_pos;
- regs.pc = (natural_t) startpc;
- thread_set_state (thread, ALPHA_THREAD_STATE,
- (thread_state_t) ®s, reg_size);
- }
-#else
-# error needs to be ported
-#endif
-
- thread_resume (thread);
- mach_port_deallocate (mach_task_self (), thread);
- return 0;
-}
-
const char *argp_program_version = STANDARD_HURD_VERSION (boot);
+#define OPT_PRIVILEGED -1
+#define OPT_BOOT_SCRIPT -2
+
static struct argp_option options[] =
{
+ { NULL, 0, NULL, 0, "Boot options:" },
+ { "boot-script", OPT_BOOT_SCRIPT, "BOOT-SCRIPT", 0,
+ "boot script to execute" },
{ "boot-root", 'D', "DIR", 0,
"Root of a directory tree in which to find files specified in BOOT-SCRIPT"
},
{ "single-user", 's', 0, 0,
@@ -412,32 +233,46 @@ static struct argp_option options[] =
{ "pause" , 'd', 0, 0,
"Pause for user confirmation at various times during booting" },
{ "isig", 'I', 0, 0,
- "Do not disable terminal signals, so you can suspend and interrupt boot."},
- { "device", 'f', "device_name=device_file", 0,
- "Specify a device file used by subhurd and its virtual name."},
+ "Do not disable terminal signals, so you can suspend and interrupt boot"},
+ { "device", 'f', "SUBHURD_NAME=DEVICE_FILE", 0,
+ "Pass the given DEVICE_FILE to the Subhurd as device SUBHURD_NAME"},
+ { "privileged", OPT_PRIVILEGED, NULL, 0,
+ "Allow the subhurd to access privileged kernel ports"},
{ 0 }
};
-static char args_doc[] = "BOOT-SCRIPT";
static char doc[] = "Boot a second hurd";
-struct dev_map
+
+
+/* Device pass through. */
+
+struct dev_map
{
- char *name;
- mach_port_t port;
+ char *device_name; /* The name of the device in the Subhurd. */
+ char *file_name; /* The filename outside the Subhurd. */
struct dev_map *next;
};
static struct dev_map *dev_map_head;
-static struct dev_map *add_dev_map (char *dev_name, char *dev_file)
+static struct dev_map *
+add_dev_map (const char *dev_name, const char *dev_file)
{
- struct dev_map *map = malloc (sizeof (*map));
+ file_t node;
+ struct dev_map *map;
+
+ /* See if we can open the file. */
+ node = file_name_lookup (dev_file, 0, 0);
+ if (! MACH_PORT_VALID (node))
+ error (1, errno, "%s", dev_file);
+ mach_port_deallocate (mach_task_self (), node);
- assert (map);
- map->name = dev_name;
- map->port = file_name_lookup (dev_file, 0, 0);
- if (map->port == MACH_PORT_NULL)
- error (1, errno, "file_name_lookup: %s", dev_file);
+ map = malloc (sizeof *map);
+ if (map == NULL)
+ return NULL;
+
+ map->device_name = strdup (dev_name);
+ map->file_name = strdup (dev_file);
map->next = dev_map_head;
dev_map_head = map;
return map;
@@ -449,7 +284,7 @@ static struct dev_map *lookup_dev (char *dev_name)
for (map = dev_map_head; map; map = map->next)
{
- if (strcmp (map->name, dev_name) == 0)
+ if (strcmp (map->device_name, dev_name) == 0)
return map;
}
return NULL;
@@ -486,13 +321,17 @@ parse_opt (int key, char *arg, struct argp_state *state)
add_dev_map (arg, dev_file+1);
break;
- case ARGP_KEY_ARG:
- if (state->arg_num == 0)
- bootscript = arg;
- else
- return ARGP_ERR_UNKNOWN;
+ case OPT_PRIVILEGED:
+ want_privileged = 1;
+ break;
+
+ case OPT_BOOT_SCRIPT:
+ bootscript = arg;
break;
+ case ARGP_KEY_ARG:
+ return ARGP_ERR_UNKNOWN;
+
case ARGP_KEY_INIT:
state->child_inputs[0] = state->input; break;
@@ -502,17 +341,142 @@ parse_opt (int key, char *arg, struct argp_state *state)
return 0;
}
+static error_t
+allocate_pseudo_ports (void)
+{
+ mach_port_t old;
+
+ /* Allocate a port that we hand out as the privileged host port. */
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_privileged_host_port);
+ mach_port_insert_right (mach_task_self (),
+ pseudo_privileged_host_port,
+ pseudo_privileged_host_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ mach_port_move_member (mach_task_self (), pseudo_privileged_host_port,
+ receive_set);
+ mach_port_request_notification (mach_task_self (),
+ pseudo_privileged_host_port,
+ MACH_NOTIFY_NO_SENDERS, 1,
+ pseudo_privileged_host_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &old);
+ assert (old == MACH_PORT_NULL);
+
+ /* Allocate a port that we hand out as the privileged processor set
+ port. */
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_pset);
+ mach_port_move_member (mach_task_self (), pseudo_pset,
+ receive_set);
+ /* Make one send right that we copy when handing it out. */
+ mach_port_insert_right (mach_task_self (),
+ pseudo_pset,
+ pseudo_pset,
+ MACH_MSG_TYPE_MAKE_SEND);
+
+ /* We will receive new task notifications on this port. */
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &task_notification_port);
+ mach_port_move_member (mach_task_self (), task_notification_port,
+ receive_set);
+
+ /* And information about dying tasks here. */
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &dead_task_notification_port);
+ mach_port_move_member (mach_task_self (), dead_task_notification_port,
+ receive_set);
+
+ return 0;
+}
+
+void
+read_boot_script (char **buffer, size_t *length)
+{
+ char *p, *buf;
+ static const char filemsg[] = "Can't open boot script\n";
+ static const char memmsg[] = "Not enough memory\n";
+ int i, fd;
+ size_t amt, len;
+
+ fd = open (bootscript, O_RDONLY, 0);
+ if (fd < 0)
+ {
+ write (2, filemsg, sizeof (filemsg));
+ host_exit (1);
+ }
+ p = buf = malloc (500);
+ if (!buf)
+ {
+ write (2, memmsg, sizeof (memmsg));
+ host_exit (1);
+ }
+ len = 500;
+ amt = 0;
+ while (1)
+ {
+ i = read (fd, p, len - (p - buf));
+ if (i <= 0)
+ break;
+ p += i;
+ amt += i;
+ if (p == buf + len)
+ {
+ char *newbuf;
+
+ len += 500;
+ newbuf = realloc (buf, len);
+ if (!newbuf)
+ {
+ write (2, memmsg, sizeof (memmsg));
+ host_exit (1);
+ }
+ p = newbuf + (p - buf);
+ buf = newbuf;
+ }
+ }
+
+ close (fd);
+ *buffer = buf;
+ *length = amt;
+}
+
+
+/* Boot script file for booting contemporary GNU Hurd systems. Each
+ line specifies a file to be loaded by the boot loader (the first
+ word), and actions to be done with it. */
+const char *default_boot_script =
+ /* First, the bootstrap filesystem. It needs several ports as
+ arguments, as well as the user flags from the boot loader. */
+ "/hurd/ext2fs.static"
+ " --readonly"
+ " --multiboot-command-line=${kernel-command-line}"
+ " --host-priv-port=${host-port}"
+ " --device-master-port=${device-port}"
+ " --exec-server-task=${exec-task}"
+ " -T device ${root-device} $(task-create) $(task-resume)"
+ "\n"
+
+ /* Now the exec server; to load the dynamically-linked exec server
+ program, we have the boot loader in fact load and run ld.so,
+ which in turn loads and runs /hurd/exec. This task is created,
+ and its task port saved in ${exec-task} to be passed to the fs
+ above, but it is left suspended; the fs will resume the exec task
+ once it is ready. */
+ "/lib/ld.so /hurd/exec $(exec-task=task-create)"
+ "\n";
+
+
int
main (int argc, char **argv, char **envp)
{
error_t err;
mach_port_t foo;
char *buf = 0;
- int i, len;
pthread_t pthread_id;
char *root_store_name;
- const struct argp_child kids[] = { { &store_argp }, { 0 }};
- struct argp argp = { options, parse_opt, args_doc, doc, kids };
+ const struct argp_child kids[] = { { &store_argp, 0, "Store options:", -2 },
+ { 0 }};
+ struct argp argp = { options, parse_opt, NULL, doc, kids };
struct store_argp_params store_argp_params = { 0 };
argp_parse (&argp, argc, argv, 0, 0, &store_argp_params);
@@ -524,16 +488,26 @@ main (int argc, char **argv, char **envp)
if (err)
error (4, err, "%s", root_store_name);
- get_privileged_ports (&privileged_host_port, &master_device_port);
+ if (want_privileged)
+ {
+ get_privileged_ports (&privileged_host_port, &master_device_port);
+ privileged = MACH_PORT_VALID (master_device_port);
+
+ if (! privileged)
+ error (1, 0, "Must be run as root for privileged subhurds");
+ }
- strcat (bootstrap_args, "f");
+ if (privileged)
+ strcat (bootstrap_args, "f");
mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
&receive_set);
if (root_store->class == &store_device_class && root_store->name
&& (root_store->flags & STORE_ENFORCED)
- && root_store->num_runs == 1 && root_store->runs[0].start == 0)
+ && root_store->num_runs == 1
+ && root_store->runs[0].start == 0
+ && privileged)
/* Let known device nodes pass through directly. */
bootdevice = root_store->name;
else
@@ -578,13 +552,33 @@ main (int argc, char **argv, char **envp)
if (foo != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), foo);
+ if (! privileged)
+ {
+ err = allocate_pseudo_ports ();
+ if (err)
+ error (1, err, "Allocating pseudo ports");
+
+ /* Create a new task namespace for us. */
+ err = proc_make_task_namespace (getproc (), task_notification_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ if (err)
+ error (1, err, "proc_make_task_namespace");
+
+ /* Create an empty task that the subhurds can freely frobnicate. */
+ err = task_create (mach_task_self (), 0, &pseudo_kernel);
+ if (err)
+ error (1, err, "task_create");
+ }
+
if (kernel_command_line == 0)
asprintf (&kernel_command_line, "%s %s root=%s",
argv[0], bootstrap_args, bootdevice);
/* Initialize boot script variables. */
if (boot_script_set_variable ("host-port", VAL_PORT,
- (int) privileged_host_port)
+ privileged
+ ? (int) privileged_host_port
+ : (int) pseudo_privileged_host_port)
|| boot_script_set_variable ("device-port", VAL_PORT,
(integer_t) pseudo_master_device_port)
|| boot_script_set_variable ("kernel-command-line", VAL_STR,
@@ -630,46 +624,12 @@ main (int argc, char **argv, char **envp)
/* Parse the boot script. */
{
char *p, *line;
- static const char filemsg[] = "Can't open boot script\n";
- static const char memmsg[] = "Not enough memory\n";
- int amt, fd, err;
+ size_t amt;
+ if (bootscript)
+ read_boot_script (&buf, &amt);
+ else
+ buf = strdup (default_boot_script), amt = strlen (default_boot_script);
- fd = open (bootscript, O_RDONLY, 0);
- if (fd < 0)
- {
- write (2, filemsg, sizeof (filemsg));
- host_exit (1);
- }
- p = buf = malloc (500);
- if (!buf)
- {
- write (2, memmsg, sizeof (memmsg));
- host_exit (1);
- }
- len = 500;
- amt = 0;
- while (1)
- {
- i = read (fd, p, len - (p - buf));
- if (i <= 0)
- break;
- p += i;
- amt += i;
- if (p == buf + len)
- {
- char *newbuf;
-
- len += 500;
- newbuf = realloc (buf, len);
- if (!newbuf)
- {
- write (2, memmsg, sizeof (memmsg));
- host_exit (1);
- }
- p = newbuf + (p - buf);
- buf = newbuf;
- }
- }
line = p = buf;
while (1)
{
@@ -709,8 +669,6 @@ main (int argc, char **argv, char **envp)
/* The boot script has now been parsed into internal data structures.
Now execute its directives. */
{
- int err;
-
err = boot_script_exec ();
if (err)
{
@@ -954,8 +912,17 @@ ds_device_open (mach_port_t master_port,
map = lookup_dev (name);
if (map)
{
+ error_t err;
+ file_t node;
+
+ node = file_name_lookup (map->file_name, 0, 0);
+ if (! MACH_PORT_VALID (node))
+ return D_NO_SUCH_DEVICE;
+
*devicetype = MACH_MSG_TYPE_MOVE_SEND;
- return device_open (map->port, mode, "", device);
+ err = device_open (node, mode, "", device);
+ mach_port_deallocate (mach_task_self (), node);
+ return err;
}
*devicetype = MACH_MSG_TYPE_MOVE_SEND;
@@ -1324,6 +1291,8 @@ do_mach_notify_send_once (mach_port_t notify)
return EOPNOTSUPP;
}
+static void task_died (mach_port_t name);
+
kern_return_t
do_mach_notify_dead_name (mach_port_t notify,
mach_port_t name)
@@ -1332,7 +1301,11 @@ do_mach_notify_dead_name (mach_port_t notify,
if (name == child_task && notify == bootport)
host_exit (0);
#endif
- return EOPNOTSUPP;
+ if (notify != dead_task_notification_port)
+ return EOPNOTSUPP;
+ task_died (name);
+ mach_port_deallocate (mach_task_self (), name);
+ return 0;
}
@@ -1598,6 +1571,8 @@ S_io_reauthenticate (mach_port_t object,
size_t gulen = 0, aulen = 0, gglen = 0, aglen = 0;
error_t err;
+ /* XXX: This cannot possibly work, authserver is 0. */
+
err = mach_port_insert_right (mach_task_self (), object, object,
MACH_MSG_TYPE_MAKE_SEND);
assert_perror (err);
@@ -1890,3 +1865,154 @@ kern_return_t S_term_on_pty
io_t *ptymaster
)
{ return EOPNOTSUPP; }
+
+/* Mach host emulation. */
+
+kern_return_t
+S_vm_set_default_memory_manager (mach_port_t host_priv,
+ mach_port_t *default_manager)
+{
+ if (host_priv != pseudo_privileged_host_port)
+ return KERN_INVALID_HOST;
+
+ if (*default_manager != MACH_PORT_NULL)
+ return KERN_INVALID_ARGUMENT;
+
+ *default_manager = MACH_PORT_NULL;
+ return KERN_SUCCESS;
+}
+
+kern_return_t
+S_host_reboot (mach_port_t host_priv,
+ int flags)
+{
+ fprintf (stderr, "Would %s the system. Bye.\n",
+ flags & RB_HALT? "halt": "reboot");
+ host_exit (0);
+}
+
+
+kern_return_t
+S_host_processor_set_priv (mach_port_t host_priv,
+ mach_port_t set_name,
+ mach_port_t *set)
+{
+ if (host_priv != pseudo_privileged_host_port)
+ return KERN_INVALID_HOST;
+
+ *set = pseudo_pset;
+ return KERN_SUCCESS;
+}
+
+mach_port_t new_task_notification;
+
+kern_return_t
+S_register_new_task_notification (mach_port_t host_priv,
+ mach_port_t notification)
+{
+ if (host_priv != pseudo_privileged_host_port)
+ return KERN_INVALID_HOST;
+
+ if (! MACH_PORT_VALID (notification))
+ return KERN_INVALID_ARGUMENT;
+
+ if (MACH_PORT_VALID (new_task_notification))
+ return KERN_NO_ACCESS;
+
+ new_task_notification = notification;
+ return KERN_SUCCESS;
+}
+
+
+/* Managing tasks. */
+
+static void
+task_ihash_cleanup (hurd_ihash_value_t value, void *cookie)
+{
+ (void) cookie;
+ mach_port_deallocate (mach_task_self (), (mach_port_t) value);
+}
+
+static struct hurd_ihash task_ihash =
+ HURD_IHASH_INITIALIZER_GKI (HURD_IHASH_NO_LOCP, task_ihash_cleanup, NULL,
+ NULL, NULL);
+
+static void
+task_died (mach_port_t name)
+{
+ hurd_ihash_remove (&task_ihash, (hurd_ihash_key_t) name);
+}
+
+/* Handle new task notifications from proc. */
+error_t
+S_mach_notify_new_task (mach_port_t notify,
+ mach_port_t task,
+ mach_port_t parent)
+{
+ error_t err;
+ mach_port_t previous;
+
+ if (notify != task_notification_port)
+ return EOPNOTSUPP;
+
+ err = mach_port_request_notification (mach_task_self (), task,
+ MACH_NOTIFY_DEAD_NAME, 0,
+ dead_task_notification_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &previous);
+ if (err)
+ goto fail;
+ assert (! MACH_PORT_VALID (previous));
+
+ mach_port_mod_refs (mach_task_self (), task, MACH_PORT_RIGHT_SEND, +1);
+ err = hurd_ihash_add (&task_ihash,
+ (hurd_ihash_key_t) task, (hurd_ihash_value_t) task);
+ if (err)
+ {
+ mach_port_deallocate (mach_task_self (), task);
+ goto fail;
+ }
+
+ if (MACH_PORT_VALID (new_task_notification))
+ /* Relay the notification. This consumes task and parent. */
+ return mach_notify_new_task (new_task_notification, task, parent);
+
+ mach_port_deallocate (mach_task_self (), task);
+ mach_port_deallocate (mach_task_self (), parent);
+ return 0;
+
+ fail:
+ task_terminate (task);
+ return err;
+}
+
+kern_return_t
+S_processor_set_tasks(mach_port_t processor_set,
+ task_array_t *task_list,
+ mach_msg_type_number_t *task_listCnt)
+{
+ error_t err;
+ size_t i;
+
+ err = vm_allocate (mach_task_self (), (vm_address_t *) task_list,
+ task_ihash.nr_items * sizeof **task_list, 1);
+ if (err)
+ return err;
+
+ /* The first task has to be the kernel. */
+ (*task_list)[0] = pseudo_kernel;
+
+ i = 1;
+ HURD_IHASH_ITERATE (&task_ihash, value)
+ {
+ task_t task = (task_t) value;
+ if (task == pseudo_kernel)
+ continue;
+
+ (*task_list)[i] = task;
+ i += 1;
+ }
+
+ *task_listCnt = task_ihash.nr_items;
+ return 0;
+}
diff --git a/boot/frank1.ld b/boot/frank1.ld
deleted file mode 100644
index 9de827a..0000000
--- a/boot/frank1.ld
+++ /dev/null
@@ -1,94 +0,0 @@
-OUTPUT_FORMAT("elf32-i386", "elf32-i386",
- "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(_start)
- SEARCH_DIR(/usr/local/i386-gnuelf/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x10020;
- .text :
- {
- *(.text)
- *(.interp)
- *(.hash)
- *(.dynsym)
- *(.dynstr)
- *(.rel.text)
- *(.rela.text)
- *(.rel.data)
- *(.rela.data)
- *(.rel.rodata)
- *(.rela.rodata)
- *(.rel.got)
- *(.rela.got)
- *(.rel.ctors)
- *(.rela.ctors)
- *(.rel.dtors)
- *(.rela.dtors)
- *(.rel.init)
- *(.rela.init)
- *(.rel.fini)
- *(.rela.fini)
- *(.rel.bss)
- *(.rela.bss)
- *(.rel.plt)
- *(.rela.plt)
- *(.init)
- *(.plt)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.fini)
- *(.rodata)
- *(.rodata1)
- _etext = .;
- PROVIDE (etext = .);
- . = ALIGN(0x1000);
- } =0x9090
- . = ALIGN(0x1000);
- .data :
- {
- *(.data)
- CONSTRUCTORS
-
- *(.data1)
- *(.ctors)
- *(.dtors)
- *(.got.plt) *(.got)
- *(.dynamic)
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- *(.sdata)
- _edata = .;
- PROVIDE (edata = .);
- . = ALIGN(0x10);
-}
- __bss_start = .;
- .bss :
- {
- *(.sbss) *(.scommon)
- *(.dynbss)
- *(.bss)
- *(COMMON)
- _end = ALIGN(4) ;
- PROVIDE (end = ALIGN(4));
- }
- /* These are needed for ELF backends which have not yet been
- converted to the new style linker. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- /* DWARF debug sections.
- Symbols in the .debug DWARF section are relative to the beginning of the
- section so we begin .debug at 0. It's not clear yet what needs to happen
- for the others. */
- .debug 0 : { *(.debug) }
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- .line 0 : { *(.line) }
- /* These must appear regardless of . */
-}
diff --git a/boot/frankemul.ld b/boot/frankemul.ld
deleted file mode 100644
index 413953e..0000000
--- a/boot/frankemul.ld
+++ /dev/null
@@ -1,107 +0,0 @@
-OUTPUT_FORMAT("elf32-i386", "elf32-i386",
- "elf32-i386")
-OUTPUT_ARCH(i386)
-ENTRY(_start)
- SEARCH_DIR(/usr/local/i386-gnuelf/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x10020;
- .text :
- {
- *(.text)
- *(.interp)
- *(.hash)
- *(.dynsym)
- *(.dynstr)
- *(.rel.text)
- *(.rela.text)
- *(.rel.data)
- *(.rela.data)
- *(.rel.rodata)
- *(.rela.rodata)
- *(.rel.got)
- *(.rela.got)
- *(.rel.ctors)
- *(.rela.ctors)
- *(.rel.dtors)
- *(.rela.dtors)
- *(.rel.init)
- *(.rela.init)
- *(.rel.fini)
- *(.rela.fini)
- *(.rel.bss)
- *(.rela.bss)
- *(.rel.plt)
- *(.rela.plt)
- *(.init)
- *(.plt)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.fini)
- *(.rodata)
- *(.rodata1)
-*(_hurd_ioctl_handler_lists)
-*(_hurd_pgrp_changed_hook)
-*(_hurd_fork_locks)
-*(_hurd_subinit)
-*(__libc_atexit)
-*(_hurd_fd_subinit)
-*(_hurd_preinit_hook)
-*(_hurd_fork_child_hook)
-*(_hurd_fork_parent_hook)
-*(_hurd_fork_prepare_hook)
-*(_hurd_reauth_hook)
-*(_hurd_proc_subinit)
-*(__libc_subinit)
- _etext = .;
- PROVIDE (etext = .);
- . = ALIGN(0x1000);
- } =0x9090
- . = ALIGN(0x1000);
- .data :
- {
- *(.data)
- CONSTRUCTORS
-
- *(.data1)
- *(.ctors)
- *(.dtors)
- *(.got.plt) *(.got)
- *(.dynamic)
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- *(.sdata)
- _edata = .;
- PROVIDE (edata = .);
- . = ALIGN(0x10);
-}
- __bss_start = .;
- .bss :
- {
- *(.sbss) *(.scommon)
- *(.dynbss)
- *(.bss)
- *(COMMON)
- _end = ALIGN(4) ;
- PROVIDE (end = ALIGN(4));
- }
- /* These are needed for ELF backends which have not yet been
- converted to the new style linker. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- /* DWARF debug sections.
- Symbols in the .debug DWARF section are relative to the beginning of the
- section so we begin .debug at 0. It's not clear yet what needs to happen
- for the others. */
- .debug 0 : { *(.debug) }
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- .line 0 : { *(.line) }
- /* These must appear regardless of . */
-}
diff --git a/boot/mach-crt0.c b/boot/mach-crt0.c
deleted file mode 100644
index 0469424..0000000
--- a/boot/mach-crt0.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or address@hidden
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement: ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)crt0.c 5.2 (Berkeley) 5/14/90";
-#endif /* not lint */
-
-/*
- * C start up routine.
- * Robert Henry, UCB, 20 Oct 81
- *
- * We make the following (true) assumptions:
- * 1) when the kernel calls start, it does a jump to location 2,
- * and thus avoids the register save mask. We are NOT called
- * with a calls! see sys1.c:setregs().
- * 2) The only register variable that we can trust is sp,
- * which points to the base of the kernel calling frame.
- * Do NOT believe the documentation in exec(2) regarding the
- * values of fp and ap.
- * 3) We can allocate as many register variables as we want,
- * and don't have to save them for anybody.
- * 4) Because of the ways that asm's work, we can't have
- * any automatic variables allocated on the stack, because
- * we must catch the value of sp before any automatics are
- * allocated.
- */
-
-#include <mach/machine/asm.h>
-
-int __data_start = 0;
-char **environ = (char **)0;
-#ifdef paranoid
-static int fd;
-#endif paranoid
-
-int (*mach_init_routine)();
-int (*_cthread_init_routine)();
-int (*_cthread_exit_routine)();
-int (*_monstartup_routine)();
-int (*_StrongBox_init_routine)();
-int errno = 0;
-int exit();
-
-extern int main();
-
-extern unsigned char etext;
-int _start()
-{
- __label__ eprol;
- struct kframe {
- int kargc;
- char *kargv[1]; /* size depends on kargc */
- char kargstr[1]; /* size varies */
- char kenvstr[1]; /* size varies */
- };
- /*
- * ALL REGISTER VARIABLES!!!
- */
- register struct kframe *kfp; /* r10 */
- register char **targv;
- register char **argv;
-
-#ifdef lint
- kfp = 0;
- initcode = initcode = 0;
-#else not lint
-#define Entry_sp() \
-({ int _spl__, _tmp1__; \
- asm volatile("leal 4(%%ebp), %0" : "=r" (_spl__) : "r" (_tmp1__)); \
- _spl__; })
-
- kfp = (struct kframe *)Entry_sp();
-#endif not lint
- for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
- /* void */ ;
- if (targv >= (char **)(*argv))
- --targv;
- environ = targv;
- if (mach_init_routine)
- (void) mach_init_routine();
-
- eprol:
-#ifdef paranoid
- /*
- * The standard I/O library assumes that file descriptors 0, 1, and 2
- * are open. If one of these descriptors is closed prior to the start
- * of the process, I/O gets very confused. To avoid this problem, we
- * insure that the first three file descriptors are open before calling
- * main(). Normally this is undefined, as it adds two unnecessary
- * system calls.
- */
- do {
- fd = open("/dev/null", 2);
- } while (fd >= 0 && fd < 3);
- close(fd);
-#endif paranoid
-
-
- if (_cthread_init_routine) {
- int new_sp;
- new_sp = (*_cthread_init_routine)();
- if (new_sp) {
- asm volatile("movl %0, %%esp" : : "g" (new_sp) );
- }
- }
- if (_StrongBox_init_routine) (*_StrongBox_init_routine)();
-
- if (_monstartup_routine) {
- _monstartup_routine(&&eprol, &etext);
- }
-
- (* (_cthread_exit_routine ? _cthread_exit_routine : exit))
- (main(kfp->kargc, argv, targv));
-}
diff --git a/proc/mig-mutate.h b/boot/mig-decls.h
similarity index 57%
copy from proc/mig-mutate.h
copy to boot/mig-decls.h
index 62dc2a5..d539659 100644
--- a/proc/mig-mutate.h
+++ b/boot/mig-decls.h
@@ -17,21 +17,11 @@
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/>. */
+#ifndef __BOOT_MIG_DECLS_H__
+#define __BOOT_MIG_DECLS_H__
-#define PROCESS_INTRAN \
- pstruct_t begin_using_proc_port (process_t)
-#define PROCESS_INTRAN_PAYLOAD \
- pstruct_t begin_using_proc_payload
-#define PROCESS_DESTRUCTOR \
- end_using_proc (pstruct_t)
-#define PROCESS_IMPORTS \
- import "mig-decls.h";
-
-#define NOTIFY_INTRAN \
- port_info_t begin_using_port_info_port (mach_port_t)
-#define NOTIFY_INTRAN_PAYLOAD \
- port_info_t begin_using_port_info_payload
-#define NOTIFY_DESTRUCTOR \
- end_using_port_info (port_info_t)
-#define NOTIFY_IMPORTS \
- import "libports/mig-decls.h";
+#include <hurd.h>
+
+#define MIG_EOPNOTSUPP EOPNOTSUPP
+
+#endif /* __BOOT_MIG_DECLS_H__ */
diff --git a/proc/mig-mutate.h b/boot/mig-mutate.h
similarity index 59%
copy from proc/mig-mutate.h
copy to boot/mig-mutate.h
index 62dc2a5..ef90b73 100644
--- a/proc/mig-mutate.h
+++ b/boot/mig-mutate.h
@@ -17,21 +17,9 @@
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/>. */
-
-#define PROCESS_INTRAN \
- pstruct_t begin_using_proc_port (process_t)
-#define PROCESS_INTRAN_PAYLOAD \
- pstruct_t begin_using_proc_payload
-#define PROCESS_DESTRUCTOR \
- end_using_proc (pstruct_t)
-#define PROCESS_IMPORTS \
+#define MACH_IMPORTS \
+ import "mig-decls.h";
+#define MACH_HOST_IMPORTS \
+ import "mig-decls.h";
+#define GNUMACH_IMPORTS \
import "mig-decls.h";
-
-#define NOTIFY_INTRAN \
- port_info_t begin_using_port_info_port (mach_port_t)
-#define NOTIFY_INTRAN_PAYLOAD \
- port_info_t begin_using_port_info_payload
-#define NOTIFY_DESTRUCTOR \
- end_using_port_info (port_info_t)
-#define NOTIFY_IMPORTS \
- import "libports/mig-decls.h";
diff --git a/boot/sigvec.S b/boot/sigvec.S
deleted file mode 100644
index cc7bb94..0000000
--- a/boot/sigvec.S
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <i386/asm.h>
-
-.text
-ENTRY(sigreturn)
- movl $0x67,%eax
- lcall $0x7,$0x0
- jb error
- ret
-ENTRY(_sigreturn)
- addl $0xc,%esp
- call EXT(sigreturn)
- ret
-ENTRY(sigvec)
- movl $0x6c,%eax
- movl $EXT(_sigreturn),%edx
- orl $0x80000000,%edx
- lcall $0x7,$0x0
- jb error
- ret
-error:
- movl %eax,EXT(errno)
- movl $-1,%eax
- ret
diff --git a/boot/syscall.S b/boot/syscall.S
deleted file mode 100644
index a04ab28..0000000
--- a/boot/syscall.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Temporary....
- Copyright (C) 1993, 1995 Free Software Foundation
-
-This file is part of the GNU Hurd.
-
-The GNU Hurd 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.
-
-The GNU Hurd 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 the GNU Hurd; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <i386/asm.h>
-
-/* .globl EXT(errno)*/
-.text
-ENTRY(syscall)
- pop %ecx
- pop %eax
- push %ecx
- lcall $7, $0
- push %ecx /* Restore stack position. */
- jb error
- ret
-error:
- movl %eax,EXT(errno)
- movl $-1,%eax
- ret
diff --git a/boot/userland-boot.c b/boot/userland-boot.c
index d048c00..583078f 100644
--- a/boot/userland-boot.c
+++ b/boot/userland-boot.c
@@ -17,11 +17,19 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <a.out.h>
+#include <elf.h>
+#include <fcntl.h>
#include <mach.h>
+#include <mach/machine/vm_param.h> /* For VM_XXX_ADDRESS */
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
#include <errno.h>
#include <error.h>
+
#include "boot_script.h"
void *
@@ -90,14 +98,23 @@ boot_script_free_task (task_t task, int aborting)
int
boot_script_insert_right (struct cmd *cmd, mach_port_t port, mach_port_t *name)
{
- error_t err = mach_port_insert_right (cmd->task,
- port, port, MACH_MSG_TYPE_COPY_SEND);
+ error_t err;
+
+ *name = MACH_PORT_NULL;
+ do
+ {
+ *name += 1;
+ err = mach_port_insert_right (cmd->task,
+ *name, port, MACH_MSG_TYPE_COPY_SEND);
+ }
+ while (err == KERN_NAME_EXISTS);
+
if (err)
{
error (0, err, "%s: mach_port_insert_right", cmd->path);
return BOOT_SCRIPT_MACH_ERROR;
}
- *name = port;
+
return 0;
}
@@ -106,3 +123,206 @@ boot_script_insert_task_port (struct cmd *cmd, task_t
task, mach_port_t *name)
{
return boot_script_insert_right (cmd, task, name);
}
+
+char *useropen_dir;
+
+static int
+useropen (const char *name, int flags, int mode)
+{
+ if (useropen_dir)
+ {
+ static int dlen;
+ if (!dlen) dlen = strlen (useropen_dir);
+ {
+ int len = strlen (name);
+ char try[dlen + 1 + len + 1];
+ int fd;
+ memcpy (try, useropen_dir, dlen);
+ try[dlen] = '/';
+ memcpy (&try[dlen + 1], name, len + 1);
+ fd = open (try, flags, mode);
+ if (fd >= 0)
+ return fd;
+ }
+ }
+ return open (name, flags, mode);
+}
+
+static vm_address_t
+load_image (task_t t,
+ char *file)
+{
+ int fd;
+ union
+ {
+ struct exec a;
+ Elf32_Ehdr e;
+ } hdr;
+ char msg[] = ": cannot open bootstrap file\n";
+
+ fd = useropen (file, O_RDONLY, 0);
+
+ if (fd == -1)
+ {
+ write (2, file, strlen (file));
+ write (2, msg, sizeof msg - 1);
+ task_terminate (t);
+ exit (1);
+ }
+
+ read (fd, &hdr, sizeof hdr);
+ /* File must have magic ELF number. */
+ if (hdr.e.e_ident[0] == 0177 && hdr.e.e_ident[1] == 'E' &&
+ hdr.e.e_ident[2] == 'L' && hdr.e.e_ident[3] == 'F')
+ {
+ Elf32_Phdr phdrs[hdr.e.e_phnum], *ph;
+ lseek (fd, hdr.e.e_phoff, SEEK_SET);
+ read (fd, phdrs, sizeof phdrs);
+ for (ph = phdrs; ph < &phdrs[sizeof phdrs/sizeof phdrs[0]]; ++ph)
+ if (ph->p_type == PT_LOAD)
+ {
+ vm_address_t buf;
+ vm_size_t offs = ph->p_offset & (ph->p_align - 1);
+ vm_size_t bufsz = round_page (ph->p_filesz + offs);
+
+ buf = (vm_address_t) mmap (0, bufsz,
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+
+ lseek (fd, ph->p_offset, SEEK_SET);
+ read (fd, (void *)(buf + offs), ph->p_filesz);
+
+ ph->p_memsz = ((ph->p_vaddr + ph->p_memsz + ph->p_align - 1)
+ & ~(ph->p_align - 1));
+ ph->p_vaddr &= ~(ph->p_align - 1);
+ ph->p_memsz -= ph->p_vaddr;
+
+ vm_allocate (t, (vm_address_t*)&ph->p_vaddr, ph->p_memsz, 0);
+ vm_write (t, ph->p_vaddr, buf, bufsz);
+ munmap ((caddr_t) buf, bufsz);
+ vm_protect (t, ph->p_vaddr, ph->p_memsz, 0,
+ ((ph->p_flags & PF_R) ? VM_PROT_READ : 0) |
+ ((ph->p_flags & PF_W) ? VM_PROT_WRITE : 0) |
+ ((ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0));
+ }
+ return hdr.e.e_entry;
+ }
+ else
+ {
+ /* a.out */
+ int magic = N_MAGIC (hdr.a);
+ int headercruft;
+ vm_address_t base = 0x10000;
+ int rndamount, amount;
+ vm_address_t bsspagestart, bssstart;
+ char *buf;
+
+ headercruft = sizeof (struct exec) * (magic == ZMAGIC);
+
+ amount = headercruft + hdr.a.a_text + hdr.a.a_data;
+ rndamount = round_page (amount);
+ buf = mmap (0, rndamount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ lseek (fd, sizeof hdr.a - headercruft, SEEK_SET);
+ read (fd, buf, amount);
+ vm_allocate (t, &base, rndamount, 0);
+ vm_write (t, base, (vm_address_t) buf, rndamount);
+ if (magic != OMAGIC)
+ vm_protect (t, base, trunc_page (headercruft + hdr.a.a_text),
+ 0, VM_PROT_READ | VM_PROT_EXECUTE);
+ munmap ((caddr_t) buf, rndamount);
+
+ bssstart = base + hdr.a.a_text + hdr.a.a_data + headercruft;
+ bsspagestart = round_page (bssstart);
+ vm_allocate (t, &bsspagestart,
+ hdr.a.a_bss - (bsspagestart - bssstart), 0);
+
+ return hdr.a.a_entry;
+ }
+}
+
+int
+boot_script_exec_cmd (void *hook,
+ mach_port_t task, char *path, int argc,
+ char **argv, char *strings, int stringlen)
+{
+ char *args, *p;
+ int arg_len, i;
+ size_t reg_size;
+ void *arg_pos;
+ vm_offset_t stack_start, stack_end;
+ vm_address_t startpc, str_start;
+ thread_t thread;
+
+ write (2, path, strlen (path));
+ for (i = 1; i < argc; ++i)
+ {
+ int quote = !! index (argv[i], ' ') || !! index (argv[i], '\t');
+ write (2, " ", 1);
+ if (quote)
+ write (2, "\"", 1);
+ write (2, argv[i], strlen (argv[i]));
+ if (quote)
+ write (2, "\"", 1);
+ }
+ write (2, "\r\n", 2);
+
+ startpc = load_image (task, path);
+ arg_len = stringlen + (argc + 2) * sizeof (char *) + sizeof (integer_t);
+ arg_len += 5 * sizeof (int);
+ stack_end = VM_MAX_ADDRESS;
+ stack_start = VM_MAX_ADDRESS - 16 * 1024 * 1024;
+ vm_allocate (task, &stack_start, stack_end - stack_start, FALSE);
+ arg_pos = (void *) ((stack_end - arg_len) & ~(sizeof (natural_t) - 1));
+ args = mmap (0, stack_end - trunc_page ((vm_offset_t) arg_pos),
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ str_start = ((vm_address_t) arg_pos
+ + (argc + 2) * sizeof (char *) + sizeof (integer_t));
+ p = args + ((vm_address_t) arg_pos & (vm_page_size - 1));
+ *(int *) p = argc;
+ p = (void *) p + sizeof (int);
+ for (i = 0; i < argc; i++)
+ {
+ *(char **) p = argv[i] - strings + (char *) str_start;
+ p = (void *) p + sizeof (char *);
+ }
+ *(char **) p = 0;
+ p = (void *) p + sizeof (char *);
+ *(char **) p = 0;
+ p = (void *) p + sizeof (char *);
+ memcpy (p, strings, stringlen);
+ memset (args, 0, (vm_offset_t)arg_pos & (vm_page_size - 1));
+ vm_write (task, trunc_page ((vm_offset_t) arg_pos), (vm_address_t) args,
+ stack_end - trunc_page ((vm_offset_t) arg_pos));
+ munmap ((caddr_t) args,
+ stack_end - trunc_page ((vm_offset_t) arg_pos));
+
+ thread_create (task, &thread);
+#ifdef i386_THREAD_STATE_COUNT
+ {
+ struct i386_thread_state regs;
+ reg_size = i386_THREAD_STATE_COUNT;
+ thread_get_state (thread, i386_THREAD_STATE,
+ (thread_state_t) ®s, ®_size);
+ regs.eip = (int) startpc;
+ regs.uesp = (int) arg_pos;
+ thread_set_state (thread, i386_THREAD_STATE,
+ (thread_state_t) ®s, reg_size);
+ }
+#elif defined(ALPHA_THREAD_STATE_COUNT)
+ {
+ struct alpha_thread_state regs;
+ reg_size = ALPHA_THREAD_STATE_COUNT;
+ thread_get_state (thread, ALPHA_THREAD_STATE,
+ (thread_state_t) ®s, ®_size);
+ regs.r30 = (natural_t) arg_pos;
+ regs.pc = (natural_t) startpc;
+ thread_set_state (thread, ALPHA_THREAD_STATE,
+ (thread_state_t) ®s, reg_size);
+ }
+#else
+# error needs to be ported
+#endif
+
+ thread_resume (thread);
+ mach_port_deallocate (mach_task_self (), thread);
+ return 0;
+}
diff --git a/boot/ux.c b/boot/ux.c
deleted file mode 100644
index 7239762..0000000
--- a/boot/ux.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/* Hacks to make boot work under UX
-
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd 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.
-
- The GNU Hurd 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 the GNU Hurd; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <mach.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <pthread.h>
-
-#include "ux.h"
-
-#if 0
-static int (* const _sc)(int, ...) = &syscall;
-int _sc_print = 1;
-
-#define syscall(num, args...) \
- ({ int _rv, _num = (num), _pr = _sc_print; \
- _sc_print = 0; \
- if (_pr) printf ("syscall (%d) start\r\n", _num); \
- _rv = (*_sc) (_num , ##args); \
- if (_pr) printf ("syscall (%d) end\r\n", _num); \
- _sc_print = _pr; \
- _rv; \
- })
-#endif
-
-extern void __mach_init ();
-void (*mach_init_routine)() = __mach_init;
-
-/* These will prevent the Hurd-ish versions from being used */
-
-struct free_reply_port
-{
- mach_port_t port;
- struct free_reply_port *next;
-};
-static struct free_reply_port *free_reply_ports = NULL;
-static pthread_spinlock_t free_reply_ports_lock = PTHREAD_SPINLOCK_INITIALIZER;
-
-mach_port_t __mig_get_reply_port ()
-{
- pthread_spin_lock (&free_reply_ports_lock);
- if (free_reply_ports == NULL)
- {
- pthread_spin_unlock (&free_reply_ports_lock);
- return __mach_reply_port ();
- }
- else
- {
- struct free_reply_port *frp = free_reply_ports;
- mach_port_t reply_port = frp->port;
- free_reply_ports = free_reply_ports->next;
- pthread_spin_unlock (&free_reply_ports_lock);
- free (frp);
- return reply_port;
- }
-}
-mach_port_t mig_get_reply_port ()
-{
- return __mig_get_reply_port ();
-}
-void __mig_put_reply_port (mach_port_t port)
-{
- struct free_reply_port *frp = malloc (sizeof (struct free_reply_port));
- frp->port = port;
- pthread_spin_lock (&free_reply_ports_lock);
- frp->next = free_reply_ports;
- free_reply_ports = frp;
- pthread_spin_unlock (&free_reply_ports_lock);
-}
-void mig_put_reply_port (mach_port_t port)
-{
- __mig_put_reply_port (port);
-}
-void __mig_dealloc_reply_port (mach_port_t port)
-{
- mach_port_mod_refs (__mach_task_self (), port,
- MACH_PORT_RIGHT_RECEIVE, -1);
-}
-void mig_dealloc_reply_port (mach_port_t port)
-{
- __mig_dealloc_reply_port (port);
-}
-void __mig_init (void *stack) {}
-void mig_init (void *stack) {}
-
-int
-task_by_pid (int pid)
-{
- return syscall (-33, pid);
-}
-
-int
-write (int fd,
- const void *buf,
- int buflen)
-{
- return syscall (4, fd, buf, buflen);
-}
-
-int
-read (int fd,
- void *buf,
- int buflen)
-{
- return syscall (3, fd, buf, buflen);
-}
-
-int
-open (const char *name,
- int flags,
- int mode)
-{
- return syscall (5, name, flags, mode);
-}
-
-int
-uxfstat (int fd, struct uxstat *buf)
-{
- return syscall (62, fd, buf);
-}
-
-int
-close (int fd)
-{
- return syscall (6, fd);
-}
-
-int
-lseek (int fd,
- int off,
- int whence)
-{
- return syscall (19, fd, off, whence);
-}
-
-int
-uxexit (int code)
-{
- return syscall (1, code);
-}
-
-int
-getpid ()
-{
- return syscall (20);
-}
-
-int
-ioctl (int fd, int code, void *buf)
-{
- return syscall (54, fd, code, buf);
-}
-
-int
-sigblock (int mask)
-{
- return syscall (109, mask);
-}
-
-int
-sigsetmask (int mask)
-{
- return syscall (110, mask);
-}
-
-int
-sigpause (int mask)
-{
- return syscall (111, mask);
-}
-
-
-#if 0
-void
-sigreturn ()
-{
- asm volatile ("movl $0x67,%eax\n"
- "lcall $0x7, $0x0\n"
- "ret");
-}
-
-void
-_sigreturn ()
-{
- asm volatile ("addl $0xc, %%esp\n"
- "call %0\n"
- "ret"::"m" (sigreturn));
-}
-
-int
-sigvec (int sig, struct sigvec *vec, struct sigvec *ovec)
-{
- asm volatile ("movl $0x6c,%%eax\n"
- "movl %0, %%edx\n"
- "orl $0x80000000, %%edx\n"
- "lcall $0x7,$0x0\n"
- "ret"::"g" (_sigreturn));
-}
-#else
-int sigvec ();
-#endif
-
-void get_privileged_ports (mach_port_t *host_port, mach_port_t *device_port)
-{
- *host_port = task_by_pid (-1);
- *device_port = task_by_pid (-2);
-}
-
-/* A *really* stupid printf that only understands %s & %d. */
-int
-printf (const char *fmt, ...)
-{
- va_list ap;
- const char *p = fmt, *q = p;
-
- void flush (const char *new)
- {
- if (p > q)
- write (1, q, p - q);
- q = p = new;
- }
-
- va_start (ap, fmt);
- while (*p)
- if (*p == '%' && p[1] == 's')
- {
- char *str = va_arg (ap, char *);
- flush (p + 2);
- write (1, str, strlen (str));
- }
- else if (*p == '%' && p[1] == 'd')
- {
- int i = va_arg (ap, int);
- char rbuf[20], *e = rbuf + sizeof (rbuf), *b = e;
-
- if (i == 0)
- *--b = '0';
- else
- while (i)
- {
- *--b = i % 10 + '0';
- i /= 10;
- }
-
- flush (p + 2);
- write (1, b, e - b);
- }
- else
- p++;
- va_end (ap);
-
- flush (0);
-
- return 0;
-}
-
-static struct sgttyb term_sgb;
-static int localbits;
-
-void
-init_termstate ()
-{
- struct sgttyb sgb;
- int bits;
- ioctl (0, TIOCGETP, &term_sgb);
- ioctl (0, TIOCLGET, &localbits);
- /* Enter raw made. Rather than try and interpret these bits,
- we just do what emacs does in .../emacs/src/sysdep.c for
- an old style terminal driver. */
- bits = localbits | LDECCTQ | LLITOUT | LPASS8 | LNOFLSH;
- ioctl (0, TIOCLSET, &bits);
- sgb = term_sgb;
- sgb.sg_flags &= ~ECHO;
- sgb.sg_flags |= RAW | ANYP;
- ioctl (0, TIOCSETN, &sgb);
-}
-
-void
-restore_termstate ()
-{
- ioctl (0, TIOCLSET, &localbits);
- ioctl (0, TIOCSETN, &term_sgb);
-}
diff --git a/boot/ux.h b/boot/ux.h
deleted file mode 100644
index d3787c5..0000000
--- a/boot/ux.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Hacks to make boot work under UX
-
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd 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.
-
- The GNU Hurd 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 the GNU Hurd; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#define sigmask(m) (1 << ((m)-1))
-
-#define IOCPARM_MASK 0x7f
-#define IOC_OUT 0x40000000
-#define IOC_IN 0x80000000
-#define _IOR(x,y,t) (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
-#define _IOW(x,y,t) (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
-#define FIONREAD _IOR('f', 127, int)
-#define FIOASYNC _IOW('f', 125, int)
-#define TIOCGETP _IOR('t', 8, struct sgttyb)
-#define TIOCLGET _IOR('t', 124, int)
-#define TIOCLSET _IOW('t', 125, int)
-#define TIOCSETN _IOW('t', 10, struct sgttyb)
-#define LDECCTQ 0x4000
-#define LLITOUT 0x0020
-#define LPASS8 0x0800
-#define LNOFLSH 0x8000
-#define RAW 0x0020
-#define ANYP 0x00c0
-#define ECHO 8
-
-
-struct sgttyb
-{
- char unused[4];
- short sg_flags;
-};
-
-#define SIGIO 23
-
-struct sigvec
-{
- void (*sv_handler)();
- int sv_mask;
- int sv_flags;
-};
-
-struct uxstat
- {
- short int st_dev; /* Device containing the file. */
- __ino_t st_ino; /* File serial number. */
- unsigned short int st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
- unsigned short int st_uid; /* User ID of the file's owner. */
- unsigned short int st_gid; /* Group ID of the file's group.*/
- short int st_rdev; /* Device number, if device. */
- __off_t st_size; /* Size of file, in bytes. */
- __time_t st_atime; /* Time of last access. */
- unsigned long int st_atime_usec;
- __time_t st_mtime; /* Time of last modification. */
- unsigned long int st_mtime_usec;
- __time_t st_ctime; /* Time of last status change. */
- unsigned long int st_ctime_usec;
- unsigned long int st_blksize; /* Optimal block size for I/O. */
- unsigned long int st_blocks; /* Number of 512-byte blocks allocated. */
- long int st_spare[2];
- };
-
-void get_privileged_ports (mach_port_t *host_port, mach_port_t *device_port);
-
-/* We can't include <unistd.h> for this, because that will fight witho
- our definitions of syscalls below. */
-int syscall (int, ...);
-
-int open (const char *name, int flags, int mode);
-int write (int fd, const void *buf, int len);
-int read (int fd, void *buf, int len);
-int uxfstat (int fd, struct uxstat *buf);
-int close (int fd);
-int lseek (int fd, int off, int whence);
-int uxexit (int code);
-int getpid ();
-int ioctl (int fd, int code, void *buf);
-int sigblock (int mask);
-int sigsetmask (int mask);
-int sigpause (int mask);
-int sigvec (int sig, struct sigvec *vec, struct sigvec *ovec);
-
-#undef O_RDONLY
-#undef O_WRONLY
-#undef O_RDWR
-#define O_RDONLY 0
-#define O_WRONLY 1
-#define O_RDWR 2
-
-#define host_exit(c) uxexit(c)
-
-typedef struct uxstat host_stat_t;
-#define host_fstat(fd, st) uxfstat (fd, st)
-
-void init_stdio ();
-
-#undef errno
-int errno;
diff --git a/console/display.c b/console/display.c
index 98c70f5..ed5571e 100644
--- a/console/display.c
+++ b/console/display.c
@@ -814,6 +814,21 @@ user_create (display_t display, uint32_t width, uint32_t
height,
user->cursor.status = CONS_CURSOR_NORMAL;
conchar_memset (user->_matrix, chr, attr,
user->screen.width * user->screen.lines);
+
+ /* FIXME: it seems we don't properly handle getting paged out.
+ * For now, just wire the pages to work around the issue. */
+ {
+ mach_port_t host;
+
+ error_t err = get_privileged_ports (&host, NULL);
+ if (err)
+ host = mach_host_self ();
+
+ vm_wire (host, mach_task_self (), (vm_offset_t) user,
+ (vm_size_t) npages * vm_page_size, VM_PROT_READ);
+ if (host != mach_host_self ())
+ mach_port_deallocate (mach_task_self (), host);
+ }
return 0;
}
diff --git a/eth-multiplexer/ChangeLog b/eth-multiplexer/ChangeLog
index 3737118..88eebaa 100644
--- a/eth-multiplexer/ChangeLog
+++ b/eth-multiplexer/ChangeLog
@@ -52,7 +52,7 @@
2008-12-12 Zheng Da <address@hidden>
* multiplexer.c (main): Initialize the file status of the root node.
-
+
* netfs_impl.c (netfs_validate_stat): Set the file status of the node
with the one in the light node.
@@ -71,7 +71,7 @@
(remove_dead_port_from_dev): Use lock.
(broadcast_pack, broadcast_msg): Use foreach_dev_do.
- * vdev.h (dev_num): Remove declaration.
+ * vdev.h (dev_num): Remove declaration.
(get_dev_num): Add declaration.
2008-11-13 Zheng Da <address@hidden>
@@ -100,7 +100,7 @@
(SRCS): Add new C files.
(LCLHDRS): Add new H files.
(HURDLIBS): Change libraries.
-
+
* demuxer.c: New file.
* device_impl.c: New file.
@@ -128,7 +128,7 @@
* README: Update.
* bpf_impl.c (destroy_filters): New function.
-
+
* multiplexer.c (nb_dev): Deleted.
(options): Remove the option '-v'.
(do_mach_notify_no_senders): Remove all port_info in the same way.
@@ -140,13 +140,13 @@
(main): Remove the code of creating virtual devices.
* util.h (ETH_P_IP): New macro.
-
+
* vdev.c (all_dev_close): Deleted.
(add_vdev): Link virtual device.
(destroy_vdev): New function.
* vdev.h (vether_device): Changed.
-
+
2008-10-03 Zheng Da <address@hidden>
@@ -274,10 +274,10 @@
* multiplexer.c (options): Change the meaning of '-v' option.
(parse_opt): Change the way of handling '-v' option.
-
+
* vdev.c (has_vdev): New function.
- * vdev.h (has_vdev): New declaration.
+ * vdev.h (has_vdev): New declaration.
2008-8-17 Zheng Da <address@hidden>
@@ -306,7 +306,7 @@
* vdev.c (all_dev_close): Change the way of testing if all devices are
closed.
-
+
* vdev.h (vether_device): Replace count field with used.
2008-8-13 Zheng Da <address@hidden>
diff --git a/eth-multiplexer/Makefile b/eth-multiplexer/Makefile
index 159f385..07f909e 100644
--- a/eth-multiplexer/Makefile
+++ b/eth-multiplexer/Makefile
@@ -26,8 +26,8 @@ MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
LCLHDRS = ethernet.h util.h vdev.h netfs_impl.h
-HURDLIBS = ihash iohelp ports fshelp shouldbeinlibc netfs bpf
-LDLIBS += -lpthread
+HURDLIBS = ports ihash fshelp shouldbeinlibc netfs bpf
+LDLIBS = -lpthread
CFLAGS += -I$(top_srcdir)/libbpf
diff --git a/eth-multiplexer/README b/eth-multiplexer/README
index 0024a93..940c7e4 100644
--- a/eth-multiplexer/README
+++ b/eth-multiplexer/README
@@ -1,6 +1,6 @@
[Introduction]
-eth-multiplexer is a network multiplexer. It creates virtual ethernet
interface and dispatches the packet to the right user program that opens its
virtual interface. It also works as a bridge to connect the real ethernet
interface and the virtual ones.
+eth-multiplexer is a network multiplexer. It creates virtual ethernet
interface and dispatches the packet to the right user program that opens its
virtual interface. It also works as a bridge to connect the real ethernet
interface and the virtual ones.
[Usage]
diff --git a/eth-multiplexer/demuxer.c b/eth-multiplexer/demuxer.c
index 68bf968..1efbc6d 100644
--- a/eth-multiplexer/demuxer.c
+++ b/eth-multiplexer/demuxer.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 1996, 2013 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
diff --git a/eth-multiplexer/dev_stat.c b/eth-multiplexer/dev_stat.c
index 43c68d6..bfbb433 100644
--- a/eth-multiplexer/dev_stat.c
+++ b/eth-multiplexer/dev_stat.c
@@ -1,25 +1,25 @@
- /*
+ /*
* Mach Operating System
* Copyright (c) 1993-1989 Carnegie Mellon University
* All Rights Reserved.
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
+ *
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or address@hidden
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
@@ -29,8 +29,8 @@
*
* Network IO.
*
- * Packet filter code taken from vaxif/enet.c written
- * CMU and Stanford.
+ * Packet filter code taken from vaxif/enet.c written
+ * CMU and Stanford.
*/
/* the code copied from device/net_io.c in Mach */
@@ -81,7 +81,7 @@ dev_getstat(struct vether_device *ifp, dev_flavor_t flavor,
memcpy(status, ifp->if_address,
addr_byte_count);
if (addr_byte_count < addr_int_count *
sizeof(int))
- memset((char *)status +
addr_byte_count, 0,
+ memset((char *)status +
addr_byte_count, 0,
(addr_int_count *
sizeof(int)
- addr_byte_count));
diff --git a/eth-multiplexer/device_impl.c b/eth-multiplexer/device_impl.c
index b15a009..4796d5b 100644
--- a/eth-multiplexer/device_impl.c
+++ b/eth-multiplexer/device_impl.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008 Free Software Foundation, Inc.
Written by Zheng Da.
@@ -47,7 +47,7 @@ extern struct port_info *notify_pi;
kern_return_t
ds_device_open (mach_port_t master_port, mach_port_t reply_port,
mach_msg_type_name_t reply_portPoly,
- dev_mode_t mode, dev_name_t name, mach_port_t *device,
+ dev_mode_t mode, dev_name_t name, mach_port_t *device,
mach_msg_type_name_t *devicetype)
{
struct vether_device *dev;
@@ -178,16 +178,10 @@ kern_return_t
ds_device_get_status (struct vether_device *vdev, dev_flavor_t flavor,
dev_status_t status, size_t *statuslen)
{
- extern io_return_t dev_getstat (struct vether_device *, dev_flavor_t,
- dev_status_t, natural_t *);
- kern_return_t ret = 0;
if (vdev == NULL)
return D_NO_SUCH_DEVICE;
- if(ether_port != MACH_PORT_NULL)
- ret = device_get_status (ether_port, flavor, status, statuslen);
- else
- ret = dev_getstat (vdev, flavor, status, statuslen);
- return ret;
+
+ return dev_getstat (vdev, flavor, status, statuslen);
}
kern_return_t
@@ -198,9 +192,9 @@ ds_device_set_filter (struct vether_device *vdev,
mach_port_t receive_port,
kern_return_t err;
if (vdev == NULL)
return D_NO_SUCH_DEVICE;
- err = mach_port_request_notification (mach_task_self (), receive_port,
+ err = mach_port_request_notification (mach_task_self (), receive_port,
MACH_NOTIFY_DEAD_NAME, 0,
- ports_get_right (notify_pi),
+ ports_get_right (notify_pi),
MACH_MSG_TYPE_MAKE_SEND_ONCE, &tmp);
if (err != KERN_SUCCESS)
goto out;
diff --git a/eth-multiplexer/ethernet.c b/eth-multiplexer/ethernet.c
index 886f5df..1f3a57c 100644
--- a/eth-multiplexer/ethernet.c
+++ b/eth-multiplexer/ethernet.c
@@ -2,7 +2,7 @@
Copyright (C) 1995, 1996, 1998, 1999, 2000, 2002, 2007, 2008
Free Software Foundation, Inc.
- Written by Zheng Da
+ Written by Zheng Da
Based on pfinet/ethernet.c, written by Michael I. Bushnell, p/BSG.
@@ -42,6 +42,10 @@ static struct port_info *readpt;
/* Port for writing message to the real network interface. */
mach_port_t ether_port;
+
+/* The ethernet address of the real network interface. */
+char ether_address[ETH_ALEN];
+
/* Port for receiving messages from the interface. */
static mach_port_t readptname;
@@ -82,27 +86,45 @@ int set_promisc (char *dev_name, mach_port_t ether_port,
int is_promisc)
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,
+ ret = device_get_status (ether_port, NET_FLAGS, (dev_status_t) &flags,
&count);
- if (ret)
+ if (ret)
{
- error (0, ret, "device_get_status");
+ error (0, ret, "device_get_status");
return -1;
- }
+ }
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)
+ if (ret)
{
error (0, ret, "device_set_status");
return -1;
- }
- return 0;
-}
+ }
+ return 0;
+}
-int ethernet_open (char *dev_name, device_t master_device,
+static error_t
+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);
+
+ err = device_get_status (port, NET_ADDRESS, net_address, &count);
+ if (err)
+ return err;
+
+ net_address[0] = ntohl (net_address[0]);
+ net_address[1] = ntohl (net_address[1]);
+ memcpy (address, net_address, ETH_ALEN);
+ return 0;
+}
+
+int ethernet_open (char *dev_name, device_t master_device,
struct port_bucket *etherport_bucket,
struct port_class *etherreadclass)
{
@@ -132,6 +154,11 @@ int ethernet_open (char *dev_name, device_t master_device,
error (2, err, "device_set_filter: %s", dev_name);
set_promisc (dev_name, ether_port, 1);
+
+ err = get_ethernet_address (ether_port, ether_address);
+ if (err)
+ error (2, err, "%s: Cannot get hardware Ethernet address", dev_name);
+
return 0;
}
diff --git a/eth-multiplexer/ethernet.h b/eth-multiplexer/ethernet.h
index 04b41e3..a2b2f5e 100644
--- a/eth-multiplexer/ethernet.h
+++ b/eth-multiplexer/ethernet.h
@@ -23,12 +23,14 @@
#ifndef ETHERNET_H
#define ETHERNET_H
+#include <mach.h>
+#include <net/if_ether.h>
#include <netinet/in.h>
-#include <stdlib.h>
extern mach_port_t ether_port;
+extern char ether_address[ETH_ALEN];
-int ethernet_open (char *dev_name, device_t master_device,
+int ethernet_open (char *dev_name, device_t master_device,
struct port_bucket *etherport_bucket,
struct port_class *etherreadclass);
int ethernet_close (char *dev_name);
diff --git a/eth-multiplexer/multiplexer.c b/eth-multiplexer/multiplexer.c
index cc0024e..9b661cd 100644
--- a/eth-multiplexer/multiplexer.c
+++ b/eth-multiplexer/multiplexer.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008 Free Software Foundation, Inc.
Written by Zheng Da.
@@ -146,7 +146,7 @@ main (int argc, char *argv[])
}
/* Prepare for the notification. */
- err = ports_create_port (other_portclass, port_bucket,
+ err = ports_create_port (other_portclass, port_bucket,
sizeof (struct port_info), ¬ify_pi);
if (err)
error (1, err, "ports_create_port for notification");
@@ -172,7 +172,7 @@ main (int argc, char *argv[])
error (5, err, "Cannot create root node");
err = io_stat (root_file, &underlying_node_stat);
- if (err)
+ if (err)
error (6, err, "Cannot stat underlying node");
struct stat stat = underlying_node_stat;
diff --git a/eth-multiplexer/netfs_impl.c b/eth-multiplexer/netfs_impl.c
index 29ae072..040512a 100644
--- a/eth-multiplexer/netfs_impl.c
+++ b/eth-multiplexer/netfs_impl.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008, 2009 Free Software Foundation, Inc.
Written by Zheng Da.
@@ -45,7 +45,7 @@
extern struct stat underlying_node_stat;
-int
+int
is_num (char *str)
{
for (; *str; str++)
@@ -164,12 +164,12 @@ error_t
netfs_validate_stat (struct node *node, struct iouser *cred)
{
struct stat st;
-
+
if (node->nn->ln)
st = node->nn->ln->st;
else
st = underlying_node_stat;
-
+
debug("node: %p", node);
node->nn_translated = S_ISLNK (st.st_mode) ? S_IFLNK : 0;
node->nn_stat = st;
diff --git a/eth-multiplexer/netfs_impl.h b/eth-multiplexer/netfs_impl.h
index 17c66f6..a3b4c7d 100644
--- a/eth-multiplexer/netfs_impl.h
+++ b/eth-multiplexer/netfs_impl.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008, 2009 Free Software Foundation, Inc.
Written by Zheng Da.
diff --git a/eth-multiplexer/notify_impl.c b/eth-multiplexer/notify_impl.c
index 947069f..eef5544 100644
--- a/eth-multiplexer/notify_impl.c
+++ b/eth-multiplexer/notify_impl.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008 Free Software Foundation, Inc.
Written by Zheng Da.
diff --git a/eth-multiplexer/test.c b/eth-multiplexer/test.c
index bf80583..7a4d63e 100644
--- a/eth-multiplexer/test.c
+++ b/eth-multiplexer/test.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008 Free Software Foundation, Inc.
Written by Zheng Da.
diff --git a/eth-multiplexer/util.h b/eth-multiplexer/util.h
index c90b0f8..1e062c4 100644
--- a/eth-multiplexer/util.h
+++ b/eth-multiplexer/util.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008 Free Software Foundation, Inc.
Written by Zheng Da.
@@ -27,6 +27,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
+#include <net/if_ether.h>
#include <netinet/ip.h>
#include <mach.h>
@@ -56,15 +57,6 @@
backtrace_symbols_fd(array, size, fileno (stderr)); \
} while (0)
-#define ETH_ALEN 6 /* Octets in one ethernet addr */
-
-struct ethhdr
-{
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
-};
-
static inline void
print_pack (char *packet, int len)
{
@@ -75,13 +67,13 @@ print_pack (char *packet, int len)
char src_str[INET_ADDRSTRLEN];
char dst_str[INET_ADDRSTRLEN];
if (ntohs (ethh->h_proto) == ETH_P_IP
- && len >= sizeof (struct ethhdr) + sizeof (struct iphdr))
+ && len >= sizeof (struct ethhdr) + sizeof (struct iphdr))
{
debug ("multiplexer: get a IP packet from %s to %s\n",
inet_ntop (AF_INET, &iph->saddr, src_str, INET_ADDRSTRLEN),
inet_ntop (AF_INET, &iph->daddr, dst_str, INET_ADDRSTRLEN));
}
- else
+ else
{
debug ("multiplexer: get a non-IP packet\n");
}
diff --git a/eth-multiplexer/vdev.c b/eth-multiplexer/vdev.c
index fd88661..47dc8d2 100644
--- a/eth-multiplexer/vdev.c
+++ b/eth-multiplexer/vdev.c
@@ -22,20 +22,22 @@
#include <string.h>
#include <stdio.h>
+#include <net/if_ether.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <error.h>
+#include <hurd/ihash.h>
#include <pthread.h>
#include "vdev.h"
+#include "ethernet.h"
#include "queue.h"
#include "bpf_impl.h"
#include "util.h"
-#define ETH_HLEN sizeof (struct ethhdr)
static struct vether_device *dev_head;
static int dev_num;
@@ -44,7 +46,7 @@ static int dev_num;
* TODO every device structure should has its own lock to protect itself. */
static pthread_mutex_t dev_list_lock = PTHREAD_MUTEX_INITIALIZER;
-mach_msg_type_t header_type =
+mach_msg_type_t header_type =
{
MACH_MSG_TYPE_BYTE,
8,
@@ -55,7 +57,7 @@ mach_msg_type_t header_type =
0
};
-mach_msg_type_t packet_type =
+mach_msg_type_t packet_type =
{
MACH_MSG_TYPE_BYTE, /* name */
8, /* size */
@@ -105,7 +107,7 @@ foreach_dev_do (int (func) (struct vether_device *))
}
/* Remove all filters with the dead name. */
-int
+int
remove_dead_port_from_dev (mach_port_t dead_port)
{
struct vether_device *vdev;
@@ -123,10 +125,11 @@ remove_dead_port_from_dev (mach_port_t dead_port)
/* Add a new virtual interface to the multiplexer. */
struct vether_device *
-add_vdev (char *name, int size,
+add_vdev (char *name, int size,
struct port_class *class, struct port_bucket *bucket)
{
error_t err;
+ uint32_t hash;
struct vether_device *vdev;
if (size < sizeof (*vdev))
@@ -143,9 +146,13 @@ add_vdev (char *name, int size,
vdev->if_header_format = HDR_ETHERNET;
vdev->if_address_size = ETH_ALEN;
vdev->if_flags = 0;
+
+ /* Compute a pseudo-random but stable ethernet address. */
vdev->if_address[0] = 0x52;
vdev->if_address[1] = 0x54;
- *(int *)(vdev->if_address + 2) = random ();
+ hash = hurd_ihash_hash32 (ether_address, ETH_ALEN, 0);
+ hash = hurd_ihash_hash32 (name, strlen (name), hash);
+ memcpy (&vdev->if_address[2], &hash, 4);
queue_init (&vdev->port_list.if_rcv_port_list);
queue_init (&vdev->port_list.if_snd_port_list);
@@ -191,7 +198,7 @@ has_vdev ()
/* Broadcast the packet to all virtual interfaces
* except the one the packet is from */
-int
+int
broadcast_pack (char *data, int datalen, struct vether_device *from_vdev)
{
int internal_deliver_pack (struct vether_device *vdev)
@@ -205,7 +212,7 @@ broadcast_pack (char *data, int datalen, struct
vether_device *from_vdev)
}
/* Create a message, and deliver it. */
-int
+int
deliver_pack (char *data, int datalen, struct vether_device *vdev)
{
struct net_rcv_msg msg;
@@ -232,7 +239,7 @@ deliver_pack (char *data, int datalen, struct vether_device
*vdev)
}
/* Broadcast the message to all virtual interfaces. */
-int
+int
broadcast_msg (struct net_rcv_msg *msg)
{
int rval = 0;
@@ -268,7 +275,7 @@ deliver_msg(struct net_rcv_msg *msg, struct vether_device
*vdev)
msg->msg_hdr.msgh_id = NET_RCV_MSG_ID;
if_port_list = &vdev->port_list.if_rcv_port_list;
- FILTER_ITERATE (if_port_list, infp, nextfp, &infp->input)
+ FILTER_ITERATE (if_port_list, infp, nextfp, &infp->input)
{
mach_port_t dest;
net_hash_entry_t entp, *hash_headp;
@@ -284,7 +291,7 @@ deliver_msg(struct net_rcv_msg *msg, struct vether_device
*vdev)
else
dest = entp->rcv_port;
- if (ret_count)
+ if (ret_count)
{
debug ("before delivering the packet\n");
msg->msg_hdr.msgh_remote_port = dest;
@@ -297,7 +304,6 @@ deliver_msg(struct net_rcv_msg *msg, struct vether_device
*vdev)
mach_port_deallocate(mach_task_self (),
((mach_msg_header_t
*)msg)->msgh_remote_port);
error (0, err, "mach_msg");
- return -1;
}
debug ("after delivering the packet\n");
}
diff --git a/eth-multiplexer/vdev.h b/eth-multiplexer/vdev.h
index c869678..c98c441 100644
--- a/eth-multiplexer/vdev.h
+++ b/eth-multiplexer/vdev.h
@@ -76,4 +76,9 @@ int broadcast_msg (struct net_rcv_msg *msg);
int get_dev_num ();
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 *);
+
+
#endif
diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c
index 1ead6d2..4f38c92 100644
--- a/ext2fs/ext2fs.c
+++ b/ext2fs/ext2fs.c
@@ -55,6 +55,9 @@ struct store *store;
struct store_parsed *store_parsed;
char *diskfs_disk_name;
+
+pthread_spinlock_t global_lock = PTHREAD_SPINLOCK_INITIALIZER;
+pthread_spinlock_t modified_global_blocks_lock = PTHREAD_SPINLOCK_INITIALIZER;
#ifdef EXT2FS_DEBUG
int ext2_debug_flag;
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index afcd25c..a3d22b2 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -433,7 +433,7 @@ void write_all_disknodes ();
/* What to lock if changing global data data (e.g., the superblock or block
group descriptors or bitmaps). */
-pthread_spinlock_t global_lock;
+extern pthread_spinlock_t global_lock;
/* Where to record such changes. */
struct pokel global_pokel;
@@ -442,7 +442,7 @@ struct pokel global_pokel;
record which disk blocks are actually modified, so we don't stomp on parts
of the disk which are backed by file pagers. */
unsigned char *modified_global_blocks;
-pthread_spinlock_t modified_global_blocks_lock;
+extern pthread_spinlock_t modified_global_blocks_lock;
extern int global_block_modified (block_t block);
extern void record_global_poke (void *ptr);
diff --git a/libbpf/Makefile b/libbpf/Makefile
index 8b02a2a..0a7ba90 100644
--- a/libbpf/Makefile
+++ b/libbpf/Makefile
@@ -23,9 +23,11 @@ SRCS= bpf_impl.c queue.c
LCLHDRS = bpf_impl.h queue.h
installhdrs = bpf_impl.h queue.h
-MIGSTUBS =
+MIGSTUBS =
OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS))
+LDLIBS = -lpthread
+
MIGCOMSFLAGS =
include ../Makeconf
diff --git a/libbpf/bpf_impl.c b/libbpf/bpf_impl.c
index c8a250b..03a2a53 100644
--- a/libbpf/bpf_impl.c
+++ b/libbpf/bpf_impl.c
@@ -1,25 +1,25 @@
- /*
+ /*
* Mach Operating System
* Copyright (c) 1993-1989 Carnegie Mellon University
* All Rights Reserved.
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
+ *
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or address@hidden
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
@@ -29,8 +29,8 @@
*
* Network IO.
*
- * Packet filter code taken from vaxif/enet.c written
- * CMU and Stanford.
+ * Packet filter code taken from vaxif/enet.c written
+ * CMU and Stanford.
*/
/* the code copied from device/net_io.c in Mach */
@@ -58,7 +58,7 @@ static struct net_hash_header filter_hash_header[N_NET_HASH];
*/
int
-bpf_do_filter(net_rcv_port_t infp, char *p, unsigned int wirelen,
+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)
{
@@ -340,9 +340,9 @@ load_byte:
* instruction. Return 2 if it is a valid filter program with a MATCH
* instruction. Otherwise, return 0.
* The constraints are that each jump be forward and to a valid
- * code. The code must terminate with either an accept or reject.
+ * code. The code must terminate with either an accept or reject.
* 'valid' is an array for use by the routine (it must be at least
- * 'len' bytes long).
+ * 'len' bytes long).
*
* The kernel needs to be able to verify an application's filter code.
* Otherwise, a bogus program could easily crash the system.
@@ -362,7 +362,7 @@ bpf_validate(bpf_insn_t f, int bytes, bpf_insn_t *match)
for (i = 1; i < len; ++i) {
/*
- * Check that that jumps are forward, and within
+ * Check that that jumps are forward, and within
* the code block.
*/
p = &f[i];
@@ -380,7 +380,7 @@ bpf_validate(bpf_insn_t f, int bytes, bpf_insn_t *match)
* Check that memory operations use valid addresses.
*/
if ((BPF_CLASS(p->code) == BPF_ST ||
- (BPF_CLASS(p->code) == BPF_LD &&
+ (BPF_CLASS(p->code) == BPF_LD &&
(p->code & 0xe0) == BPF_MEM)) &&
(p->k >= BPF_MEMWORDS || p->k < 0)) {
return 0;
@@ -534,7 +534,7 @@ net_free_dead_infp (queue_entry_t dead_infp)
mach_port_deallocate(mach_task_self(), infp->rcv_port);
free(infp);
debug ("a dead infp is freed\n");
- }
+ }
}
/*
@@ -657,7 +657,7 @@ net_set_filter(if_filter_list_t *ifp, mach_port_t rcv_port,
int priority,
do {
nextentp = (net_hash_entry_t)
entp->he_next;
- /* checked without
+ /* checked without
ip_lock(entp->rcv_port) */
if (entp->rcv_port == rcv_port)
{
ret = hash_ent_remove
(ifp,
@@ -825,7 +825,7 @@ remove_dead_filter (if_filter_list_t *ifp, queue_head_t
*if_port_list,
do {
nextentp = (net_hash_entry_t)
entp->he_next;
- /* checked without
+ /* checked without
ip_lock(entp->rcv_port) */
if (entp->rcv_port == dead_port) {
ret = hash_ent_remove (ifp,
diff --git a/libbpf/bpf_impl.h b/libbpf/bpf_impl.h
index 9073fda..2b092b7 100644
--- a/libbpf/bpf_impl.h
+++ b/libbpf/bpf_impl.h
@@ -1,25 +1,25 @@
- /*
+ /*
* Mach Operating System
* Copyright (c) 1993-1989 Carnegie Mellon University
* All Rights Reserved.
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
+ *
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or address@hidden
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
@@ -29,8 +29,8 @@
*
* Network IO.
*
- * Packet filter code taken from vaxif/enet.c written
- * CMU and Stanford.
+ * Packet filter code taken from vaxif/enet.c written
+ * CMU and Stanford.
*/
/* the code copied from device/net_io.c in Mach */
@@ -125,7 +125,7 @@ typedef struct net_hash_entry *net_hash_entry_t;
* This structure represents a packet filter with multiple sessions.
*
* For example, all application level TCP sessions might be
- * represented by one of these structures. It looks like a
+ * represented by one of these structures. It looks like a
* net_rcv_port struct so that both types can live on the
* same packet filter queues.
*/
@@ -138,7 +138,7 @@ struct net_hash_header {
typedef struct net_hash_header *net_hash_header_t;
-int bpf_do_filter(net_rcv_port_t infp, char *p, unsigned int wirelen,
+int 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);
io_return_t net_set_filter(if_filter_list_t *ifp, mach_port_t rcv_port,
@@ -154,7 +154,7 @@ int hash_ent_remove (if_filter_list_t *ifp,
net_hash_header_t hp, int used,
net_hash_entry_t *head, net_hash_entry_t entp, queue_entry_t
*dead_p);
void net_free_dead_infp (queue_entry_t dead_infp);
void net_free_dead_entp (queue_entry_t dead_entp);
-void remove_dead_filter (if_filter_list_t *ifp,
+void remove_dead_filter (if_filter_list_t *ifp,
queue_head_t *if_port_list, mach_port_t dead_port);
void destroy_filters (if_filter_list_t *ifp);
diff --git a/libbpf/queue.c b/libbpf/queue.c
index a43a21b..3323434 100644
--- a/libbpf/queue.c
+++ b/libbpf/queue.c
@@ -1,25 +1,25 @@
-/*
+/*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
* All Rights Reserved.
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
+ *
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or address@hidden
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
diff --git a/libbpf/util.h b/libbpf/util.h
index c90b0f8..b062638 100644
--- a/libbpf/util.h
+++ b/libbpf/util.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 2008 Free Software Foundation, Inc.
Written by Zheng Da.
@@ -58,7 +58,7 @@
#define ETH_ALEN 6 /* Octets in one ethernet addr */
-struct ethhdr
+struct ethhdr
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
@@ -75,13 +75,13 @@ print_pack (char *packet, int len)
char src_str[INET_ADDRSTRLEN];
char dst_str[INET_ADDRSTRLEN];
if (ntohs (ethh->h_proto) == ETH_P_IP
- && len >= sizeof (struct ethhdr) + sizeof (struct iphdr))
+ && len >= sizeof (struct ethhdr) + sizeof (struct iphdr))
{
debug ("multiplexer: get a IP packet from %s to %s\n",
inet_ntop (AF_INET, &iph->saddr, src_str, INET_ADDRSTRLEN),
inet_ntop (AF_INET, &iph->daddr, dst_str, INET_ADDRSTRLEN));
}
- else
+ else
{
debug ("multiplexer: get a non-IP packet\n");
}
diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile
index 803761d..93c96fa 100644
--- a/libdiskfs/Makefile
+++ b/libdiskfs/Makefile
@@ -40,8 +40,8 @@ IFSOCKSRCS=ifsock.c
OTHERSRCS = conch-fetch.c conch-set.c dir-clear.c dir-init.c dir-renamed.c \
extern-inline.c \
node-create.c node-drop.c node-make.c node-rdwr.c node-update.c \
- node-nref.c node-nput.c node-nrele.c node-nrefl.c node-nputl.c \
- node-nrelel.c node-cache.c \
+ node-nref.c node-nput.c node-nrele.c node-lastref.c node-nrefl.c \
+ node-nputl.c node-nrelel.c node-cache.c \
peropen-make.c peropen-rele.c protid-make.c protid-rele.c \
init-init.c init-startup.c init-first.c init-main.c \
rdwr-internal.c boot-start.c demuxer.c node-times.c shutdown.c \
diff --git a/libdiskfs/file-utimes.c b/libdiskfs/file-utimes.c
index 39fac50..29839fc 100644
--- a/libdiskfs/file-utimes.c
+++ b/libdiskfs/file-utimes.c
@@ -28,6 +28,9 @@ diskfs_S_file_utimes (struct protid *cred,
({
if (!(err = fshelp_isowner (&np->dn_stat, cred->user)))
{
+ /* Flush pending updates first. */
+ diskfs_set_node_times (np);
+
if (atime.microseconds == -1)
np->dn_set_atime = 1;
else
diff --git a/libdiskfs/io-stubs.c b/libdiskfs/io-stubs.c
index 592b3d8..103591f 100644
--- a/libdiskfs/io-stubs.c
+++ b/libdiskfs/io-stubs.c
@@ -23,7 +23,7 @@
/* Implement io_readsleep as described in <hurd/io.defs>
Semantics of ordinary files say this shouldn't happen, because
we never set use_read_size in the shared data. */
-kern_return_t
+kern_return_t __attribute__((weak))
diskfs_S_io_readsleep (struct protid *cred)
{
if (!cred)
@@ -34,7 +34,7 @@ diskfs_S_io_readsleep (struct protid *cred)
/* Implement io_eofnotify as described in <hurd/io.defs>.
We don't use this feature. */
-kern_return_t
+kern_return_t __attribute__((weak))
diskfs_S_io_eofnotify (struct protid *cred)
{
if (!cred)
@@ -45,7 +45,7 @@ diskfs_S_io_eofnotify (struct protid *cred)
/* Implement io_postnotify as described in <hurd/io.defs>.
We don't use this feature. */
-kern_return_t
+kern_return_t __attribute__((weak))
diskfs_S_io_postnotify (struct protid *cred,
vm_offset_t start __attribute__ ((unused)),
vm_offset_t end __attribute__ ((unused)))
@@ -55,7 +55,7 @@ diskfs_S_io_postnotify (struct protid *cred,
/* Implement io_readnotify as described in <hurd/io.defs>.
We don't use this feature. */
-kern_return_t
+kern_return_t __attribute__((weak))
diskfs_S_io_readnotify (struct protid *cred)
{
return cred ? 0 : EOPNOTSUPP;
diff --git a/libdiskfs/node-lastref.c b/libdiskfs/node-lastref.c
new file mode 100644
index 0000000..068566a
--- /dev/null
+++ b/libdiskfs/node-lastref.c
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 1999 Free Software Foundation, Inc.
+ Written by Thomas Bushnell, BSG.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd 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.
+
+ The GNU Hurd 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, USA. */
+
+#include "priv.h"
+
+/* Called when the last hard reference is released. If there are no
+ links, then request soft references to be dropped. */
+void
+_diskfs_lastref (struct node *np)
+{
+ /* This is our cue that something akin to "last process closes file"
+ in the POSIX.1 sense happened, so make sure any pending node time
+ updates now happen in a timely fashion. */
+ diskfs_set_node_times (np);
+ diskfs_lost_hardrefs (np);
+ if (!np->dn_stat.st_nlink)
+ {
+ if (np->sockaddr != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (), np->sockaddr);
+ np->sockaddr = MACH_PORT_NULL;
+ }
+
+ /* There are no links. If there are soft references that
+ can be dropped, we can't let them postpone deallocation.
+ So attempt to drop them. But that's a user-supplied
+ routine, which might result in further recursive calls to
+ the ref-counting system. This is not a problem, as we
+ hold a weak reference ourselves. */
+ diskfs_try_dropping_softrefs (np);
+ }
+}
diff --git a/libdiskfs/node-nput.c b/libdiskfs/node-nput.c
index d59769b..73f6b2c 100644
--- a/libdiskfs/node-nput.c
+++ b/libdiskfs/node-nput.c
@@ -34,29 +34,7 @@ diskfs_nput (struct node *np)
refcounts_demote (&np->refcounts, &result);
if (result.hard == 0)
- {
- /* This is our cue that something akin to "last process closes file"
- in the POSIX.1 sense happened, so make sure any pending node time
- updates now happen in a timely fashion. */
- diskfs_set_node_times (np);
- diskfs_lost_hardrefs (np);
- if (!np->dn_stat.st_nlink)
- {
- if (np->sockaddr != MACH_PORT_NULL)
- {
- mach_port_deallocate (mach_task_self (), np->sockaddr);
- np->sockaddr = MACH_PORT_NULL;
- }
-
- /* There are no links. If there are soft references that
- can be dropped, we can't let them postpone deallocation.
- So attempt to drop them. But that's a user-supplied
- routine, which might result in further recursive calls to
- the ref-counting system. This is not a problem, as we
- hold a weak reference ourselves. */
- diskfs_try_dropping_softrefs (np);
- }
- }
+ _diskfs_lastref (np);
/* Finally get rid of our reference. */
refcounts_deref_weak (&np->refcounts, &result);
diff --git a/libdiskfs/node-nrele.c b/libdiskfs/node-nrele.c
index a96d134..6b7b707 100644
--- a/libdiskfs/node-nrele.c
+++ b/libdiskfs/node-nrele.c
@@ -40,17 +40,7 @@ diskfs_nrele (struct node *np)
{
locked = TRUE;
pthread_mutex_lock (&np->lock);
- diskfs_lost_hardrefs (np);
- if (!np->dn_stat.st_nlink)
- {
- /* There are no links. If there are soft references that
- can be dropped, we can't let them postpone deallocation.
- So attempt to drop them. But that's a user-supplied
- routine, which might result in further recursive calls to
- the ref-counting system. This is not a problem, as we
- hold a weak reference ourselves. */
- diskfs_try_dropping_softrefs (np);
- }
+ _diskfs_lastref (np);
}
/* Finally get rid of our reference. */
diff --git a/libdiskfs/priv.h b/libdiskfs/priv.h
index 2ac3c9e..276d093 100644
--- a/libdiskfs/priv.h
+++ b/libdiskfs/priv.h
@@ -96,6 +96,10 @@ void _diskfs_boot_privports (void);
/* Clean routine for control port. */
void _diskfs_control_clean (void *);
+/* Called when the last hard reference is released. If there are no
+ links, then request soft references to be dropped. */
+void _diskfs_lastref (struct node *np);
+
/* Number of outstanding PT_CTL ports. */
extern int _diskfs_ncontrol_ports;
diff --git a/libnetfs/fsstubs.c b/libnetfs/fsstubs.c
index 75bd790..b260f5d 100644
--- a/libnetfs/fsstubs.c
+++ b/libnetfs/fsstubs.c
@@ -23,21 +23,21 @@
#include "fs_S.h"
#include "ifsock_S.h"
-error_t
+error_t __attribute__((weak))
netfs_S_file_notice_changes (struct protid *user,
mach_port_t port)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_file_getfh (struct protid *user,
char **data, mach_msg_type_number_t *ndata)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_ifsock_getsockaddr (struct protid *user,
mach_port_t *address)
{
diff --git a/libnetfs/fsysstubs.c b/libnetfs/fsysstubs.c
index a64fd64..6cf12cc 100644
--- a/libnetfs/fsysstubs.c
+++ b/libnetfs/fsysstubs.c
@@ -22,7 +22,7 @@
#include "netfs.h"
#include "fsys_S.h"
-error_t
+error_t __attribute__((weak))
netfs_S_fsys_getfile (struct netfs_control *cntl,
mach_port_t reply,
mach_msg_type_name_t reply_type,
@@ -34,7 +34,7 @@ netfs_S_fsys_getfile (struct netfs_control *cntl,
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_fsys_getpriv (struct netfs_control *cntl,
mach_port_t reply,
mach_msg_type_name_t reply_type,
@@ -45,7 +45,7 @@ netfs_S_fsys_getpriv (struct netfs_control *cntl,
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_fsys_init (struct netfs_control *cntl,
mach_port_t reply,
mach_msg_type_name_t reply_type,
@@ -54,7 +54,7 @@ netfs_S_fsys_init (struct netfs_control *cntl,
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_fsys_forward (mach_port_t cntl,
mach_port_t reply,
mach_msg_type_name_t reply_type,
@@ -64,7 +64,7 @@ netfs_S_fsys_forward (mach_port_t cntl,
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_fsys_startup (mach_port_t bootstrap,
mach_port_t reply,
mach_msg_type_name_t reply_type,
diff --git a/libnetfs/iostubs.c b/libnetfs/iostubs.c
index 1465b43..a5ff450 100644
--- a/libnetfs/iostubs.c
+++ b/libnetfs/iostubs.c
@@ -22,7 +22,7 @@
#include "netfs.h"
#include "io_S.h"
-error_t
+error_t __attribute__((weak))
netfs_S_io_map (struct protid *user,
mach_port_t *rdobj, mach_msg_type_name_t *rdobjtype,
mach_port_t *wrobj, mach_msg_type_name_t *wrobjtype)
@@ -30,7 +30,7 @@ netfs_S_io_map (struct protid *user,
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_map_cntl (struct protid *user,
mach_port_t *obj,
mach_msg_type_name_t *objtype)
@@ -38,51 +38,51 @@ netfs_S_io_map_cntl (struct protid *user,
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_get_conch (struct protid *user)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_release_conch (struct protid *user)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_eofnotify (struct protid *user)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_prenotify (struct protid *user,
vm_offset_t start, vm_offset_t stop)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_postnotify (struct protid *user,
vm_offset_t start, vm_offset_t stop)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_readnotify (struct protid *user)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_readsleep (struct protid *user)
{
return EOPNOTSUPP;
}
-error_t
+error_t __attribute__((weak))
netfs_S_io_sigio (struct protid *user)
{
return EOPNOTSUPP;
diff --git a/libpager/data-unlock.c b/libpager/data-unlock.c
index 8c9680c..077e673 100644
--- a/libpager/data-unlock.c
+++ b/libpager/data-unlock.c
@@ -73,7 +73,7 @@ _pager_S_memory_object_data_unlock (struct pager *p,
/* Flush the page, and set a bit so that m_o_data_request knows
to issue an error. */
_pager_lock_object (p, offset, length, MEMORY_OBJECT_RETURN_NONE, 1,
- VM_PROT_WRITE, 1);
+ VM_PROT_WRITE, 0);
_pager_mark_next_request_error (p, offset, length, err);
}
out:
diff --git a/libpager/stubs.c b/libpager/stubs.c
index 9a766ec..964985b 100644
--- a/libpager/stubs.c
+++ b/libpager/stubs.c
@@ -20,7 +20,7 @@
#include "memory_object_S.h"
#include <stdio.h>
-kern_return_t
+kern_return_t __attribute__((weak))
_pager_S_memory_object_copy (struct pager *p,
memory_object_control_t obj_ctl,
vm_offset_t off,
@@ -31,7 +31,7 @@ _pager_S_memory_object_copy (struct pager *p,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
_pager_S_memory_object_data_write (struct pager *p,
mach_port_t ctl,
vm_offset_t off,
@@ -42,7 +42,7 @@ _pager_S_memory_object_data_write (struct pager *p,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
_pager_S_memory_object_supply_completed (struct pager *p,
mach_port_t ctl,
vm_offset_t off,
diff --git a/libtreefs/xinl.c b/libtreefs/xinl.c
index fe83e5a..ca7073a 100644
--- a/libtreefs/xinl.c
+++ b/libtreefs/xinl.c
@@ -1,3 +1,5 @@
#define TREEFS_DEFINE_EI
#include "treefs.h"
#include "mig-decls.h"
+
+pthread_spinlock_t treefs_node_refcnt_lock = PTHREAD_SPINLOCK_INITIALIZER;
diff --git a/libtrivfs/fsys-stubs.c b/libtrivfs/fsys-stubs.c
index 313328a..44d411c 100644
--- a/libtrivfs/fsys-stubs.c
+++ b/libtrivfs/fsys-stubs.c
@@ -22,7 +22,7 @@
#include "priv.h"
#include "trivfs_fsys_S.h"
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_fsys_startup (mach_port_t bootport,
mach_port_t reply,
mach_msg_type_name_t replytype,
@@ -34,7 +34,7 @@ trivfs_S_fsys_startup (mach_port_t bootport,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_fsys_getpriv (struct trivfs_control *cntl,
mach_port_t reply,
mach_msg_type_name_t replytype,
@@ -45,7 +45,7 @@ trivfs_S_fsys_getpriv (struct trivfs_control *cntl,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_fsys_init (struct trivfs_control *control,
mach_port_t reply,
mach_msg_type_name_t replytype,
@@ -55,7 +55,7 @@ trivfs_S_fsys_init (struct trivfs_control *control,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_fsys_getfile (struct trivfs_control *cntl,
mach_port_t reply,
mach_msg_type_name_t replytype,
diff --git a/libtrivfs/io-stubs.c b/libtrivfs/io-stubs.c
index ab6b1b3..1686f3f 100644
--- a/libtrivfs/io-stubs.c
+++ b/libtrivfs/io-stubs.c
@@ -22,7 +22,7 @@
#include "priv.h"
#include "trivfs_io_S.h"
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_map_cntl (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype,
@@ -32,7 +32,7 @@ trivfs_S_io_map_cntl (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_get_conch (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype)
@@ -40,7 +40,7 @@ trivfs_S_io_get_conch (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_release_conch (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype)
@@ -48,7 +48,7 @@ trivfs_S_io_release_conch (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_eofnotify (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype)
@@ -56,7 +56,7 @@ trivfs_S_io_eofnotify (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_prenotify (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype,
@@ -66,7 +66,7 @@ trivfs_S_io_prenotify (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_postnotify (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype,
@@ -76,7 +76,7 @@ trivfs_S_io_postnotify (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_readsleep (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype)
@@ -84,7 +84,7 @@ trivfs_S_io_readsleep (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_sigio (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype)
@@ -92,7 +92,7 @@ trivfs_S_io_sigio (struct trivfs_protid *cred,
return EOPNOTSUPP;
}
-kern_return_t
+kern_return_t __attribute__((weak))
trivfs_S_io_readnotify (struct trivfs_protid *cred,
mach_port_t reply,
mach_msg_type_name_t replytype)
diff --git a/mach-defpager/main.c b/mach-defpager/main.c
index e33c2b3..71615c8 100644
--- a/mach-defpager/main.c
+++ b/mach-defpager/main.c
@@ -104,9 +104,11 @@ main (int argc, char **argv)
exitting, and the child sends that signal after it is set up. */
sigset_t set;
signal (SIGUSR1, nohandler);
+ signal (SIGCHLD, nohandler);
sigemptyset (&set);
sigaddset (&set, SIGUSR1);
- sigprocmask (SIG_BLOCK, &set, 0);
+ sigaddset (&set, SIGCHLD);
+ sigprocmask (SIG_SETMASK, &set, NULL);
switch (fork ())
{
case -1:
diff --git a/proc/mgt.c b/proc/mgt.c
index cb442b0..8dc82f1 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -41,6 +41,7 @@
#include "mutated_ourmsg_U.h"
#include "proc_exc_S.h"
#include "proc_exc_U.h"
+#include "task_notify_S.h"
#include <hurd/signal.h>
/* Create a new id structure with the given genuine uids and gids. */
@@ -1048,13 +1049,13 @@ S_proc_get_code (struct proc *callerp,
/* Handle new task notifications from the kernel. */
error_t
-S_mach_notify_new_task (mach_port_t notify,
+S_mach_notify_new_task (struct port_info *notify,
mach_port_t task,
mach_port_t parent)
{
struct proc *parentp, *childp;
- if (notify != generic_port)
+ if (! notify || notify->class != generic_port_class)
return EOPNOTSUPP;
parentp = task_find_nocreate (parent);
@@ -1079,9 +1080,10 @@ S_mach_notify_new_task (mach_port_t 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);
- if (! err)
- /* Relay the notification. This consumes TASK and PARENT. */
- return mach_notify_new_task (childp->p_task_namespace, task, parent);
+ assert_perror (err);
+
+ /* Relay the notification. This consumes task and parent. */
+ return mach_notify_new_task (childp->p_task_namespace, task, parent);
}
mach_port_deallocate (mach_task_self (), task);
diff --git a/proc/mig-mutate.h b/proc/mig-mutate.h
index 62dc2a5..35b0241 100644
--- a/proc/mig-mutate.h
+++ b/proc/mig-mutate.h
@@ -35,3 +35,12 @@
end_using_port_info (port_info_t)
#define NOTIFY_IMPORTS \
import "libports/mig-decls.h";
+
+#define TASK_NOTIFY_INTRAN \
+ port_info_t begin_using_port_info_port (mach_port_t)
+#define TASK_NOTIFY_INTRAN_PAYLOAD \
+ port_info_t begin_using_port_info_payload
+#define TASK_NOTIFY_DESTRUCTOR \
+ end_using_port_info (port_info_t)
+#define TASK_NOTIFY_IMPORTS \
+ import "libports/mig-decls.h";
diff --git a/startup/startup.c b/startup/startup.c
index f54de5e..2eba563 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -880,6 +880,23 @@ init_stdarrays ()
so the kernel command line can be read as for a normal Hurd process. */
void
+dump_processes (void)
+{
+ pid_t pid;
+ for (pid = 1; pid < 100; pid++)
+ {
+ char args[256], *buffer = args;
+ size_t len = sizeof args;
+ if (proc_getprocargs (procserver, pid, &buffer, &len) == 0)
+ {
+ fprintf (stderr, "pid%d\t%s\n", (int) pid, buffer);
+ if (buffer != args)
+ vm_deallocate (mach_task_self (), (vm_offset_t) buffer, len);
+ }
+ }
+}
+
+void
frob_kernel_process (void)
{
error_t err;
@@ -904,7 +921,10 @@ frob_kernel_process (void)
/* Make the kernel our child. */
err = proc_child (procserver, task);
if (err)
- error (0, err, "cannot make the kernel our child");
+ {
+ error (0, err, "cannot make the kernel our child");
+ dump_processes ();
+ }
err = proc_task2proc (procserver, task, &proc);
if (err)
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index 25d9bc6..cb4df8a 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -1307,7 +1307,7 @@ trace_and_forward (mach_msg_header_t *inp,
mach_msg_header_t *outp)
/* Print something about the message header. */
print_request_header ((struct sender_info *) info, inp);
- /* It's a nofication message. */
+ /* It's a notification message. */
if (inp->msgh_id <= 72 && inp->msgh_id >= 64)
{
assert (info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE);
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git
- [hurd] branch master updated (13a4a20 -> 2210f0b), Samuel Thibault, 2016/11/16
- [hurd] 05/05: rules: Disable pie hardening, Samuel Thibault, 2016/11/16
- [hurd] 04/05: upload, Samuel Thibault, 2016/11/16
- [hurd] 03/05: patches/{console-wire.patch, time-fix.patch}: Drop, merged upstream, Samuel Thibault, 2016/11/16
- [hurd] 02/05: Merge branch 'upstream-merged', Samuel Thibault, 2016/11/16
- [hurd] 01/05: New upstream snapshot,
Samuel Thibault <=