Example #1
0
int
main (int argc, char **argv)
{
  error_t err;
  mach_port_t bootstrap;

  argp_parse (&argp, argc, argv, 0, 0, 0);

  if (MACH_PORT_VALID (opt_device_master))
    {
      err = open_console (opt_device_master);
      assert_perror (err);
      mach_port_deallocate (mach_task_self (), opt_device_master);
    }

  save_argv = argv;

  task_get_bootstrap_port (mach_task_self (), &bootstrap);
  if (bootstrap == MACH_PORT_NULL)
    error (2, 0, "Must be started as a translator");

  /* Fetch our proc server port for easy use.  If we are booting, it is not
     set yet and `getproc' returns MACH_PORT_NULL; we reset PROCSERVER in
     S_exec_init (below).  */
  procserver = getproc ();

  err = trivfs_add_port_bucket (&port_bucket);
  if (err)
    error (1, 0, "error creating port bucket");

  err = trivfs_add_control_port_class (&trivfs_control_class);
  if (err)
    error (1, 0, "error creating control port class");

  err = trivfs_add_protid_port_class (&trivfs_protid_class);
  if (err)
    error (1, 0, "error creating protid port class");

  execboot_portclass = ports_create_class (deadboot, NULL);

  /* Reply to our parent.  */
  err = trivfs_startup (bootstrap, 0,
                        trivfs_control_class, port_bucket,
                        trivfs_protid_class, port_bucket, &fsys);

  /* Reply to our parent.  */
  err = trivfs_startup (bootstrap, 0,
			trivfs_control_class, port_bucket,
			trivfs_protid_class, port_bucket,
			&fsys);
  mach_port_deallocate (mach_task_self (), bootstrap);
  if (err)
    error (3, err, "Contacting parent");

  /* Launch.  */
  ports_manage_port_operations_multithread (port_bucket, exec_demuxer,
					    2 * 60 * 1000, 0, 0);

  return 0;
}
Example #2
0
void
pfinet_bind (int portclass, const char *name)
{
    struct trivfs_control *cntl;
    error_t err = 0;
    mach_port_t right;
    file_t file = file_name_lookup (name, O_CREAT|O_NOTRANS, 0666);

    if (file == MACH_PORT_NULL)
        err = errno;

    if (! err) {
        if (pfinet_protid_portclasses[portclass] != MACH_PORT_NULL)
            error (1, 0, "Cannot bind one protocol to multiple nodes.\n");

#ifdef CONFIG_IPV6
        if (portclass == PORTCLASS_INET6)
            pfinet_activate_ipv6 ();
#endif
        //mark
        err = trivfs_add_protid_port_class (&pfinet_protid_portclasses[portclass]);
        if (err)
            error (1, 0, "error creating control port class");

        err = trivfs_add_control_port_class (&pfinet_cntl_portclasses[portclass]);
        if (err)
            error (1, 0, "error creating control port class");

        err = trivfs_create_control (file, pfinet_cntl_portclasses[portclass],
                                     pfinet_bucket,
                                     pfinet_protid_portclasses[portclass],
                                     pfinet_bucket, &cntl);
    }

    if (! err)
    {
        right = ports_get_send_right (cntl);
        err = file_set_translator (file, 0, FS_TRANS_EXCL | FS_TRANS_SET,
                                   0, 0, 0, right, MACH_MSG_TYPE_COPY_SEND);
        mach_port_deallocate (mach_task_self (), right);
    }

    if (err)
        error (1, err, "%s", name);

    ports_port_deref (cntl);

}
/* Create a new trivfs control port, with underlying node UNDERLYING, and
   return it in CONTROL.  CONTROL_CLASS & CONTROL_BUCKET are passed to
   the ports library to create the control port, and PROTID_CLASS &
   PROTID_BUCKET are used when creating ports representing opens of this
   node.  */
error_t
trivfs_create_control (mach_port_t underlying,
		       struct port_class *control_class,
		       struct port_bucket *control_bucket,
		       struct port_class *protid_class,
		       struct port_bucket *protid_bucket,
		       struct trivfs_control **control)
{
  error_t err;

  /* Perhaps allocate, and perhaps add the specified port classes the ones
     recognized by trivfs.  */
  err = trivfs_add_control_port_class (&control_class);
  if (! err)
    err = trivfs_add_protid_port_class (&protid_class);
  else
    protid_class = 0;

  /* Perhaps allocate new port buckets.  */
  if (! err)
    err = trivfs_add_port_bucket (&control_bucket);
  else
    control_bucket = 0;
  if (! err)
    {
      if (! protid_bucket)
	/* By default, use the same port bucket for both.  */
	protid_bucket = control_bucket;
      err = trivfs_add_port_bucket (&protid_bucket);
    }
  else
    protid_bucket = 0;

  if (! err)
    err = ports_create_port (control_class, control_bucket, 
			     sizeof (struct trivfs_control), control);

  if (! err)
    {
      (*control)->underlying = underlying;
      (*control)->protid_class = protid_class;
      (*control)->protid_bucket = protid_bucket;
      err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
				&(*control)->filesys_id);
      if (err)
	{
	  ports_port_deref (*control);
	  goto out;
	}
      
      err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
				&(*control)->file_id);
      if (err)
	{
	  mach_port_destroy (mach_task_self (), (*control)->filesys_id);
	  ports_port_deref (*control);
	  goto out;
	}

      (*control)->hook = 0;
      mutex_init (&(*control)->lock);
    }

out:
  if (err)
    {
      trivfs_remove_control_port_class (control_class);
      trivfs_remove_protid_port_class (protid_class);
      trivfs_remove_port_bucket (control_bucket);
      trivfs_remove_port_bucket (protid_bucket);
    }

  return err;
}
Example #4
0
int
main (int argc,
      char **argv)
{
    error_t err;
    mach_port_t bootstrap;
    struct stat st;
    pthread_t thread;

    pfinet_bucket = ports_create_bucket ();
    addrport_class = ports_create_class (clean_addrport, 0);
    socketport_class = ports_create_class (clean_socketport, 0);
    mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
                        &fsys_identity);

    /* Generic initialization */

    init_time ();
    ethernet_initialize ();
    err = pthread_create (&thread, NULL, net_bh_worker, NULL);
    if (!err)
        pthread_detach (thread);
    else
    {
        errno = err;
        perror ("pthread_create");
    }

    pthread_mutex_lock (&global_lock);

    prepare_current (1);		/* Set up to call into Linux initialization. */

    sk_init ();
#ifdef SLAB_SKB
    skb_init ();
#endif
    inet_proto_init (0);

    /* This initializes the Linux network device layer, including
       initializing each device on the `dev_base' list.  For us,
       that means just loopback_dev, which will get fully initialized now.
       After this, we can use `register_netdevice' for new interfaces.  */
    net_dev_init ();

    /* ifconfig lo up 127.0.0.1 netmask 0xff000000 */
    configure_device (&loopback_dev,
                      htonl (INADDR_LOOPBACK), htonl (IN_CLASSA_NET),
                      htonl (INADDR_NONE), htonl (INADDR_NONE));

    pthread_mutex_unlock (&global_lock);

    /* Parse options.  When successful, this configures the interfaces
       before returning; to do so, it will acquire the global_lock.
       (And when not successful, it never returns.)  */
    argp_parse (&pfinet_argp, argc, argv, 0,0,0);

    task_get_bootstrap_port (mach_task_self (), &bootstrap);

    pfinet_owner = pfinet_group = 0;

    if (bootstrap != MACH_PORT_NULL) {
        /* Create portclass to install on the bootstrap port. */
        if(pfinet_protid_portclasses[pfinet_bootstrap_portclass]
                != MACH_PORT_NULL)
            error(1, 0, "No portclass left to assign to bootstrap port");

#ifdef CONFIG_IPV6
        if (pfinet_bootstrap_portclass == PORTCLASS_INET6)
            pfinet_activate_ipv6 ();
#endif

        err = trivfs_add_protid_port_class (
                  &pfinet_protid_portclasses[pfinet_bootstrap_portclass]);
        if (err)
            error (1, 0, "error creating control port class");

        err = trivfs_add_control_port_class (
                  &pfinet_cntl_portclasses[pfinet_bootstrap_portclass]);
        if (err)
            error (1, 0, "error creating control port class");

        /* Talk to parent and link us in.  */
        err = trivfs_startup (bootstrap, 0,
                              pfinet_cntl_portclasses[pfinet_bootstrap_portclass],
                              pfinet_bucket,
                              pfinet_protid_portclasses[pfinet_bootstrap_portclass],
                              pfinet_bucket,
                              &pfinetctl);

        if (err)
            error (1, err, "contacting parent");

        /* Initialize status from underlying node.  */
        err = io_stat (pfinetctl->underlying, &st);
        if (! err)
        {
            pfinet_owner = st.st_uid;
            pfinet_group = st.st_gid;
        }
    }
    else { /* no bootstrap port. */
        int i;
        /* Check that at least one portclass has been bound,
           error out otherwise. */
        for (i = 0; i < ARRAY_SIZE (pfinet_protid_portclasses); i++)
            if (pfinet_protid_portclasses[i] != MACH_PORT_NULL)
                break;

        if (i == ARRAY_SIZE (pfinet_protid_portclasses))
            error (1, 0, "should be started as a translator.\n");
    }

    /* Ask init to tell us when the system is going down,
       so we can try to be friendly to our correspondents on the network.  */
    arrange_shutdown_notification ();

    /* Launch */
    ports_manage_port_operations_multithread (pfinet_bucket,
            pfinet_demuxer,
            30 * 1000, 2 * 60 * 1000, 0);
    return 0;
}