summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1997-06-21 05:34:18 +0000
committerMiles Bader <miles@gnu.org>1997-06-21 05:34:18 +0000
commit77458530c0e21bf5c3eb993334f02333c4e7c91a (patch)
tree5d2840a50900e80c81a8b173369170c842ba7f5e
parent09791c7ac023fe6688c072c1aae6c50daee1f061 (diff)
(parse_opt):
New function. (pseudo_root, root_store): New variables. (bootscript_args): Now an array. (ds_device_open, ds_device_close, ds_device_write, ds_device_write_inband, ds_device_read, ds_device_read_inband, ds_device_get_status, ds_device_set_status, ds_device_map, ds_xxx_device_set_filter, ds_xxx_device_get_status, ds_xxx_device_set_status, ds_device_set_filter): Handle "pseudo-root" device. (main): Use argp to parse args, and implement the pseudo-root device. Include <argp.h> & <hurd/store.h> (options, doc, args_doc): New variables. (bootscript): Made global.
-rw-r--r--boot/boot.c338
1 files changed, 227 insertions, 111 deletions
diff --git a/boot/boot.c b/boot/boot.c
index f52cf1b1..b92761d6 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -1,6 +1,6 @@
/* Load a task using the single server, and then run it
as if we were the kernel.
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -34,6 +34,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <elf.h>
#include <mach/mig_support.h>
#include <mach/default_pager.h>
+#include <argp.h>
+#include <hurd/store.h>
#include "notify_S.h"
#include "exec_S.h"
@@ -50,6 +52,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <hurd/auth.h>
#ifdef UX
+#undef STORE /* We can't use libstore when under UX. */
+#else
+#define STORE
+#endif
+
+#ifdef UX
#include "ux.h"
@@ -96,9 +104,11 @@ typedef struct stat host_stat_t;
mach_port_t privileged_host_port, master_device_port, defpager;
mach_port_t pseudo_master_device_port;
mach_port_t receive_set;
-mach_port_t pseudo_console;
+mach_port_t pseudo_console, pseudo_root;
auth_t authserver;
+struct store *root_store;
+
spin_lock_t queuelock = SPIN_LOCK_INITIALIZER;
spin_lock_t readlock = SPIN_LOCK_INITIALIZER;
@@ -117,8 +127,9 @@ void restore_termstate ();
char *fsname;
-char *bootstrap_args;
-char *bootdevice = "sd0a";
+char bootstrap_args[100] = "-";
+char *bootdevice = 0;
+char *bootscript = 0;
void set_mach_stack_args (task_t, thread_t, char *, ...);
@@ -381,58 +392,95 @@ boot_script_exec_cmd (mach_port_t task, char *path, int argc,
return 0;
}
+static struct argp_option options[] =
+{
+ { "boot-root", 'D', "DIR", 0,
+ "Root of a directory tree in which to find files specified in BOOT-SCRIPT" },
+ { "single-user", 's', 0, 0,
+ "Boot in single user mode" },
+ { "pause" , 'd', 0, 0,
+ "Pause for user confirmation at various times during booting" },
+ { 0 }
+};
+static char args_doc[] = "BOOT-SCRIPT";
+static char doc[] = "Boot a second hurd";
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ switch (key)
+ {
+ size_t len;
+
+ case 'D': useropen_dir = arg; break;
+
+ case 's': case 'd':
+ len = strlen (bootstrap_args);
+ if (len >= sizeof bootstrap_args - 1)
+ argp_error (state, "Too many bootstrap args");
+ bootstrap_args[len++] = key;
+ bootstrap_args[len] = '\0';
+ break;
+
+ case ARGP_KEY_ARG:
+ if (state->arg_num == 0)
+ bootscript = arg;
+ else
+ return ARGP_ERR_UNKNOWN;
+ break;
+
+ case ARGP_KEY_INIT:
+ state->child_inputs[0] = state->input; break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
int
main (int argc, char **argv, char **envp)
{
+ error_t err;
mach_port_t foo;
- static const char usagemsg[]
- = "Usage: boot [-D dir] [SWITCHES] SCRIPT ROOT-DEVICE\n";
char *buf = 0;
- char *bootscript;
int i, len;
- char *newargs;
+ char *root_store_name;
+ const struct argp_child kids[] = { { &store_argp }, { 0 }};
+ struct argp argp = { options, parse_opt, args_doc, doc, kids };
+ struct store_argp_params store_argp_params = { 0 };
+
+ argp_parse (&argp, argc, argv, 0, 0, &store_argp_params);
+ err = store_parsed_name (store_argp_params.result, &root_store_name);
+ if (err)
+ error (2, err, "store_parsed_name");
+
+ err = store_parsed_open (store_argp_params.result, 0, &root_store);
+ if (err)
+ error (4, err, "%s", root_store_name);
get_privileged_ports (&privileged_host_port, &master_device_port);
defpager = MACH_PORT_NULL;
vm_set_default_memory_manager (privileged_host_port, &defpager);
- if (argc < 2 || (argv[1][0] == '-' && argc < 3))
- {
- usage:
- write (2, usagemsg, sizeof usagemsg);
- host_exit (1);
- }
+ strcat (bootstrap_args, "f");
- if (!strcmp (argv[1], "-D"))
- {
- if (argc < 4)
- goto usage;
- useropen_dir = argv[2];
- argv += 2;
- }
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
+ &receive_set);
- if (argv[1][0] != '-')
- {
- bootstrap_args = "-x";
- bootscript = argv[1];
- bootdevice = argv[2];
- }
+ if (root_store->class == &store_device_class && root_store->name)
+ /* Let known device nodes pass through directly. */
+ bootdevice = root_store->name;
else
+ /* Pass a magic value that we can use to do I/O to ROOT_STORE. */
{
- bootstrap_args = argv[1];
- bootscript = argv[2];
- bootdevice = argv[3];
+ bootdevice = "pseudo-root";
+ mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pseudo_root);
+ mach_port_move_member (mach_task_self (), pseudo_root, receive_set);
}
- newargs = malloc (strlen (bootstrap_args) + 2);
- strcpy (newargs, bootstrap_args);
- strcat (newargs, "f");
- bootstrap_args = newargs;
-
- mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
- &receive_set);
-
mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
&pseudo_master_device_port);
mach_port_insert_right (mach_task_self (),
@@ -1009,6 +1057,13 @@ ds_device_open (mach_port_t master_port,
*devicetype = MACH_MSG_TYPE_MAKE_SEND;
return 0;
}
+ else if (strcmp (name, "pseudo-root") == 0)
+ /* Magic root device. */
+ {
+ *device = pseudo_root;
+ *devicetype = MACH_MSG_TYPE_MAKE_SEND;
+ return 0;
+ }
*devicetype = MACH_MSG_TYPE_MOVE_SEND;
return device_open (master_device_port, mode, name, device);
@@ -1017,7 +1072,7 @@ ds_device_open (mach_port_t master_port,
kern_return_t
ds_device_close (device_t device)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return 0;
}
@@ -1032,21 +1087,28 @@ ds_device_write (device_t device,
unsigned int datalen,
int *bytes_written)
{
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
-
-#if 0
- if (console_send_rights)
+ if (device == pseudo_console)
{
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+#if 0
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- *bytes_written = write (1, data, datalen);
+ *bytes_written = write (1, data, datalen);
- return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else if (device == pseudo_root)
+ return
+ (store_write (root_store, recnum, data, datalen, bytes_written) == 0
+ ? D_SUCCESS
+ : D_IO_ERROR);
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
@@ -1059,21 +1121,28 @@ ds_device_write_inband (device_t device,
unsigned int datalen,
int *bytes_written)
{
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
-
-#if 0
- if (console_send_rights)
+ if (device == pseudo_console)
{
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+#if 0
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- *bytes_written = write (1, data, datalen);
+ *bytes_written = write (1, data, datalen);
- return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else if (device == pseudo_root)
+ return
+ (store_write (root_store, recnum, data, datalen, bytes_written) == 0
+ ? D_SUCCESS
+ : D_IO_ERROR);
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
@@ -1086,35 +1155,45 @@ ds_device_read (device_t device,
io_buf_ptr_t *data,
unsigned int *datalen)
{
- int avail;
-
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
+ if (device == pseudo_console)
+ {
+ int avail;
#if 0
- if (console_send_rights)
- {
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- spin_lock (&readlock);
- ioctl (0, FIONREAD, &avail);
- if (avail)
- {
- vm_allocate (mach_task_self (), (pointer_t *)data, bytes_wanted, 1);
- *datalen = read (0, *data, bytes_wanted);
- unlock_readlock ();
- return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ spin_lock (&readlock);
+ ioctl (0, FIONREAD, &avail);
+ if (avail)
+ {
+ vm_allocate (mach_task_self (), (pointer_t *)data, bytes_wanted, 1);
+ *datalen = read (0, *data, bytes_wanted);
+ unlock_readlock ();
+ return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else
+ {
+ unlock_readlock ();
+ queue_read (DEV_READ, reply_port, reply_type, bytes_wanted);
+ return MIG_NO_REPLY;
+ }
}
- else
+ else if (device == pseudo_root)
{
- unlock_readlock ();
- queue_read (DEV_READ, reply_port, reply_type, bytes_wanted);
- return MIG_NO_REPLY;
+ *datalen = 0;
+ return
+ (store_read (root_store, recnum, bytes_wanted, (void **)data, datalen) == 0
+ ? D_SUCCESS
+ : D_IO_ERROR);
}
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
@@ -1127,34 +1206,58 @@ ds_device_read_inband (device_t device,
io_buf_ptr_inband_t data,
unsigned int *datalen)
{
- int avail;
-
- if (device != pseudo_console)
- return D_NO_SUCH_DEVICE;
+ if (device == pseudo_console)
+ {
+ int avail;
#if 0
- if (console_send_rights)
- {
- mach_port_mod_refs (mach_task_self (), pseudo_console,
- MACH_PORT_TYPE_SEND, -console_send_rights);
- console_send_rights = 0;
- }
+ if (console_send_rights)
+ {
+ mach_port_mod_refs (mach_task_self (), pseudo_console,
+ MACH_PORT_TYPE_SEND, -console_send_rights);
+ console_send_rights = 0;
+ }
#endif
- spin_lock (&readlock);
- ioctl (0, FIONREAD, &avail);
- if (avail)
- {
- *datalen = read (0, data, bytes_wanted);
- unlock_readlock ();
- return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ spin_lock (&readlock);
+ ioctl (0, FIONREAD, &avail);
+ if (avail)
+ {
+ *datalen = read (0, data, bytes_wanted);
+ unlock_readlock ();
+ return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
+ }
+ else
+ {
+ unlock_readlock ();
+ queue_read (DEV_READI, reply_port, reply_type, bytes_wanted);
+ return MIG_NO_REPLY;
+ }
}
- else
+ else if (device == pseudo_root)
{
- unlock_readlock ();
- queue_read (DEV_READI, reply_port, reply_type, bytes_wanted);
- return MIG_NO_REPLY;
+ error_t err;
+ void *returned = data;
+
+ *datalen = bytes_wanted;
+ err =
+ store_read (root_store, recnum, bytes_wanted, (void **)&returned, datalen);
+
+ if (! err)
+ {
+ if (returned != data)
+ {
+ bcopy (returned, (void *)data, *datalen);
+ vm_deallocate (mach_task_self (),
+ (vm_address_t)returned, *datalen);
+ }
+ return D_SUCCESS;
+ }
+ else
+ return D_IO_ERROR;
}
+ else
+ return D_NO_SUCH_DEVICE;
}
kern_return_t
@@ -1174,7 +1277,7 @@ ds_xxx_device_get_status (device_t device,
dev_status_t status,
u_int *statuscnt)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1186,7 +1289,7 @@ ds_xxx_device_set_filter (device_t device,
filter_array_t filt,
unsigned int len)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1199,7 +1302,7 @@ ds_device_map (device_t device,
memory_object_t *pager,
int unmap)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1210,7 +1313,7 @@ ds_device_set_status (device_t device,
dev_status_t status,
unsigned int statuslen)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}
@@ -1221,9 +1324,22 @@ ds_device_get_status (device_t device,
dev_status_t status,
unsigned int *statuslen)
{
- if (device != pseudo_console)
+ 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;
+ return D_SUCCESS;
+ }
+ else
+ return D_INVALID_OPERATION;
+ else
return D_NO_SUCH_DEVICE;
- return D_INVALID_OPERATION;
}
kern_return_t
@@ -1233,7 +1349,7 @@ ds_device_set_filter (device_t device,
filter_array_t filter,
unsigned int filterlen)
{
- if (device != pseudo_console)
+ if (device != pseudo_console && device != pseudo_root)
return D_NO_SUCH_DEVICE;
return D_INVALID_OPERATION;
}