/* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights * Reserved. This file contains Original Code and/or Modifications of * Original Code as defined in and that are subject to the Apple Public * Source License Version 1.0 (the 'License'). You may not use this file * except in compliance with the License. Please obtain a copy of the * License at http://www.apple.com/publicsource and read it before using * this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License." * * @APPLE_LICENSE_HEADER_END@ */ /* * bootstrap -- fundamental service initiator and port server * Mike DeMoney, NeXT, Inc. * Copyright, 1990. All rights reserved. * * bootstrap.defs -- Mig interface definition */ subsystem bootstrap 400; /* * Interface: Bootstrap server * * The bootstrap server is the first user-mode task initiated by the Mach * kernel at system boot time. The bootstrap server provides two services, * it initiates other system tasks, and manages a table of name-port bindings * for fundamental system services (e.g. the NetMsgServer, and the Unix * emulation service). * * The file /etc/bootstrap.conf is read by bootstrap to determine other system * services to initiate at system boot time. The format of this file is * described later. * * Name-port bindings can be established with the bootstrap server by either * of two mechanisms: * * 1. The binding can be indicated in the file /etc/bootstrap.conf. In this * case, bootstrap will immediately create a port and bind the indicated name * with that port. At a later time, a service may "checkin" for the name-port * binding and will be returned receive rights for the bound port. Lookup's * on bindings created by this mechanism will return send rights to the port, * even if no service has "checked-in". In this case, requests sent to the * bound port will be queued until a server has checked-in and can satisfy the * request. * * 2. Bindings can be established dynamically via a "register" request. In * this case, the register request provides bootstrap with a name and send * rights for a port. Bootstrap will provide send rights for the bound port * to any requestor via the lookup request. * * Bootstrap provides its service port to descendant tasks via the Mach * "bootstrap" special task port. All direct descendants of bootstrap receive * a "privileged" bootstrap service port. System services that initiate * untrusted tasks should replace the Mach bootstrap task special port with * a subset bootstrap port to prevent them from infecting the namespace. * * The bootstrap server creates a "backup" port for each service that it * creates. This is used to detect when a checked out service is no longer * being served. The bootstrap server regains all rights to the port and * it is marked available for check-out again. This allows crashed servers to * resume service to previous clients. Lookup's on this named port will * continue to be serviced by bootstrap while holding receive rights for the * bound port. A client may detect that the service is inactive via the. * bootstrap status request. If the service re-registers rather than * "checking-in" the original bound port is destroyed. * * The status of a named service may be obtained via the "status" request. * A service is "active" if a name-port binding exists and receive rights * to the bound port are held by a task other than bootstrap. * * Bootstrap initiates server tasks and creates initial name-port bindings as * directed by the configuration file /etc/bootstrap.conf. This file has * entries with the following formats: * * services [ SERVICE_NAME ]+ ; * * E.g: * services OldService=1 SomeService; * * Creates a port and binds the name "OldService" to it. * For compatability, assigns the port via mach_ports_register to * slot 1. Also creates a port and binds the name "SomeService". * * self [ SERVICE_NAME ]+ ; * * E.g: * self BootStrapService; * * Provides a binding to bootstrap's own service port named * "BootStrapService". * * [restartable] server SERVER_FILE_AND_ARGS [ services ... ] ; * * E.g: * server "/usr/etc/sigserver -i" services UnixSignalService; * * Initiates the server task "/usr/etc/sigserver" with * command-line argument "-i", and also creates a name-port * binding for the name UnixSignalService. Checkin requests for * UnixSignalService are only accepted via the bootstrap service * port passed to/usr/etc/sigserver. If the "restartable" option * had been specified, bootstrap will reinitiate the server task * if it receives notification that all of the server's service * ports have been destroyed or deallocated. The server command * may be specified without surrounding quotes if it does not * include blanks. * * init SERVER_FILE_AND_ARGS [ services ... ] ; * * E.g: * init /etc/init services NetMsgService=0 PSWindowService=4; * * Functions like "server" request above, except process is * started as pid 1. Illegal if bootstrap itself was not * initiated as pid 1. * * forward; * * If present, bootstrap will forward unknown lookup requests to * its bootstrap service port (if not PORT_NULL), and forward any * reply to the original requester. * * # Comment string up to end of line. * * A line terminated comment starts with a sharp sign (#). * * Lexical notes: Strings are either enclosed in double quotes ("), or must * start with a letter or underscore (_) and followed by a string of * alphanumerics and underscores; backslash (\) escapes the following * character. Strings are limited to a (large) length. Numbers must be * decimal. Blanks and newlines may be freely used outside of strings. */ #include import ; type name_t = c_string[128]; type name_array_t = ^array [] of name_t; type bool_array_t = ^array [] of boolean_t; serverprefix x_; /* old service_checkin */ skip; /* old service_status */ skip; /* * kern_return_t * bootstrap_check_in(mach_port_t bootstrap_port, * name_t service_name, * port_all_t *service_port) * * Returns all rights to service_port of service named by service_name. * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to * bootstrap port without privilege. * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been * registered or checked-in. */ routine bootstrap_check_in( bootstrap_port : mach_port_t; service_name : name_t; out service_port : mach_port_move_receive_t); /* * kern_return_t * bootstrap_register(mach_port_t bootstrap_port, * name_t service_name, * mach_port_t service_port) * * Registers send rights for the port service_port for the service named by * service_name. Attempts to registering a service where an active binding * already exists are rejected. On the otherhand, registering a service where * and inactive binding exists (i.e. bootstrap currently holds receive rights * for the service port) is allowed; in this case the previous service port * will be deallocated. Restarting services wishing to resume service for * previous clients must first attempt to checkin to the service in order to * recover the previous service port. * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to * bootstrap port without privilege. * Returns BOOTSTRAP_NAME_IN_USE, if service has already been * register or checked-in. */ routine bootstrap_register( bootstrap_port : mach_port_t; service_name : name_t; service_port : mach_port_t); /* * kern_return_t * bootstrap_look_up(mach_port_t bootstrap_port, * name_t service_name, * mach_port_t *service_port) * * Returns send rights for the service port of the service named by * service_name in service_port. Service is not guaranteed to be active. * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. */ routine bootstrap_look_up( bootstrap_port : mach_port_t; service_name : name_t; out service_port : mach_port_t); /* * kern_return_t * bootstrap_look_up_array(mach_port_t bootstrap_port, * name_array_t service_names, * int service_names_cnt, * port_array_t *service_port, * int *service_ports_cnt, * boolean_t *all_services_known) * * Returns port send rights in corresponding entries of the array service_ports * for all services named in the array service_names. Service_ports_cnt is * returned and will always equal service_names_cnt (assuming service_names_cnt * is greater than or equal to zero). * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_NO_MEMORY, if server couldn't obtain memory * for response. * Unknown service names have the corresponding service port set * to PORT_NULL. * If all services are known, all_services_known is true on * return, if any service is unknown, it's false. */ routine bootstrap_look_up_array( bootstrap_port : mach_port_t; service_names : name_array_t; out service_ports : mach_port_array_t; out all_services_known: boolean_t); /* old bootstrap_get_unpriv_port */ skip; /* * kern_return_t * bootstrap_status(mach_port_t bootstrap_port, * name_t service_name, * boolean_t *service_active); * * Returns: service_active is true if service is available. * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. */ routine bootstrap_status( bootstrap_port : mach_port_t; service_name : name_t; out service_active : boolean_t); /* * kern_return_t * bootstrap_info(port_t bootstrap_port, * name_array_t *service_names, * int *service_names_cnt, * name_array_t *server_names, * int *server_names_cnt, * bool_array_t *service_active, * int *service_active_cnt); * * Errors: Returns appropriate kernel errors on rpc failure. */ routine bootstrap_info( bootstrap_port : mach_port_t; out service_names : name_array_t, dealloc; out server_names : name_array_t, dealloc; out service_active : bool_array_t, dealloc); /* * kern_return_t * bootstrap_subset(mach_port_t bootstrap_port, * mach_port_t requestor_port, * mach_port_t *subset_port); * * Returns a new port to use as a bootstrap port. This port behaves * exactly like the previous bootstrap_port, except that ports dynamically * registered via bootstrap_register() are available only to users of this * specific subset_port. Lookups on the subset_port will return ports * registered with this port specifically, and ports registered with * ancestors of this subset_port. Duplications of services already * registered with an ancestor port may be registered with the subset port * are allowed. Services already advertised may then be effectively removed * by registering PORT_NULL for the service. * When it is detected that the requestor_port is destroied the subset * port and all services advertized by it are destroied as well. * * Errors: Returns appropriate kernel errors on rpc failure. */ routine bootstrap_subset( bootstrap_port : mach_port_t; requestor_port : mach_port_t; out subset_port : mach_port_t); /* * kern_return_t * bootstrap_create_service(mach_port_t bootstrap_port, * name_t service_name, * mach_port_t *service_port) * * Creates a service named "service_name" and returns send rights to that * port in "service_port." The port may later be checked in as if this * port were configured in the bootstrap configuration file. * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_SERVICE_ACTIVE, if service already exists. */ routine bootstrap_create_service( bootstrap_port : mach_port_t; service_name : name_t; out service_port : mach_port_t);