[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 01/02: New upstream snapshot
From: |
Samuel Thibault |
Subject: |
[hurd] 01/02: New upstream snapshot |
Date: |
Wed, 10 Dec 2014 15:17:02 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch master
in repository hurd.
commit f248a21a78d1ea3c025da928de4e950511f637f6
Author: Samuel Thibault <address@hidden>
Date: Wed Dec 10 01:15:05 2014 +0000
New upstream snapshot
---
Makeconf | 4 +-
Makefile | 4 +-
auth/mig-decls.h | 6 +
auth/mig-mutate.h | 1 +
boot/boot.c | 290 ++--
boot/boot_script.h | 4 -
console-client/trans.c | 12 +-
console/mutations.h | 3 +
console/pager.c | 1 +
daemons/Makefile | 4 +-
daemons/rc.sh | 3 -
daemons/{runsystem.sh => runsystem.hurd} | 0
daemons/runsystem.sh | 80 +-
devnode/devnode.c | 21 -
doc/hurd.texi | 6 +-
eth-filter/filter.c | 21 -
eth-multiplexer/demuxer.c | 37 +-
eth-multiplexer/device.h | 336 ----
eth-multiplexer/device_impl.c | 26 -
eth-multiplexer/ethernet.c | 7 +-
exec/execmutations.h | 3 +
exec/main.c | 11 +-
exec/mig-decls.h | 6 +
hurd/default_pager.defs | 1 +
hurd/hurd_types.defs | 120 +-
hurd/paths.h | 3 +-
hurd/process.defs | 6 +-
hurd/process_reply.defs | 2 +-
hurd/process_request.defs | 7 +-
hurd/term.defs | 3 +
include/Makefile | 2 +-
include/pids.h | 7 +-
init/Makefile | 15 +-
init/init.c | 1614 ++------------------
init/stubs.c | 139 --
libcons/mutations.h | 1 +
libcons/priv.h | 6 +
libdiskfs/boot-start.c | 11 +-
libdiskfs/dir-init.c | 3 +-
libdiskfs/dir-lookup.c | 11 +-
libdiskfs/disk-pager.c | 1 +
libdiskfs/diskfs.h | 29 +
libdiskfs/fsmutations.h | 5 +
libdiskfs/init-startup.c | 13 +-
libdiskfs/opts-std-startup.c | 2 +-
libfshelp/lock-acquire.c | 95 +-
libmachdev/Makefile | 3 -
libmachdev/ds_routines.c | 45 -
libmachdev/net.c | 36 +-
libnetfs/dir-lookup.c | 13 +-
libnetfs/mutations.h | 3 +
libnetfs/priv.h | 12 +
libpager/demuxer.c | 66 +-
libpager/mig-decls.h | 6 +
libpager/mig-mutate.h | 3 +
libpager/pager-memcpy.c | 2 +
libports/Makefile | 2 +-
random/mig-mutate.h => libports/extern-inline.c | 13 +-
libports/mig-decls.h | 6 +
libports/mig-mutate.h | 4 +
libports/ports.h | 53 +
libshouldbeinlibc/Makefile | 8 +-
.../mig-mutate.h => libshouldbeinlibc/refcount.c | 14 +-
{include => libshouldbeinlibc}/refcount.h | 40 +-
libstore/memobj.c | 1 +
libtrivfs/mig-decls.h | 58 +
libtrivfs/mig-mutate.h | 3 +
mach-defpager/kalloc.c | 14 +-
pfinet/ethernet.c | 20 +-
pfinet/main.c | 24 +-
pfinet/mig-decls.h | 12 +
pfinet/mig-mutate.h | 4 +
pflocal/mig-decls.h | 12 +
pflocal/mig-mutate.h | 3 +
proc/main.c | 53 +-
proc/mgt.c | 76 +-
proc/mig-decls.h | 17 +
proc/mig-mutate.h | 4 +
proc/notify.c | 6 +-
proc/proc.h | 8 +-
proc/proc_exc.defs | 1 +
procfs/main.c | 27 +-
random/Makefile | 1 -
random/mig-decls.h | 47 -
random/random.c | 5 +-
{init => startup}/Makefile | 12 +-
init/init.c => startup/startup.c | 180 ++-
sutils/fstab.c | 103 +-
term/Makefile | 1 +
term/mig-decls.h | 6 +
term/mig-mutate.h | 3 +
term/ptyio.c | 2 +-
tmpfs/node.c | 1 +
trans/Makefile | 9 +
trans/fakeroot.c | 31 +-
trans/mtab.c | 46 +-
utils/rpctrace.c | 31 +-
utils/umount.c | 4 +-
98 files changed, 1390 insertions(+), 2746 deletions(-)
diff --git a/Makeconf b/Makeconf
index 32eec13..f0d3fe3 100644
--- a/Makeconf
+++ b/Makeconf
@@ -575,7 +575,9 @@ vpath %.defs $(top_srcdir)/hurd
# These we want to find in the libc include directory...
mach_defs_names = bootstrap exc mach mach4 \
mach_host mach_port mach_timer_reply memory_object \
- memory_object_default notify
+ memory_object_default notify \
+ gnumach \
+
mach_debug_defs_names = mach_debug
device_defs_names = dev_forward device device_reply device_request
diff --git a/Makefile b/Makefile
index 0b9eff2..3178740 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ lib-subdirs = libshouldbeinlibc libihash libiohelp libports
libthreads \
libnetfs libpipe libstore libhurdbugaddr libftpconn libcons
# Hurd programs
-prog-subdirs = auth proc exec init term \
+prog-subdirs = auth proc exec term \
ext2fs isofs tmpfs fatfs \
storeio pflocal pfinet defpager mach-defpager \
login daemons boot console \
@@ -40,6 +40,8 @@ prog-subdirs = auth proc exec init term \
benchmarks fstests \
random \
procfs \
+ startup \
+ init \
ifeq ($(HAVE_SUN_RPC),yes)
prog-subdirs += nfs nfsd
diff --git a/auth/mig-decls.h b/auth/mig-decls.h
index 09c7c70..fa7b06d 100644
--- a/auth/mig-decls.h
+++ b/auth/mig-decls.h
@@ -32,6 +32,12 @@ auth_port_to_handle (mach_port_t auth)
return ports_lookup_port (auth_bucket, auth, authhandle_portclass);
}
+static inline struct authhandle * __attribute__ ((unused))
+auth_payload_to_handle (unsigned long payload)
+{
+ return ports_lookup_payload (auth_bucket, payload, authhandle_portclass);
+}
+
static inline void __attribute__ ((unused))
end_using_authhandle (struct authhandle *auth)
{
diff --git a/auth/mig-mutate.h b/auth/mig-mutate.h
index ea40c70..5cc8914 100644
--- a/auth/mig-mutate.h
+++ b/auth/mig-mutate.h
@@ -20,5 +20,6 @@
/* CPP definitions for MiG processing of auth.defs for auth server. */
#define AUTH_INTRAN authhandle_t auth_port_to_handle (auth_t)
+#define AUTH_INTRAN_PAYLOAD authhandle_t auth_payload_to_handle
#define AUTH_DESTRUCTOR end_using_authhandle (authhandle_t)
#define AUTH_IMPORTS import "mig-decls.h";
diff --git a/boot/boot.c b/boot/boot.c
index 03617f5..e2cb907 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -109,10 +109,10 @@ typedef struct stat host_stat_t;
#endif /* UX */
-mach_port_t privileged_host_port, master_device_port, defpager;
+mach_port_t privileged_host_port, master_device_port;
mach_port_t pseudo_master_device_port;
mach_port_t receive_set;
-mach_port_t pseudo_console, pseudo_root;
+mach_port_t pseudo_console, pseudo_root, pseudo_time;
auth_t authserver;
struct store *root_store;
@@ -169,36 +169,55 @@ useropen (const char *name, int flags, int mode)
return open (name, flags, mode);
}
-int
-request_server (mach_msg_header_t *inp,
- mach_msg_header_t *outp)
-{
- extern int io_server (mach_msg_header_t *, mach_msg_header_t *);
- extern int device_server (mach_msg_header_t *, mach_msg_header_t *);
- extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
- extern int term_server (mach_msg_header_t *, mach_msg_header_t *);
-/* extern int tioctl_server (mach_msg_header_t *, mach_msg_header_t *); */
- extern int bootstrap_server (mach_msg_header_t *, mach_msg_header_t *);
- extern void bootstrap_compat ();
+/* XXX: glibc should provide mig_reply_setup but does not. */
+/* Fill in default response. */
+void
+mig_reply_setup (
+ const mach_msg_header_t *in,
+ mach_msg_header_t *out)
+{
+ static const mach_msg_type_t RetCodeType = {
+ /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32,
+ /* msgt_size = */ 32,
+ /* msgt_number = */ 1,
+ /* msgt_inline = */ TRUE,
+ /* msgt_longform = */ FALSE,
+ /* msgt_deallocate = */ FALSE,
+ /* msgt_unused = */ 0
+ };
+
+#define InP (in)
+#define OutP ((mig_reply_header_t *) out)
+ OutP->Head.msgh_bits =
+ MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(InP->msgh_bits), 0);
+ OutP->Head.msgh_size = sizeof *OutP;
+ OutP->Head.msgh_remote_port = InP->msgh_remote_port;
+ OutP->Head.msgh_local_port = MACH_PORT_NULL;
+ OutP->Head.msgh_seqno = 0;
+ OutP->Head.msgh_id = InP->msgh_id + 100;
+ OutP->RetCodeType = RetCodeType;
+ OutP->RetCode = MIG_BAD_ID;
+#undef InP
+#undef OutP
+}
-#if 0
- if (inp->msgh_local_port == bootport && boot_like_cmudef)
+int
+boot_demuxer (mach_msg_header_t *inp,
+ mach_msg_header_t *outp)
+{
+ mig_routine_t routine;
+ mig_reply_setup (inp, outp);
+ if ((routine = io_server_routine (inp)) ||
+ (routine = device_server_routine (inp)) ||
+ (routine = notify_server_routine (inp)) ||
+ (routine = term_server_routine (inp))
+ /* (routine = tioctl_server_routine (inp)) */)
{
- if (inp->msgh_id == 999999)
- {
- bootstrap_compat (inp, outp);
- return 1;
- }
- else
- return bootstrap_server (inp, outp);
+ (*routine) (inp, outp);
+ return TRUE;
}
else
-#endif
- return (io_server (inp, outp)
- || device_server (inp, outp)
- || notify_server (inp, outp)
- || term_server (inp, outp)
- /* || tioctl_server (inp, outp) */);
+ return FALSE;
}
vm_address_t
@@ -295,47 +314,6 @@ void read_reply ();
void * msg_thread (void *);
/* Callbacks for boot_script.c; see boot_script.h. */
-
-mach_port_t
-boot_script_read_file (const char *filename)
-{
- static const char msg[] = ": cannot open\n";
- int fd = useropen (filename, O_RDONLY, 0);
- host_stat_t st;
- error_t err;
- mach_port_t memobj;
- vm_address_t region;
-
- write (2, filename, strlen (filename));
- if (fd < 0)
- {
- write (2, msg, sizeof msg - 1);
- host_exit (1);
- }
- else
- write (2, msg + sizeof msg - 2, 1);
-
- host_fstat (fd, &st);
-
- err = default_pager_object_create (defpager, &memobj,
- round_page (st.st_size));
- if (err)
- {
- static const char msg[] = "cannot create default-pager object\n";
- write (2, msg, sizeof msg - 1);
- host_exit (1);
- }
-
- region = 0;
- vm_map (mach_task_self (), ®ion, round_page (st.st_size),
- 0, 1, memobj, 0, 0, VM_PROT_ALL, VM_PROT_ALL, VM_INHERIT_NONE);
- read (fd, (char *) region, st.st_size);
- munmap ((caddr_t) region, round_page (st.st_size));
-
- close (fd);
- return memobj;
-}
-
int
boot_script_exec_cmd (void *hook,
mach_port_t task, char *path, int argc,
@@ -546,9 +524,6 @@ main (int argc, char **argv, char **envp)
get_privileged_ports (&privileged_host_port, &master_device_port);
- defpager = MACH_PORT_NULL;
- vm_set_default_memory_manager (privileged_host_port, &defpager);
-
strcat (bootstrap_args, "f");
mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
@@ -592,6 +567,15 @@ main (int argc, char **argv, char **envp)
if (foo != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), foo);
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_time);
+ mach_port_move_member (mach_task_self (), pseudo_time, receive_set);
+ mach_port_request_notification (mach_task_self (), pseudo_time,
+ MACH_NOTIFY_NO_SENDERS, 1, pseudo_time,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &foo);
+ if (foo != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), foo);
+
if (kernel_command_line == 0)
asprintf (&kernel_command_line, "%s %s root=%s",
argv[0], bootstrap_args, bootdevice);
@@ -759,15 +743,13 @@ main (int argc, char **argv, char **envp)
else /* We hosed */
error (5, errno, "select");
}
-
-/* mach_msg_server (request_server, __vm_page_size * 2, receive_set); */
}
void *
msg_thread (void *arg)
{
while (1)
- mach_msg_server (request_server, 0, receive_set);
+ mach_msg_server (boot_demuxer, 0, receive_set);
}
@@ -914,8 +896,6 @@ unlock_readlock ()
/*
* Handle bootstrap requests.
*/
-/* These two functions from .../mk/bootstrap/default_pager.c. */
-
kern_return_t
do_bootstrap_privileged_ports(bootstrap, hostp, devicep)
mach_port_t bootstrap;
@@ -925,68 +905,6 @@ do_bootstrap_privileged_ports(bootstrap, hostp, devicep)
*devicep = pseudo_master_device_port;
return KERN_SUCCESS;
}
-
-void
-bootstrap_compat(in, out)
- mach_msg_header_t *in, *out;
-{
- mig_reply_header_t *reply = (mig_reply_header_t *) out;
- mach_msg_return_t mr;
-
- struct imsg {
- mach_msg_header_t hdr;
- mach_msg_type_t port_desc_1;
- mach_port_t port_1;
- mach_msg_type_t port_desc_2;
- mach_port_t port_2;
- } imsg;
-
- /*
- * Send back the host and device ports.
- */
-
- imsg.hdr.msgh_bits = MACH_MSGH_BITS_COMPLEX |
- MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(in->msgh_bits), 0);
- /* msgh_size doesn't need to be initialized */
- imsg.hdr.msgh_remote_port = in->msgh_remote_port;
- imsg.hdr.msgh_local_port = MACH_PORT_NULL;
- /* msgh_seqno doesn't need to be initialized */
- imsg.hdr.msgh_id = in->msgh_id + 100; /* this is a reply msg */
-
- imsg.port_desc_1.msgt_name = MACH_MSG_TYPE_COPY_SEND;
- imsg.port_desc_1.msgt_size = (sizeof(mach_port_t) * 8);
- imsg.port_desc_1.msgt_number = 1;
- imsg.port_desc_1.msgt_inline = TRUE;
- imsg.port_desc_1.msgt_longform = FALSE;
- imsg.port_desc_1.msgt_deallocate = FALSE;
- imsg.port_desc_1.msgt_unused = 0;
-
- imsg.port_1 = privileged_host_port;
-
- imsg.port_desc_2 = imsg.port_desc_1;
-
- imsg.port_desc_2.msgt_name = MACH_MSG_TYPE_MAKE_SEND;
- imsg.port_2 = pseudo_master_device_port;
-
- /*
- * Send the reply message.
- * (mach_msg_server can not do this, because the reply
- * is not in standard format.)
- */
-
- mr = mach_msg(&imsg.hdr, MACH_SEND_MSG,
- sizeof imsg, 0, MACH_PORT_NULL,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (mr != MACH_MSG_SUCCESS)
- (void) mach_port_deallocate(mach_task_self (),
- imsg.hdr.msgh_remote_port);
-
- /*
- * Tell mach_msg_server to do nothing.
- */
-
- reply->RetCode = MIG_NO_REPLY;
-}
/* Implementation of device interface */
@@ -1016,6 +934,12 @@ ds_device_open (mach_port_t master_port,
*devicetype = MACH_MSG_TYPE_MAKE_SEND;
return 0;
}
+ else if (!strcmp (name, "time"))
+ {
+ *device = pseudo_time;
+ *devicetype = MACH_MSG_TYPE_MAKE_SEND;
+ return 0;
+ }
else if (strcmp (name, "pseudo-root") == 0)
/* Magic root device. */
{
@@ -1240,40 +1164,6 @@ ds_device_read_inband (device_t device,
}
kern_return_t
-ds_xxx_device_set_status (device_t device,
- dev_flavor_t flavor,
- dev_status_t status,
- size_t statu_cnt)
-{
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_get_status (device_t device,
- dev_flavor_t flavor,
- dev_status_t status,
- size_t *statuscnt)
-{
- if (device != pseudo_console && device != pseudo_root)
- return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_set_filter (device_t device,
- mach_port_t rec,
- int pri,
- filter_array_t filt,
- size_t len)
-{
- if (device != pseudo_console && device != pseudo_root)
- return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
ds_device_map (device_t device,
vm_prot_t prot,
vm_offset_t offset,
@@ -1281,9 +1171,26 @@ ds_device_map (device_t device,
memory_object_t *pager,
int unmap)
{
- if (device != pseudo_console && device != pseudo_root)
+ if (device == pseudo_console || device == pseudo_root)
+ return D_INVALID_OPERATION;
+ else if (device == pseudo_time)
+ {
+ error_t err;
+ mach_port_t wr_memobj;
+ file_t node = file_name_lookup ("/dev/time", O_RDONLY, 0);
+
+ if (node == MACH_PORT_NULL)
+ return D_IO_ERROR;
+
+ err = io_map (node, pager, &wr_memobj);
+ if (!err && MACH_PORT_VALID (wr_memobj))
+ mach_port_deallocate (mach_task_self (), wr_memobj);
+
+ mach_port_deallocate (mach_task_self (), node);
+ return D_SUCCESS;
+ }
+ else
return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
}
kern_return_t
@@ -1306,18 +1213,27 @@ ds_device_get_status (device_t device,
if (device == pseudo_console)
return D_INVALID_OPERATION;
else if (device == pseudo_root)
- if (flavor == DEV_GET_SIZE)
- if (*statuslen < DEV_GET_SIZE_COUNT)
- return D_INVALID_SIZE;
- else
- {
- status[DEV_GET_SIZE_DEVICE_SIZE] = root_store->size;
- status[DEV_GET_SIZE_RECORD_SIZE] = root_store->block_size;
- *statuslen = DEV_GET_SIZE_COUNT;
- return D_SUCCESS;
- }
- else
- return D_INVALID_OPERATION;
+ switch (flavor)
+ {
+ case DEV_GET_SIZE:
+ if (*statuslen < DEV_GET_SIZE_COUNT)
+ return D_INVALID_SIZE;
+ status[DEV_GET_SIZE_DEVICE_SIZE] = root_store->size;
+ status[DEV_GET_SIZE_RECORD_SIZE] = root_store->block_size;
+ *statuslen = DEV_GET_SIZE_COUNT;
+ return D_SUCCESS;
+
+ case DEV_GET_RECORDS:
+ if (*statuslen < DEV_GET_RECORDS_COUNT)
+ return D_INVALID_SIZE;
+ status[DEV_GET_RECORDS_DEVICE_RECORDS] = root_store->blocks;
+ status[DEV_GET_RECORDS_RECORD_SIZE] = root_store->block_size;
+ *statuslen = DEV_GET_RECORDS_COUNT;
+ return D_SUCCESS;
+
+ default:
+ return D_INVALID_OPERATION;
+ }
else
return D_NO_SUCH_DEVICE;
}
diff --git a/boot/boot_script.h b/boot/boot_script.h
index 6245869..da52e6f 100644
--- a/boot/boot_script.h
+++ b/boot/boot_script.h
@@ -69,10 +69,6 @@ int boot_script_exec_cmd (void *hook,
task_t task, char *path, int argc,
char **argv, char *strings, int stringlen);
-/* The user must define this function. Load the contents of FILE
- into a fresh anonymous memory object and return the memory object port. */
-mach_port_t boot_script_read_file (const char *file);
-
/* The user must define this functions to perform the corresponding
Mach task manipulations. */
int boot_script_task_create (struct cmd *); /* task_create + task_suspend */
diff --git a/console-client/trans.c b/console-client/trans.c
index 67cd149..224229e 100644
--- a/console-client/trans.c
+++ b/console-client/trans.c
@@ -63,8 +63,16 @@ console_demuxer (mach_msg_header_t *inp,
ret = netfs_demuxer (inp, outp);
if (ret)
return ret;
-
- user = ports_lookup_port (netfs_port_bucket, inop->msgh_local_port,
netfs_protid_class);
+
+ if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) ==
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+ user = ports_lookup_payload (netfs_port_bucket,
+ inop->msgh_protected_payload,
+ netfs_protid_class);
+ else
+ user = ports_lookup_port (netfs_port_bucket,
+ inop->msgh_local_port,
+ netfs_protid_class);
if (!user)
return ret;
diff --git a/console/mutations.h b/console/mutations.h
index 4e1cc7e..87906cc 100644
--- a/console/mutations.h
+++ b/console/mutations.h
@@ -21,12 +21,15 @@
/* Only CPP macro definitions should go in this file. */
#define IO_INTRAN protid_t begin_using_protid_port (io_t)
+#define IO_INTRAN_PAYLOAD protid_t begin_using_protid_payload
#define IO_DESTRUCTOR end_using_protid_port (protid_t)
#define TIOCTL_IMPORTS import "libnetfs/priv.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 \
diff --git a/console/pager.c b/console/pager.c
index 3568211..5e13ba4 100644
--- a/console/pager.c
+++ b/console/pager.c
@@ -169,6 +169,7 @@ user_pager_create (struct user_pager *user_pager, unsigned
int npages,
mach_port_insert_right (mach_task_self (), user_pager->memobj,
user_pager->memobj, MACH_MSG_TYPE_MAKE_SEND);
+ *user = 0;
err = vm_map (mach_task_self (),
(vm_address_t *) user,
(vm_size_t) npages * vm_page_size,
diff --git a/daemons/Makefile b/daemons/Makefile
index d16680e..db1acc7 100644
--- a/daemons/Makefile
+++ b/daemons/Makefile
@@ -22,7 +22,9 @@ makemode := utilities
targets = rc getty mail.local console-run runttys runsystem
special-targets = rc runsystem
-SRCS = rc.sh runsystem.sh getty.c lmail.c console-run.c runttys.c
+SRCS = rc.sh runsystem.sh getty.c lmail.c console-run.c runttys.c \
+ runsystem.hurd \
+
installationdir = $(libexecdir)
HURDLIBS = fshelp ports shouldbeinlibc
diff --git a/daemons/rc.sh b/daemons/rc.sh
index 5cf44fa..1240883 100644
--- a/daemons/rc.sh
+++ b/daemons/rc.sh
@@ -2,9 +2,6 @@
PATH=/bin:/sbin
-# Start the default pager. It will bail if there is already one running.
-/hurd/mach-defpager
-
# Set up swap space. This will complain if no default pager is functioning.
swapon -a
diff --git a/daemons/runsystem.sh b/daemons/runsystem.hurd
similarity index 100%
copy from daemons/runsystem.sh
copy to daemons/runsystem.hurd
diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh
index f4f2771..ae25a7d 100644
--- a/daemons/runsystem.sh
+++ b/daemons/runsystem.sh
@@ -1,9 +1,9 @@
#!/bin/bash
#
# This program is run by /hurd/init at boot time after the essential
-# servers are up, and is responsible for running the "userland" parts of a
-# normal system. This includes running the single-user shell as well as a
-# multi-user system. This program is expected never to exit.
+# servers are up. It does some initialization of its own and then
+# execs /hurd/init or any other roughly SysV init-compatible program
+# to bring up the "userland" parts of a normal system.
#
@@ -22,11 +22,10 @@ fallback_shells='/bin/sh /bin/bash /bin/csh /bin/ash
/bin/shd'
# Shell used for normal single-user startup.
SHELL=/bin/sh
-# Programs that do multi-user startup.
-RUNCOM=/libexec/rc
-RUNTTYS=/libexec/runttys
-# Signals that we should pass down to runttys.
-runttys_sigs='TERM INT HUP TSTP'
+# The init program to call.
+#
+# Can be overridden using init=something in the kernel command line.
+init=/hurd/init
###
@@ -44,7 +43,7 @@ trap 'reopen_console' SIGLOST
# startup entirely. We exec a single-user shell, so we will not come back
# here. The only way to get to multi-user from that shell will be
# explicitly exec this script or something like that.
-function singleuser ()
+function singleuser()
{
test $# -eq 0 || echo "$0: $*"
for try in ${fallback_shells}; do
@@ -54,6 +53,8 @@ function singleuser ()
exit 127
}
+# Print a newline.
+echo
# See whether pflocal is set up already, and do so if not (install case)
#
@@ -85,20 +86,23 @@ fi
# The first argument is the kernel file name; skip that.
shift
flags=
+single=
while [ $# -gt 0 ]; do
arg="$1"
shift
case "$arg" in
--*) ;;
+ init=*)
+ eval "${arg}"
+ ;;
*=*) ;;
-*)
flags="${flags}${arg#-}"
;;
- 'single'|'emergency') # Linux compat
- flags="${flags}s"
+ 'single')
+ single="-s"
;;
- 'fastboot')
- flags="${flags}f"
+ 'fastboot'|'emergency')
;;
esac
done
@@ -106,50 +110,18 @@ done
# Check boot flags.
case "$flags" in
*s*)
- rc=false # force single-user
- ;;
-*f*)
- rc="${RUNCOM}" # fastboot
- ;;
-*)
- rc="${RUNCOM} autoboot" # multi-user default
+ single="-s" # force single-user
;;
esac
-# Large infinite loop. If this script ever exits, init considers that
-# a serious bogosity and punts to a fallback single-user shell.
-# We handle here the normal transitions between single-user and multi-user.
-while : ; do
-
- # Run the rc script. As long as it exits nonzero, punt to single-user.
- # After the single-user shell exits, we will start over attempting to
- # run rc; but later invocations strip the `autoboot' argument.
- until $rc; do
- rc=${RUNCOM}
-
- # Run single-user shell and repeat as long as it dies with a signal.
- until ${SHELL} || test $? -lt 128; do
- :
- done
- done
-
- # Now we are officially ready for normal multi-user operation.
-
- # Trap certain signals and send them on to runttys. For this to work, we
- # must run it asynchronously and wait for it with the `wait' built-in.
- runttys_pid=0
- for sig in $runttys_sigs; do
- trap "kill -$sig \${runttys_pid}" $sig
- done
+# Start the default pager. It will bail if there is already one running.
+/hurd/mach-defpager
- # This program reads /etc/ttys and starts the programs it says to.
- ${RUNTTYS} &
- runttys_pid=$!
+# This is necessary to make stat / return the correct device ids.
+# Work around a race condition (probably in the root translator).
+for i in `seq 1 100000` ; do : ; done # XXX
- # Wait for runttys to die, meanwhile handling trapped signals.
- wait
+fsysopts / --update --readonly
- # Go back to the top of the infinite loop, as if booting single-user.
- rc=false
-
-done
+# Finally, start the actual init.
+exec ${init} ${single} -a
diff --git a/devnode/devnode.c b/devnode/devnode.c
index 789bf51..f9f0359 100644
--- a/devnode/devnode.c
+++ b/devnode/devnode.c
@@ -138,27 +138,6 @@ do_mach_notify_dead_name (struct port_info *pi,
}
/* Implementation of device interface */
-kern_return_t
-ds_xxx_device_set_status (device_t device, dev_flavor_t flavor,
- dev_status_t status, size_t statu_cnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_get_status (device_t device, dev_flavor_t flavor,
- dev_status_t status, size_t *statuscnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_set_filter (device_t device, mach_port_t rec,
- int pri, filter_array_t filt, size_t len)
-{
- return D_INVALID_OPERATION;
-}
-
kern_return_t
ds_device_open (mach_port_t master_port, mach_port_t reply_port,
mach_msg_type_name_t reply_portPoly,
diff --git a/doc/hurd.texi b/doc/hurd.texi
index 8fa6da7..7e7b5ee 100644
--- a/doc/hurd.texi
+++ b/doc/hurd.texi
@@ -563,10 +563,10 @@ bootstrapped by starting the GNU Mach microkernel and two
programs:
the root filesystem and the exec server.
The @option{--multiboot-command-line} option tells the file system server that
-it is a root filesystem, which triggers it to run @command{/hurd/init} as PID
-1. @command{/hurd/init} starts the @command{/hurd/proc} and
+it is a root filesystem, which triggers it to run @command{/hurd/startup} as
PID
+2. @command{/hurd/startup} starts the @command{/hurd/proc} and
@command{/hurd/auth} servers. After the servers are launched
address@hidden/hurd/init} starts the @command{/libexec/runsystem.sh} script to
address@hidden/hurd/startup} starts the @command{/libexec/runsystem.sh} script
to
finish booting.
After the Hurd has been booted, other sets of core Hurd servers can be
diff --git a/eth-filter/filter.c b/eth-filter/filter.c
index 482b080..13dd03b 100644
--- a/eth-filter/filter.c
+++ b/eth-filter/filter.c
@@ -294,27 +294,6 @@ do_mach_notify_dead_name (struct port_info *pi,
}
/* Implementation of device interface */
-kern_return_t
-ds_xxx_device_set_status (struct proxy_user *device, dev_flavor_t flavor,
- dev_status_t status, size_t statu_cnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_get_status (struct proxy_user *device, dev_flavor_t flavor,
- dev_status_t status, size_t *statuscnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_set_filter (struct proxy_user *device, mach_port_t rec,
- int pri, filter_array_t filt, size_t len)
-{
- return D_INVALID_OPERATION;
-}
-
kern_return_t
ds_device_open (mach_port_t master_port, mach_port_t reply_port,
mach_msg_type_name_t reply_portPoly,
diff --git a/eth-multiplexer/demuxer.c b/eth-multiplexer/demuxer.c
index 1f671b2..68bf968 100644
--- a/eth-multiplexer/demuxer.c
+++ b/eth-multiplexer/demuxer.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 2013 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -20,22 +20,31 @@
#include <hurd/netfs.h>
+#include "libnetfs/io_S.h"
+#include "libnetfs/fs_S.h"
+#include "libports/notify_S.h"
+#include "libnetfs/fsys_S.h"
+#include "libports/interrupt_S.h"
+#include "libnetfs/ifsock_S.h"
+#include "device_S.h"
+
int
netfs_demuxer (mach_msg_header_t *inp,
mach_msg_header_t *outp)
{
- int netfs_fs_server (mach_msg_header_t *, mach_msg_header_t *);
- int netfs_io_server (mach_msg_header_t *, mach_msg_header_t *);
- int netfs_fsys_server (mach_msg_header_t *, mach_msg_header_t *);
- int netfs_ifsock_server (mach_msg_header_t *, mach_msg_header_t *);
- int device_server (mach_msg_header_t *, mach_msg_header_t *);
-
- return (netfs_io_server (inp, outp)
- || netfs_fs_server (inp, outp)
- || ports_notify_server (inp, outp)
- || netfs_fsys_server (inp, outp)
- || ports_interrupt_server (inp, outp)
- || netfs_ifsock_server (inp, outp)
- || device_server (inp, outp));
+ mig_routine_t routine;
+ if ((routine = netfs_io_server_routine (inp)) ||
+ (routine = netfs_fs_server_routine (inp)) ||
+ (routine = ports_notify_server_routine (inp)) ||
+ (routine = netfs_fsys_server_routine (inp)) ||
+ (routine = ports_interrupt_server_routine (inp)) ||
+ (routine = netfs_ifsock_server_routine (inp)) ||
+ (routine = device_server_routine (inp)))
+ {
+ (*routine) (inp, outp);
+ return TRUE;
+ }
+ else
+ return FALSE;
}
diff --git a/eth-multiplexer/device.h b/eth-multiplexer/device.h
deleted file mode 100644
index db0798d..0000000
--- a/eth-multiplexer/device.h
+++ /dev/null
@@ -1,336 +0,0 @@
-#ifndef _device_user_
-#define _device_user_
-
-/* Module device */
-
-#include <mach/kern_return.h>
-#include <mach/port.h>
-#include <mach/message.h>
-
-#include <mach/std_types.h>
-#include <mach/mach_types.h>
-#include <device/device_types.h>
-#include <device/net_status.h>
-
-/* Routine device_open */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_open
-#if defined(LINTLIBRARY)
- (master_port, mode, name, device)
- mach_port_t master_port;
- dev_mode_t mode;
- dev_name_t name;
- mach_port_t *device;
-{ return device_open(master_port, mode, name, device); }
-#else
-(
- mach_port_t master_port,
- dev_mode_t mode,
- dev_name_t name,
- mach_port_t *device
-);
-#endif
-
-/* Routine device_close */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_close
-#if defined(LINTLIBRARY)
- (device)
- mach_port_t device;
-{ return device_close(device); }
-#else
-(
- mach_port_t device
-);
-#endif
-
-/* Routine device_write */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_write
-#if defined(LINTLIBRARY)
- (device, mode, recnum, data, dataCnt, bytes_written)
- mach_port_t device;
- dev_mode_t mode;
- recnum_t recnum;
- io_buf_ptr_t data;
- mach_msg_type_number_t dataCnt;
- int *bytes_written;
-{ return device_write(device, mode, recnum, data, dataCnt, bytes_written); }
-#else
-(
- mach_port_t device,
- dev_mode_t mode,
- recnum_t recnum,
- io_buf_ptr_t data,
- mach_msg_type_number_t dataCnt,
- int *bytes_written
-);
-#endif
-
-/* Routine device_write_inband */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_write_inband
-#if defined(LINTLIBRARY)
- (device, mode, recnum, data, dataCnt, bytes_written)
- mach_port_t device;
- dev_mode_t mode;
- recnum_t recnum;
- io_buf_ptr_inband_t data;
- mach_msg_type_number_t dataCnt;
- int *bytes_written;
-{ return device_write_inband(device, mode, recnum, data, dataCnt,
bytes_written); }
-#else
-(
- mach_port_t device,
- dev_mode_t mode,
- recnum_t recnum,
- io_buf_ptr_inband_t data,
- mach_msg_type_number_t dataCnt,
- int *bytes_written
-);
-#endif
-
-/* Routine device_read */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_read
-#if defined(LINTLIBRARY)
- (device, mode, recnum, bytes_wanted, data, dataCnt)
- mach_port_t device;
- dev_mode_t mode;
- recnum_t recnum;
- int bytes_wanted;
- io_buf_ptr_t *data;
- mach_msg_type_number_t *dataCnt;
-{ return device_read(device, mode, recnum, bytes_wanted, data, dataCnt); }
-#else
-(
- mach_port_t device,
- dev_mode_t mode,
- recnum_t recnum,
- int bytes_wanted,
- io_buf_ptr_t *data,
- mach_msg_type_number_t *dataCnt
-);
-#endif
-
-/* Routine device_read_inband */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_read_inband
-#if defined(LINTLIBRARY)
- (device, mode, recnum, bytes_wanted, data, dataCnt)
- mach_port_t device;
- dev_mode_t mode;
- recnum_t recnum;
- int bytes_wanted;
- io_buf_ptr_inband_t data;
- mach_msg_type_number_t *dataCnt;
-{ return device_read_inband(device, mode, recnum, bytes_wanted, data,
dataCnt); }
-#else
-(
- mach_port_t device,
- dev_mode_t mode,
- recnum_t recnum,
- int bytes_wanted,
- io_buf_ptr_inband_t data,
- mach_msg_type_number_t *dataCnt
-);
-#endif
-
-/* Routine xxx_device_set_status */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t xxx_device_set_status
-#if defined(LINTLIBRARY)
- (device, flavor, status, statusCnt)
- mach_port_t device;
- dev_flavor_t flavor;
- dev_status_t status;
- mach_msg_type_number_t statusCnt;
-{ return xxx_device_set_status(device, flavor, status, statusCnt); }
-#else
-(
- mach_port_t device,
- dev_flavor_t flavor,
- dev_status_t status,
- mach_msg_type_number_t statusCnt
-);
-#endif
-
-/* Routine xxx_device_get_status */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t xxx_device_get_status
-#if defined(LINTLIBRARY)
- (device, flavor, status, statusCnt)
- mach_port_t device;
- dev_flavor_t flavor;
- dev_status_t status;
- mach_msg_type_number_t *statusCnt;
-{ return xxx_device_get_status(device, flavor, status, statusCnt); }
-#else
-(
- mach_port_t device,
- dev_flavor_t flavor,
- dev_status_t status,
- mach_msg_type_number_t *statusCnt
-);
-#endif
-
-/* Routine xxx_device_set_filter */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t xxx_device_set_filter
-#if defined(LINTLIBRARY)
- (device, receive_port, receive_portPoly, priority, filter, filterCnt)
- mach_port_t device;
- mach_port_t receive_port;
- mach_msg_type_name_t receive_portPoly;
- int priority;
- filter_array_t filter;
- mach_msg_type_number_t filterCnt;
-{ return xxx_device_set_filter(device, receive_port, receive_portPoly,
priority, filter, filterCnt); }
-#else
-(
- mach_port_t device,
- mach_port_t receive_port,
- mach_msg_type_name_t receive_portPoly,
- int priority,
- filter_array_t filter,
- mach_msg_type_number_t filterCnt
-);
-#endif
-
-/* Routine device_map */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_map
-#if defined(LINTLIBRARY)
- (device, prot, offset, size, pager, unmap)
- mach_port_t device;
- vm_prot_t prot;
- vm_offset_t offset;
- vm_size_t size;
- mach_port_t *pager;
- int unmap;
-{ return device_map(device, prot, offset, size, pager, unmap); }
-#else
-(
- mach_port_t device,
- vm_prot_t prot,
- vm_offset_t offset,
- vm_size_t size,
- mach_port_t *pager,
- int unmap
-);
-#endif
-
-/* Routine device_set_status */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_set_status
-#if defined(LINTLIBRARY)
- (device, flavor, status, statusCnt)
- mach_port_t device;
- dev_flavor_t flavor;
- dev_status_t status;
- mach_msg_type_number_t statusCnt;
-{ return device_set_status(device, flavor, status, statusCnt); }
-#else
-(
- mach_port_t device,
- dev_flavor_t flavor,
- dev_status_t status,
- mach_msg_type_number_t statusCnt
-);
-#endif
-
-/* Routine device_get_status */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_get_status
-#if defined(LINTLIBRARY)
- (device, flavor, status, statusCnt)
- mach_port_t device;
- dev_flavor_t flavor;
- dev_status_t status;
- mach_msg_type_number_t *statusCnt;
-{ return device_get_status(device, flavor, status, statusCnt); }
-#else
-(
- mach_port_t device,
- dev_flavor_t flavor,
- dev_status_t status,
- mach_msg_type_number_t *statusCnt
-);
-#endif
-
-/* Routine device_set_filter */
-#ifdef mig_external
-mig_external
-#else
-extern
-#endif
-kern_return_t device_set_filter
-#if defined(LINTLIBRARY)
- (device, receive_port, receive_portPoly, priority, filter, filterCnt)
- mach_port_t device;
- mach_port_t receive_port;
- mach_msg_type_name_t receive_portPoly;
- int priority;
- filter_array_t filter;
- mach_msg_type_number_t filterCnt;
-{ return device_set_filter(device, receive_port, receive_portPoly, priority,
filter, filterCnt); }
-#else
-(
- mach_port_t device,
- mach_port_t receive_port,
- mach_msg_type_name_t receive_portPoly,
- int priority,
- filter_array_t filter,
- mach_msg_type_number_t filterCnt
-);
-#endif
-
-#endif /* not defined(_device_user_) */
diff --git a/eth-multiplexer/device_impl.c b/eth-multiplexer/device_impl.c
index 35a4da4..7d82b8d 100644
--- a/eth-multiplexer/device_impl.c
+++ b/eth-multiplexer/device_impl.c
@@ -39,32 +39,6 @@ extern struct port_class *other_portclass;
extern struct port_info *notify_pi;
/* Implementation of device interface */
-kern_return_t
-ds_xxx_device_set_status (struct vether_device *vdev, dev_flavor_t flavor,
- dev_status_t status, size_t statu_cnt)
-{
- if (vdev == NULL)
- return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_get_status (struct vether_device *vdev, dev_flavor_t flavor,
- dev_status_t status, size_t *statuscnt)
-{
- if (vdev == NULL)
- return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_set_filter (struct vether_device *vdev, mach_port_t rec,
- int pri, filter_array_t filt, size_t len)
-{
- if (vdev == NULL)
- return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
-}
/*
* This function is currently running in the multithread environment,
diff --git a/eth-multiplexer/ethernet.c b/eth-multiplexer/ethernet.c
index 32c5589..886f5df 100644
--- a/eth-multiplexer/ethernet.c
+++ b/eth-multiplexer/ethernet.c
@@ -76,12 +76,12 @@ int set_promisc (char *dev_name, mach_port_t ether_port,
int is_promisc)
#ifndef NET_FLAGS
#define NET_FLAGS (('n'<<16) + 4)
#endif
- short flags;
+ int flags;
int ret;
size_t count;
debug ("set_promisc is called, is_promisc: %d\n", is_promisc);
- count = sizeof (flags);
+ count = 1;
ret = device_get_status (ether_port, NET_FLAGS, (dev_status_t) &flags,
&count);
if (ret)
@@ -93,8 +93,7 @@ int set_promisc (char *dev_name, mach_port_t ether_port, int
is_promisc)
flags |= IFF_PROMISC;
else
flags &= ~IFF_PROMISC;
- ret = device_set_status(ether_port, NET_FLAGS, (dev_status_t) &flags,
- sizeof (flags));
+ ret = device_set_status(ether_port, NET_FLAGS, (dev_status_t) &flags, 1);
if (ret)
{
error (0, ret, "device_set_status");
diff --git a/exec/execmutations.h b/exec/execmutations.h
index 2acca7a..0b5b8bb 100644
--- a/exec/execmutations.h
+++ b/exec/execmutations.h
@@ -1,6 +1,7 @@
/* CPP definitions for MiG processing of exec.defs for exec server. */
#define FILE_INTRAN trivfs_protid_t trivfs_begin_using_protid (file_t)
+#define FILE_INTRAN_PAYLOAD trivfs_protid_t trivfs_begin_using_protid_payload
#define FILE_DESTRUCTOR trivfs_end_using_protid (trivfs_protid_t)
#define EXEC_IMPORTS \
@@ -9,6 +10,8 @@
#define EXEC_STARTUP_INTRAN \
bootinfo_t begin_using_bootinfo_port (exec_startup_t)
+#define EXEC_STARTUP_INTRAN_PAYLOAD \
+ bootinfo_t begin_using_bootinfo_payload
#define EXEC_STARTUP_DESTRUCTOR \
end_using_bootinfo (bootinfo_t)
#define EXEC_STARTUP_IMPORTS \
diff --git a/exec/main.c b/exec/main.c
index 784000b..c86c000 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -331,8 +331,15 @@ S_exec_init (struct trivfs_protid *protid,
proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION);
- err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup);
- assert_perror (err);
+ startup = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+ if (startup == MACH_PORT_NULL)
+ {
+ error (0, errno, "%s", _SERVERS_STARTUP);
+
+ /* Fall back to abusing the message port lookup. */
+ err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup);
+ assert_perror (err);
+ }
mach_port_deallocate (mach_task_self (), procserver);
/* Call startup_essential task last; init assumes we are ready to
diff --git a/exec/mig-decls.h b/exec/mig-decls.h
index 0437414..cf3e17d 100644
--- a/exec/mig-decls.h
+++ b/exec/mig-decls.h
@@ -30,6 +30,12 @@ begin_using_bootinfo_port (mach_port_t port)
return ports_lookup_port (port_bucket, port, execboot_portclass);
}
+static inline struct bootinfo * __attribute__ ((unused))
+begin_using_bootinfo_payload (unsigned long payload)
+{
+ return ports_lookup_payload (port_bucket, payload, execboot_portclass);
+}
+
static inline void __attribute__ ((unused))
end_using_bootinfo (struct bootinfo *b)
{
diff --git a/hurd/default_pager.defs b/hurd/default_pager.defs
index 1a4290d..a97bff2 100644
--- a/hurd/default_pager.defs
+++ b/hurd/default_pager.defs
@@ -29,6 +29,7 @@
subsystem default_pager 2275;
+#include <hurd/hurd_types.defs> /* For `MACH_PAYLOAD_TO_PORT'. */
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
#include <mach/default_pager_types.defs>
diff --git a/hurd/hurd_types.defs b/hurd/hurd_types.defs
index 129a68c..57af6dc 100644
--- a/hurd/hurd_types.defs
+++ b/hurd/hurd_types.defs
@@ -18,13 +18,67 @@ along with the GNU Hurd; see the file COPYING. If not,
write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* The Hurd uses protected payloads to quickly look up the object
+ receiving a message. Looking up objects is optimized at the cost
+ of having to translate payloads back to port names if the server
+ function expect a port name rather than an object.
+
+ Support for this is implemented in libports. Almost all of Hurd's
+ servers use libports. For servers using libports, the optimized
+ lookup is completely transparent.
+
+ Servers not using libports are not using protected payloads
+ automatically. Define HURD_DEFAULT_PAYLOAD_TO_PORT to 1 (1 like
+ the identity function) for programs not using libports to avoid
+ injecting the default payload-to-port translation function which is
+ in libports. If you want to use protected payloads without
+ libports, you can use HURD_DEFAULT_PAYLOAD_TO_PORT to inject a
+ custom translation function. */
+
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+#if HURD_DEFAULT_PAYLOAD_TO_PORT
+/* Any non-numeric value will fail this test. If 1 (or any number) is
+ given, do not inject the default translator function. */
+#undef HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
+#else
+ import <hurd/ports.h>;
+#define HURD_DEFAULT_PAYLOAD_TO_PORT ports_payload_get_name
+#endif
+
+/* Override the mach_port_t. Use the default payload to port
+ translation function to convert payloads back to port names for
+ this type. */
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+#define MACH_PAYLOAD_TO_PORT HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
+
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
#include <device/device_types.defs>
+
+/* The Hurd types. You can inject translation functions for type X
+ using the X_INTRAN, X_INTRAN_PAYLOAD, X_OUTTRAN, and X_DESTRUCTOR.
+
+ If you define X_INTRAN and your server is using libports, you also
+ have to define X_INTRAN_PAYLOAD.
+
+ If you do not use libports, and do not want to use the protected
+ payload mechanism, but you do want to use X_INTRAN, you must
+ provide a X_INTRAN_PAYLOAD that either ignores the message by
+ returning NULL, or indicates an error condition in some appropriate
+ way. If you do want to use the protected payload mechanism, make
+ sure you also define an appropriate HURD_DEFAULT_PAYLOAD_TO_PORT
+ translation function. */
type file_t = mach_port_copy_send_t
#ifdef FILE_INTRAN
intran: FILE_INTRAN
+intranpayload: FILE_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: file_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef FILE_OUTTRAN
outtran: FILE_OUTTRAN
@@ -37,6 +91,11 @@ destructor: FILE_DESTRUCTOR
type fsys_t = mach_port_copy_send_t
#ifdef FSYS_INTRAN
intran: FSYS_INTRAN
+intranpayload: FSYS_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: fsys_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef FSYS_OUTTRAN
outtran: FSYS_OUTTRAN
@@ -50,6 +109,11 @@ destructor: FSYS_DESTRUCTOR
type io_t = mach_port_copy_send_t
#ifdef IO_INTRAN
intran: IO_INTRAN
+intranpayload: IO_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: io_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef IO_OUTTRAN
outtran: IO_OUTTRAN
@@ -62,6 +126,11 @@ destructor: IO_DESTRUCTOR
type process_t = mach_port_copy_send_t
#ifdef PROCESS_INTRAN
intran: PROCESS_INTRAN
+intranpayload: PROCESS_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: process_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef PROCESS_OUTTRAN
outtran: PROCESS_OUTTRAN
@@ -74,6 +143,11 @@ destructor: PROCESS_DESTRUCTOR
type auth_t = mach_port_copy_send_t
#ifdef AUTH_INTRAN
intran: AUTH_INTRAN
+intranpayload: AUTH_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: auth_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef AUTH_OUTTRAN
outtran: AUTH_OUTTRAN
@@ -86,6 +160,11 @@ destructor: AUTH_DESTRUCTOR
type socket_t = mach_port_copy_send_t
#ifdef SOCKET_INTRAN
intran: SOCKET_INTRAN
+intranpayload: SOCKET_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: socket_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef SOCKET_OUTTRAN
outtran: SOCKET_OUTTRAN
@@ -99,6 +178,11 @@ destructor: SOCKET_DESTRUCTOR
type pf_t = mach_port_copy_send_t
#ifdef PF_INTRAN
intran: PF_INTRAN
+intranpayload: PF_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: pf_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef PF_OUTTRAN
outtran: PF_OUTTRAN
@@ -111,6 +195,11 @@ destructor: PF_DESTRUCTOR
type addr_port_t = mach_port_copy_send_t
#ifdef ADDRPORT_INTRAN
intran: ADDRPORT_INTRAN
+intranpayload: ADDRPORT_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: addr_port_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef ADDRPORT_OUTTRAN
outtran: ADDRPORT_OUTTRAN
@@ -123,6 +212,11 @@ destructor: ADDRPORT_DESTRUCTOR
type term_t = mach_port_copy_send_t
#ifdef TERM_INTRAN
intran: TERM_INTRAN
+intranpayload: TERM_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: term_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef TERM_OUTTRAN
outtran: TERM_OUTTRAN
@@ -135,6 +229,11 @@ destructor: TERM_DESTRUCTOR
type startup_t = mach_port_copy_send_t
#ifdef STARTUP_INTRAN
intran: STARTUP_INTRAN
+intranpayload: STARTUP_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: startup_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef STARTUP_OUTTRAN
outtran: STARTUP_OUTTRAN
@@ -147,6 +246,11 @@ destructor: STARTUP_DESTRUCTOR
type fs_notify_t = mach_port_copy_send_t
#ifdef FS_NOTIFY_INTRAN
intran: FS_NOTIFY_INTRAN
+intranpayload: FS_NOTIFY_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: fs_notify_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef FS_NOTIFY_OUTTRAN
outtran: FS_NOTIFY_OUTTRAN
@@ -159,6 +263,11 @@ destructor: FS_NOTIFY_DESTRUCTOR
type exec_startup_t = mach_port_copy_send_t
#ifdef EXEC_STARTUP_INTRAN
intran: EXEC_STARTUP_INTRAN
+intranpayload: EXEC_STARTUP_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: exec_startup_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef EXEC_STARTUP_OUTTRAN
outtran: EXEC_STARTUP_OUTTRAN
@@ -171,6 +280,11 @@ destructor: EXEC_STARTUP_DESTRUCTOR
type interrupt_t = mach_port_copy_send_t
#ifdef INTERRUPT_INTRAN
intran: INTERRUPT_INTRAN
+intranpayload: INTERRUPT_INTRAN_PAYLOAD
+#else
+#ifdef HURD_DEFAULT_PAYLOAD_TO_PORT
+intranpayload: exec_startup_t HURD_DEFAULT_PAYLOAD_TO_PORT
+#endif
#endif
#ifdef INTERRUPT_OUTTRAN
outtran: INTERRUPT_OUTTRAN
@@ -184,7 +298,11 @@ destructor: INTERRUPT_DESTRUCTOR
type proccoll_t = mach_port_copy_send_t;
type sreply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE | polymorphic
- ctype: mach_port_t;
+ ctype: mach_port_t
+#ifdef MACH_PAYLOAD_TO_PORT
+intranpayload: mach_port_t MACH_PAYLOAD_TO_PORT
+#endif /* MACH_PAYLOAD_TO_PORT */
+;
/* These macros are used in some .defs files so that every routine has a
server reply port argument #ifdef REPLY_PORTS. */
diff --git a/hurd/paths.h b/hurd/paths.h
index 92875b2..a13ba9b 100644
--- a/hurd/paths.h
+++ b/hurd/paths.h
@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA
02139, USA. */
#define _SERVERS "/servers/"
#define _SERVERS_CRASH _SERVERS "crash"
#define _SERVERS_EXEC _SERVERS "exec"
+#define _SERVERS_STARTUP _SERVERS "startup"
#define _SERVERS_PROC _SERVERS "proc"
#define _SERVERS_PASSWORD _SERVERS "password"
#define _SERVERS_DEFPAGER _SERVERS "default-pager"
@@ -39,7 +40,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA
02139, USA. */
the canonical pathname being /hurd/foo. */
#define _HURD "/hurd/"
-#define _HURD_INIT _HURD "init"
+#define _HURD_STARTUP _HURD "startup"
#define _HURD_PROC _HURD "proc"
#define _HURD_AUTH _HURD "auth"
diff --git a/hurd/process.defs b/hurd/process.defs
index bf90556..498faba 100644
--- a/hurd/process.defs
+++ b/hurd/process.defs
@@ -373,7 +373,11 @@ routine proc_getnports (
/*** Routines related to early server bootstrapping ***/
-skip; /* Reserved for proc_set_init_task */
+/* Set the task of process HURD_PID_INIT. Only the startup process
+ HURD_PID_STARTUP may use this interface. */
+routine proc_set_init_task (
+ process: process_t;
+ task: task_t);
/* Inform the process server that the process is important. */
routine proc_mark_important (
diff --git a/hurd/process_reply.defs b/hurd/process_reply.defs
index ed46d55..80454a6 100644
--- a/hurd/process_reply.defs
+++ b/hurd/process_reply.defs
@@ -177,7 +177,7 @@ simpleroutine proc_getnports_reply (
/*** Routines related to early server bootstrapping ***/
-skip; /* Reserved for proc_set_init_task */
+skip; /* proc_set_init_task */
skip; /* proc_mark_important */
simpleroutine proc_is_important_reply (
diff --git a/hurd/process_request.defs b/hurd/process_request.defs
index 38e7146..7565f03 100644
--- a/hurd/process_request.defs
+++ b/hurd/process_request.defs
@@ -374,7 +374,12 @@ simpleroutine proc_getnports_request (
/*** Routines related to early server bootstrapping ***/
-skip; /* Reserved for proc_set_init_task */
+/* Set the task of process HURD_PID_INIT. Only the startup process
+ HURD_PID_STARTUP may use this interface. */
+simpleroutine proc_set_init_task_request (
+ process: process_t;
+ ureplyport reply: reply_port_t;
+ task: task_t);
/* Inform the process server that the process is important. */
simpleroutine proc_mark_important_request (
diff --git a/hurd/term.defs b/hurd/term.defs
index 45d825d..29b94ef 100644
--- a/hurd/term.defs
+++ b/hurd/term.defs
@@ -33,6 +33,9 @@ type ctty_t = mach_port_copy_send_t
#ifdef CTTY_INTRAN
intran: CTTY_INTRAN
#endif
+#ifdef CTTY_INTRAN_PAYLOAD
+intranpayload: CTTY_INTRAN_PAYLOAD
+#endif
#ifdef CTTY_OUTTRAN
outtran: CTTY_OUTTRAN
#endif
diff --git a/include/Makefile b/include/Makefile
index 4de165d..b8773fe 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -22,7 +22,7 @@
dir := include
makemode := misc
-installhdrs := sys/procfs.h refcount.h
+installhdrs := sys/procfs.h
include ../Makeconf
diff --git a/include/pids.h b/include/pids.h
index 22415f4..dff7635 100644
--- a/include/pids.h
+++ b/include/pids.h
@@ -22,8 +22,9 @@
#ifndef _HURD_PROCESSES_H
#define _HURD_PROCESSES_H
-#define HURD_PID_STARTUP 1
-#define HURD_PID_KERNEL 2
-#define HURD_PID_PROC 3
+#define HURD_PID_INIT 1
+#define HURD_PID_STARTUP 2
+#define HURD_PID_KERNEL 3
+#define HURD_PID_PROC 4
#endif /* _HURD_PROCESSES_H */
diff --git a/init/Makefile b/init/Makefile
index ffb82ff..07b8026 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 1994,95,96,99,2001 Free Software Foundation, Inc.
+# Copyright (C) 2013 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -12,20 +12,13 @@
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
dir := init
makemode := server
-SRCS = init.c stubs.c
-OBJS = $(SRCS:.c=.o) \
- startupServer.o notifyServer.o startup_replyUser.o msgServer.o \
- startup_notifyUser.o
+SRCS = init.c
+OBJS = $(SRCS:.c=.o)
target = init
-HURDLIBS = shouldbeinlibc
include ../Makeconf
-
-mung_msg_S.h: msg_S.h
- sed 's/msg_server/mung_msg_server/' < $< > $@
diff --git a/init/init.c b/init/init.c
index b7b40bd..b3d3301 100644
--- a/init/init.c
+++ b/init/init.c
@@ -1,7 +1,6 @@
-/* Start and maintain hurd core servers and system run state
+/* A minimalist init for the Hurd
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2005, 2008, 2013 Free Software Foundation, Inc.
+ Copyright (C) 2013,14 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
@@ -15,1579 +14,142 @@
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. */
+ along with the Hurd. If not, see <http://www.gnu.org/licenses/>. */
-/* Written by Michael I. Bushnell and Roland McGrath. */
-
-/* This is probably more include files than I've ever seen before for
- one file. */
+#include <argp.h>
+#include <error.h>
#include <hurd.h>
-#include <hurd/fs.h>
-#include <hurd/fsys.h>
-#include <device/device.h>
+#include <signal.h>
#include <stdio.h>
-#include <assert.h>
-#include <hurd/paths.h>
-#include <sys/reboot.h>
-#include <sys/file.h>
-#include <unistd.h>
#include <string.h>
-#include <mach/notify.h>
-#include <stdlib.h>
-#include <hurd/msg.h>
-#include <hurd/term.h>
-#include <hurd/fshelp.h>
-#include <paths.h>
-#include <sys/mman.h>
-#include <hurd/msg_server.h>
-#include <wire.h>
+#include <sys/types.h>
#include <sys/wait.h>
-#include <error.h>
-#include <hurd/msg_reply.h>
-#include <argz.h>
-#include <maptime.h>
+#include <unistd.h>
#include <version.h>
-#include <argp.h>
-#include <pids.h>
-
-#include "startup_notify_U.h"
-#include "startup_reply_U.h"
-#include "startup_S.h"
-#include "notify_S.h"
-#include "mung_msg_S.h"
-
-/* host_reboot flags for when we crash. */
-static int crash_flags = RB_AUTOBOOT;
-
-#define BOOT(flags) ((flags & RB_HALT) ? "halt" : "reboot")
-
const char *argp_program_version = STANDARD_HURD_VERSION (init);
-
+static pid_t child_pid;
+static int single;
+
static struct argp_option
options[] =
{
- {"single-user", 's', 0, 0, "Startup system in single-user mode"},
- {"query", 'q', 0, 0, "Ask for the names of servers to start"},
- {"init-name", 'n', 0, 0 },
- {"crash-debug", 'H', 0, 0, "On system crash, go to kernel debugger"},
- {"debug", 'd', 0, 0 },
- {"fake-boot", 'f', 0, 0, "This hurd hasn't been booted on the raw
machine"},
- {0, 'x', 0, OPTION_HIDDEN},
+ /* XXX: Currently, -s does nothing. */
+ {"single-user", 's', NULL, 0, "Startup system in single-user mode", 0},
+ {NULL, 'a', NULL, 0, "Ignored for compatibility with sysvinit", 0},
{0}
};
-static char doc[] = "Start and maintain hurd core servers and system run
state";
-
-static int booted; /* Set when the core servers are up. */
-
-/* This structure keeps track of each notified task. */
-struct ntfy_task
- {
- mach_port_t notify_port;
- struct ntfy_task *next;
- char *name;
- };
-
-/* This structure keeps track of each registered essential task. */
-struct ess_task
- {
- struct ess_task *next;
- task_t task_port;
- char *name;
- };
-
-/* These are linked lists of all of the registered items. */
-static struct ess_task *ess_tasks;
-static struct ntfy_task *ntfy_tasks;
-
-
-/* Our receive right */
-static mach_port_t startup;
-
-/* Ports to the kernel */
-static mach_port_t host_priv, device_master;
-
-/* Args to bootstrap, expressed as flags */
-static int bootstrap_args = 0;
-
-/* Stored information for returning proc and auth startup messages. */
-static mach_port_t procreply, authreply;
-static mach_msg_type_name_t procreplytype, authreplytype;
-
-/* Our ports to auth and proc. */
-static mach_port_t authserver;
-static mach_port_t procserver;
-
-/* Our bootstrap port, on which we call fsys_getpriv and fsys_init. */
-static mach_port_t bootport;
-
-/* Set iff we are a `fake' bootstrap. */
-static int fakeboot;
-
-/* The tasks of auth and proc and the bootstrap filesystem. */
-static task_t authtask, proctask, fstask;
-
-static mach_port_t default_ports[INIT_PORT_MAX];
-static mach_port_t default_dtable[3];
-static int default_ints[INIT_INT_MAX];
-
-static char **global_argv;
-static char *startup_envz;
-static size_t startup_envz_len;
-
-void launch_system (void);
-void process_signal (int signo);
-
-/** Utility functions **/
-
-/* Read a string from stdin into BUF. */
-static int
-getstring (char *buf, size_t bufsize)
-{
- if (fgets (buf, bufsize, stdin) != NULL && buf[0] != '\0')
- {
- size_t len = strlen (buf);
- if (buf[len - 1] == '\n' || buf[len - 1] == '\r')
- buf[len - 1] = '\0';
- return 1;
- }
- return 0;
-}
-
-
-/** System shutdown **/
-
-/* Reboot the microkernel. */
-void
-reboot_mach (int flags)
-{
- if (fakeboot)
- {
- printf ("%s: Would %s Mach with flags %#x\n",
- program_invocation_short_name, BOOT (flags), flags);
- fflush (stdout);
- exit (1);
- }
- else
- {
- error_t err;
- printf ("%s: %sing Mach (flags %#x)...\n",
- program_invocation_short_name, BOOT (flags), flags);
- fflush (stdout);
- sleep (5);
- while ((err = host_reboot (host_priv, flags)))
- error (0, err, "reboot");
- for (;;);
- }
-}
-
-/* Reboot the microkernel, specifying that this is a crash. */
-void
-crash_mach (void)
-{
- reboot_mach (crash_flags);
-}
-
-/* Notify all tasks that have requested shutdown notifications */
-void
-notify_shutdown (const char *msg)
-{
- struct ntfy_task *n;
-
- for (n = ntfy_tasks; n != NULL; n = n->next)
- {
- error_t err;
- printf ("%s: notifying %s of %s...",
- program_invocation_short_name, n->name, msg);
- fflush (stdout);
- err = startup_dosync (n->notify_port, 60000); /* 1 minute to reply */
- if (err == MACH_SEND_INVALID_DEST)
- puts ("(no longer present)");
- else if (err)
- puts (strerror (err));
- else
- puts ("done");
- fflush (stdout);
- }
-}
-
-/* Reboot the Hurd. */
-void
-reboot_system (int flags)
-{
- notify_shutdown ("shutdown");
-
- if (fakeboot)
- {
- pid_t *pp;
- size_t npids = 0;
- error_t err;
- int ind;
-
- err = proc_getallpids (procserver, &pp, &npids);
- if (err == MACH_SEND_INVALID_DEST)
- {
- procbad:
- /* The procserver must have died. Give up. */
- error (0, 0, "Can't simulate crash; proc has died");
- reboot_mach (flags);
- }
- for (ind = 0; ind < npids; ind++)
- {
- task_t task;
-
- err = proc_pid2task (procserver, pp[ind], &task);
- if (err == MACH_SEND_INVALID_DEST)
- goto procbad;
- else if (err)
- {
- error (0, err, "Getting task for pid %d", pp[ind]);
- continue;
- }
-
- /* Postpone self so we can finish; postpone proc
- so that we can finish. */
- if (task != mach_task_self () && task != proctask)
- {
- struct procinfo *pi = 0;
- size_t pisize = 0;
- char *noise;
- size_t noise_len = 0;
- int flags;
- err = proc_getprocinfo (procserver, pp[ind], &flags,
- (int **)&pi, &pisize,
- &noise, &noise_len);
- if (err == MACH_SEND_INVALID_DEST)
- goto procbad;
- if (err)
- {
- error (0, err, "Getting procinfo for pid %d", pp[ind]);
- continue;
- }
- if (!(pi->state & PI_NOPARENT))
- {
- printf ("%s: Killing pid %d\n",
- program_invocation_short_name, pp[ind]);
- fflush (stdout);
- task_terminate (task);
- }
- if (noise_len > 0)
- munmap (noise, noise_len);
- }
- }
- printf ("%s: Killing proc server\n", program_invocation_short_name);
- fflush (stdout);
- task_terminate (proctask);
- printf ("%s: Exiting", program_invocation_short_name);
- fflush (stdout);
- }
- reboot_mach (flags);
-}
-
-/* Reboot the Hurd, specifying that this is a crash. */
-void
-crash_system (void)
-{
- reboot_system (crash_flags);
-}
-
-
+static char doc[] = "A minimalist init for the Hurd";
-/* Request a dead-name notification sent to our port. */
-static void
-request_dead_name (mach_port_t name)
-{
- mach_port_t prev;
- mach_port_request_notification (mach_task_self (), name,
- MACH_NOTIFY_DEAD_NAME, 1, startup,
- MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev);
- if (prev != MACH_PORT_NULL)
- mach_port_deallocate (mach_task_self (), prev);
-}
-
-/* Record an essential task in the list. */
static error_t
-record_essential_task (const char *name, task_t task)
-{
- struct ess_task *et;
- /* Record this task as essential. */
- et = malloc (sizeof (struct ess_task));
- if (et == NULL)
- return ENOMEM;
- et->task_port = task;
- et->name = strdup (name);
- if (et->name == NULL)
- {
- free (et);
- return ENOMEM;
- }
- et->next = ess_tasks;
- ess_tasks = et;
-
- /* Dead-name notification on the task port will tell us when it dies. */
- request_dead_name (task);
-
-#if 0
- /* Taking over the exception port will give us a better chance
- if the task tries to get wedged on a fault. */
- task_set_special_port (task, TASK_EXCEPTION_PORT, startup);
-#endif
-
- return 0;
-}
-
-
-/** Starting programs **/
-
-/* Run SERVER, giving it INIT_PORT_MAX initial ports from PORTS.
- Set TASK to be the task port of the new image. */
-void
-run (const char *server, mach_port_t *ports, task_t *task)
-{
- char buf[BUFSIZ];
- const char *prog = server;
-
- if (bootstrap_args & RB_INITNAME)
- {
- printf ("Server file name (default %s): ", server);
- if (getstring (buf, sizeof (buf)))
- prog = buf;
- }
-
- while (1)
- {
- file_t file;
- error_t err;
-
- file = file_name_lookup (prog, O_EXEC, 0);
- if (file == MACH_PORT_NULL)
- error (0, errno, "%s", prog);
- else
- {
- task_create (mach_task_self (),
-#ifdef KERN_INVALID_LEDGER
- NULL, 0, /* OSF Mach */
-#endif
- 0, task);
- if (bootstrap_args & RB_KDB)
- {
- printf ("Pausing for %s\n", prog);
- getchar ();
- }
- err = file_exec (file, *task, 0,
- (char *)prog, strlen (prog) + 1, /* Args. */
- startup_envz, startup_envz_len,
- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
- ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
- default_ints, INIT_INT_MAX,
- NULL, 0, NULL, 0);
- if (!err)
- break;
-
- error (0, err, "%s", prog);
- }
-
- printf ("File name for server %s (or nothing to reboot): ", server);
- if (getstring (buf, sizeof (buf)))
- prog = buf;
- else
- crash_system ();
- }
-
-#if 0
- printf ("started %s\n", prog);
- fflush (stdout);
-#endif
-
- /* Dead-name notification on the task port will tell us when it dies,
- so we can crash if we don't make it to a fully bootstrapped Hurd. */
- request_dead_name (*task);
-}
-
-/* Run FILENAME as root with ARGS as its argv (length ARGLEN). Return
- the task that we started. If CTTY is set, then make that the
- controlling terminal of the new process and put it in its own login
- collection. If SETSID is set, put it in a new session. Return
- 0 if the task was not created successfully. */
-pid_t
-run_for_real (char *filename, char *args, int arglen, mach_port_t ctty,
- int setsid)
-{
- file_t file;
- error_t err;
- task_t task;
- char *progname;
- int pid;
-
-#if 0
- char buf[512];
- do
- {
- printf ("File name [%s]: ", filename);
- if (getstring (buf, sizeof (buf)) && *buf)
- filename = buf;
- file = file_name_lookup (filename, O_EXEC, 0);
- if (file == MACH_PORT_NULL)
- error (0, errno, "%s", filename);
- }
- while (file == MACH_PORT_NULL);
-#else
- file = file_name_lookup (filename, O_EXEC, 0);
- if (file == MACH_PORT_NULL)
- {
- error (0, errno, "%s", filename);
- return 0;
- }
-#endif
-
- task_create (mach_task_self (),
-#ifdef KERN_INVALID_LEDGER
- NULL, 0, /* OSF Mach */
-#endif
- 0, &task);
- proc_child (procserver, task);
- proc_task2pid (procserver, task, &pid);
- proc_task2proc (procserver, task, &default_ports[INIT_PORT_PROC]);
- proc_mark_exec (default_ports[INIT_PORT_PROC]);
- if (setsid)
- proc_setsid (default_ports[INIT_PORT_PROC]);
- if (ctty != MACH_PORT_NULL)
- {
- term_getctty (ctty, &default_ports[INIT_PORT_CTTYID]);
- io_mod_owner (ctty, -pid);
- proc_make_login_coll (default_ports[INIT_PORT_PROC]);
- }
- if (bootstrap_args & RB_KDB)
- {
- printf ("Pausing for %s\n", filename);
- getchar ();
- }
- progname = strrchr (filename, '/');
- if (progname)
- ++progname;
- else
- progname = filename;
- err = file_exec (file, task, 0,
- args, arglen,
- startup_envz, startup_envz_len,
- default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
- default_ports, MACH_MSG_TYPE_COPY_SEND,
- INIT_PORT_MAX,
- default_ints, INIT_INT_MAX,
- NULL, 0, NULL, 0);
- mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]);
- mach_port_deallocate (mach_task_self (), task);
- if (ctty != MACH_PORT_NULL)
- {
- mach_port_deallocate (mach_task_self (),
- default_ports[INIT_PORT_CTTYID]);
- default_ports[INIT_PORT_CTTYID] = MACH_PORT_NULL;
- }
- mach_port_deallocate (mach_task_self (), file);
- if (err)
- {
- error (0, err, "Cannot execute %s", filename);
- return 0;
- }
- return pid;
-}
-
-
-/** Main program and setup **/
-
-static int
-demuxer (mach_msg_header_t *inp,
- mach_msg_header_t *outp)
-{
- extern int notify_server (), startup_server (), msg_server ();
-
- return (notify_server (inp, outp) ||
- msg_server (inp, outp) ||
- startup_server (inp, outp));
-}
-
-static int
parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
- case 'q': bootstrap_args |= RB_ASKNAME; break;
- case 's': bootstrap_args |= RB_SINGLE; break;
- case 'd': bootstrap_args |= RB_KDB; break;
- case 'n': bootstrap_args |= RB_INITNAME; break;
- case 'f': fakeboot = 1; break;
- case 'H': crash_flags = RB_DEBUGGER; break;
- case 'x': /* NOP */ break;
- default: return ARGP_ERR_UNKNOWN;
- }
- return 0;
-}
-
-int
-main (int argc, char **argv, char **envp)
-{
- volatile int err;
- int i;
- int flags;
- mach_port_t consdev;
- struct argp argp = { options, parse_opt, 0, doc };
-
- /* Parse the arguments. We don't want the vector reordered, we
- should pass on to our child the exact arguments we got and just
- ignore any arguments that aren't flags for us. ARGP_NO_ERRS
- suppresses --help and --version, so we only use that option if we
- are booting. */
- flags = ARGP_IN_ORDER;
- if (getpid () == 0)
- flags |= ARGP_NO_ERRS;
- argp_parse (&argp, argc, argv, flags, 0, 0);
-
- if (getpid () > 0)
- error (2, 0, "can only be run by bootstrap filesystem");
-
- global_argv = argv;
-
- /* Fetch a port to the bootstrap filesystem, the host priv and
- master device ports, and the console. */
- if (task_get_bootstrap_port (mach_task_self (), &bootport)
- || fsys_getpriv (bootport, &host_priv, &device_master, &fstask)
- || device_open (device_master, D_WRITE, "console", &consdev))
- crash_mach ();
-
- wire_task_self ();
-
- /* Clear our bootstrap port so our children don't inherit it. */
- task_set_bootstrap_port (mach_task_self (), MACH_PORT_NULL);
-
- stderr = stdout = mach_open_devstream (consdev, "w");
- stdin = mach_open_devstream (consdev, "r");
- if (stdout == NULL || stdin == NULL)
- crash_mach ();
- setbuf (stdout, NULL);
-
- err = argz_create (envp, &startup_envz, &startup_envz_len);
- assert_perror (err);
-
- /* At this point we can use assert to check for errors. */
- err = mach_port_allocate (mach_task_self (),
- MACH_PORT_RIGHT_RECEIVE, &startup);
- assert_perror (err);
- err = mach_port_insert_right (mach_task_self (), startup, startup,
- MACH_MSG_TYPE_MAKE_SEND);
- assert_perror (err);
-
- /* Crash if the boot filesystem task dies. */
- request_dead_name (fstask);
-
- /* Set up the set of ports we will pass to the programs we exec. */
- for (i = 0; i < INIT_PORT_MAX; i++)
- switch (i)
- {
- case INIT_PORT_CRDIR:
- default_ports[i] = getcrdir ();
- break;
- case INIT_PORT_CWDIR:
- default_ports[i] = getcwdir ();
- break;
- default:
- default_ports[i] = MACH_PORT_NULL;
- break;
- }
-
- default_dtable[0] = getdport (0);
- default_dtable[1] = getdport (1);
- default_dtable[2] = getdport (2);
-
- /* All programs we start should ignore job control stop signals.
- That way Posix.1 B.2.2.2 is satisfied where it says that programs
- not run under job control shells are protected. */
- default_ints[INIT_SIGIGN] = (sigmask (SIGTSTP)
- | sigmask (SIGTTIN)
- | sigmask (SIGTTOU));
-
- default_ports[INIT_PORT_BOOTSTRAP] = startup;
- run ("/hurd/proc", default_ports, &proctask);
- printf (" proc");
- fflush (stdout);
- run ("/hurd/auth", default_ports, &authtask);
- printf (" auth");
- fflush (stdout);
- default_ports[INIT_PORT_BOOTSTRAP] = MACH_PORT_NULL;
-
- /* Wait for messages. When both auth and proc have started, we
- run launch_system which does the rest of the boot. */
- while (1)
- {
- err = mach_msg_server (demuxer, 0, startup);
- assert_perror (err);
- }
-}
-
-void
-launch_core_servers (void)
-{
- mach_port_t old;
- mach_port_t authproc, fsproc, procproc;
- error_t err;
-
- /* Reply to the proc and auth servers. */
- startup_procinit_reply (procreply, procreplytype, 0,
- mach_task_self (), authserver,
- host_priv, MACH_MSG_TYPE_COPY_SEND,
- device_master, MACH_MSG_TYPE_COPY_SEND);
- if (!fakeboot)
- {
- mach_port_deallocate (mach_task_self (), device_master);
- device_master = 0;
- }
-
- /* Mark us as important. */
- proc_mark_important (procserver);
- proc_mark_exec (procserver);
-
- /* Declare that the filesystem and auth are our children. */
- proc_child (procserver, fstask);
- proc_child (procserver, authtask);
-
- proc_task2proc (procserver, authtask, &authproc);
- proc_mark_important (authproc);
- proc_mark_exec (authproc);
- startup_authinit_reply (authreply, authreplytype, 0, authproc,
- MACH_MSG_TYPE_COPY_SEND);
- mach_port_deallocate (mach_task_self (), authproc);
-
- /* Give the library our auth and proc server ports. */
- _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], authserver);
- _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver);
-
- /* Do NOT run _hurd_proc_init! That will start signals, which we do not
- want. We listen to our own message port. Tell the proc server where
- our args and environment are. */
- proc_set_arg_locations (procserver,
- (vm_address_t) global_argv, (vm_address_t) environ);
-
- default_ports[INIT_PORT_AUTH] = authserver;
-
- /* Declare that the proc server is our child. */
- proc_child (procserver, proctask);
- err = proc_task2proc (procserver, proctask, &procproc);
- if (!err)
- {
- proc_mark_important (procproc);
- proc_mark_exec (procproc);
- mach_port_deallocate (mach_task_self (), procproc);
- }
-
- proc_register_version (procserver, host_priv, "init", "", HURD_VERSION);
-
- /* Get the bootstrap filesystem's proc server port.
- We must do this before calling proc_setmsgport below. */
- proc_task2proc (procserver, fstask, &fsproc);
- proc_mark_important (fsproc);
- proc_mark_exec (fsproc);
-
-#if 0
- printf ("Init has completed.\n");
- fflush (stdout);
-#endif
- printf (".\n");
- fflush (stdout);
-
- /* Tell the proc server our msgport. Be sure to do this after we are all
- done making requests of proc. Once we have done this RPC, proc
- assumes it can send us requests, so we cannot block on proc again
- before accepting more RPC requests! However, we must do this before
- calling fsys_init, because fsys_init blocks on exec_init, and
- exec_init will block waiting on our message port. */
- proc_setmsgport (procserver, startup, &old);
- if (old != MACH_PORT_NULL)
- mach_port_deallocate (mach_task_self (), old);
-
- /* Give the bootstrap FS its proc and auth ports. */
- err = fsys_init (bootport, fsproc, MACH_MSG_TYPE_COPY_SEND, authserver);
- mach_port_deallocate (mach_task_self (), fsproc);
- if (err)
- error (0, err, "fsys_init"); /* Not necessarily fatal. */
-}
-
-/* Set up the initial value of the standard exec data. */
-void
-init_stdarrays ()
-{
- auth_t nullauth;
- mach_port_t pt;
- mach_port_t ref;
- mach_port_t *std_port_array;
- int *std_int_array;
- int i;
-
- std_port_array = alloca (sizeof (mach_port_t) * INIT_PORT_MAX);
- std_int_array = alloca (sizeof (int) * INIT_INT_MAX);
-
- bzero (std_port_array, sizeof (mach_port_t) * INIT_PORT_MAX);
- bzero (std_int_array, sizeof (int) * INIT_INT_MAX);
-
- __USEPORT (AUTH, auth_makeauth (port, 0, MACH_MSG_TYPE_COPY_SEND, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, &nullauth));
-
- /* MAKE_SEND is safe in these transactions because we destroy REF
- ourselves each time. */
- pt = getcwdir ();
- ref = mach_reply_port ();
- io_reauthenticate (pt, ref, MACH_MSG_TYPE_MAKE_SEND);
- auth_user_authenticate (nullauth, ref, MACH_MSG_TYPE_MAKE_SEND,
- &std_port_array[INIT_PORT_CWDIR]);
- mach_port_destroy (mach_task_self (), ref);
- mach_port_deallocate (mach_task_self (), pt);
-
- pt = getcrdir ();
- ref = mach_reply_port ();
- io_reauthenticate (pt, ref, MACH_MSG_TYPE_MAKE_SEND);
- auth_user_authenticate (nullauth, ref, MACH_MSG_TYPE_MAKE_SEND,
- &std_port_array[INIT_PORT_CRDIR]);
- mach_port_destroy (mach_task_self (), ref);
- mach_port_deallocate (mach_task_self (), pt);
-
- std_port_array[INIT_PORT_AUTH] = nullauth;
-
- std_int_array[INIT_UMASK] = CMASK;
-
- __USEPORT (PROC, proc_setexecdata (port, std_port_array,
- MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
- std_int_array, INIT_INT_MAX));
- for (i = 0; i < INIT_PORT_MAX; i++)
- mach_port_deallocate (mach_task_self (), std_port_array[i]);
-}
-
-/* Frobnicate the kernel task and the proc server's idea of it (PID 2),
- so the kernel command line can be read as for a normal Hurd process. */
-
-void
-frob_kernel_process (void)
-{
- error_t err;
- int argc, i;
- char *argz, *entry;
- size_t argzlen;
- size_t windowsz;
- vm_address_t mine, his;
- task_t task;
- process_t proc, kbs;
-
- err = proc_pid2task (procserver, HURD_PID_KERNEL, &task);
- if (err)
- {
- error (0, err, "cannot get kernel task port");
- return;
- }
- err = proc_task2proc (procserver, task, &proc);
- if (err)
- {
- error (0, err, "cannot get kernel task's proc server port");
- mach_port_deallocate (mach_task_self (), task);
- return;
- }
-
- /* Mark the kernel task as an essential task so that we or the proc server
- never want to task_terminate it. */
- proc_mark_important (proc);
-
- err = record_essential_task ("kernel", task);
- assert_perror (err);
-
- err = task_get_bootstrap_port (task, &kbs);
- assert_perror (err);
- if (kbs == MACH_PORT_NULL)
- {
- /* The kernel task has no bootstrap port set, so we are presumably
- the first Hurd to boot. Install the kernel task's proc port from
- this Hurd's proc server as the task bootstrap port. Additional
- Hurds will see this. */
+ case 's':
+ single = 1;
+ break;
- err = task_set_bootstrap_port (task, proc);
- if (err)
- error (0, err, "cannot set kernel task's bootstrap port");
+ case 'a':
+ /* Ignored. */
+ break;
- if (fakeboot)
- error (0, 0, "warning: --fake-boot specified but I see no other Hurd");
+ default:
+ return ARGP_ERR_UNKNOWN;
}
- else
- {
- /* The kernel task has a bootstrap port set. Perhaps it is its proc
- server port from another Hurd. If so, propagate the kernel
- argument locations from that Hurd rather than diddling with the
- kernel task ourselves. */
-
- vm_address_t kargv, kenvp;
- err = proc_get_arg_locations (kbs, &kargv, &kenvp);
- mach_port_deallocate (mach_task_self (), kbs);
- if (err)
- error (0, err, "kernel task bootstrap port (ignoring)");
- else
- {
- err = proc_set_arg_locations (proc, kargv, kenvp);
- if (err)
- error (0, err, "cannot propagate original kernel command line");
- else
- {
- mach_port_deallocate (mach_task_self (), proc);
- mach_port_deallocate (mach_task_self (), task);
- if (! fakeboot)
- error (0, 0, "warning: "
- "I see another Hurd, but --fake-boot was not given");
- return;
- }
- }
- }
-
- /* Our arguments make up the multiboot command line used to boot the
- kernel. We'll write into the kernel task a page containing a
- canonical argv array and argz of those words. */
-
- err = argz_create (&global_argv[1], &argz, &argzlen);
- assert_perror (err);
- argc = argz_count (argz, argzlen);
-
- windowsz = round_page (((argc + 1) * sizeof (char *)) + argzlen);
- mine = (vm_address_t) mmap (0, windowsz, PROT_READ|PROT_WRITE,
- MAP_ANON, 0, 0);
- assert (mine != -1);
- err = vm_allocate (task, &his, windowsz, 1);
- if (err)
- {
- error (0, err, "cannot allocate %Zu bytes in kernel task", windowsz);
- free (argz);
- mach_port_deallocate (mach_task_self (), proc);
- mach_port_deallocate (mach_task_self (), task);
- munmap ((caddr_t) mine, windowsz);
- return;
- }
-
- for (i = 0, entry = argz; entry != NULL;
- ++i, entry = argz_next (argz, argzlen, entry))
- ((char **) mine)[i] = ((char *) &((char **) his)[argc + 1]
- + (entry - argz));
- ((char **) mine)[argc] = NULL;
- memcpy (&((char **) mine)[argc + 1], argz, argzlen);
-
- free (argz);
-
- /* We have the data all set up in our copy, now just write it over. */
- err = vm_write (task, his, mine, windowsz);
- mach_port_deallocate (mach_task_self (), task);
- munmap ((caddr_t) mine, windowsz);
- if (err)
- {
- error (0, err, "cannot write command line into kernel task");
- return;
- }
-
- /* The argument vector is set up in the kernel task at address HIS.
- Finally, we can inform the proc server where to find it. */
- err = proc_set_arg_locations (proc, his, his + (argc * sizeof (char *)));
- mach_port_deallocate (mach_task_self (), proc);
- if (err)
- error (0, err, "proc_set_arg_locations for kernel task");
+ return 0;
}
-/** Running userland. **/
-
-/* In the "split-init" setup, we just run a single program (usually
- /libexec/runsystem) that is not expected to ever exit (or stop).
- If it does exit (or can't be started), we go to an emergency single-user
- shell as a fallback. */
-
-
-static pid_t child_pid; /* PID of the child we run */
-static task_t child_task; /* and its (original) task port */
-
-error_t send_signal (mach_port_t msgport, int signal, mach_port_t refport,
- mach_msg_timeout_t);
-
-static void launch_something (const char *why);
-
-
-/* SIGNO has arrived and has been validated. Do whatever work it
- implies. */
void
-process_signal (int signo)
+sigchld_handler(int signal)
{
- if (signo == SIGCHLD)
- {
- /* A child died. Find its status. */
- int status;
- pid_t pid;
-
- while (1)
- {
- pid = waitpid (WAIT_ANY, &status, WNOHANG | WUNTRACED);
- if (pid <= 0)
- break; /* No more children. */
-
- /* Since we are init, orphaned processes get reparented to us and
- alas, all our adopted children eventually die. Woe is us. We
- just need to reap the zombies to relieve the proc server of
- its burden, and then we can forget about the little varmints. */
-
- if (pid == child_pid)
- {
- /* The big magilla bit the dust. */
-
- char *desc = 0;
-
- mach_port_deallocate (mach_task_self (), child_task);
- child_task = MACH_PORT_NULL;
- child_pid = -1;
-
- if (WIFSIGNALED (status))
- asprintf (&desc, "terminated abnormally (%s)",
- strsignal (WTERMSIG (status)));
- else if (WIFSTOPPED (status))
- asprintf (&desc, "stopped abnormally (%s)",
- strsignal (WTERMSIG (status)));
- else if (WEXITSTATUS (status) == 0)
- desc = strdup ("finished");
- else
- asprintf (&desc, "exited with status %d",
- WEXITSTATUS (status));
-
- {
- char buf[40];
- snprintf (buf, sizeof buf, "%d", status);
- setenv ("STATUS", buf, 1);
- }
+ /* A child died. Find its status. */
+ int status;
+ pid_t pid;
- launch_something (desc);
- free (desc);
- }
- }
- }
- else
+ while (1)
{
- /* Pass the signal on to the child. */
- task_t task;
- error_t err;
+ pid = waitpid (WAIT_ANY, &status, WNOHANG | WUNTRACED);
+ if (pid <= 0)
+ break; /* No more children. */
- err = proc_pid2task (procserver, child_pid, &task);
- if (err)
- {
- error (0, err, "proc_pid2task on %d", child_pid);
- task = child_task;
- }
- else
- {
- mach_port_deallocate (mach_task_self (), child_task);
- child_task = task;
- }
+ /* Since we are init, orphaned processes get reparented to us and
+ alas, all our adopted children eventually die. Woe is us. We
+ just need to reap the zombies to relieve the proc server of
+ its burden, and then we can forget about the little varmints. */
- if (signo == SIGKILL)
- {
- err = task_terminate (task);
- if (err != MACH_SEND_INVALID_DEST)
- error (0, err, "task_terminate");
- }
- else
+ if (pid == child_pid)
{
- mach_port_t msgport;
- err = proc_getmsgport (procserver, child_pid, &msgport);
- if (err)
- error (0, err, "proc_getmsgport");
+ /* The big magilla bit the dust. */
+ child_pid = -1;
+
+ char *desc = NULL;
+ if (WIFSIGNALED (status))
+ asprintf (&desc, "terminated abnormally (%s)",
+ strsignal (WTERMSIG (status)));
+ else if (WIFSTOPPED (status))
+ asprintf (&desc, "stopped abnormally (%s)",
+ strsignal (WTERMSIG (status)));
+ else if (WEXITSTATUS (status) == 0)
+ desc = strdup ("finished");
else
- {
- err = send_signal (msgport, signo, task,
- 500); /* Block only half a second. */
- mach_port_deallocate (mach_task_self (), msgport);
- if (err)
- {
- error (0, err, "cannot send %s to child %d",
- strsignal (signo), child_pid);
- err = task_terminate (task);
- if (err != MACH_SEND_INVALID_DEST)
- error (0, err, "task_terminate");
- }
- }
- }
- }
-}
+ asprintf (&desc, "exited with status %d",
+ WEXITSTATUS (status));
-/* Start the child program PROG. It is run via /libexec/console-run
- with the given additional arguments. */
-static int
-start_child (const char *prog, char **progargs)
-{
- file_t file;
- error_t err;
- char *args;
- size_t arglen;
-
- if (progargs == 0)
- {
- const char *argv[] = { "/libexec/console-run", prog, 0 };
- err = argz_create ((char **) argv, &args, &arglen);
- }
- else
- {
- int argc = 0;
- while (progargs[argc] != 0)
- ++argc;
- {
- const char *argv[2 + argc + 1];
- argv[0] = "/libexec/console-run";
- argv[1] = prog;
- argv[2 + argc] = 0;
- while (argc-- > 0)
- argv[2 + argc] = progargs[argc];
- err = argz_create ((char **) argv, &args, &arglen);
- }
- }
- assert_perror (err);
-
- file = file_name_lookup (args, O_EXEC, 0);
- if (file == MACH_PORT_NULL)
- {
- error (0, errno, "%s", args);
- free (args);
- return -1;
- }
-
- task_create (mach_task_self (),
-#ifdef KERN_INVALID_LEDGER
- NULL, 0, /* OSF Mach */
-#endif
- 0, &child_task);
- proc_child (procserver, child_task);
- proc_task2pid (procserver, child_task, &child_pid);
- proc_task2proc (procserver, child_task, &default_ports[INIT_PORT_PROC]);
-
- if (bootstrap_args & RB_KDB)
- {
- printf ("Pausing for %s\n", args);
- getchar ();
- }
+ error (0, 0, "child %s", desc);
+ free (desc);
- err = file_exec (file, child_task, 0,
- args, arglen,
- startup_envz, startup_envz_len,
- NULL, MACH_MSG_TYPE_COPY_SEND, 0, /* No fds. */
- default_ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
- default_ints, INIT_INT_MAX,
- NULL, 0, NULL, 0);
- proc_mark_important (default_ports[INIT_PORT_PROC]);
- mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]);
- mach_port_deallocate (mach_task_self (), file);
- if (err)
- {
- error (0, err, "Cannot execute %s", args);
- free (args);
- return -1;
- }
- free (args);
- return 0;
-}
-
-static void
-launch_something (const char *why)
-{
- file_t something;
- static unsigned int try;
- static const char *const tries[] =
- {
- "/libexec/runsystem",
- _PATH_BSHELL,
- "/bin/shd", /* XXX */
- };
-
- if (why)
- error (0, 0, "%s %s", tries[try - 1], why);
-
- something = file_name_lookup (tries[try], O_EXEC, 0);
- if (something != MACH_PORT_NULL)
- {
- mach_port_deallocate (mach_task_self (), something);
- if (try == 0 && start_child (tries[try++], &global_argv[1]) == 0)
- return;
- }
- else
- try++;
-
- while (try < sizeof tries / sizeof tries[0])
- {
- something = file_name_lookup (tries[try], O_EXEC, 0);
- if (something != MACH_PORT_NULL)
- {
- mach_port_deallocate (mach_task_self (), something);
- if (start_child (tries[try++], NULL) == 0)
- return;
+ /* XXX: launch emergency shell. */
+ error (23, 0, "panic!!");
}
}
-
- crash_system ();
-}
-
-void
-launch_system (void)
-{
- launch_something (0);
}
-/** RPC servers **/
-
-kern_return_t
-S_startup_procinit (startup_t server,
- mach_port_t reply,
- mach_msg_type_name_t reply_porttype,
- process_t proc,
- mach_port_t *startuptask,
- auth_t *auth,
- mach_port_t *priv,
- mach_msg_type_name_t *hostprivtype,
- mach_port_t *dev,
- mach_msg_type_name_t *devtype)
-{
- if (procserver)
- /* Only one proc server. */
- return EPERM;
-
- procserver = proc;
-
- procreply = reply;
- procreplytype = reply_porttype;
-
- /* Save the reply port until we get startup_authinit. */
- if (authserver)
- launch_core_servers ();
-
- return MIG_NO_REPLY;
-}
-
-/* Called by the auth server when it starts up. */
-
-kern_return_t
-S_startup_authinit (startup_t server,
- mach_port_t reply,
- mach_msg_type_name_t reply_porttype,
- mach_port_t auth,
- mach_port_t *proc,
- mach_msg_type_name_t *proctype)
-{
- if (authserver)
- /* Only one auth server. */
- return EPERM;
-
- authserver = auth;
-
- /* Save the reply port until we get startup_procinit. */
- authreply = reply;
- authreplytype = reply_porttype;
-
- if (procserver)
- launch_core_servers ();
-
- return MIG_NO_REPLY;
-}
-
-
-kern_return_t
-S_startup_essential_task (mach_port_t server,
- mach_port_t reply,
- mach_msg_type_name_t replytype,
- task_t task,
- mach_port_t excpt,
- char *name,
- mach_port_t credential)
+int
+main (int argc, char **argv)
{
- static int authinit, procinit, execinit;
- int fail;
-
- /* Always deallocate the extra reference this message carries. */
- if (MACH_PORT_VALID (credential))
- mach_port_deallocate (mach_task_self (), credential);
-
- if (credential != host_priv)
- return EPERM;
-
- fail = record_essential_task (name, task);
- if (fail)
- return fail;
-
- if (!booted)
+ struct argp argp =
{
- if (!strcmp (name, "auth"))
- authinit = 1;
- else if (!strcmp (name, "exec"))
- {
- execinit = 1;
- mach_port_t execproc;
- proc_task2proc (procserver, task, &execproc);
- proc_mark_important (execproc);
- }
- else if (!strcmp (name, "proc"))
- procinit = 1;
+ .options = options,
+ .parser = parse_opt,
+ .doc = doc,
+ };
+ argp_parse (&argp, argc, argv, 0, 0, 0);
- if (authinit && execinit && procinit)
- {
- /* Reply to this RPC, after that everything
- is ready for real startup to begin. */
- startup_essential_task_reply (reply, replytype, 0);
+ if (getpid () != 1)
+ error (1, 0, "can only be run as PID 1");
- init_stdarrays ();
- frob_kernel_process ();
+ struct sigaction sa;
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigemptyset (&sa.sa_mask);
- launch_system ();
+ sigaction (SIGHUP, &sa, NULL);
+ sigaction (SIGINT, &sa, NULL);
+ sigaction (SIGQUIT, &sa, NULL);
+ sigaction (SIGTERM, &sa, NULL);
+ sigaction (SIGUSR1, &sa, NULL);
+ sigaction (SIGUSR2, &sa, NULL);
+ sigaction (SIGTSTP, &sa, NULL);
- booted = 1;
+ sa.sa_handler = sigchld_handler;
+ sa.sa_flags |= SA_RESTART;
+ sigaction (SIGCHLD, &sa, NULL);
- return MIG_NO_REPLY;
- }
- }
+ char *args[] = { "/etc/hurd/runsystem.hurd", NULL };
- return 0;
-}
-
-kern_return_t
-S_startup_request_notification (mach_port_t server,
- mach_port_t notify,
- char *name)
-{
- struct ntfy_task *nt;
-
- request_dead_name (notify);
-
- /* Note that the ntfy_tasks list is kept in inverse order of the
- calls; this is important. We need later notification requests
- to get executed first. */
- nt = malloc (sizeof (struct ntfy_task));
- nt->notify_port = notify;
- nt->next = ntfy_tasks;
- ntfy_tasks = nt;
- nt->name = malloc (strlen (name) + 1);
- strcpy (nt->name, name);
- return 0;
-}
-
-kern_return_t
-do_mach_notify_dead_name (mach_port_t notify,
- mach_port_t name)
-{
- struct ntfy_task *nt, *pnt;
- struct ess_task *et;
-
- assert (notify == startup);
-
- /* Deallocate the extra reference the notification carries. */
- mach_port_deallocate (mach_task_self (), name);
-
- for (et = ess_tasks; et != NULL; et = et->next)
- if (et->task_port == name)
- /* An essential task has died. */
- {
- error (0, 0, "Crashing system; essential task %s died", et->name);
- crash_system ();
- }
-
- for (nt = ntfy_tasks, pnt = NULL; nt != NULL; pnt = nt, nt = nt->next)
- if (nt->notify_port == name)
- {
- /* Someone who wanted to be notified is gone. */
- mach_port_deallocate (mach_task_self (), name);
- if (pnt != NULL)
- pnt->next = nt->next;
- else
- ntfy_tasks = nt->next;
- free (nt);
-
- return 0;
- }
-
- if (! booted)
+ switch (child_pid = fork ())
{
- /* The system has not come up yet, so essential tasks are not yet
- registered. But the essential servers involved in the bootstrap
- handshake might crash before completing it, so we have requested
- dead-name notification on those tasks. */
- static const struct { task_t *taskp; const char *name; } boots[] =
- {
- {&fstask, "bootstrap filesystem"},
- {&authtask, "auth"},
- {&proctask, "proc"},
- };
- size_t i;
- for (i = 0; i < sizeof boots / sizeof boots[0]; ++i)
- if (name == *boots[i].taskp)
- {
- error (0, 0, "Crashing system; %s server died during bootstrap",
- boots[i].name);
- crash_mach ();
- }
- error (0, 0, "BUG! Unexpected dead-name notification (name %#zx)",
- name);
- crash_mach ();
+ case -1:
+ error (1, errno, "failed to fork");
+ case 0:
+ execv (args[0], args);
+ error (2, errno, "failed to execv child");
}
- return 0;
-}
-
-kern_return_t
-S_startup_reboot (mach_port_t server,
- mach_port_t refpt,
- int code)
-{
- if (refpt != host_priv)
- return EPERM;
-
- reboot_system (code);
- for (;;);
-}
-
-/* Stubs for unused notification RPCs. */
-
-kern_return_t
-do_mach_notify_port_destroyed (mach_port_t notify,
- mach_port_t rights)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_no_senders (mach_port_t port, mach_port_mscount_t mscount)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_port_deleted (mach_port_t notify,
- mach_port_t name)
-{
- return EOPNOTSUPP;
-}
-
-kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify,
- mach_port_t name)
-{
- return EOPNOTSUPP;
-}
-
-/* msg server */
-
-kern_return_t
-S_msg_sig_post_untraced (mach_port_t msgport,
- mach_port_t reply, mach_msg_type_name_t reply_type,
- int signo, natural_t sigcode, mach_port_t refport)
-{
- if (refport != mach_task_self ())
- return EPERM;
- mach_port_deallocate (mach_task_self (), refport);
-
- /* Reply immediately */
- msg_sig_post_untraced_reply (reply, reply_type, 0);
-
- process_signal (signo);
- return MIG_NO_REPLY;
-}
-
-kern_return_t
-S_msg_sig_post (mach_port_t msgport,
- mach_port_t reply, mach_msg_type_name_t reply_type,
- int signo, natural_t sigcode, mach_port_t refport)
-{
- if (refport != mach_task_self ())
- return EPERM;
- mach_port_deallocate (mach_task_self (), refport);
-
- /* Reply immediately */
- msg_sig_post_reply (reply, reply_type, 0);
-
- process_signal (signo);
- return MIG_NO_REPLY;
-}
-
-
-/* For the rest of the msg functions, just call the C library's
- internal server stubs usually run in the signal thread. */
-
-kern_return_t
-S_msg_proc_newids (mach_port_t process,
- mach_port_t task,
- pid_t ppid,
- pid_t pgrp,
- int orphaned)
-{ return _S_msg_proc_newids (process, task, ppid, pgrp, orphaned); }
-
-
-kern_return_t
-S_msg_add_auth (mach_port_t process,
- auth_t auth)
-{ return _S_msg_add_auth (process, auth); }
-
-
-kern_return_t
-S_msg_del_auth (mach_port_t process,
- mach_port_t task,
- intarray_t uids,
- mach_msg_type_number_t uidsCnt,
- intarray_t gids,
- mach_msg_type_number_t gidsCnt)
-{ return _S_msg_del_auth (process, task, uids, uidsCnt, gids, gidsCnt); }
-
-
-kern_return_t
-S_msg_get_init_port (mach_port_t process,
- mach_port_t refport,
- int which,
- mach_port_t *port,
- mach_msg_type_name_t *portPoly)
-{ return _S_msg_get_init_port (process, refport, which, port, portPoly); }
-
-
-kern_return_t
-S_msg_set_init_port (mach_port_t process,
- mach_port_t refport,
- int which,
- mach_port_t port)
-{ return _S_msg_set_init_port (process, refport, which, port); }
-
-
-kern_return_t
-S_msg_get_init_ports (mach_port_t process,
- mach_port_t refport,
- portarray_t *ports,
- mach_msg_type_name_t *portsPoly,
- mach_msg_type_number_t *portsCnt)
-{ return _S_msg_get_init_ports (process, refport, ports, portsPoly, portsCnt);
}
-
-
-kern_return_t
-S_msg_set_init_ports (mach_port_t process,
- mach_port_t refport,
- portarray_t ports,
- mach_msg_type_number_t portsCnt)
-{ return _S_msg_set_init_ports (process, refport, ports, portsCnt); }
-
-
-kern_return_t
-S_msg_get_init_int (mach_port_t process,
- mach_port_t refport,
- int which,
- int *value)
-{ return _S_msg_get_init_int (process, refport, which, value); }
-
-
-kern_return_t
-S_msg_set_init_int (mach_port_t process,
- mach_port_t refport,
- int which,
- int value)
-{ return _S_msg_set_init_int (process, refport, which, value); }
-
-
-kern_return_t
-S_msg_get_init_ints (mach_port_t process,
- mach_port_t refport,
- intarray_t *values,
- mach_msg_type_number_t *valuesCnt)
-{ return _S_msg_get_init_ints (process, refport, values, valuesCnt); }
-
-
-kern_return_t
-S_msg_set_init_ints (mach_port_t process,
- mach_port_t refport,
- intarray_t values,
- mach_msg_type_number_t valuesCnt)
-{ return _S_msg_set_init_ints (process, refport, values, valuesCnt); }
-
-
-kern_return_t
-S_msg_get_dtable (mach_port_t process,
- mach_port_t refport,
- portarray_t *dtable,
- mach_msg_type_name_t *dtablePoly,
- mach_msg_type_number_t *dtableCnt)
-{ return _S_msg_get_dtable (process, refport, dtable, dtablePoly, dtableCnt); }
-
-
-kern_return_t
-S_msg_set_dtable (mach_port_t process,
- mach_port_t refport,
- portarray_t dtable,
- mach_msg_type_number_t dtableCnt)
-{ return _S_msg_set_dtable (process, refport, dtable, dtableCnt); }
-
-
-kern_return_t
-S_msg_get_fd (mach_port_t process,
- mach_port_t refport,
- int fd,
- mach_port_t *port,
- mach_msg_type_name_t *portPoly)
-{ return _S_msg_get_fd (process, refport, fd, port, portPoly); }
-
-
-kern_return_t
-S_msg_set_fd (mach_port_t process,
- mach_port_t refport,
- int fd,
- mach_port_t port)
-{ return _S_msg_set_fd (process, refport, fd, port); }
-
-
-kern_return_t
-S_msg_get_environment (mach_port_t process,
- data_t *value,
- mach_msg_type_number_t *valueCnt)
-{ return _S_msg_get_environment (process, value, valueCnt); }
-
-
-kern_return_t
-S_msg_set_environment (mach_port_t process,
- mach_port_t refport,
- data_t value,
- mach_msg_type_number_t valueCnt)
-{ return _S_msg_set_environment (process, refport, value, valueCnt); }
-
-
-kern_return_t
-S_msg_get_env_variable (mach_port_t process,
- string_t variable,
- data_t *value,
- mach_msg_type_number_t *valueCnt)
-{ return _S_msg_get_env_variable (process, variable, value, valueCnt); }
-
-
-kern_return_t
-S_msg_set_env_variable (mach_port_t process,
- mach_port_t refport,
- string_t variable,
- string_t value,
- boolean_t replace)
-{ return _S_msg_set_env_variable (process, refport, variable, value, replace);
}
-
-error_t
-S_msg_describe_ports (mach_port_t process,
- mach_port_t refport,
- mach_port_array_t names,
- mach_msg_type_number_t namesCnt,
- data_t *descriptions,
- mach_msg_type_number_t *descriptionsCnt)
-{
- return _S_msg_describe_ports (process, refport, names, namesCnt,
- descriptions, descriptionsCnt);
-}
-
-error_t
-S_msg_report_wait (mach_port_t process, thread_t thread,
- string_t desc, mach_msg_id_t *rpc)
-{
- *desc = 0;
- *rpc = 0;
+ select (0, NULL, NULL, NULL, NULL);
+ /* Not reached. */
return 0;
}
diff --git a/init/stubs.c b/init/stubs.c
deleted file mode 100644
index 5292ab6..0000000
--- a/init/stubs.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* By-hand stubs for some RPC calls
- Copyright (C) 1994,96,99,2000 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdlib.h>
-#include <hurd/hurd_types.h>
-#include <mach.h>
-#include <string.h>
-#include <assert.h>
-
-/* From hurd/msg.defs: */
-#define RPCID_SIG_POST 23000
-
-
-/* Send signal SIGNO to MSGPORT with REFPORT as reference. Don't
- block in any fashion. */
-error_t
-send_signal (mach_port_t msgport,
- int signal,
- mach_port_t refport,
- mach_msg_timeout_t timeout)
-{
- error_t err;
-
- /* This message buffer might be modified by mach_msg in some error cases,
- so we cannot safely reuse a static buffer. */
- struct
- {
- mach_msg_header_t head;
- mach_msg_type_t signaltype;
- int signal;
- mach_msg_type_t sigcode_type;
- natural_t sigcode;
- mach_msg_type_t refporttype;
- mach_port_t refport;
- }
- message =
- {
- {
- /* Message header: */
- (MACH_MSGH_BITS_COMPLEX
- | MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
- MACH_MSG_TYPE_MAKE_SEND_ONCE)), /* msgh_bits */
- sizeof message, /* msgh_size */
- msgport, /* msgh_remote_port */
- MACH_PORT_NULL, /* msgh_local_port */
- 0, /* msgh_seqno */
- RPCID_SIG_POST, /* msgh_id */
- },
- {
- /* Type descriptor for signo */
- MACH_MSG_TYPE_INTEGER_32, /* msgt_name */
- 32, /* msgt_size */
- 1, /* msgt_number */
- 1, /* msgt_inline */
- 0, /* msgt_longform */
- 0, /* msgt_deallocate */
- 0, /* msgt_unused */
- },
- /* Signal number */
- signal,
- /* Type descriptor for sigcode */
- {
- MACH_MSG_TYPE_INTEGER_32, /* msgt_name */
- 32, /* msgt_size */
- 1, /* msgt_number */
- 1, /* msgt_inline */
- 0, /* msgt_longform */
- 0, /* msgt_deallocate */
- 0, /* msgt_unused */
- },
- /* Sigcode */
- 0,
- {
- /* Type descriptor for refport */
- MACH_MSG_TYPE_COPY_SEND, /* msgt_name */
- 32, /* msgt_size */
- 1, /* msgt_number */
- 1, /* msgt_inline */
- 0, /* msgt_longform */
- 0, /* msgt_deallocate */
- 0, /* msgt_unused */
- },
- /* Reference port */
- refport
- };
-
- err = mach_msg (&message.head,
- MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof message, 0,
- MACH_PORT_NULL, timeout, MACH_PORT_NULL);
-
- switch (err)
- {
- case MACH_SEND_TIMED_OUT:
- /* The send could not complete in time. In this error case, the
- kernel has modified the message buffer in a pseudo-receive
- operation. That means our COPY_SEND refs might now be MOVE_SEND
- refs, in which case each has gained user ref accordingly. To
- avoid leaking those refs, we must clean up the buffer. We don't
- use mach_msg_destroy because it assumes the local/remote ports in
- the header have been reversed as from a real receive, while a
- pseudo-receive leaves them as they were. */
- if (MACH_MSGH_BITS_REMOTE (message.head.msgh_bits)
- == MACH_MSG_TYPE_MOVE_SEND)
- mach_port_deallocate (mach_task_self (),
- message.head.msgh_remote_port);
- if (message.refporttype.msgt_name == MACH_MSG_TYPE_MOVE_SEND)
- mach_port_deallocate (mach_task_self (), message.refport);
- break;
-
- /* These are the other codes that mean a pseudo-receive modified
- the message buffer and we might need to clean up the send rights.
- None of them should be possible in our usage. */
- case MACH_SEND_INTERRUPTED:
- case MACH_SEND_INVALID_NOTIFY:
- case MACH_SEND_NO_NOTIFY:
- case MACH_SEND_NOTIFY_IN_PROGRESS:
- assert_perror (err);
- break;
-
- default: /* Other errors are safe to ignore. */
- break;
- }
-
- return err;
-}
diff --git a/libcons/mutations.h b/libcons/mutations.h
index c895447..4751340 100644
--- a/libcons/mutations.h
+++ b/libcons/mutations.h
@@ -21,6 +21,7 @@
/* Only CPP macro definitions should go in this file. */
#define FS_NOTIFY_INTRAN cons_notify_t begin_using_notify_port (fs_notify_t)
+#define FS_NOTIFY_INTRAN_PAYLOAD cons_notify_t begin_using_notify_payload
#define FS_NOTIFY_DESTRUCTOR end_using_notify_port (cons_notify_t)
#define FS_NOTIFY_IMPORTS import "priv.h";
diff --git a/libcons/priv.h b/libcons/priv.h
index 38971ff..6cdf3db 100644
--- a/libcons/priv.h
+++ b/libcons/priv.h
@@ -80,6 +80,12 @@ begin_using_notify_port (fs_notify_t port)
return ports_lookup_port (cons_port_bucket, port, cons_port_class);
}
+static inline cons_notify_t
+begin_using_notify_payload (unsigned long payload)
+{
+ return ports_lookup_payload (cons_port_bucket, payload, cons_port_class);
+}
+
/* Called by MiG after server routines have been run; this balances
begin_using_notify_port, and is arranged for the fs_notify
interfaces by mutations.h. */
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index a590975..cfe2303 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -33,7 +33,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA
02139, USA. */
#include <string.h>
#include <argz.h>
#include <error.h>
-#include <pids.h>
#include "exec_S.h"
#include "exec_startup_S.h"
#include "fsys_S.h"
@@ -46,7 +45,7 @@ static task_t parent_task = MACH_PORT_NULL;
static pthread_mutex_t execstartlock;
static pthread_cond_t execstarted;
-const char *diskfs_boot_init_program = _HURD_INIT;
+const char *diskfs_boot_init_program = _HURD_STARTUP;
static void start_execserver ();
@@ -602,9 +601,12 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
proc_register_version (procserver, host, diskfs_server_name, "",
diskfs_server_version);
+ mach_port_deallocate (mach_task_self (), procserver);
- err = proc_getmsgport (procserver, HURD_PID_STARTUP, &startup);
- if (!err)
+ startup = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+ if (startup == MACH_PORT_NULL)
+ error (0, errno, "%s", _SERVERS_STARTUP);
+ else
{
startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL,
diskfs_server_name, host);
@@ -612,7 +614,6 @@ diskfs_S_fsys_init (struct diskfs_control *pt,
}
mach_port_deallocate (mach_task_self (), host);
- mach_port_deallocate (mach_task_self (), procserver);
_diskfs_init_completed ();
diff --git a/libdiskfs/dir-init.c b/libdiskfs/dir-init.c
index 4efded0..8301ca1 100644
--- a/libdiskfs/dir-init.c
+++ b/libdiskfs/dir-init.c
@@ -33,7 +33,8 @@ diskfs_init_dir (struct node *dp, struct node *pdp, struct
protid *cred)
static uid_t zero = 0;
static struct idvec vec = {&zero, 1, 1};
static struct iouser user = {&vec, &vec, 0};
- struct protid lookupcred = {{0, 0, 0, 0}, &user, cred->po, 0, 0};
+ struct protid lookupcred = {{ .refcounts = { .references = {1, 0}}},
+ &user, cred->po, 0, 0};
/* New links */
if (pdp->dn_stat.st_nlink == diskfs_link_max - 1)
diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c
index 3950bf9..e228745 100644
--- a/libdiskfs/dir-lookup.c
+++ b/libdiskfs/dir-lookup.c
@@ -314,6 +314,7 @@ diskfs_S_dir_lookup (struct protid *dircred,
if (register_translator)
{
char *translator_path = strdupa (relpath);
+ char *complete_path;
if (nextname != NULL)
{
/* This was not the last path component.
@@ -326,9 +327,17 @@ diskfs_S_dir_lookup (struct protid *dircred,
translator_path[end - path_start] = '\0';
}
+ if (dircred->po->path == NULL)
+ /* dircred is the root directory. */
+ complete_path = translator_path;
+ else
+ asprintf (&complete_path, "%s/%s", dircred->po->path,
translator_path);
+
error = fshelp_set_active_translator (&newpi->pi,
- translator_path,
+ complete_path,
np->transbox.active);
+ if (complete_path != translator_path)
+ free(complete_path);
if (error)
goto out;
}
diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c
index 4083ef2..008aa2d 100644
--- a/libdiskfs/disk-pager.c
+++ b/libdiskfs/disk-pager.c
@@ -60,6 +60,7 @@ diskfs_start_disk_pager (struct user_pager_info *upi,
MACH_MSG_TYPE_MAKE_SEND);
/* Now map the disk image. */
+ *image = 0;
err = vm_map (mach_task_self (), (vm_address_t *)image, size,
0, 1, disk_pager_port, 0, 0,
VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE),
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index e59ba99..2818225 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -833,8 +833,14 @@ error_t diskfs_start_protid (struct peropen *po, struct
protid **cred);
void diskfs_finish_protid (struct protid *cred, struct iouser *user);
extern struct protid * diskfs_begin_using_protid_port (file_t port);
+extern struct protid *
+diskfs_begin_using_protid_payload (unsigned long payload);
extern struct diskfs_control * diskfs_begin_using_control_port (fsys_t port);
+extern struct diskfs_control *
+diskfs_begin_using_control_port_payload (unsigned long payload);
extern struct bootinfo *diskfs_begin_using_bootinfo_port (exec_startup_t port);
+struct bootinfo *
+diskfs_begin_using_bootinfo_payload (unsigned long payload);
extern void diskfs_end_using_protid_port (struct protid *cred);
extern void diskfs_end_using_control_port (struct diskfs_control *cred);
@@ -851,6 +857,14 @@ diskfs_begin_using_protid_port (file_t port)
return ports_lookup_port (diskfs_port_bucket, port, diskfs_protid_class);
}
+DISKFS_EXTERN_INLINE struct protid *
+diskfs_begin_using_protid_payload (unsigned long payload)
+{
+ return ports_lookup_payload (diskfs_port_bucket,
+ payload,
+ diskfs_protid_class);
+}
+
/* And for the fsys interface. */
DISKFS_EXTERN_INLINE struct diskfs_control *
diskfs_begin_using_control_port (fsys_t port)
@@ -858,6 +872,14 @@ diskfs_begin_using_control_port (fsys_t port)
return ports_lookup_port (diskfs_port_bucket, port, NULL);
}
+DISKFS_EXTERN_INLINE struct diskfs_control *
+diskfs_begin_using_control_port_payload (unsigned long payload)
+{
+ return ports_lookup_payload (diskfs_port_bucket,
+ payload,
+ NULL);
+}
+
/* And for the exec_startup interface. */
DISKFS_EXTERN_INLINE struct bootinfo *
diskfs_begin_using_bootinfo_port (exec_startup_t port)
@@ -865,6 +887,13 @@ diskfs_begin_using_bootinfo_port (exec_startup_t port)
return ports_lookup_port (diskfs_port_bucket, port, diskfs_execboot_class);
}
+DISKFS_EXTERN_INLINE struct bootinfo *
+diskfs_begin_using_bootinfo_payload (unsigned long payload)
+{
+ return ports_lookup_payload (diskfs_port_bucket,
+ payload,
+ diskfs_execboot_class);
+}
/* Called by MiG after server routines have been run; this
balances begin_using_protid_port, and is arranged for the io
diff --git a/libdiskfs/fsmutations.h b/libdiskfs/fsmutations.h
index 3f9362b..c2167c6 100644
--- a/libdiskfs/fsmutations.h
+++ b/libdiskfs/fsmutations.h
@@ -18,12 +18,15 @@
/* Only CPP macro definitions should go in this file. */
#define FILE_INTRAN protid_t diskfs_begin_using_protid_port (file_t)
+#define FILE_INTRAN_PAYLOAD protid_t diskfs_begin_using_protid_payload
#define FILE_DESTRUCTOR diskfs_end_using_protid_port (protid_t)
#define IO_INTRAN protid_t diskfs_begin_using_protid_port (io_t)
+#define IO_INTRAN_PAYLOAD protid_t diskfs_begin_using_protid_payload
#define IO_DESTRUCTOR diskfs_end_using_protid_port (protid_t)
#define FSYS_INTRAN control_t diskfs_begin_using_control_port (fsys_t)
+#define FSYS_INTRAN_PAYLOAD control_t diskfs_begin_using_control_port_payload
#define FSYS_DESTRUCTOR diskfs_end_using_control_port (control_t)
#define FILE_IMPORTS import "libdiskfs/priv.h";
@@ -33,6 +36,8 @@
#define EXEC_STARTUP_INTRAN \
bootinfo_t diskfs_begin_using_bootinfo_port (exec_startup_t)
+#define EXEC_STARTUP_INTRAN_PAYLOAD \
+ bootinfo_t diskfs_begin_using_bootinfo_payload
#define EXEC_STARTUP_DESTRUCTOR \
diskfs_end_using_bootinfo (bootinfo_t)
#define EXEC_STARTUP_IMPORTS \
diff --git a/libdiskfs/init-startup.c b/libdiskfs/init-startup.c
index d10c964..3a588e1 100644
--- a/libdiskfs/init-startup.c
+++ b/libdiskfs/init-startup.c
@@ -25,8 +25,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA
02139, USA. */
#include <fcntl.h>
#include <error.h>
#include <hurd/fsys.h>
+#include <hurd/paths.h>
#include <hurd/startup.h>
-#include <pids.h>
#include "startup_S.h"
@@ -195,15 +195,18 @@ _diskfs_init_completed ()
/* Mark us as important. */
err = proc_mark_important (proc);
+ mach_port_deallocate (mach_task_self (), proc);
/* This might fail due to permissions or because the old proc server
is still running, ignore any such errors. */
if (err && err != EPERM && err != EMIG_BAD_ID)
goto errout;
- err = proc_getmsgport (proc, HURD_PID_STARTUP, &init);
- mach_port_deallocate (mach_task_self (), proc);
- if (err)
- goto errout;
+ init = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+ if (init == MACH_PORT_NULL)
+ {
+ err = errno;
+ goto errout;
+ }
notify = ports_get_send_right (pi);
ports_port_deref (pi);
diff --git a/libdiskfs/opts-std-startup.c b/libdiskfs/opts-std-startup.c
index 6fe2875..ed25a18 100644
--- a/libdiskfs/opts-std-startup.c
+++ b/libdiskfs/opts-std-startup.c
@@ -59,7 +59,7 @@ startup_options[] =
"Required for bootstrap filesystem, the multiboot kernel command line"},
{"bootflags", 0, 0, OPTION_ALIAS|OPTION_HIDDEN},
{"boot-init-program", OPT_BOOT_INIT_PROGRAM, "FILE", 0,
- "For bootstrap filesystem, init program to run (default " _HURD_INIT ")"},
+ "For bootstrap filesystem, init program to run (default " _HURD_STARTUP
")"},
{"boot-debug-pause", OPT_BOOT_PAUSE, 0, 0,
"Pause for keystroke before starting bootstrap programs"},
{"boot-command", OPT_BOOT_COMMAND, 0, 0,
diff --git a/libfshelp/lock-acquire.c b/libfshelp/lock-acquire.c
index 574bc5c..06c93d8 100644
--- a/libfshelp/lock-acquire.c
+++ b/libfshelp/lock-acquire.c
@@ -23,17 +23,30 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA
02139, USA. */
#define EWOULDBLOCK EAGAIN /* XXX */
+/* Remove this when glibc has it. */
+#ifndef __LOCK_ATOMIC
+#define __LOCK_ATOMIC 16
+#endif
+
error_t
fshelp_acquire_lock (struct lock_box *box, int *user, pthread_mutex_t *mut,
int flags)
{
+ int atomic = 0;
+
if (!(flags & (LOCK_UN | LOCK_EX | LOCK_SH)))
return 0;
if ((flags & LOCK_UN)
&& (flags & (LOCK_SH | LOCK_EX)))
return EINVAL;
-
+
+ if (flags & __LOCK_ATOMIC)
+ {
+ atomic = 1;
+ flags &= ~__LOCK_ATOMIC;
+ }
+
if (flags & LOCK_EX)
flags &= ~LOCK_SH;
@@ -44,8 +57,10 @@ fshelp_acquire_lock (struct lock_box *box, int *user,
pthread_mutex_t *mut,
if (*user & LOCK_UN)
return 0;
- assert (*user == box->type);
- assert (*user == LOCK_SH || *user == LOCK_EX);
+ assert (*user == box->type ||
+ (*user == LOCK_SH && box->type == (LOCK_SH | LOCK_EX)));
+ assert (*user == LOCK_SH || *user == LOCK_EX ||
+ *user == (LOCK_SH | LOCK_EX));
if (*user == LOCK_SH)
{
@@ -60,12 +75,39 @@ fshelp_acquire_lock (struct lock_box *box, int *user,
pthread_mutex_t *mut,
box->waiting = 0;
pthread_cond_broadcast (&box->wait);
}
+ if (box->type == (LOCK_SH | LOCK_EX) && box->shcount == 1 &&
box->waiting)
+ {
+ box->waiting = 0;
+ pthread_cond_broadcast (&box->wait);
+ }
*user = LOCK_UN;
}
else
{
+ if (atomic && *user == (flags & (LOCK_SH | LOCK_EX)))
+ /* Already have it the right way. */
+ return 0;
+
+ if (atomic && *user == LOCK_EX && flags & LOCK_SH)
+ {
+ /* Easy atomic change. */
+ *user = LOCK_SH;
+ box->type = LOCK_SH;
+ box->shcount = 1;
+ if (box->waiting)
+ {
+ box->waiting = 0;
+ pthread_cond_broadcast (&box->wait);
+ }
+ return 0;
+ }
+
+ /* We can not have two people upgrading their lock, this is a deadlock!
*/
+ if (*user == LOCK_SH && atomic && box->type == (LOCK_SH | LOCK_EX))
+ return EDEADLK;
+
/* If we have an exclusive lock, release it. */
- if (*user == LOCK_EX)
+ if (*user == LOCK_EX && !atomic)
{
*user = LOCK_UN;
box->type = LOCK_UN;
@@ -75,19 +117,9 @@ fshelp_acquire_lock (struct lock_box *box, int *user,
pthread_mutex_t *mut,
pthread_cond_broadcast (&box->wait);
}
}
-
- /* If there is an exclusive lock, wait for it to end. */
- while (box->type == LOCK_EX)
- {
- if (flags & LOCK_NB)
- return EWOULDBLOCK;
- box->waiting = 1;
- if (pthread_hurd_cond_wait_np (&box->wait, mut))
- return EINTR;
- }
/* If we have a shared lock, release it. */
- if (*user == LOCK_SH)
+ if (*user == LOCK_SH && !atomic)
{
*user = LOCK_UN;
if (!--box->shcount)
@@ -99,12 +131,29 @@ fshelp_acquire_lock (struct lock_box *box, int *user,
pthread_mutex_t *mut,
pthread_cond_broadcast (&box->wait);
}
}
+ if (box->type == (LOCK_SH | LOCK_EX) && box->shcount == 1 &&
+ box->waiting)
+ {
+ box->waiting = 0;
+ pthread_cond_broadcast (&box->wait);
+ }
}
-
+
+ /* If there is another exclusive lock or a pending upgrade, wait for it
to
+ end. */
+ while (box->type & LOCK_EX)
+ {
+ if (flags & LOCK_NB)
+ return EWOULDBLOCK;
+ box->waiting = 1;
+ if (pthread_hurd_cond_wait_np (&box->wait, mut))
+ return EINTR;
+ }
+
assert ((flags & LOCK_SH) || (flags & LOCK_EX));
if (flags & LOCK_SH)
{
- assert (box->type != LOCK_EX);
+ assert (!(box->type & LOCK_EX));
*user = LOCK_SH;
box->type = LOCK_SH;
box->shcount++;
@@ -112,17 +161,27 @@ fshelp_acquire_lock (struct lock_box *box, int *user,
pthread_mutex_t *mut,
else if (flags & LOCK_EX)
{
/* Wait for any shared (and exclusive) locks to finish. */
- while (box->type != LOCK_UN)
+ while ((*user == LOCK_SH && box->shcount > 1) ||
+ (*user == LOCK_UN && box->type != LOCK_UN))
{
if (flags & LOCK_NB)
return EWOULDBLOCK;
else
{
+ /* Tell others that we are upgrading. */
+ if (*user == LOCK_SH && atomic)
+ box->type = LOCK_SH | LOCK_EX;
+
box->waiting = 1;
if (pthread_hurd_cond_wait_np (&box->wait, mut))
return EINTR;
}
}
+ if (*user == LOCK_SH)
+ {
+ assert (box->shcount == 1);
+ box->shcount = 0;
+ }
box->type = LOCK_EX;
*user = LOCK_EX;
}
diff --git a/libmachdev/Makefile b/libmachdev/Makefile
index a47bf32..345c004 100644
--- a/libmachdev/Makefile
+++ b/libmachdev/Makefile
@@ -31,6 +31,3 @@ OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
include ../Makeconf
-
-$(libname).so.$(hurd-version):
- echo "INPUT ( $(libname).a )" > $@
diff --git a/libmachdev/ds_routines.c b/libmachdev/ds_routines.c
index 6bd5a12..e9fbe94 100644
--- a/libmachdev/ds_routines.c
+++ b/libmachdev/ds_routines.c
@@ -87,52 +87,7 @@ boolean_t is_master_device (mach_port_t port);
* What follows is the interface for the native Mach devices.
*/
-static inline mach_port_t
-mach_convert_device_to_port (mach_device_t device)
-{
- if (device == NULL)
- return MACH_PORT_NULL;
-
- // TODO I have to somehow dereference it when it is called at the first time.
- return ports_get_right (device);
-}
-
/* Implementation of device interface */
-kern_return_t
-ds_xxx_device_set_status (struct mach_device *device, dev_flavor_t flavor,
- dev_status_t status, size_t statu_cnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_get_status (struct mach_device *device, dev_flavor_t flavor,
- dev_status_t status, size_t *statuscnt)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_xxx_device_set_filter (struct mach_device *device, mach_port_t rec,
- int pri, filter_array_t filt, size_t len)
-{
- return D_INVALID_OPERATION;
-}
-
-io_return_t
-ds_device_intr_register (mach_port_t master_port, int irq,
- int flags, int id, mach_port_t receive_port)
-{
- return D_INVALID_OPERATION;
-}
-
-kern_return_t
-ds_device_intr_enable (mach_port_t master_port,
- int line, char status)
-{
- return D_INVALID_OPERATION;
-}
-
io_return_t
ds_device_open (mach_port_t open_port, mach_port_t reply_port,
mach_msg_type_name_t reply_port_type, dev_mode_t mode,
diff --git a/libmachdev/net.c b/libmachdev/net.c
index e04b558..220121a 100644
--- a/libmachdev/net.c
+++ b/libmachdev/net.c
@@ -104,8 +104,6 @@ static struct net_data *nd_head;
extern struct device_emulation_ops linux_net_emulation_ops;
-static int print_packet_size = 1;
-
static mach_msg_type_t header_type =
{
MACH_MSG_TYPE_BYTE,
@@ -225,32 +223,25 @@ static void
netif_rx_handle (char *data, int len, struct net_device *dev)
{
int pack_size;
- net_rcv_msg_t net_msg;
+ struct net_rcv_msg net_msg;
struct ether_header *eh;
struct packet_header *ph;
struct net_data *nd;
- if (print_packet_size)
- printf ("netif_rx: length %d\n", len);
-
nd = search_nd(dev);
assert (nd);
- /* Allocate a kernel message buffer. */
- net_msg = malloc (sizeof (*net_msg));
- if (!net_msg)
- return;
-
pack_size = len - sizeof (struct ethhdr);
/* remember message sizes must be rounded up */
- net_msg->msg_hdr.msgh_size =
+ net_msg.msg_hdr.msgh_size =
(((mach_msg_size_t) (sizeof (struct net_rcv_msg)
- - sizeof net_msg->sent
+ - sizeof net_msg.sent
+ + sizeof (struct packet_header)
- NET_RCV_MAX + pack_size)) + 3) & ~3;
/* Copy packet into message buffer. */
- eh = (struct ether_header *) (net_msg->header);
- ph = (struct packet_header *) (net_msg->packet);
+ eh = (struct ether_header *) (net_msg.header);
+ ph = (struct packet_header *) (net_msg.packet);
memcpy (eh, data, sizeof (struct ether_header));
/* packet is prefixed with a struct packet_header,
see include/device/net_status.h. */
@@ -258,13 +249,12 @@ netif_rx_handle (char *data, int len, struct net_device
*dev)
ph->type = eh->h_proto;
ph->length = pack_size + sizeof (struct packet_header);
- net_msg->sent = FALSE; /* Mark packet as received. */
+ net_msg.sent = FALSE; /* Mark packet as received. */
- net_msg->header_type = header_type;
- net_msg->packet_type = packet_type;
- net_msg->net_rcv_msg_packet_count = ph->length;
- deliver_msg (net_msg, &nd->ifnet.port_list);
- free (net_msg);
+ net_msg.header_type = header_type;
+ net_msg.packet_type = packet_type;
+ net_msg.net_rcv_msg_packet_count = ph->length;
+ deliver_msg (&net_msg, &nd->ifnet.port_list);
}
/* Mach device interface routines. */
@@ -513,10 +503,10 @@ device_get_status (void *d, dev_flavor_t flavor,
dev_status_t status,
if (flavor == NET_FLAGS)
{
- if (*count != sizeof(short))
+ if (*count != 1)
return D_INVALID_SIZE;
- *(short *) status = netdev_flags (net->dev);
+ *(int *) status = netdev_flags (net->dev);
return D_SUCCESS;
}
diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c
index 99a8746..77cbbbd 100644
--- a/libnetfs/dir-lookup.c
+++ b/libnetfs/dir-lookup.c
@@ -260,7 +260,7 @@ netfs_S_dir_lookup (struct protid *diruser,
}
}
- boolean_t register_translator;
+ boolean_t register_translator = 0;
if (! error)
{
dirport = ports_get_send_right (newpi);
@@ -297,6 +297,7 @@ netfs_S_dir_lookup (struct protid *diruser,
if (register_translator)
{
char *translator_path = strdupa (relpath);
+ char *complete_path;
if (nextname != NULL)
{
/* This was not the last path component.
@@ -309,9 +310,17 @@ netfs_S_dir_lookup (struct protid *diruser,
translator_path[end - filename_start] = '\0';
}
+ if (diruser->po->path == NULL)
+ /* diruser is the root directory. */
+ complete_path = translator_path;
+ else
+ asprintf (&complete_path, "%s/%s", diruser->po->path,
translator_path);
+
error = fshelp_set_active_translator (&newpi->pi,
- translator_path,
+ complete_path,
np->transbox.active);
+ if (complete_path != translator_path)
+ free(complete_path);
if (error)
{
ports_port_deref (newpi);
diff --git a/libnetfs/mutations.h b/libnetfs/mutations.h
index e60a220..088d8a0 100644
--- a/libnetfs/mutations.h
+++ b/libnetfs/mutations.h
@@ -23,12 +23,15 @@
#define IO_SELECT_REPLY_PORT
#define FILE_INTRAN protid_t begin_using_protid_port (file_t)
+#define FILE_INTRAN_PAYLOAD protid_t begin_using_protid_payload
#define FILE_DESTRUCTOR end_using_protid_port (protid_t)
#define IO_INTRAN protid_t begin_using_protid_port (io_t)
+#define IO_INTRAN_PAYLOAD protid_t begin_using_protid_payload
#define IO_DESTRUCTOR end_using_protid_port (protid_t)
#define FSYS_INTRAN control_t begin_using_control_port (fsys_t)
+#define FSYS_INTRAN_PAYLOAD control_t begin_using_control_payload
#define FSYS_DESTRUCTOR end_using_control_port (control_t)
#define FILE_IMPORTS import "libnetfs/netfs.h"; import "libnetfs/priv.h";
diff --git a/libnetfs/priv.h b/libnetfs/priv.h
index ba31080..3c5bcd4 100644
--- a/libnetfs/priv.h
+++ b/libnetfs/priv.h
@@ -31,6 +31,12 @@ begin_using_protid_port (file_t port)
return ports_lookup_port (netfs_port_bucket, port, netfs_protid_class);
}
+static inline struct protid * __attribute__ ((unused))
+begin_using_protid_payload (unsigned long payload)
+{
+ return ports_lookup_payload (netfs_port_bucket, payload, netfs_protid_class);
+}
+
static inline void __attribute__ ((unused))
end_using_protid_port (struct protid *cred)
{
@@ -44,6 +50,12 @@ begin_using_control_port (fsys_t port)
return ports_lookup_port (netfs_port_bucket, port, netfs_control_class);
}
+static inline struct netfs_control * __attribute__ ((unused))
+begin_using_control_payload (unsigned long payload)
+{
+ return ports_lookup_payload (netfs_port_bucket, payload,
netfs_control_class);
+}
+
static inline void __attribute__ ((unused))
end_using_control_port (struct netfs_control *cred)
{
diff --git a/libpager/demuxer.c b/libpager/demuxer.c
index efdf285..a06c4bf 100644
--- a/libpager/demuxer.c
+++ b/libpager/demuxer.c
@@ -47,10 +47,16 @@ struct request
{
struct item item;
mig_routine_t routine;
- mach_msg_header_t *inp;
- mach_msg_header_t *outp;
};
+/* A struct request object is immediately followed by the received
+ message. */
+static inline mach_msg_header_t *
+request_inp (const struct request *r)
+{
+ return (mach_msg_header_t *) ((char *) r + sizeof *r);
+}
+
/* A worker. */
struct worker
{
@@ -81,10 +87,6 @@ pager_demuxer (struct requests *requests,
{
error_t err = MIG_NO_REPLY;
- /* The maximum size of the reply is 2048 bytes. See the MIG source
- for details. */
- const mach_msg_size_t max_size = 2048;
-
mig_routine_t routine;
if (! ((routine = _pager_seqnos_memory_object_server_routine (inp)) ||
(routine = _pager_seqnos_notify_server_routine (inp))))
@@ -94,7 +96,7 @@ pager_demuxer (struct requests *requests,
mach_msg_size_t padded_size = (inp->msgh_size + MASK) & ~MASK;
#undef MASK
- struct request *r = malloc (sizeof *r + padded_size + max_size);
+ struct request *r = malloc (sizeof *r + padded_size);
if (r == NULL)
{
err = ENOMEM;
@@ -102,11 +104,7 @@ pager_demuxer (struct requests *requests,
}
r->routine = routine;
- r->inp = (mach_msg_header_t *) ((char *) r + sizeof *r);
- memcpy (r->inp, inp, inp->msgh_size);
-
- r->outp = (mach_msg_header_t *) ((char *) r + sizeof *r + padded_size);
- memcpy (r->outp, outp, sizeof *outp);
+ memcpy (request_inp (r), inp, inp->msgh_size);
pthread_mutex_lock (&requests->lock);
@@ -126,6 +124,37 @@ pager_demuxer (struct requests *requests,
return TRUE;
}
+/* XXX: The libc should provide this function. */
+static void
+mig_reply_setup (
+ const mach_msg_header_t *in,
+ mach_msg_header_t *out)
+{
+ static const mach_msg_type_t RetCodeType = {
+ /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32,
+ /* msgt_size = */ 32,
+ /* msgt_number = */ 1,
+ /* msgt_inline = */ TRUE,
+ /* msgt_longform = */ FALSE,
+ /* msgt_deallocate = */ FALSE,
+ /* msgt_unused = */ 0
+ };
+
+#define InP (in)
+#define OutP ((mig_reply_header_t *) out)
+ OutP->Head.msgh_bits =
+ MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(InP->msgh_bits), 0);
+ OutP->Head.msgh_size = sizeof *OutP;
+ OutP->Head.msgh_remote_port = InP->msgh_remote_port;
+ OutP->Head.msgh_local_port = MACH_PORT_NULL;
+ OutP->Head.msgh_seqno = 0;
+ OutP->Head.msgh_id = InP->msgh_id + 100;
+ OutP->RetCodeType = RetCodeType;
+ OutP->RetCode = MIG_BAD_ID;
+#undef InP
+#undef OutP
+}
+
/* Consumes requests from the queue. */
static void *
worker_func (void *arg)
@@ -133,6 +162,7 @@ worker_func (void *arg)
struct worker *self = (struct worker *) arg;
struct requests *requests = self->requests;
struct request *r = NULL;
+ mig_reply_header_t reply_msg;
while (1)
{
@@ -165,7 +195,7 @@ worker_func (void *arg)
for (i = 0; i < WORKER_COUNT; i++)
if (requests->workers[i].tag
- == (unsigned long) r->inp->msgh_local_port)
+ == (unsigned long) request_inp (r)->msgh_local_port)
{
/* Some other thread is working on that object. Delegate
the request to that worker. */
@@ -174,18 +204,20 @@ worker_func (void *arg)
}
/* Claim responsibility for this object by setting our tag. */
- self->tag = (unsigned long) r->inp->msgh_local_port;
+ self->tag = (unsigned long) request_inp (r)->msgh_local_port;
got_one:
pthread_mutex_unlock (&requests->lock);
+ mig_reply_setup (request_inp (r), (mach_msg_header_t *) &reply_msg);
+
/* Call the server routine. */
- (*r->routine) (r->inp, r->outp);
+ (*r->routine) (request_inp (r), (mach_msg_header_t *) &reply_msg);
/* What follows is basically the second part of
mach_msg_server_timeout. */
- mig_reply_header_t *request = (mig_reply_header_t *) r->inp;
- mig_reply_header_t *reply = (mig_reply_header_t *) r->outp;
+ mig_reply_header_t *request = (mig_reply_header_t *) request_inp (r);
+ mig_reply_header_t *reply = &reply_msg;
switch (reply->RetCode)
{
diff --git a/libpager/mig-decls.h b/libpager/mig-decls.h
index 0c7b402..7e6b64f 100644
--- a/libpager/mig-decls.h
+++ b/libpager/mig-decls.h
@@ -32,6 +32,12 @@ begin_using_pager (mach_port_t port)
return ports_lookup_port (0, port, _pager_class);
}
+static inline struct pager * __attribute__ ((unused))
+begin_using_pager_payload (unsigned long payload)
+{
+ return ports_lookup_payload (0, payload, _pager_class);
+}
+
static inline void __attribute__ ((unused))
end_using_pager (struct pager *p)
{
diff --git a/libpager/mig-mutate.h b/libpager/mig-mutate.h
index 9e9065f..c4f30ce 100644
--- a/libpager/mig-mutate.h
+++ b/libpager/mig-mutate.h
@@ -18,11 +18,14 @@
along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
#define MEMORY_OBJECT_INTRAN pager_t begin_using_pager (memory_object_t)
+#define MEMORY_OBJECT_INTRAN_PAYLOAD pager_t begin_using_pager_payload
#define MEMORY_OBJECT_DESTRUCTOR end_using_pager (pager_t)
#define MEMORY_OBJECT_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 \
diff --git a/libpager/pager-memcpy.c b/libpager/pager-memcpy.c
index f2be558..7bdc248 100644
--- a/libpager/pager-memcpy.c
+++ b/libpager/pager-memcpy.c
@@ -64,6 +64,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
assert (window_size >= VMCOPY_BETTER_THAN_MEMCPY);
assert ((window_size & (vm_page_size - 1)) == 0);
+ window = 0;
err = vm_map (mach_task_self (), &window, window_size, 0, 1,
memobj, offset, 0, prot, prot, VM_INHERIT_NONE);
if (err)
@@ -110,6 +111,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
window_size = round_page (pageoff + to_copy);
}
+ window = 0;
err = vm_map (mach_task_self (), &window, window_size, 0, 1,
memobj, offset - pageoff, 0,
prot, prot, VM_INHERIT_NONE);
diff --git a/libports/Makefile b/libports/Makefile
index 30da1c1..f49cb9f 100644
--- a/libports/Makefile
+++ b/libports/Makefile
@@ -36,7 +36,7 @@ SRCS = create-bucket.c create-class.c \
interrupt-operation.c interrupt-on-notify.c interrupt-notified-rpcs.c \
dead-name.c create-port.c import-port.c default-uninhibitable-rpcs.c \
claim-right.c transfer-right.c create-port-noinstall.c create-internal.c \
- interrupted.c
+ interrupted.c extern-inline.c
installhdrs = ports.h
diff --git a/random/mig-mutate.h b/libports/extern-inline.c
similarity index 75%
copy from random/mig-mutate.h
copy to libports/extern-inline.c
index dab89e5..fbc9e53 100644
--- a/random/mig-mutate.h
+++ b/libports/extern-inline.c
@@ -1,6 +1,7 @@
-/*
+/* Run time callable functions for extern inlines.
Copyright (C) 2014 Free Software Foundation, Inc.
- Written by Justus Winter.
+
+ Written by Justus Winter <address@hidden>
This file is part of the GNU Hurd.
@@ -17,9 +18,5 @@
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 STARTUP_INTRAN \
- port_info_t begin_using_startup_port (mach_port_t)
-#define STARTUP_DESTRUCTOR \
- end_using_startup (port_info_t)
-#define STARTUP_IMPORTS \
- import "mig-decls.h";
+#define PORTS_DEFINE_EI
+#include "ports.h"
diff --git a/libports/mig-decls.h b/libports/mig-decls.h
index f8c4f15..c88ff26 100644
--- a/libports/mig-decls.h
+++ b/libports/mig-decls.h
@@ -30,6 +30,12 @@ begin_using_port_info_port (mach_port_t port)
return ports_lookup_port (0, port, 0);
}
+static inline struct port_info * __attribute__ ((unused))
+begin_using_port_info_payload (unsigned long payload)
+{
+ return ports_lookup_payload (0, payload, 0);
+}
+
static inline void __attribute__ ((unused))
end_using_port_info (struct port_info *p)
{
diff --git a/libports/mig-mutate.h b/libports/mig-mutate.h
index 4c011b6..1c96fea 100644
--- a/libports/mig-mutate.h
+++ b/libports/mig-mutate.h
@@ -19,6 +19,8 @@
#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 \
@@ -26,6 +28,8 @@
#define INTERRUPT_INTRAN \
port_info_t begin_using_port_info_port (mach_port_t)
+#define INTERRUPT_INTRAN_PAYLOAD \
+ port_info_t begin_using_port_info_payload
#define INTERRUPT_DESTRUCTOR \
end_using_port_info (port_info_t)
#define INTERRUPT_IMPORTS \
diff --git a/libports/ports.h b/libports/ports.h
index 652edb8..a625b47 100644
--- a/libports/ports.h
+++ b/libports/ports.h
@@ -29,6 +29,12 @@
#include <pthread.h>
#include <refcount.h>
+#ifdef PORTS_DEFINE_EI
+#define PORTS_EI
+#else
+#define PORTS_EI __extern_inline
+#endif
+
/* These are global values for common flags used in the various structures.
Not all of these are meaningful in all flag fields. */
#define PORTS_INHIBITED 0x0100 /* block RPC's */
@@ -234,6 +240,53 @@ mach_port_t ports_get_send_right (void *port);
void *ports_lookup_port (struct port_bucket *bucket,
mach_port_t port, struct port_class *class);
+/* Like ports_lookup_port, but uses PAYLOAD to look up the object. If
+ this function is used, PAYLOAD must be a pointer to the port
+ structure. */
+extern void *ports_lookup_payload (struct port_bucket *bucket,
+ unsigned long payload,
+ struct port_class *class);
+
+/* This returns the ports name. This function can be used as
+ intranpayload function turning payloads back into port names. If
+ this function is used, PAYLOAD must be a pointer to the port
+ structure. */
+extern mach_port_t ports_payload_get_name (unsigned int payload);
+
+#if defined(__USE_EXTERN_INLINES) || defined(PORTS_DEFINE_EI)
+
+PORTS_EI void *
+ports_lookup_payload (struct port_bucket *bucket,
+ unsigned long payload,
+ struct port_class *class)
+{
+ struct port_info *pi = (struct port_info *) payload;
+
+ if (pi && bucket && pi->bucket != bucket)
+ pi = NULL;
+
+ if (pi && class && pi->class != class)
+ pi = NULL;
+
+ if (pi)
+ refcounts_unsafe_ref (&pi->refcounts, NULL);
+
+ return pi;
+}
+
+PORTS_EI mach_port_t
+ports_payload_get_name (unsigned int payload)
+{
+ struct port_info *pi = (struct port_info *) payload;
+
+ if (pi)
+ return pi->port_right;
+
+ return MACH_PORT_NULL;
+}
+
+#endif /* Use extern inlines. */
+
/* Allocate another reference to PORT. */
void ports_port_ref (void *port);
diff --git a/libshouldbeinlibc/Makefile b/libshouldbeinlibc/Makefile
index 14a7939..633d60e 100644
--- a/libshouldbeinlibc/Makefile
+++ b/libshouldbeinlibc/Makefile
@@ -27,9 +27,13 @@ SRCS = termsize.c timefmt.c exec-reauth.c maptime-funcs.c \
idvec-impgids.c idvec-verify.c idvec-rep.c \
ugids.c ugids-argp.c ugids-rep.c ugids-verify.c ugids-subtract.c \
ugids-auth.c ugids-xinl.c ugids-merge.c ugids-imply.c ugids-posix.c \
- ugids-verify-auth.c nullauth.c
+ ugids-verify-auth.c nullauth.c \
+ refcount.c \
+
installhdrs = idvec.h timefmt.h maptime.h \
- wire.h portinfo.h portxlate.h cacheq.h ugids.h nullauth.h
+ wire.h portinfo.h portxlate.h cacheq.h ugids.h nullauth.h \
+ refcount.h \
+
installhdrsubdir = .
OBJS = $(SRCS:.c=.o)
diff --git a/random/mig-mutate.h b/libshouldbeinlibc/refcount.c
similarity index 75%
rename from random/mig-mutate.h
rename to libshouldbeinlibc/refcount.c
index dab89e5..17e01c5 100644
--- a/random/mig-mutate.h
+++ b/libshouldbeinlibc/refcount.c
@@ -1,6 +1,8 @@
-/*
+/* Lock-less reference counting primitives
+
Copyright (C) 2014 Free Software Foundation, Inc.
- Written by Justus Winter.
+
+ Written by Justus Winter <address@hidden>
This file is part of the GNU Hurd.
@@ -17,9 +19,5 @@
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 STARTUP_INTRAN \
- port_info_t begin_using_startup_port (mach_port_t)
-#define STARTUP_DESTRUCTOR \
- end_using_startup (port_info_t)
-#define STARTUP_IMPORTS \
- import "mig-decls.h";
+#define REFCOUNT_DEFINE_EI
+#include "refcount.h"
diff --git a/include/refcount.h b/libshouldbeinlibc/refcount.h
similarity index 96%
rename from include/refcount.h
rename to libshouldbeinlibc/refcount.h
index ebde42d..e8b0f5b 100644
--- a/include/refcount.h
+++ b/libshouldbeinlibc/refcount.h
@@ -22,6 +22,12 @@
#ifndef _HURD_REFCOUNT_H_
#define _HURD_REFCOUNT_H_
+#ifdef REFCOUNT_DEFINE_EI
+#define REFCOUNT_EI
+#else
+#define REFCOUNT_EI __extern_inline
+#endif
+
#include <assert.h>
#include <limits.h>
#include <stdint.h>
@@ -32,7 +38,7 @@
typedef unsigned int refcount_t;
/* Initialize REF with REFERENCES. REFERENCES must not be zero. */
-static inline void
+REFCOUNT_EI void
refcount_init (refcount_t *ref, unsigned int references)
{
assert (references > 0 || !"references must not be zero!");
@@ -46,7 +52,7 @@ refcount_init (refcount_t *ref, unsigned int references)
This is the unsafe version of refcount_ref. refcount_ref also
checks for use-after-free errors. When in doubt, use that one
instead. */
-static inline unsigned int
+REFCOUNT_EI unsigned int
refcount_unsafe_ref (refcount_t *ref)
{
unsigned int r;
@@ -58,7 +64,7 @@ refcount_unsafe_ref (refcount_t *ref)
/* Increment REF. Return the result of the operation. This function
uses atomic operations. It is not required to serialize calls to
this function. */
-static inline unsigned int
+REFCOUNT_EI unsigned int
refcount_ref (refcount_t *ref)
{
unsigned int r;
@@ -70,7 +76,7 @@ refcount_ref (refcount_t *ref)
/* Decrement REF. Return the result of the operation. This function
uses atomic operations. It is not required to serialize calls to
this function. */
-static inline unsigned int
+REFCOUNT_EI unsigned int
refcount_deref (refcount_t *ref)
{
unsigned int r;
@@ -81,7 +87,7 @@ refcount_deref (refcount_t *ref)
/* Return REF. This function uses atomic operations. It is not
required to serialize calls to this function. */
-static inline unsigned int
+REFCOUNT_EI unsigned int
refcount_references (refcount_t *ref)
{
return __atomic_load_n (ref, __ATOMIC_RELAXED);
@@ -120,7 +126,7 @@ union _references {
/* Initialize REF with HARD and WEAK references. HARD and WEAK must
not both be zero. */
-static inline void
+REFCOUNT_EI void
refcounts_init (refcounts_t *ref, uint32_t hard, uint32_t weak)
{
assert ((hard != 0 || weak != 0) || !"references must not both be zero!");
@@ -135,7 +141,7 @@ refcounts_init (refcounts_t *ref, uint32_t hard, uint32_t
weak)
This is the unsafe version of refcounts_ref. refcounts_ref also
checks for use-after-free errors. When in doubt, use that one
instead. */
-static inline void
+REFCOUNT_EI void
refcounts_unsafe_ref (refcounts_t *ref, struct references *result)
{
const union _references op = { .references = { .hard = 1 } };
@@ -150,7 +156,7 @@ refcounts_unsafe_ref (refcounts_t *ref, struct references
*result)
the result of the operation is written there. This function uses
atomic operations. It is not required to serialize calls to this
function. */
-static inline void
+REFCOUNT_EI void
refcounts_ref (refcounts_t *ref, struct references *result)
{
struct references r;
@@ -165,7 +171,7 @@ refcounts_ref (refcounts_t *ref, struct references *result)
the result of the operation is written there. This function uses
atomic operations. It is not required to serialize calls to this
function. */
-static inline void
+REFCOUNT_EI void
refcounts_deref (refcounts_t *ref, struct references *result)
{
const union _references op = { .references = { .hard = 1 } };
@@ -180,7 +186,7 @@ refcounts_deref (refcounts_t *ref, struct references
*result)
NULL, the result of the operation is written there. This function
uses atomic operations. It is not required to serialize calls to
this function. */
-static inline void
+REFCOUNT_EI void
refcounts_promote (refcounts_t *ref, struct references *result)
{
/* To promote a weak reference, we need to atomically subtract 1
@@ -211,7 +217,7 @@ refcounts_promote (refcounts_t *ref, struct references
*result)
NULL, the result of the operation is written there. This function
uses atomic operations. It is not required to serialize calls to
this function. */
-static inline void
+REFCOUNT_EI void
refcounts_demote (refcounts_t *ref, struct references *result)
{
/* To demote a hard reference, we need to atomically subtract 1 from
@@ -243,7 +249,7 @@ refcounts_demote (refcounts_t *ref, struct references
*result)
This is the unsafe version of refcounts_ref_weak.
refcounts_ref_weak also checks for use-after-free errors. When in
doubt, use that one instead. */
-static inline void
+REFCOUNT_EI void
refcounts_unsafe_ref_weak (refcounts_t *ref, struct references *result)
{
const union _references op = { .references = { .weak = 1 } };
@@ -258,7 +264,7 @@ refcounts_unsafe_ref_weak (refcounts_t *ref, struct
references *result)
the result of the operation is written there. This function uses
atomic operations. It is not required to serialize calls to this
function. */
-static inline void
+REFCOUNT_EI void
refcounts_ref_weak (refcounts_t *ref, struct references *result)
{
struct references r;
@@ -273,7 +279,7 @@ refcounts_ref_weak (refcounts_t *ref, struct references
*result)
the result of the operation is written there. This function uses
atomic operations. It is not required to serialize calls to this
function. */
-static inline void
+REFCOUNT_EI void
refcounts_deref_weak (refcounts_t *ref, struct references *result)
{
const union _references op = { .references = { .weak = 1 } };
@@ -287,7 +293,7 @@ refcounts_deref_weak (refcounts_t *ref, struct references
*result)
/* Store the current reference counts of REF in RESULT. This function
uses atomic operations. It is not required to serialize calls to
this function. */
-static inline void
+REFCOUNT_EI void
refcounts_references (refcounts_t *ref, struct references *result)
{
union _references r;
@@ -298,7 +304,7 @@ refcounts_references (refcounts_t *ref, struct references
*result)
/* Return the hard reference count of REF. This function uses atomic
operations. It is not required to serialize calls to this
function. */
-static inline uint32_t
+REFCOUNT_EI uint32_t
refcounts_hard_references (refcounts_t *ref)
{
struct references result;
@@ -309,7 +315,7 @@ refcounts_hard_references (refcounts_t *ref)
/* Return the weak reference count of REF. This function uses atomic
operations. It is not required to serialize calls to this
function. */
-static inline uint32_t
+REFCOUNT_EI uint32_t
refcounts_weak_references (refcounts_t *ref)
{
struct references result;
diff --git a/libstore/memobj.c b/libstore/memobj.c
index 0d5c816..cc6c7ca 100644
--- a/libstore/memobj.c
+++ b/libstore/memobj.c
@@ -133,6 +133,7 @@ memobj_read (struct store *store,
if (((size_t) addr & (vm_page_size - 1)) == 0)
{
*len = amount;
+ *buf = 0;
return vm_map (mach_task_self (), (vm_address_t *) buf, amount,
0, 1, store->port, addr << store->log2_block_size, 0,
VM_PROT_READ, VM_PROT_ALL, VM_INHERIT_NONE);
diff --git a/libtrivfs/mig-decls.h b/libtrivfs/mig-decls.h
index 2baaee8..13a9eb7 100644
--- a/libtrivfs/mig-decls.h
+++ b/libtrivfs/mig-decls.h
@@ -61,6 +61,35 @@ trivfs_begin_using_protid (mach_port_t port)
return ports_lookup_port (0, port, trivfs_dynamic_protid_port_classes[0]);
}
+static inline struct trivfs_protid * __attribute__ ((unused))
+trivfs_begin_using_protid_payload (unsigned long payload)
+{
+ if (trivfs_protid_nportclasses + trivfs_num_dynamic_protid_port_classes > 1)
+ {
+ struct port_info *pi = ports_lookup_payload (NULL, payload, NULL);
+ int i;
+
+ if (pi)
+ {
+ for (i = 0; i < trivfs_protid_nportclasses; i++)
+ if (pi->class == trivfs_protid_portclasses[i])
+ return (struct trivfs_protid *) pi;
+ for (i = 0; i < trivfs_num_dynamic_protid_port_classes; i++)
+ if (pi->class == trivfs_dynamic_protid_port_classes[i])
+ return (struct trivfs_protid *) pi;
+ ports_port_deref (pi);
+ }
+
+ return NULL;
+ }
+ else if (trivfs_protid_nportclasses == 1)
+ return ports_lookup_payload (NULL, payload,
+ trivfs_protid_portclasses[0]);
+ else
+ return ports_lookup_payload (NULL, payload,
+ trivfs_dynamic_protid_port_classes[0]);
+}
+
static inline void __attribute__ ((unused))
trivfs_end_using_protid (struct trivfs_protid *cred)
{
@@ -95,6 +124,35 @@ trivfs_begin_using_control (mach_port_t port)
return ports_lookup_port (0, port, trivfs_dynamic_control_port_classes[0]);
}
+static inline struct trivfs_control * __attribute__ ((unused))
+trivfs_begin_using_control_payload (unsigned long payload)
+{
+ if (trivfs_cntl_nportclasses + trivfs_num_dynamic_control_port_classes > 1)
+ {
+ struct port_info *pi = ports_lookup_payload (NULL, payload, NULL);
+ int i;
+
+ if (pi)
+ {
+ for (i = 0; i < trivfs_cntl_nportclasses; i++)
+ if (pi->class == trivfs_cntl_portclasses[i])
+ return (struct trivfs_control *) pi;
+ for (i = 0; i < trivfs_num_dynamic_control_port_classes; i++)
+ if (pi->class == trivfs_dynamic_control_port_classes[i])
+ return (struct trivfs_control *) pi;
+ ports_port_deref (pi);
+ }
+
+ return NULL;
+ }
+ else if (trivfs_cntl_nportclasses == 1)
+ return ports_lookup_payload (NULL, payload,
+ trivfs_cntl_portclasses[0]);
+ else
+ return ports_lookup_payload (NULL, payload,
+ trivfs_dynamic_control_port_classes[0]);
+}
+
static inline void __attribute__ ((unused))
trivfs_end_using_control (struct trivfs_control *cred)
{
diff --git a/libtrivfs/mig-mutate.h b/libtrivfs/mig-mutate.h
index cc15d38..dcbebf6 100644
--- a/libtrivfs/mig-mutate.h
+++ b/libtrivfs/mig-mutate.h
@@ -20,13 +20,16 @@
#define REPLY_PORTS
#define FILE_INTRAN trivfs_protid_t trivfs_begin_using_protid (file_t)
+#define FILE_INTRAN_PAYLOAD trivfs_protid_t trivfs_begin_using_protid_payload
#define FILE_DESTRUCTOR trivfs_end_using_protid (trivfs_protid_t)
#define FILE_IMPORTS import "libtrivfs/mig-decls.h";
#define IO_INTRAN trivfs_protid_t trivfs_begin_using_protid (io_t)
+#define IO_INTRAN_PAYLOAD trivfs_protid_t trivfs_begin_using_protid_payload
#define IO_DESTRUCTOR trivfs_end_using_protid (trivfs_protid_t)
#define IO_IMPORTS import "libtrivfs/mig-decls.h";
#define FSYS_INTRAN trivfs_control_t trivfs_begin_using_control (fsys_t)
+#define FSYS_INTRAN_PAYLOAD trivfs_control_t trivfs_begin_using_control_payload
#define FSYS_DESTRUCTOR trivfs_end_using_control (trivfs_control_t)
#define FSYS_IMPORTS import "libtrivfs/mig-decls.h";
diff --git a/mach-defpager/kalloc.c b/mach-defpager/kalloc.c
index 2f8f002..ef844ac 100644
--- a/mach-defpager/kalloc.c
+++ b/mach-defpager/kalloc.c
@@ -58,7 +58,7 @@ void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook)
(void) = init_hook;
* next highest power of 2.
*/
vm_size_t kalloc_max; /* max before we use vm_allocate */
-#define MINSIZE 4 /* minimum allocation size */
+#define MINSIZE sizeof(vm_offset_t) /* minimum
allocation size */
struct free_list {
pthread_spinlock_t lock;
@@ -99,8 +99,8 @@ void kalloc_init(void)
* 16Kbytes, whichever is less.
*/
- if (vm_page_size > 16*1024)
- kalloc_max = 16*1024;
+ if (vm_page_size > (MINSIZE << (KLIST_MAX-1)))
+ kalloc_max = (MINSIZE << (KLIST_MAX-1));
else
kalloc_max = vm_page_size;
@@ -197,7 +197,7 @@ void *kalloc(vm_size_t size)
/* compute the size of the block that we will actually allocate */
allocsize = size;
- if (size < kalloc_max) {
+ if (size <= kalloc_max) {
allocsize = MINSIZE;
fl = kfree_list;
while (allocsize < size) {
@@ -211,7 +211,7 @@ void *kalloc(vm_size_t size)
* and allocate.
*/
- if (allocsize < kalloc_max) {
+ if (allocsize <= kalloc_max) {
pthread_spin_lock(&fl->lock);
if ((addr = fl->head) != 0) {
fl->head = *(vm_offset_t *)addr;
@@ -241,7 +241,7 @@ kfree( void *data,
struct free_list *fl;
freesize = size;
- if (size < kalloc_max) {
+ if (size <= kalloc_max) {
freesize = MINSIZE;
fl = kfree_list;
while (freesize < size) {
@@ -250,7 +250,7 @@ kfree( void *data,
}
}
- if (freesize < kalloc_max) {
+ if (freesize <= kalloc_max) {
pthread_spin_lock(&fl->lock);
*(vm_offset_t *)data = fl->head;
fl->head = (vm_offset_t) data;
diff --git a/pfinet/ethernet.c b/pfinet/ethernet.c
index 053fd1b..1678243 100644
--- a/pfinet/ethernet.c
+++ b/pfinet/ethernet.c
@@ -116,12 +116,30 @@ ethernet_demuxer (mach_msg_header_t *inp,
int datalen;
struct ether_device *edev;
struct device *dev = 0;
+ mach_port_t local_port;
if (inp->msgh_id != NET_RCV_MSG_ID)
return 0;
+ if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) ==
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+ {
+ struct port_info *pi = ports_lookup_payload (NULL,
+ inp->msgh_protected_payload,
+ NULL);
+ if (pi)
+ {
+ local_port = pi->port_right;
+ ports_port_deref (pi);
+ }
+ else
+ local_port = MACH_PORT_NULL;
+ }
+ else
+ local_port = inp->msgh_local_port;
+
for (edev = ether_dev; edev; edev = edev->next)
- if (inp->msgh_local_port == edev->readptname)
+ if (local_port == edev->readptname)
dev = &edev->dev;
if (! dev)
diff --git a/pfinet/main.c b/pfinet/main.c
index d52d9a3..8716fdb 100644
--- a/pfinet/main.c
+++ b/pfinet/main.c
@@ -24,11 +24,11 @@
#include <arpa/inet.h>
#include <error.h>
#include <argp.h>
+#include <hurd/paths.h>
#include <hurd/startup.h>
#include <string.h>
#include <fcntl.h>
#include <version.h>
-#include <pids.h>
/* Include Hurd's errno.h file, but don't include glue-include/linux/errno.h,
since it #undef's the errno macro. */
@@ -86,8 +86,16 @@ pfinet_demuxer (mach_msg_header_t *inp,
/* We have several classes in one bucket, which need to be demuxed
differently. */
- pi = ports_lookup_port(pfinet_bucket, inp->msgh_local_port,
socketport_class);
-
+ if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) ==
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+ pi = ports_lookup_payload (pfinet_bucket,
+ inp->msgh_protected_payload,
+ socketport_class);
+ else
+ pi = ports_lookup_port (pfinet_bucket,
+ inp->msgh_local_port,
+ socketport_class);
+
if (pi)
{
ports_port_deref (pi);
@@ -154,7 +162,6 @@ arrange_shutdown_notification ()
{
error_t err;
mach_port_t initport, notify;
- process_t procserver;
struct port_info *pi;
shutdown_notify_class = ports_create_class (0, 0);
@@ -169,13 +176,8 @@ arrange_shutdown_notification ()
if (err)
return;
- procserver = getproc ();
- if (!procserver)
- return;
-
- err = proc_getmsgport (procserver, HURD_PID_STARTUP, &initport);
- mach_port_deallocate (mach_task_self (), procserver);
- if (err)
+ initport = file_name_lookup (_SERVERS_STARTUP, 0, 0);
+ if (initport == MACH_PORT_NULL)
return;
notify = ports_get_send_right (pi);
diff --git a/pfinet/mig-decls.h b/pfinet/mig-decls.h
index ec8fb23..67bcbfc 100644
--- a/pfinet/mig-decls.h
+++ b/pfinet/mig-decls.h
@@ -32,6 +32,12 @@ begin_using_socket_port (mach_port_t port)
return ports_lookup_port (pfinet_bucket, port, socketport_class);
}
+static inline struct sock_user * __attribute__ ((unused))
+begin_using_socket_payload (unsigned long payload)
+{
+ return ports_lookup_payload (pfinet_bucket, payload, socketport_class);
+}
+
static inline void __attribute__ ((unused))
end_using_socket_port (struct sock_user *user)
{
@@ -45,6 +51,12 @@ begin_using_sockaddr_port (mach_port_t port)
return ports_lookup_port (pfinet_bucket, port, addrport_class);
}
+static inline struct sock_addr * __attribute__ ((unused))
+begin_using_sockaddr_payload (unsigned long payload)
+{
+ return ports_lookup_payload (pfinet_bucket, payload, addrport_class);
+}
+
static inline void __attribute__ ((unused))
end_using_sockaddr_port (struct sock_addr *addr)
{
diff --git a/pfinet/mig-mutate.h b/pfinet/mig-mutate.h
index 0a1eeb8..2bc385b 100644
--- a/pfinet/mig-mutate.h
+++ b/pfinet/mig-mutate.h
@@ -23,18 +23,22 @@
#define IO_SELECT_REPLY_PORT
#define IO_INTRAN sock_user_t begin_using_socket_port (io_t)
+#define IO_INTRAN_PAYLOAD sock_user_t begin_using_socket_payload
#define IO_DESTRUCTOR end_using_socket_port (sock_user_t)
#define IO_IMPORTS import "mig-decls.h";
#define IIOCTL_IMPORTS import "mig-decls.h";
#define SOCKET_INTRAN sock_user_t begin_using_socket_port (socket_t)
+#define SOCKET_INTRAN_PAYLOAD sock_user_t begin_using_socket_payload
#define SOCKET_DESTRUCTOR end_using_socket_port (sock_user_t)
#define SOCKET_IMPORTS \
import "mig-decls.h"; \
import "../libtrivfs/mig-decls.h"; \
#define ADDRPORT_INTRAN sock_addr_t begin_using_sockaddr_port (addr_port_t)
+#define ADDRPORT_INTRAN_PAYLOAD sock_addr_t begin_using_sockaddr_payload
#define ADDRPORT_DESTRUCTOR end_using_sockaddr_port (sock_addr_t)
#define PF_INTRAN trivfs_protid_t trivfs_begin_using_protid (pf_t)
+#define PF_INTRAN_PAYLOAD trivfs_protid_t trivfs_begin_using_protid_payload
#define PF_DESTRUCTOR trivfs_end_using_protid (trivfs_protid_t)
diff --git a/pflocal/mig-decls.h b/pflocal/mig-decls.h
index 983de9d..b1da797 100644
--- a/pflocal/mig-decls.h
+++ b/pflocal/mig-decls.h
@@ -36,6 +36,12 @@ begin_using_sock_user_port(mach_port_t port)
return (sock_user_t)ports_lookup_port (0, port, sock_user_port_class);
}
+static inline sock_user_t __attribute__ ((unused))
+begin_using_sock_user_payload (unsigned long payload)
+{
+ return ports_lookup_payload (NULL, payload, sock_user_port_class);
+}
+
static inline void __attribute__ ((unused))
end_using_sock_user_port (sock_user_t sock_user)
{
@@ -49,6 +55,12 @@ begin_using_addr_port(mach_port_t port)
return (addr_t)ports_lookup_port (0, port, addr_port_class);
}
+static inline addr_t __attribute__ ((unused))
+begin_using_addr_payload (unsigned long payload)
+{
+ return ports_lookup_port (NULL, payload, addr_port_class);
+}
+
static inline void __attribute__ ((unused))
end_using_addr_port (addr_t addr)
{
diff --git a/pflocal/mig-mutate.h b/pflocal/mig-mutate.h
index b149473..238c806 100644
--- a/pflocal/mig-mutate.h
+++ b/pflocal/mig-mutate.h
@@ -21,13 +21,16 @@
#define IO_SELECT_REPLY_PORT
#define IO_INTRAN sock_user_t begin_using_sock_user_port (io_t)
+#define IO_INTRAN_PAYLOAD sock_user_t begin_using_sock_user_payload
#define IO_DESTRUCTOR end_using_sock_user_port (sock_user_t)
#define IO_IMPORTS import "mig-decls.h";
#define SOCKET_INTRAN sock_user_t begin_using_sock_user_port (socket_t)
+#define SOCKET_INTRAN_PAYLOAD sock_user_t begin_using_sock_user_payload
#define SOCKET_DESTRUCTOR end_using_sock_user_port (sock_user_t)
#define ADDRPORT_INTRAN addr_t begin_using_addr_port (addr_port_t)
+#define ADDRPORT_INTRAN_PAYLOAD addr_t begin_using_addr_payload
#define ADDRPORT_DESTRUCTOR end_using_addr_port (addr_t)
#define SOCKET_IMPORTS import "mig-decls.h";
diff --git a/proc/main.c b/proc/main.c
index 73742ed..3419d44 100644
--- a/proc/main.c
+++ b/proc/main.c
@@ -1,5 +1,5 @@
/* Initialization of the proc server
- Copyright (C) 1993,94,95,96,97,99,2000,01 Free Software Foundation, Inc.
+ Copyright (C) 1993,94,95,96,97,99,2000,01,13 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -60,12 +60,40 @@ message_demuxer (mach_msg_header_t *inp,
pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER;
+error_t
+increase_priority (void)
+{
+ mach_port_t pset = MACH_PORT_NULL, psetcntl = MACH_PORT_NULL;
+ error_t err;
+
+ err = thread_get_assignment (mach_thread_self (), &pset);
+ if (err)
+ goto out;
+
+ err = host_processor_set_priv (_hurd_host_priv, pset, &psetcntl);
+ if (err)
+ goto out;
+
+ err = thread_max_priority (mach_thread_self (), psetcntl, 0);
+ if (err)
+ goto out;
+
+ err = task_priority (mach_task_self (), 2, 1);
+
+ out:
+ if (MACH_PORT_VALID (pset))
+ mach_port_deallocate (mach_task_self (), pset);
+ if (MACH_PORT_VALID (psetcntl))
+ mach_port_deallocate (mach_task_self (), psetcntl);
+
+ return err;
+}
+
int
main (int argc, char **argv, char **envp)
{
mach_port_t boot;
error_t err;
- mach_port_t pset, psetcntl;
void *genport;
process_t startup_port;
struct argp argp = { 0, 0, 0, "Hurd process server" };
@@ -88,7 +116,12 @@ main (int argc, char **argv, char **envp)
generic_port = ports_get_right (genport);
/* Create the initial proc object for init (PID 1). */
- startup_proc = create_startup_proc ();
+ init_proc = create_init_proc ();
+
+ /* Create the startup proc object for /hurd/init (PID 2). */
+ startup_proc = allocate_proc (MACH_PORT_NULL);
+ startup_proc->p_deadmsg = 1;
+ complete_proc (startup_proc, HURD_PID_STARTUP);
/* Create our own proc object. */
self_proc = allocate_proc (mach_task_self ());
@@ -115,17 +148,9 @@ main (int argc, char **argv, char **envp)
/* Give ourselves good scheduling performance, because we are so
important. */
- err = thread_get_assignment (mach_thread_self (), &pset);
- assert_perror (err);
- err = host_processor_set_priv (_hurd_host_priv, pset, &psetcntl);
- assert_perror (err);
- thread_max_priority (mach_thread_self (), psetcntl, 0);
- assert_perror (err);
- err = task_priority (mach_task_self (), 2, 1);
- assert_perror (err);
-
- mach_port_deallocate (mach_task_self (), pset);
- mach_port_deallocate (mach_task_self (), psetcntl);
+ err = increase_priority ();
+ if (err)
+ error (0, err, "Increasing priority failed");
{
/* Get our stderr set up to print on the console, in case we have
diff --git a/proc/mgt.c b/proc/mgt.c
index b8aa0fc..02d69db 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -1,5 +1,6 @@
/* Process management
- Copyright (C) 1992,93,94,95,96,99,2000,01,02 Free Software Foundation, Inc.
+ Copyright (C) 1992,93,94,95,96,99,2000,01,02,13
+ Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -184,7 +185,7 @@ S_proc_child (struct proc *parentp,
/* Process hierarchy. Remove from our current location
and place us under our new parent. Sanity check to make sure
parent is currently init. */
- assert (childp->p_parent == startup_proc);
+ assert (childp->p_parent == init_proc);
if (childp->p_sib)
childp->p_sib->p_prevsib = childp->p_prevsib;
*childp->p_prevsib = childp->p_sib;
@@ -586,7 +587,7 @@ allocate_proc (task_t task)
/* Allocate and initialize the proc structure for init (PID 1),
the original parent of all other procs. */
struct proc *
-create_startup_proc (void)
+create_init_proc (void)
{
static const uid_t zero;
struct proc *p;
@@ -595,7 +596,7 @@ create_startup_proc (void)
p = allocate_proc (MACH_PORT_NULL);
assert (p);
- p->p_pid = HURD_PID_STARTUP;
+ p->p_pid = HURD_PID_INIT;
p->p_parent = p;
p->p_sib = 0;
@@ -643,7 +644,7 @@ proc_death_notify (struct proc *p)
}
/* Complete a new process that has been allocated but not entirely initialized.
- This gets called for every process except startup_proc (PID 1). */
+ This gets called for every process except init_proc (PID 1). */
void
complete_proc (struct proc *p, pid_t pid)
{
@@ -662,30 +663,47 @@ complete_proc (struct proc *p, pid_t pid)
p->p_pid = pid;
- ids_ref (&nullids);
- p->p_id = &nullids;
+ if (pid == HURD_PID_STARTUP)
+ {
+ /* Equip HURD_PID_STARTUP with the same credentials as
+ HURD_PID_INIT. */
+ static const uid_t zero;
+ p->p_id = make_ids (&zero, 1);
+ assert (p->p_id);
+ }
+ else
+ {
+ ids_ref (&nullids);
+ p->p_id = &nullids;
+ }
p->p_login = nulllogin;
p->p_login->l_refcnt++;
/* Our parent is init for now. */
- p->p_parent = startup_proc;
+ p->p_parent = init_proc;
- p->p_sib = startup_proc->p_ochild;
- p->p_prevsib = &startup_proc->p_ochild;
+ p->p_sib = init_proc->p_ochild;
+ p->p_prevsib = &init_proc->p_ochild;
if (p->p_sib)
p->p_sib->p_prevsib = &p->p_sib;
- startup_proc->p_ochild = p;
+ init_proc->p_ochild = p;
p->p_loginleader = 0;
p->p_ochild = 0;
p->p_parentset = 0;
p->p_noowner = 1;
- p->p_pgrp = startup_proc->p_pgrp;
+ p->p_pgrp = init_proc->p_pgrp;
- proc_death_notify (p);
- add_proc_to_hash (p);
+ /* At this point, we do not know the task of the startup process,
+ defer registering death notifications and adding it to the hash
+ tables. */
+ if (pid != HURD_PID_STARTUP)
+ {
+ proc_death_notify (p);
+ add_proc_to_hash (p);
+ }
join_pgrp (p);
}
@@ -747,7 +765,7 @@ process_has_exited (struct proc *p)
nowait_msg_proc_newids (tp->p_msgport, tp->p_task,
1, tp->p_pgrp->pg_pgid,
!tp->p_pgrp->pg_orphcnt);
- tp->p_parent = startup_proc;
+ tp->p_parent = init_proc;
if (tp->p_dead)
isdead = 1;
}
@@ -755,17 +773,17 @@ process_has_exited (struct proc *p)
nowait_msg_proc_newids (tp->p_msgport, tp->p_task,
1, tp->p_pgrp->pg_pgid,
!tp->p_pgrp->pg_orphcnt);
- tp->p_parent = startup_proc;
+ tp->p_parent = init_proc;
/* And now append the lists. */
- tp->p_sib = startup_proc->p_ochild;
+ tp->p_sib = init_proc->p_ochild;
if (tp->p_sib)
tp->p_sib->p_prevsib = &tp->p_sib;
- startup_proc->p_ochild = p->p_ochild;
- p->p_ochild->p_prevsib = &startup_proc->p_ochild;
+ init_proc->p_ochild = p->p_ochild;
+ p->p_ochild->p_prevsib = &init_proc->p_ochild;
if (isdead)
- alert_parent (startup_proc);
+ alert_parent (init_proc);
}
/* If an operation is in progress for this process, cause it
@@ -883,6 +901,24 @@ genpid ()
return nextpid++;
}
+/* Implement proc_set_init_task as described in <hurd/process.defs>. */
+error_t
+S_proc_set_init_task(struct proc *callerp,
+ task_t task)
+{
+ if (! callerp)
+ return EOPNOTSUPP;
+
+ if (callerp != startup_proc)
+ return EPERM;
+
+ init_proc->p_task = task;
+ proc_death_notify (init_proc);
+ add_proc_to_hash (init_proc);
+
+ return 0;
+}
+
/* Implement proc_mark_important as described in <hurd/process.defs>. */
kern_return_t
S_proc_mark_important (struct proc *p)
diff --git a/proc/mig-decls.h b/proc/mig-decls.h
index 7d36a87..eb33ef3 100644
--- a/proc/mig-decls.h
+++ b/proc/mig-decls.h
@@ -35,6 +35,17 @@ begin_using_proc_port (mach_port_t port)
return (!p || p->p_dead) ? NULL : p;
}
+static inline struct proc * __attribute__ ((unused))
+begin_using_proc_payload (unsigned long payload)
+{
+ struct proc *p;
+ p = ports_lookup_payload (proc_bucket, payload, proc_class);
+ if (p && p->p_dead)
+ ports_port_deref (p);
+ return (!p || p->p_dead) ? 0 : p;
+}
+
+
static inline void __attribute__ ((unused))
end_using_proc (struct proc *p)
{
@@ -50,6 +61,12 @@ begin_using_exc_port (mach_port_t port)
return ports_lookup_port (NULL, port, exc_class);
}
+static inline exc_t __attribute__ ((unused))
+begin_using_exc_payload (unsigned long payload)
+{
+ return ports_lookup_payload (NULL, payload, exc_class);
+}
+
static inline void __attribute__ ((unused))
end_using_exc (exc_t exc)
{
diff --git a/proc/mig-mutate.h b/proc/mig-mutate.h
index ce9f88e..62dc2a5 100644
--- a/proc/mig-mutate.h
+++ b/proc/mig-mutate.h
@@ -20,6 +20,8 @@
#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 \
@@ -27,6 +29,8 @@
#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 \
diff --git a/proc/notify.c b/proc/notify.c
index b6731ae..c5734b0 100644
--- a/proc/notify.c
+++ b/proc/notify.c
@@ -41,6 +41,9 @@ do_mach_notify_dead_name (struct port_info *pi,
{
struct proc *p;
+ if (!pi)
+ return EOPNOTSUPP;
+
if (pi->port_right == generic_port)
{
check_dead_execdata_notify (deadport);
@@ -50,8 +53,7 @@ do_mach_notify_dead_name (struct port_info *pi,
p = (struct proc *) pi;
- if (!p
- || p->p_pi.bucket != proc_bucket
+ if (p->p_pi.bucket != proc_bucket
|| p->p_pi.class != proc_class)
return EOPNOTSUPP;
diff --git a/proc/proc.h b/proc/proc.h
index a2e3c53..6196697 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -1,5 +1,6 @@
/* Process server definitions
- Copyright (C) 1992,93,94,95,96,99,2000,01 Free Software Foundation, Inc.
+ Copyright (C) 1992,93,94,95,96,99,2000,01,13
+ Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -134,7 +135,8 @@ struct exc
mach_port_t authserver;
struct proc *self_proc; /* process HURD_PID_PROC (us) */
-struct proc *startup_proc; /* process 1 (init) */
+struct proc *init_proc; /* process 1 (sysvinit) */
+struct proc *startup_proc; /* process 2 (hurd/init) */
struct port_bucket *proc_bucket;
struct port_class *proc_class;
@@ -183,7 +185,7 @@ void exc_clean (void *);
struct proc *add_tasks (task_t);
int pidfree (pid_t);
-struct proc *create_startup_proc (void);
+struct proc *create_init_proc (void);
struct proc *allocate_proc (task_t);
void proc_death_notify (struct proc *);
void complete_proc (struct proc *, pid_t);
diff --git a/proc/proc_exc.defs b/proc/proc_exc.defs
index c910824..9dc3626 100644
--- a/proc/proc_exc.defs
+++ b/proc/proc_exc.defs
@@ -38,6 +38,7 @@ import "mig-decls.h";
type exception_t = mach_port_copy_send_t
cusertype: mach_port_t
intran: exc_t begin_using_exc_port (exception_t)
+ intranpayload: exc_t begin_using_exc_payload
destructor: end_using_exc (exc_t);
routine proc_exception_raise (
diff --git a/procfs/main.c b/procfs/main.c
index 54e9682..320f55b 100644
--- a/procfs/main.c
+++ b/procfs/main.c
@@ -25,6 +25,7 @@
#include <argz.h>
#include <hurd/netfs.h>
#include <ps.h>
+#include <pids.h>
#include "procfs.h"
#include "proclist.h"
#include "rootdir.h"
@@ -42,7 +43,7 @@ uid_t opt_anon_owner;
#define OPT_CLK_TCK sysconf(_SC_CLK_TCK)
#define OPT_STAT_MODE 0400
#define OPT_FAKE_SELF -1
-#define OPT_KERNEL_PID 2
+#define OPT_KERNEL_PID HURD_PID_KERNEL
#define OPT_ANON_OWNER 0
#define NODEV_KEY -1 /* <= 0, so no short option. */
@@ -137,15 +138,17 @@ argp_parser (int key, char *arg, struct argp_state *state)
}
struct argp_option common_options[] = {
+#define STR(X) XSTR (X)
+#define XSTR(X) #X
{ "clk-tck", 'h', "HZ", 0,
"Unit used for the values expressed in system clock ticks "
- "(default: sysconf(_SC_CLK_TCK))" },
+ "(default: " STR (OPT_CLK_TCK) ")" },
{ "stat-mode", 's', "MODE", 0,
"The [pid]/stat file publishes information which on Hurd is only "
"available to the process owner. "
"You can use this option to override its mode to be more permissive "
"for compatibility purposes. "
- "(default: 0400)" },
+ "(default: " STR (OPT_STAT_MODE) ")" },
{ "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL,
"Provide a fake \"self\" symlink to the given PID, for compatibility "
"purposes. If PID is omitted, \"self\" will point to init. "
@@ -153,7 +156,7 @@ struct argp_option common_options[] = {
{ "kernel-process", 'k', "PID", 0,
"Process identifier for the kernel, used to retreive its command "
"line, as well as the global up and idle times. "
- "(default: 2)" },
+ "(default: " STR (OPT_KERNEL_PID) ")" },
{ "compatible", 'c', NULL, 0,
"Try to be compatible with the Linux procps utilities. "
"Currently equivalent to -h 100 -s 0444 -S 1." },
@@ -161,7 +164,7 @@ struct argp_option common_options[] = {
"Make USER the owner of files related to processes without one. "
"Be aware that USER will be granted access to the environment and "
"other sensitive information about the processes in question. "
- "(default: use uid 0)" },
+ "(default: use uid " STR (OPT_ANON_OWNER) ")" },
{ "nodev", NODEV_KEY, NULL, 0,
"Ignored for compatibility with Linux' procfs." },
{ "noexec", NOEXEC_KEY, NULL, 0,
@@ -169,6 +172,8 @@ struct argp_option common_options[] = {
{ "nosuid", NOSUID_KEY, NULL, 0,
"Ignored for compatibility with Linux' procfs." },
{}
+#undef XSTR
+#undef STR
};
struct argp argp = {
@@ -259,6 +264,18 @@ netfs_append_args (char **argz, size_t *argz_len)
return err;
}
+
+/* The user may define this function. The function must set source to
+ the source of CRED. The function may return an EOPNOTSUPP to
+ indicate that the concept of a source device is not applicable. The
+ default function always returns EOPNOTSUPP. */
+error_t netfs_get_source (struct protid *cred, char *source, size_t source_len)
+{
+ if (! cred)
+ return EOPNOTSUPP;
+ snprintf (source, source_len, "proc");
+ return 0;
+}
error_t
root_make_node (struct ps_context *pc, struct node **np)
diff --git a/random/Makefile b/random/Makefile
index 6291da0..0949b63 100644
--- a/random/Makefile
+++ b/random/Makefile
@@ -26,6 +26,5 @@ OBJS = $(SRCS:.c=.o) startup_notifyServer.o
LCLHDRS = gnupg-random.h gnupg-rmd.h gnupg-bithelp.h random.h
HURDLIBS = trivfs ports fshelp ihash shouldbeinlibc
OTHERLIBS = -lpthread
-MIGSFLAGS = -DSEQNOS -imacros $(srcdir)/mig-mutate.h
include ../Makeconf
diff --git a/random/mig-decls.h b/random/mig-decls.h
deleted file mode 100644
index 87b7eb2..0000000
--- a/random/mig-decls.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- Copyright (C) 2014 Free Software Foundation, Inc.
- Written by Justus Winter.
-
- 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. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef __RANDOM_MIG_DECLS_H__
-#define __RANDOM_MIG_DECLS_H__
-
-#include <hurd/ports.h>
-
-typedef struct port_info *port_info_t;
-
-extern struct trivfs_control *fsys;
-extern struct port_class *shutdown_notify_class;
-
-/* Called by server stub functions. */
-
-static inline struct port_info * __attribute__ ((unused))
-begin_using_startup_port (mach_port_t port)
-{
- return ports_lookup_port (fsys->pi.bucket,
- handle,
- shutdown_notify_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_startup (struct port_info *p)
-{
- if (p)
- ports_port_deref (p);
-}
-
-#endif /* __RANDOM_MIG_DECLS_H__ */
diff --git a/random/random.c b/random/random.c
index 6eea363..15be383 100644
--- a/random/random.c
+++ b/random/random.c
@@ -537,8 +537,11 @@ struct port_class *shutdown_notify_class;
/* The system is going down; destroy all the extant port rights. That
will cause net channels and such to close promptly. */
error_t
-S_startup_dosync (struct port_info *inpi)
+S_startup_dosync (mach_port_t handle)
{
+ struct port_info *inpi = ports_lookup_port (fsys->pi.bucket, handle,
+ shutdown_notify_class);
+
if (!inpi)
return EOPNOTSUPP;
diff --git a/init/Makefile b/startup/Makefile
similarity index 81%
copy from init/Makefile
copy to startup/Makefile
index ffb82ff..ee2ecdd5 100644
--- a/init/Makefile
+++ b/startup/Makefile
@@ -15,16 +15,20 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-dir := init
+dir := startup
makemode := server
-SRCS = init.c stubs.c
+SRCS = startup.c
OBJS = $(SRCS:.c=.o) \
startupServer.o notifyServer.o startup_replyUser.o msgServer.o \
- startup_notifyUser.o
-target = init
+ startup_notifyUser.o fsysServer.o
+target = startup
HURDLIBS = shouldbeinlibc
+# startup does not use libports. Disable the default payload to port
+# conversion.
+MIGSFLAGS="-DHURD_DEFAULT_PAYLOAD_TO_PORT=1"
+
include ../Makeconf
mung_msg_S.h: msg_S.h
diff --git a/init/init.c b/startup/startup.c
similarity index 93%
copy from init/init.c
copy to startup/startup.c
index b7b40bd..e177075 100644
--- a/init/init.c
+++ b/startup/startup.c
@@ -63,7 +63,7 @@ static int crash_flags = RB_AUTOBOOT;
#define BOOT(flags) ((flags & RB_HALT) ? "halt" : "reboot")
-const char *argp_program_version = STANDARD_HURD_VERSION (init);
+const char *argp_program_version = STANDARD_HURD_VERSION (startup);
static struct argp_option
options[] =
@@ -217,7 +217,7 @@ notify_shutdown (const char *msg)
void
reboot_system (int flags)
{
- notify_shutdown ("shutdown");
+ notify_shutdown (BOOT (flags));
if (fakeboot)
{
@@ -501,10 +501,14 @@ static int
demuxer (mach_msg_header_t *inp,
mach_msg_header_t *outp)
{
- extern int notify_server (), startup_server (), msg_server ();
+ extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
+ extern int startup_server (mach_msg_header_t *, mach_msg_header_t *);
+ extern int msg_server (mach_msg_header_t *, mach_msg_header_t *);
+ extern int fsys_server (mach_msg_header_t *, mach_msg_header_t *);
return (notify_server (inp, outp) ||
msg_server (inp, outp) ||
+ fsys_server (inp, outp) ||
startup_server (inp, outp));
}
@@ -553,7 +557,7 @@ main (int argc, char **argv, char **envp)
master device ports, and the console. */
if (task_get_bootstrap_port (mach_task_self (), &bootport)
|| fsys_getpriv (bootport, &host_priv, &device_master, &fstask)
- || device_open (device_master, D_WRITE, "console", &consdev))
+ || device_open (device_master, D_READ|D_WRITE, "console", &consdev))
crash_mach ();
wire_task_self ();
@@ -581,6 +585,18 @@ main (int argc, char **argv, char **envp)
/* Crash if the boot filesystem task dies. */
request_dead_name (fstask);
+ file_t node = file_name_lookup (_SERVERS_STARTUP, O_NOTRANS, 0);
+ if (node == MACH_PORT_NULL)
+ error (0, errno, "%s", _SERVERS_STARTUP);
+ else
+ {
+ file_set_translator (node,
+ 0, FS_TRANS_SET, 0,
+ NULL, 0,
+ startup, MACH_MSG_TYPE_COPY_SEND);
+ mach_port_deallocate (mach_task_self (), node);
+ }
+
/* Set up the set of ports we will pass to the programs we exec. */
for (i = 0; i < INIT_PORT_MAX; i++)
switch (i)
@@ -904,9 +920,6 @@ frob_kernel_process (void)
static pid_t child_pid; /* PID of the child we run */
static task_t child_task; /* and its (original) task port */
-error_t send_signal (mach_port_t msgport, int signal, mach_port_t refport,
- mach_msg_timeout_t);
-
static void launch_something (const char *why);
@@ -965,52 +978,6 @@ process_signal (int signo)
}
}
}
- else
- {
- /* Pass the signal on to the child. */
- task_t task;
- error_t err;
-
- err = proc_pid2task (procserver, child_pid, &task);
- if (err)
- {
- error (0, err, "proc_pid2task on %d", child_pid);
- task = child_task;
- }
- else
- {
- mach_port_deallocate (mach_task_self (), child_task);
- child_task = task;
- }
-
- if (signo == SIGKILL)
- {
- err = task_terminate (task);
- if (err != MACH_SEND_INVALID_DEST)
- error (0, err, "task_terminate");
- }
- else
- {
- mach_port_t msgport;
- err = proc_getmsgport (procserver, child_pid, &msgport);
- if (err)
- error (0, err, "proc_getmsgport");
- else
- {
- err = send_signal (msgport, signo, task,
- 500); /* Block only half a second. */
- mach_port_deallocate (mach_task_self (), msgport);
- if (err)
- {
- error (0, err, "cannot send %s to child %d",
- strsignal (signo), child_pid);
- err = task_terminate (task);
- if (err != MACH_SEND_INVALID_DEST)
- error (0, err, "task_terminate");
- }
- }
- }
- }
}
/* Start the child program PROG. It is run via /libexec/console-run
@@ -1058,7 +1025,7 @@ start_child (const char *prog, char **progargs)
NULL, 0, /* OSF Mach */
#endif
0, &child_task);
- proc_child (procserver, child_task);
+ proc_set_init_task (procserver, child_task);
proc_task2pid (procserver, child_task, &child_pid);
proc_task2proc (procserver, child_task, &default_ports[INIT_PORT_PROC]);
@@ -1591,3 +1558,108 @@ S_msg_report_wait (mach_port_t process, thread_t thread,
*rpc = 0;
return 0;
}
+
+/* fsys */
+error_t
+S_fsys_getroot (mach_port_t fsys_t,
+ mach_port_t dotdotnode,
+ uid_t *uids, size_t nuids,
+ uid_t *gids, size_t ngids,
+ int flags,
+ retry_type *do_retry,
+ char *retry_name,
+ mach_port_t *ret,
+ mach_msg_type_name_t *rettype)
+{
+ int is_root = 0;
+ size_t i;
+
+ for (i = 0; i < nuids; i++)
+ if (uids[i] == 0)
+ {
+ is_root = 1;
+ break;
+ }
+
+ if (! is_root)
+ return EPERM;
+
+ *do_retry = FS_RETRY_NORMAL;
+ *retry_name = '\0';
+ *ret = startup;
+ *rettype = MACH_MSG_TYPE_COPY_SEND;
+ return 0;
+}
+
+error_t
+S_fsys_goaway (mach_port_t control, int flags)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_startup (mach_port_t bootstrap, int flags, mach_port_t control,
+ mach_port_t *real, mach_msg_type_name_t *realtype)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_syncfs (mach_port_t control,
+ int wait,
+ int recurse)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_set_options (mach_port_t control,
+ char *data, mach_msg_type_number_t len,
+ int do_children)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_get_options (mach_port_t control,
+ char **data, mach_msg_type_number_t *len)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_getfile (mach_port_t control,
+ uid_t *uids, size_t nuids,
+ uid_t *gids, size_t ngids,
+ char *handle, size_t handllen,
+ mach_port_t *pt,
+ mach_msg_type_name_t *pttype)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_getpriv (mach_port_t control,
+ mach_port_t *host_priv, mach_msg_type_name_t *host_priv_type,
+ mach_port_t *dev_master, mach_msg_type_name_t *dev_master_type,
+ task_t *fs_task, mach_msg_type_name_t *fs_task_type)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_init (mach_port_t control,
+ mach_port_t reply,
+ mach_msg_type_name_t replytype,
+ mach_port_t proc,
+ auth_t auth)
+{
+ return EOPNOTSUPP;
+}
+
+error_t
+S_fsys_forward (mach_port_t server, mach_port_t requestor,
+ char *argz, size_t argz_len)
+{
+ return EOPNOTSUPP;
+}
diff --git a/sutils/fstab.c b/sutils/fstab.c
index ed59151..e13f15b 100644
--- a/sutils/fstab.c
+++ b/sutils/fstab.c
@@ -240,16 +240,32 @@ fstypes_find_program (struct fstypes *types, const char
*program,
/* Copy MNTENT into FS, copying component strings as well. */
error_t
-fs_set_mntent (struct fs *fs, const struct mntent *mntent)
+fs_set_mntent (struct fs *fs, const struct mntent *provided_mntent)
{
char *end;
size_t needed = 0;
+ struct mntent mntent = *provided_mntent;
+ char *real_fsname = NULL;
+ char *real_dir = NULL;
if (fs->storage)
free (fs->storage);
+ if (mntent.mnt_fsname)
+ {
+ real_fsname = realpath (mntent.mnt_fsname, NULL);
+ if (real_fsname)
+ mntent.mnt_fsname = real_fsname;
+ }
+ if (mntent.mnt_dir)
+ {
+ real_dir = realpath (mntent.mnt_dir, NULL);
+ if (real_dir)
+ mntent.mnt_dir = real_dir;
+ }
+
/* Allocate space for all string mntent fields in FS. */
-#define COUNT(field) if (mntent->field) needed += strlen (mntent->field) + 1;
+#define COUNT(field) if (mntent.field) needed += strlen (mntent.field) + 1;
COUNT (mnt_fsname);
COUNT (mnt_dir);
COUNT (mnt_type);
@@ -258,10 +274,14 @@ fs_set_mntent (struct fs *fs, const struct mntent *mntent)
fs->storage = malloc (needed);
if (! fs->storage)
- return ENOMEM;
+ {
+ free (real_fsname);
+ free (real_dir);
+ return ENOMEM;
+ }
- if (!fs->mntent.mnt_dir || !mntent->mnt_dir
- || strcmp (fs->mntent.mnt_dir, mntent->mnt_dir) != 0)
+ if (!fs->mntent.mnt_dir || !mntent.mnt_dir
+ || strcmp (fs->mntent.mnt_dir, mntent.mnt_dir) != 0)
{
fs->mounted = fs->readonly = -1;
if (fs->fsys != MACH_PORT_NULL)
@@ -270,15 +290,15 @@ fs_set_mntent (struct fs *fs, const struct mntent *mntent)
}
/* Copy MNTENT into FS; string-valued fields will be fixed up next. */
- fs->mntent = *mntent;
+ fs->mntent = mntent;
/* Copy each mntent field from MNTENT into FS's version. */
end = fs->storage;
#define STORE(field) \
- if (mntent->field) \
+ if (mntent.field) \
{ \
fs->mntent.field = end; \
- end = stpcpy (end, mntent->field) + 1; \
+ end = stpcpy (end, mntent.field) + 1; \
} \
else \
fs->mntent.field = 0;
@@ -289,10 +309,13 @@ fs_set_mntent (struct fs *fs, const struct mntent *mntent)
#undef STORE
if (fs->type
- && (!mntent->mnt_type
- || strcasecmp (fs->type->name, mntent->mnt_type) != 0))
+ && (!mntent.mnt_type
+ || strcasecmp (fs->type->name, mntent.mnt_type) != 0))
fs->type = 0; /* Type is different. */
+ free (real_fsname);
+ free (real_dir);
+
return 0;
}
@@ -470,11 +493,21 @@ fstab_find_device (const struct fstab *fstab, const char
*name)
if (strcmp (name, "none") == 0)
return NULL;
+ char *real_name = realpath (name, NULL);
+ const char *lookup_name;
+
+ if (real_name)
+ lookup_name = real_name;
+ else
+ lookup_name = name;
+
struct fs *fs;
for (fs = fstab->entries; fs; fs = fs->next)
- if (strcmp (fs->mntent.mnt_fsname, name) == 0)
- return fs;
- return 0;
+ if (strcmp (fs->mntent.mnt_fsname, lookup_name) == 0)
+ break;
+
+ free (real_name);
+ return fs;
}
/* Returns the FS entry in FSTAB with the mount point NAME (there can only
@@ -482,8 +515,6 @@ fstab_find_device (const struct fstab *fstab, const char
*name)
inline struct fs *
fstab_find_mount (const struct fstab *fstab, const char *name)
{
- struct fs *fs;
-
/* Don't count "none" or "-" as matching any other mount point.
It is canonical to use "none" for swap partitions, and multiple
such do not in fact conflict with each other. Likewise, the
@@ -494,10 +525,21 @@ fstab_find_mount (const struct fstab *fstab, const char
*name)
|| !strcmp (name, "ignore"))
return 0;
+ char *real_name = realpath (name, NULL);
+ const char *lookup_name;
+
+ if (real_name)
+ lookup_name = real_name;
+ else
+ lookup_name = name;
+
+ struct fs *fs;
for (fs = fstab->entries; fs; fs = fs->next)
- if (strcmp (fs->mntent.mnt_dir, name) == 0)
- return fs;
- return 0;
+ if (strcmp (fs->mntent.mnt_dir, lookup_name) == 0)
+ break;
+
+ free (real_name);
+ return fs;
}
/* Returns the FS entry in FSTAB with the device or mount point NAME (there
@@ -505,29 +547,7 @@ fstab_find_mount (const struct fstab *fstab, const char
*name)
inline struct fs *
fstab_find (const struct fstab *fstab, const char *name)
{
- struct fs *ret;
- char *real_name;
-
- ret = fstab_find_device (fstab, name);
- if (ret)
- return ret;
-
- ret = fstab_find_mount (fstab, name);
- if (ret)
- return ret;
-
- real_name = realpath (name, NULL);
-
- ret = fstab_find_device (fstab, real_name);
- if (ret) {
- free (real_name);
- return ret;
- }
-
- ret = fstab_find_mount (fstab, real_name);
- free (real_name);
-
- return ret;
+ return fstab_find_device (fstab, name) ?: fstab_find_mount (fstab, name);
}
/* Cons FS onto the beginning of FSTAB's entry list. */
@@ -690,6 +710,7 @@ fstab_read (struct fstab *fstab, const char *name)
{
while (!err && !feof (stream))
{
+ errno = 0;
struct mntent *mntent = getmntent (stream);
if (! mntent)
diff --git a/term/Makefile b/term/Makefile
index 5006c0d..1419d2a 100644
--- a/term/Makefile
+++ b/term/Makefile
@@ -33,5 +33,6 @@ include ../Makeconf
device_replyServer-CPPFLAGS = -DTypeCheck=0 -Wno-unused # XXX
+device_reply-MIGSFLAGS = -DMACH_PAYLOAD_TO_PORT=ports_payload_get_name
tioctl-MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
term-MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
diff --git a/term/mig-decls.h b/term/mig-decls.h
index c91b133..09b45c6 100644
--- a/term/mig-decls.h
+++ b/term/mig-decls.h
@@ -32,6 +32,12 @@ begin_using_ctty_port (mach_port_t port)
return ports_lookup_port (term_bucket, port, cttyid_class);
}
+static inline struct port_info * __attribute__ ((unused))
+begin_using_ctty_payload (unsigned long payload)
+{
+ return ports_lookup_payload (term_bucket, payload, cttyid_class);
+}
+
static inline void __attribute__ ((unused))
end_using_ctty (struct port_info *p)
{
diff --git a/term/mig-mutate.h b/term/mig-mutate.h
index 1545719..af8877e 100644
--- a/term/mig-mutate.h
+++ b/term/mig-mutate.h
@@ -20,10 +20,13 @@
/* Only CPP macro definitions should go in this file. */
#define IO_INTRAN trivfs_protid_t trivfs_begin_using_protid (io_t)
+#define IO_INTRAN_PAYLOAD trivfs_protid_t trivfs_begin_using_protid_payload
#define IO_DESTRUCTOR trivfs_end_using_protid (trivfs_protid_t)
#define CTTY_INTRAN \
port_info_t begin_using_ctty_port (mach_port_t)
+#define CTTY_INTRAN_PAYLOAD \
+ port_info_t begin_using_ctty_payload
#define CTTY_DESTRUCTOR \
end_using_ctty (port_info_t)
diff --git a/term/ptyio.c b/term/ptyio.c
index 211e70a..6b01585 100644
--- a/term/ptyio.c
+++ b/term/ptyio.c
@@ -331,7 +331,7 @@ pty_io_read (struct trivfs_protid *cred,
}
}
- if (!(termflags & TTY_OPEN))
+ if (!(termflags & TTY_OPEN) && !qsize (outputq))
{
pthread_mutex_unlock (&global_lock);
return EIO;
diff --git a/tmpfs/node.c b/tmpfs/node.c
index acc029a..8835e3f 100644
--- a/tmpfs/node.c
+++ b/tmpfs/node.c
@@ -508,6 +508,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
/* XXX we need to keep a reference to the object, or GNU Mach
will terminate it when we release the map. */
+ np->dn->u.reg.memref = 0;
vm_map (mach_task_self (), &np->dn->u.reg.memref, 4096, 0, 1,
np->dn->u.reg.memobj, 0, 0, VM_PROT_NONE, VM_PROT_NONE,
VM_INHERIT_NONE);
diff --git a/trans/Makefile b/trans/Makefile
index 71e6424..ce1eae7 100644
--- a/trans/Makefile
+++ b/trans/Makefile
@@ -34,14 +34,23 @@ LDLIBS += -lpthread
password-LDLIBS = -lcrypt
password-MIGSFLAGS=\
"-DIO_INTRAN=trivfs_protid_t trivfs_begin_using_protid (io_t)" \
+ "-DIO_INTRAN_PAYLOAD=trivfs_protid_t trivfs_begin_using_protid_payload" \
"-DIO_DESTRUCTOR=trivfs_end_using_protid (trivfs_protid_t)" \
"-DPASSWORD_IMPORTS=import \"../libtrivfs/mig-decls.h\";"
ifsock-MIGSFLAGS=\
"-DFILE_INTRAN=trivfs_protid_t trivfs_begin_using_protid (io_t)" \
+ "-DFILE_INTRAN_PAYLOAD=trivfs_protid_t trivfs_begin_using_protid_payload" \
"-DFILE_DESTRUCTOR=trivfs_end_using_protid (trivfs_protid_t)" \
"-DIFSOCK_IMPORTS=import \"../libtrivfs/mig-decls.h\";"
+# device_replyServer is used by the streamio translator.
+device_reply-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
+
+# fsysServer is only used by the symlink translator which does not use
+# libports. Disable the default payload to port conversion.
+fsys-MIGSFLAGS = "-DHURD_DEFAULT_PAYLOAD_TO_PORT=1"
+
include ../Makeconf
vpath elfcore.c $(top_srcdir)/exec
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index df2de64..a223bc4 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -103,6 +103,7 @@ new_node (file_t file, mach_port_t idport, int locked, int
openmodes,
return err;
}
}
+ nn->faked = FAKE_DEFAULT;
if (!locked)
pthread_mutex_lock (&idport_ihash_lock);
@@ -679,13 +680,22 @@ netfs_attempt_mkfile (struct iouser *user, struct node
*dir,
mode_t mode, struct node **np)
{
file_t newfile;
+ mode_t real_mode = real_from_fake_mode (mode);
error_t err = dir_mkfile (netfs_node_netnode (dir)->file, O_RDWR|O_EXEC,
- real_from_fake_mode (mode), &newfile);
+ real_mode, &newfile);
pthread_mutex_unlock (&dir->lock);
if (err == 0)
err = new_node (newfile, MACH_PORT_NULL, 0, O_RDWR|O_EXEC, np);
if (err == 0)
- pthread_mutex_unlock (&(*np)->lock);
+ {
+ pthread_mutex_unlock (&(*np)->lock);
+ set_default_attributes (*np);
+ if (real_mode != mode)
+ {
+ set_faked_attribute (*np, FAKE_MODE);
+ (*np)->nn_stat.st_mode = mode;
+ }
+ }
return err;
}
@@ -964,9 +974,16 @@ netfs_demuxer (mach_msg_header_t *inp,
{
/* We didn't recognize the message ID, so pass the message through
unchanged to the underlying file. */
- struct protid *cred = ports_lookup_port (netfs_port_bucket,
- inp->msgh_local_port,
- netfs_protid_class);
+ struct protid *cred;
+ if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) ==
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+ cred = ports_lookup_payload (netfs_port_bucket,
+ inp->msgh_protected_payload,
+ netfs_protid_class);
+ else
+ cred = ports_lookup_port (netfs_port_bucket,
+ inp->msgh_local_port,
+ netfs_protid_class);
if (cred == 0)
/* This must be an unknown message on our fsys control port. */
return 0;
@@ -974,7 +991,9 @@ netfs_demuxer (mach_msg_header_t *inp,
{
error_t err;
assert (MACH_MSGH_BITS_LOCAL (inp->msgh_bits)
- == MACH_MSG_TYPE_MOVE_SEND);
+ == MACH_MSG_TYPE_MOVE_SEND
+ || MACH_MSGH_BITS_LOCAL (inp->msgh_bits)
+ == MACH_MSG_TYPE_PROTECTED_PAYLOAD);
inp->msgh_bits = (inp->msgh_bits & MACH_MSGH_BITS_COMPLEX)
| MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
MACH_MSGH_BITS_REMOTE (inp->msgh_bits));
diff --git a/trans/mtab.c b/trans/mtab.c
index 5207c1e..a9928b3 100644
--- a/trans/mtab.c
+++ b/trans/mtab.c
@@ -24,6 +24,7 @@
#include <error.h>
#include <fcntl.h>
#include <hurd.h>
+#include <hurd/ihash.h>
#include <hurd/trivfs.h>
#include <inttypes.h>
#include <mntent.h>
@@ -55,6 +56,7 @@ struct mtab
char *contents;
size_t contents_len;
off_t offs;
+ struct hurd_ihash ports_seen;
};
const char *argp_program_version = STANDARD_HURD_VERSION (mtab);
@@ -244,7 +246,11 @@ main (int argc, char *argv[])
else
{
/* One-shot mode. */
- struct mtab mtab = { .lock = PTHREAD_MUTEX_INITIALIZER };
+ struct mtab mtab =
+ {
+ .lock = PTHREAD_MUTEX_INITIALIZER,
+ .ports_seen = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP),
+ };
err = mtab_populate (&mtab, target_path, insecure);
if (err)
error (5, err, "%s", target_path);
@@ -301,6 +307,33 @@ is_filesystem_translator (file_t node)
}
}
+/* Records NODE's idport in ports_seen, returns true if we have
+ already seen this node or there was an error getting the id
+ port. */
+boolean_t
+mtab_mark_as_seen (struct mtab *mtab, mach_port_t node)
+{
+ error_t err;
+ mach_port_t idport, fsidport;
+ ino_t fileno;
+
+ err = io_identity (node, &idport, &fsidport, &fileno);
+ if (err)
+ return TRUE;
+
+ mach_port_deallocate (mach_task_self (), fsidport);
+
+ if (hurd_ihash_find (&mtab->ports_seen, idport))
+ {
+ /* Already seen. Get rid of the extra reference. */
+ mach_port_deallocate (mach_task_self (), idport);
+ return TRUE;
+ }
+
+ hurd_ihash_add (&mtab->ports_seen, idport, idport);
+ return FALSE;
+}
+
/* Populates the given MTAB object with the information for PATH. If
INSECURE is given, also follow translators bound to nodes not owned
by root or the current user. */
@@ -363,6 +396,13 @@ mtab_populate (struct mtab *mtab, const char *path, int
insecure)
goto errout;
}
+ /* Avoid running in circles. */
+ if (mtab_mark_as_seen (mtab, node))
+ {
+ err = 0;
+ goto errout;
+ }
+
/* Query its options. */
err = file_get_fs_options (node, &argz, &argz_len);
if (err)
@@ -602,6 +642,7 @@ open_hook (struct trivfs_peropen *peropen)
mtab->offs = 0;
mtab->contents = NULL;
mtab->contents_len = 0;
+ hurd_ihash_init (&mtab->ports_seen, HURD_IHASH_NO_LOCP);
/* The mtab object is initialized, but not yet populated. We delay
that until that data is really needed. This avoids the following
@@ -635,6 +676,9 @@ close_hook (struct trivfs_peropen *peropen)
struct mtab *op = peropen->hook;
pthread_mutex_destroy (&op->lock);
free (op->contents);
+ HURD_IHASH_ITERATE (&op->ports_seen, p)
+ mach_port_deallocate (mach_task_self (), (mach_port_t) p);
+ hurd_ihash_destroy (&op->ports_seen);
free (op);
}
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index b11fea4..62d3c87 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -1195,6 +1195,16 @@ wrap_new_task (mach_msg_header_t *inp, struct req_info
*req)
ports_port_deref (task_wrapper1);
}
+/* Returns true if the given message is a Mach notification. */
+static inline int
+is_notification (const mach_msg_header_t *InHeadP)
+{
+ int msgh_id = InHeadP->msgh_id - 64;
+ if ((msgh_id > 8) || (msgh_id < 0))
+ return 0;
+ return 1;
+}
+
int
trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp)
{
@@ -1219,7 +1229,24 @@ trace_and_forward (mach_msg_header_t *inp,
mach_msg_header_t *outp)
/* Look up our record for the receiving port. There is no need to check
the class, because our port bucket only ever contains one class of
ports (traced_class). */
- info = ports_lookup_port (traced_bucket, inp->msgh_local_port, 0);
+
+ if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) == MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+ {
+ info = ports_lookup_payload (traced_bucket, inp->msgh_protected_payload,
+ NULL);
+ if (info)
+ {
+ /* Undo the protected payload optimization. */
+ inp->msgh_bits = MACH_MSGH_BITS (
+ MACH_MSGH_BITS_REMOTE (inp->msgh_bits),
+ is_notification (inp)? MACH_MSG_TYPE_MOVE_SEND_ONCE: info->type)
+ | MACH_MSGH_BITS_OTHER (inp->msgh_bits);
+ inp->msgh_local_port = ports_payload_get_name (info);
+ }
+ }
+ else
+ info = ports_lookup_port (traced_bucket, inp->msgh_local_port, NULL);
+
assert (info);
/* A notification message from the kernel appears to have been sent
@@ -1606,7 +1633,7 @@ print_data (mach_msg_type_name_t type,
the first character that has not yet been printed. */
const char *p, *q;
p = q = (const char *) data;
- while (*q && q - (const char *) data < (int) (nelt * eltsize))
+ while (q && *q && q - (const char *) data < (int) (nelt * eltsize))
{
if (isgraph (*q) || *q == ' ')
{
diff --git a/utils/umount.c b/utils/umount.c
index cf6be22..4005029 100644
--- a/utils/umount.c
+++ b/utils/umount.c
@@ -292,8 +292,6 @@ main (int argc, char **argv)
fs = fstab_find_device (fstab, t);
if (! fs)
{
- error (0, 0, "could not find entry for: %s", t);
-
/* As last resort, just assume it is the mountpoint. */
struct mntent m =
{
@@ -307,7 +305,7 @@ main (int argc, char **argv)
err = fstab_add_mntent (fstab, &m, &fs);
if (err)
- error (2, err, "%s", t);
+ error (2, err, "could not find entry for: %s", t);
}
}
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git