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 <[email protected]> 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 [email protected] - * 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 <[email protected]> * 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 <[email protected]> @@ -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 <[email protected]> @@ -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 <[email protected]> @@ -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 <[email protected]> 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 [email protected] * 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 [email protected] * 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 [email protected] * 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 [email protected] * 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
