diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-01-21 00:26:21 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-01-21 00:26:21 +0100 |
commit | 977a83c997bd40b8504dfda38c55d934ff91aebe (patch) | |
tree | f87133001a9ca4f1bb9eeb0b36ef501b05683010 /debian/patches/0003-trans-add-startup-standalone-XXX.patch | |
parent | a107ea39ab787ef239ee24dc2d2a24d33651d403 (diff) |
add patch series
Diffstat (limited to 'debian/patches/0003-trans-add-startup-standalone-XXX.patch')
-rw-r--r-- | debian/patches/0003-trans-add-startup-standalone-XXX.patch | 493 |
1 files changed, 493 insertions, 0 deletions
diff --git a/debian/patches/0003-trans-add-startup-standalone-XXX.patch b/debian/patches/0003-trans-add-startup-standalone-XXX.patch new file mode 100644 index 00000000..c187c28f --- /dev/null +++ b/debian/patches/0003-trans-add-startup-standalone-XXX.patch @@ -0,0 +1,493 @@ +From a8c0a69d53d3dc310536a338e6d3ab34f75bb9cb Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Tue, 13 Jan 2015 19:01:50 +0100 +Subject: [PATCH hurd 3/5] trans: add `startup-standalone' XXX + +Provide a stripped-down version of the startup translator that +supervises core servers and handles system shutdown. + +* trans/startup-standalone.c: New file. +* trans/Makefile: Add `startup-standalone'. +--- + trans/Makefile | 9 +- + trans/startup-standalone.c | 435 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 440 insertions(+), 4 deletions(-) + create mode 100644 trans/startup-standalone.c + +diff --git a/trans/Makefile b/trans/Makefile +index ce1eae7..5153361 100644 +--- a/trans/Makefile ++++ b/trans/Makefile +@@ -21,14 +21,14 @@ makemode := servers + + targets = symlink firmlink ifsock magic null fifo new-fifo fwd crash \ + password hello hello-mt streamio fakeroot proxy-defpager remap \ +- mtab ++ mtab startup-standalone + SRCS = ifsock.c symlink.c magic.c null.c fifo.c new-fifo.c fwd.c \ + crash.c firmlink.c password.c hello.c hello-mt.c streamio.c \ +- fakeroot.c proxy-defpager.c remap.c mtab.c ++ fakeroot.c proxy-defpager.c remap.c mtab.c startup-standalone.c + OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o passwordServer.o \ + crashServer.o crash_replyUser.o msgServer.o \ + default_pagerServer.o default_pagerUser.o \ +- device_replyServer.o elfcore.o ++ device_replyServer.o elfcore.o startupServer.o + HURDLIBS = ports netfs trivfs iohelp fshelp pipe ihash shouldbeinlibc + LDLIBS += -lpthread + password-LDLIBS = -lcrypt +@@ -61,8 +61,9 @@ crash: crashServer.o crash_replyUser.o msgServer.o elfcore.o + password: passwordServer.o + streamio: device_replyServer.o + proxy-defpager: default_pagerServer.o default_pagerUser.o ++startup-standalone: startupServer.o startup_notifyUser.o + +-proxy-defpager crash password streamio: ../libports/libports.a ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a ++proxy-defpager crash password streamio startup-standalone: ../libports/libports.a ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a + fifo new-fifo: ../libpipe/libpipe.a + fwd: ../libfshelp/libfshelp.a ../libports/libports.a + hello-mt magic null ifsock fifo new-fifo firmlink: ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a ../libports/libports.a ../libihash/libihash.a +diff --git a/trans/startup-standalone.c b/trans/startup-standalone.c +new file mode 100644 +index 0000000..87acd0e +--- /dev/null ++++ b/trans/startup-standalone.c +@@ -0,0 +1,435 @@ ++/* Start and maintain hurd core servers and system run state ++ ++ Copyright (C) 1993-2015 Free Software Foundation, Inc. ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2, or (at your option) ++ any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd; see the file COPYING. If not, write to ++ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ++ ++/* 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 <argz.h> ++#include <error.h> ++#include <fcntl.h> ++#include <hurd/ports.h> ++#include <hurd/trivfs.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <string.h> ++#include <sys/mman.h> ++#include <sys/reboot.h> ++#include <unistd.h> ++#include <version.h> ++ ++#include "startup_notify_U.h" ++#include "startup_reply_U.h" ++#include "startup_S.h" ++#include "notify_S.h" ++ ++/* The privileged host control port. Used for authentication. */ ++mach_port_t host_priv; ++ ++/* We receive dead-name notifications here. */ ++struct port_info *notification; ++ ++/* 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 (startup-standalone); ++ ++/* Trivfs hooks. */ ++int trivfs_fstype = FSTYPE_MISC; ++int trivfs_fsid = 0; ++ ++int trivfs_allow_open = 0; ++int trivfs_support_read = 0; ++int trivfs_support_write = 0; ++int trivfs_support_exec = 0; ++ ++void ++trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st) ++{ ++ /* Mark the node as a read-only plain file. */ ++ st->st_mode &= ~(S_IFMT | ALLPERMS); ++ st->st_mode |= (S_IFREG | S_IRUSR | S_IRGRP | S_IROTH); ++ st->st_size = 0; ++} ++ ++error_t ++trivfs_goaway (struct trivfs_control *cntl, int flags) ++{ ++ exit (0); ++} ++ ++/* Options processing. We accept the same options on the command line ++ and from fsys_set_options. */ ++ ++static const struct argp_option options[] = ++{ ++ {"crash-debug", 'H', 0, 0, "On system crash, go to kernel debugger"}, ++ {0} ++}; ++ ++static error_t ++parse_opt (int opt, char *arg, struct argp_state *state) ++{ ++ switch (opt) ++ { ++ case 'H': crash_flags = RB_DEBUGGER; break; ++ default: ++ return ARGP_ERR_UNKNOWN; ++ case ARGP_KEY_INIT: ++ case ARGP_KEY_SUCCESS: ++ case ARGP_KEY_ERROR: ++ break; ++ } ++ return 0; ++} ++ ++/* This will be called from libtrivfs to help construct the answer ++ to an fsys_get_options RPC. */ ++error_t ++trivfs_append_args (struct trivfs_control *fsys, ++ char **argz, size_t *argz_len) ++{ ++ error_t err = 0; ++ ++ if (crash_flags == RB_DEBUGGER) ++ err = argz_add (argz, argz_len, "--crash-debug"); ++ ++ return err; ++} ++ ++static const char doc[] = ++ "Supervise Hurd core servers and manage system shutdown"; ++ ++static struct argp hello_argp = ++{ options, parse_opt, 0, doc }; ++ ++/* Setting this variable makes libtrivfs use our argp to ++ parse options passed in an fsys_set_options RPC. */ ++struct argp *trivfs_runtime_argp = &hello_argp; ++ ++static int ++demuxer (mach_msg_header_t *inp, ++ mach_msg_header_t *outp) ++{ ++ // XXX nicer demuxer ++ extern int startup_server (mach_msg_header_t *, mach_msg_header_t *); ++ ++ return startup_server (inp, outp) || trivfs_demuxer (inp, outp); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ error_t err; ++ mach_port_t bootstrap; ++ struct trivfs_control *fsys; ++ struct port_class *notification_class; ++ ++ /* We use the same argp for options available at startup ++ as for options we'll accept in an fsys_set_options RPC. */ ++ argp_parse (&hello_argp, argc, argv, 0, 0, 0); ++ ++ err = get_privileged_ports (&host_priv, NULL); ++ if (err) ++ error (1, err, "Must be started as root"); ++ ++ task_get_bootstrap_port (mach_task_self (), &bootstrap); ++ if (bootstrap == MACH_PORT_NULL) ++ error (1, 0, "Must be started as a translator"); ++ ++ /* Reply to our parent */ ++ err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &fsys); ++ if (err) ++ error (3, err, "trivfs_startup"); ++ ++ err = mach_port_deallocate (mach_task_self (), bootstrap); ++ assert_perror (err); ++ ++ notification_class = ports_create_class (NULL, NULL); ++ if (! notification_class) ++ error (1, errno, "ports_create_class"); ++ ++ err = ports_create_port (notification_class, fsys->pi.bucket, 0, ++ ¬ification); ++ if (err) ++ error (1, err, "ports_create_port"); ++ ++ /* Launch. */ ++ ports_manage_port_operations_one_thread (fsys->pi.bucket, demuxer, 0); ++ ++ return 0; ++} ++ ++/* 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; ++ ++/** System shutdown **/ ++ ++/* Reboot the microkernel. */ ++void ++reboot_mach (int flags) ++{ ++ 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 (BOOT (flags)); ++ reboot_mach (flags); ++} ++ ++/* Reboot the Hurd, specifying that this is a crash. */ ++void ++crash_system (void) ++{ ++ reboot_system (crash_flags); ++} ++ ++/* Request a dead-name notification sent to our port. */ ++static error_t ++request_dead_name (mach_port_t name) ++{ ++ error_t err; ++ mach_port_t prev; ++ err = mach_port_request_notification (mach_task_self (), name, ++ MACH_NOTIFY_DEAD_NAME, 1, ++ notification->port_right, ++ MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev); ++ if (prev != MACH_PORT_NULL) ++ mach_port_deallocate (mach_task_self (), prev); ++ return err; ++} ++ ++/* Record an essential task in the list. */ ++static error_t ++record_essential_task (const char *name, task_t task) ++{ ++ error_t err; ++ 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. */ ++ err = request_dead_name (task); ++ if (err) ++ return err; ++ ++ return 0; ++} ++ ++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) ++{ ++ error_t err; ++ if (credential != host_priv) ++ return EPERM; ++ ++ err = mach_port_deallocate (mach_task_self (), credential); ++ assert_perror (err); ++ ++ err = record_essential_task (name, task); ++ if (err) ++ return err; ++ ++ return 0; ++} ++ ++kern_return_t ++S_startup_request_notification (mach_port_t server, ++ mach_port_t notify, ++ char *name) ++{ ++ error_t err; ++ struct ntfy_task *nt; ++ ++ err = request_dead_name (notify); ++ if (err) ++ return err; ++ ++ /* 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; ++ nt->name = strdup (name); ++ ntfy_tasks = nt; ++ return 0; ++} ++ ++kern_return_t ++S_startup_procinit (startup_t bootstrap, ++ mach_port_t reply, ++ mach_msg_type_name_t replyPoly, ++ process_t procserver, ++ mach_port_t *startuptask, ++ auth_t *auth, ++ mach_port_t *hostpriv, ++ mach_msg_type_name_t *hostprivPoly, ++ mach_port_t *devmaster, ++ mach_msg_type_name_t *devmasterPoly) ++{ ++ return EOPNOTSUPP; ++} ++ ++kern_return_t ++S_startup_authinit (startup_t bootstrap, ++ mach_port_t reply, ++ mach_msg_type_name_t replyPoly, ++ mach_port_t auth, ++ mach_port_t *proc, ++ mach_msg_type_name_t *procPoly) ++{ ++ return EOPNOTSUPP; ++} ++ ++error_t ++ports_do_mach_notify_dead_name (struct port_info *pi, ++ mach_port_t dead_name) ++{ ++ error_t err; ++ struct ntfy_task *nt, *pnt; ++ struct ess_task *et; ++ ++ if (!pi) ++ return EOPNOTSUPP; ++ ++ ports_dead_name (pi, dead_name); ++ ++ /* Drop gratuitous extra reference that the notification creates. */ ++ err = mach_port_deallocate (mach_task_self (), dead_name); ++ assert_perror (err); ++ ++ if (pi != notification) ++ return 0; ++ ++ for (et = ess_tasks; et != NULL; et = et->next) ++ if (et->task_port == dead_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 == dead_name) ++ { ++ /* Someone who wanted to be notified is gone. */ ++ err = mach_port_deallocate (mach_task_self (), dead_name); ++ assert_perror (err); ++ if (pnt != NULL) ++ pnt->next = nt->next; ++ else ++ ntfy_tasks = nt->next; ++ free (nt); ++ ++ return 0; ++ } ++ ++ 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 (;;); ++} +-- +2.1.4 + |