Example #1
0
void domain_mgmt_init(void)
{
    errval_t err;

    /* Register notification endpoint with kernel */
    struct capref epcap;
    struct lmp_endpoint *notifyep;
    // XXX: This has to be huge so we can receive a batch of
    // notifications when deleting CNodes recursively.
    err = endpoint_create(100 * 12, &epcap, &notifyep);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "failed creating endpoint");
    }

    // register to receive on this endpoint
    struct event_closure cl = {
        .handler = handle_notification,
        .arg = notifyep,
    };
    err = lmp_endpoint_register(notifyep, get_default_waitset(), cl);
    assert(err_is_ok(err));

    err = invoke_monitor_register(epcap);
    if(err_is_fail(err)) {
        USER_PANIC_ERR(err, "Could not register with kernel");
    }
    else {
#ifdef DEBUG_MONITOR_ALL
        debug_printf("monitor ep registered\n");
#endif
    }
}
Example #2
0
/**
 * \brief A monitor receives request to setup a connection
 * with another newly booted monitor from a third monitor
 */
static void bind_monitor_request_scc(struct intermon_binding *b,
                                     coreid_t core_id,
                                     intermon_caprep_t caprep,
                                     chanid_t chan_id,
                                     coreid_t from_core_id)
{
    struct intermon_ump_ipi_binding *umpb = NULL;
    errval_t err;

    /* Create the cap */
    struct capability cap_raw;
    caprep_to_capability(&caprep, &cap_raw);
    if (cap_raw.type != ObjType_Frame) {
        err = MON_ERR_WRONG_CAP_TYPE;
        goto error;
    }

    struct capref frame;
    err = slot_alloc(&frame);
    if (err_is_fail(err)) {
        goto error;
    }

    ram_set_affinity(cap_raw.u.frame.base, cap_raw.u.frame.base + ((genpaddr_t)1 << cap_raw.u.frame.bits));
    err = frame_alloc(&frame, ((genpaddr_t)1 << cap_raw.u.frame.bits), NULL);
    ram_set_affinity(0,0);

    /* err = monitor_cap_create(frame, &cap_raw, core_id); */
    if (err_is_fail(err)) {
        goto error;
    }

    struct frame_identity frameid = { .base = 0, .bits = 0 };
    err = invoke_frame_identify(frame, &frameid);
    assert(err == SYS_ERR_OK);

    printf("bind_monitor_request: URPC physical frame at 0x%llx\n", frameid.base);

    /* Setup the connection */
    void *buf;
    err = vspace_map_one_frame_attr(&buf, MON_URPC_SIZE, frame,
                                    VREGION_FLAGS_READ_WRITE_NOCACHE, NULL,
                                    NULL);
    if (err_is_fail(err)) {
        err = err_push(err, LIB_ERR_VSPACE_MAP);
        goto error;
    }

    // Create remote notify cap
    struct capref notify_cap;
    err = notification_create_cap(chan_id, core_id, &notify_cap);
    assert(err == SYS_ERR_OK);

    // Allocate my own notification caps
    struct capref ep, my_notify_cap;
    struct lmp_endpoint *iep;
    int chanid;
    err = endpoint_create(LMP_RECV_LENGTH, &ep, &iep);
    assert(err_is_ok(err));
    err = notification_allocate(ep, &chanid);
    assert(err == SYS_ERR_OK);
    err = notification_create_cap(chanid, my_core_id, &my_notify_cap);
    assert(err == SYS_ERR_OK);

    // setup our side of the binding
    umpb = malloc(sizeof(struct intermon_ump_ipi_binding));
    assert(umpb != NULL);

    err = intermon_ump_ipi_init(umpb, get_default_waitset(),
                                buf + MON_URPC_CHANNEL_LEN,
                                MON_URPC_CHANNEL_LEN,
                                buf, MON_URPC_CHANNEL_LEN, notify_cap,
                                my_notify_cap, ep, iep);
    assert(err_is_ok(err));

    // Identify UMP frame for tracing
    struct frame_identity umpid;
    err = invoke_frame_identify(frame, &umpid);
    assert(err_is_ok(err));
    umpb->ump_state.chan.recvid = (uintptr_t)umpid.base;
    umpb->ump_state.chan.sendid =
        (uintptr_t)(umpid.base + MON_URPC_CHANNEL_LEN);

    // connect it to our request handlers
    err = intermon_init(&umpb->b, core_id);
    assert(err_is_ok(err));

    /* Send reply */
reply:
    assert(umpb != NULL);
    bind_monitor_reply_scc_cont(&umpb->b, err, chanid);
    return;

error:
    assert(!"Argh");
    // FIXME: cleanup!
    goto reply;
}

/**
 * \brief The monitor that proxied the request for one monitor to
 * setup a connection with another monitor gets the reply
 */
static void bind_monitor_reply_scc(struct intermon_binding *binding,
                                   errval_t err, chanid_t chan_id,
                                   coreid_t core_id)
{
    struct intermon_ump_ipi_binding *b = (struct intermon_ump_ipi_binding *)binding;

    // Create notify cap to that core
    struct capref notify_cap;
    err = notification_create_cap(chan_id, core_id, &notify_cap);
    assert(err == SYS_ERR_OK);

    // And assign it to the binding
    err = ipi_notify_set(&b->ipi_notify, notify_cap);
    assert(err_is_ok(err));

    if (err_is_fail(err)) { // XXX
        DEBUG_ERR(err, "Got error in bind monitor reply");
    }
}

/******* stack-ripped bind_monitor_proxy_scc *******/

static void bind_monitor_request_scc_handler(struct intermon_binding *b,
        struct intermon_msg_queue_elem *e);

struct bind_monitor_request_scc_state {
    struct intermon_msg_queue_elem elem;
    struct intermon_bind_monitor_request_scc__args args;
};

static void bind_monitor_request_scc_cont(struct intermon_binding *dst_binding,
        coreid_t src_core_id,
        intermon_caprep_t caprep,
        chanid_t chan_id,
        coreid_t core_id)
{
    errval_t err;

    err = dst_binding->tx_vtbl.
          bind_monitor_request_scc(dst_binding, NOP_CONT, src_core_id,
                                   caprep, chan_id, core_id);
    if (err_is_fail(err)) {
        if(err_no(err) == FLOUNDER_ERR_TX_BUSY) {
            struct bind_monitor_request_scc_state *me =
                malloc(sizeof(struct bind_monitor_request_scc_state));
            assert(me != NULL);
            struct intermon_state *ist = dst_binding->st;
            assert(ist != NULL);
            me->args.core_id = src_core_id;
            me->args.cap = caprep;
            me->args.chan_id = chan_id;
            me->args.from_core_id = core_id;
            me->elem.cont = bind_monitor_request_scc_handler;

            err = intermon_enqueue_send(dst_binding, &ist->queue,
                                        get_default_waitset(), &me->elem.queue);
            assert(err_is_ok(err));
            return;
        }

        DEBUG_ERR(err, "forwarding bind request failed");
    }
}
Example #3
0
/**
 * \brief Notification of a newly booted monitor.
 *  Setup our connection and request the sender to proxy
 *  the bind request to the monitor
 */
static void new_monitor_notify(struct intermon_binding *b,
                               coreid_t core_id)
{
    errval_t err;

    /* Setup the connection */
    ram_set_affinity(SHARED_MEM_MIN + (PERCORE_MEM_SIZE * my_core_id),
                     SHARED_MEM_MIN + (PERCORE_MEM_SIZE * (my_core_id + 1)));
    struct capref frame;
    err = frame_alloc(&frame, MON_URPC_SIZE, NULL);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "frame_alloc failed");
        return; // FIXME: cleanup
    }
    ram_set_affinity(0, 0);     // Reset affinity

    void *buf;
    err = vspace_map_one_frame_attr(&buf, MON_URPC_SIZE, frame, VREGION_FLAGS_READ_WRITE_NOCACHE, NULL, NULL);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "vspace_map_one_frame failed");
        assert(buf); // XXX
    }
    // XXX: Clear the frame (kernel can't do it for us)
    memset(buf, 0, MON_URPC_SIZE);

    // Allocate my own notification caps
    struct capref ep, my_notify_cap;
    struct lmp_endpoint *iep;
    int chanid;
    err = endpoint_create(LMP_RECV_LENGTH, &ep, &iep);
    assert(err_is_ok(err));
    err = notification_allocate(ep, &chanid);
    assert(err == SYS_ERR_OK);
    err = notification_create_cap(chanid, my_core_id, &my_notify_cap);
    assert(err == SYS_ERR_OK);

    // init our end of the binding and channel
    struct intermon_ump_ipi_binding *ump_binding =
        malloc(sizeof(struct intermon_ump_ipi_binding));
    assert(ump_binding != NULL);
    err = intermon_ump_ipi_init(ump_binding, get_default_waitset(),
                                buf, MON_URPC_CHANNEL_LEN,
                                buf + MON_URPC_CHANNEL_LEN,
                                MON_URPC_CHANNEL_LEN, NULL_CAP, my_notify_cap,
                                ep, iep);
    assert(err_is_ok(err));
    /* if (err_is_fail(err)) { */
    /*     cap_destroy(frame); */
    /*     return err_push(err, LIB_ERR_UMP_CHAN_BIND); */
    /* } */

    // Identify UMP frame for tracing
    struct frame_identity umpid = { .base = 0, .bits = 0 };
    err = invoke_frame_identify(frame, &umpid);
    assert(err_is_ok(err));
    ump_binding->ump_state.chan.recvid = (uintptr_t)umpid.base;
    ump_binding->ump_state.chan.sendid =
        (uintptr_t)(umpid.base + MON_URPC_CHANNEL_LEN);

    err = intermon_init(&ump_binding->b, core_id);
    assert(err_is_ok(err));

    /* Identify the frame cap */
    struct capability frame_cap;
    err = monitor_cap_identify(frame, &frame_cap);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "monitor_cap_identify failed");
        return; // FIXME: cleanup
    }

    intermon_caprep_t caprep;
    capability_to_caprep(&frame_cap, &caprep);

    /* reply to the sending monitor to proxy request */
    err = b->tx_vtbl.bind_monitor_proxy_scc(b, NOP_CONT, core_id,
                                            caprep, chanid, my_core_id);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "bind proxy request failed");
    }
}

errval_t arch_intermon_init(struct intermon_binding *b)
{
    b->rx_vtbl.bind_monitor_request_scc = bind_monitor_request_scc;
    b->rx_vtbl.bind_monitor_reply_scc = bind_monitor_reply_scc;
    b->rx_vtbl.bind_monitor_proxy_scc = bind_monitor_proxy_scc;
    b->rx_vtbl.new_monitor_notify = new_monitor_notify;

    return SYS_ERR_OK;
}
Example #4
0
DDS_DataReader DDS_Subscriber_create_datareader (DDS_Subscriber               sp,
						 DDS_TopicDescription         topic,
						 const DDS_DataReaderQos      *qos,
						 const DDS_DataReaderListener *listener,
						 DDS_StatusMask               mask)
{
	Domain_t	*dp;
	Topic_t		*tp;
	Participant_t	*pp;
	Reader_t	*rp;
	Cache_t		cp;
	EntityId_t	eid;
#ifdef DDS_NATIVE_SECURITY
	unsigned	secure;
	DDS_ReturnCode_t ret;
#endif
	const TypeSupport_t *ts;
	int		error;

	ctrc_begind (DCPS_ID, DCPS_S_C_DR, &sp, sizeof (sp));
	ctrc_contd (&topic, sizeof (topic));
	ctrc_contd (&qos, sizeof (qos));
	ctrc_contd (&listener, sizeof (listener));
	ctrc_contd (&mask, sizeof (mask));
	ctrc_endd ();

	prof_start (dcps_create_reader);

	if (!subscriber_ptr (sp, NULL))
		return (NULL);

	dp = sp->domain;
	if (!dp || lock_take (dp->lock))
		return (NULL);

	if (sp->domain != dp)
		goto inv_topic; /*DDS_RETCODE_BAD_PARAMETER*/

	tp = topic_ptr (topic, 1, NULL);
	if (!tp)
		goto inv_topic;

	rp = NULL;

	/* Don't check whether reader is already created!  Multiple readers and
	   or writers on the same topic are definitely allowed! */

	if (qos == DDS_DATAREADER_QOS_DEFAULT)
		qos = &sp->def_reader_qos;
	else if (qos != DDS_DATAREADER_QOS_USE_TOPIC_QOS &&
	         !qos_valid_reader_qos (qos))
		goto done;

#ifdef DDS_SECURITY

	/* Check if security policy allows this datareader. */
#ifdef DDS_NATIVE_SECURITY
	if (sec_check_create_reader (dp->participant.p_permissions,
				     str_ptr (tp->name),
				     NULL, qos, sp->qos.partition,
				     NULL, &secure)) {
#else
	if (check_create_reader (dp->participant.p_permissions, tp,
						qos, sp->qos.partition)) {
#endif
		log_printf (DCPS_ID, 0, "create_datareader: reader create not allowed!\r\n");
		goto done;
	}
#endif

	/* Create an Entity Identifier. */
	ts = tp->type->type_support;
	if ((sp->entity.flags & EF_BUILTIN) != 0) {
		eid.id [0] = eid.id [1] = 0;
		eid.id [2] = 0x10 + tp->type->index;
		eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_BUILTIN | ENTITY_KIND_READER_KEY;
	}
	else {
		++dcps_entity_count;
		eid.id [0] = (dcps_entity_count >> 16) & 0xff;
		eid.id [1] = (dcps_entity_count >> 8) & 0xff;
		eid.id [2] = dcps_entity_count & 0xff;
		if (ts->ts_keys)
			eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_USER | ENTITY_KIND_READER_KEY;
		else
			eid.id [ENTITY_KIND_INDEX] = ENTITY_KIND_USER | ENTITY_KIND_READER;
	}
	pp = &dp->participant;
	rp = (Reader_t *) endpoint_create (pp, sp, &eid, NULL);
	if (!rp) {
		warn_printf ("create_datareader: out of memory for DataReader structure.\r\n");
		goto done;
	}
#ifdef RW_LOCKS
	lock_take (rp->r_lock);
#endif
	if ((sp->entity.flags & EF_BUILTIN) != 0)
		rp->r_flags |= EF_BUILTIN;

	if (qos == DDS_DATAREADER_QOS_USE_TOPIC_QOS) {
		rp->r_qos = tp->qos;
		tp->qos->users++;
		qos_init_time_based_filter (&rp->r_time_based_filter);
		qos_init_reader_data_lifecycle (&rp->r_data_lifecycle);
	}
	else {
		rp->r_qos = qos_reader_new (qos);
		rp->r_time_based_filter = qos->time_based_filter;
		rp->r_data_lifecycle = qos->reader_data_lifecycle;
	}
	if (!rp->r_qos)
		goto free_pool;

	rp->r_mask = mask;
	if (listener)
		rp->r_listener = *listener;
	else
		memset (&rp->r_listener, 0, sizeof (rp->r_listener));

	memset (&rp->r_rdm_status, 0, sizeof (rp->r_rdm_status));
	memset (&rp->r_riq_status, 0, sizeof (rp->r_riq_status));
	memset (&rp->r_sl_status, 0, sizeof (rp->r_sl_status));
	memset (&rp->r_sr_status, 0, sizeof (rp->r_sr_status));
	memset (&rp->r_lc_status, 0, sizeof (rp->r_lc_status));
	memset (&rp->r_sm_status, 0, sizeof (rp->r_sm_status));
	rp->r_changes.buffer = NULL;
	rp->r_changes.length = rp->r_changes.maximum = 0;
	rp->r_prev_info = NULL;
	rp->r_prev_data = NULL;
	rp->r_n_prev = 0;
	rp->r_topic = tp;
	rp->r_next = tp->readers;
	tp->readers = &rp->r_ep;

#ifdef DDS_NATIVE_SECURITY

	/* Set security attributes. */
	rp->r_access_prot = 0;
	rp->r_disc_prot = 0;
	rp->r_submsg_prot = 0;
	rp->r_payload_prot = 0;
	rp->r_crypto_type = 0;
	rp->r_crypto = 0;
	if (secure && 
	    (dp->participant.p_sec_caps & (SECC_DDS_SEC | (SECC_DDS_SEC << SECC_LOCAL))) != 0) {
		log_printf (DCPS_ID, 0, "DDS: Reader security attributes: 0x%x\r\n", secure);
		rp->r_access_prot = (secure & DDS_SECA_ACCESS_PROTECTED) != 0;
		rp->r_disc_prot = (secure & DDS_SECA_DISC_PROTECTED) != 0;
		rp->r_submsg_prot = (secure & DDS_SECA_SUBMSG_PROTECTED) != 0;
		rp->r_payload_prot = (secure & DDS_SECA_PAYLOAD_PROTECTED) != 0;
		if (rp->r_submsg_prot || rp->r_payload_prot) {
			rp->r_crypto_type = secure >> DDS_SECA_ENCRYPTION_SHIFT;
			rp->r_crypto = sec_register_local_datareader (dp->participant.p_crypto,
								             rp, &ret);
		}
	}
Example #5
0
void sedp_publication_event (Reader_t *rp,
			     NotificationType_t t,
			     int cdd,
			     int secure)
{
	Domain_t		*dp = rp->r_subscriber->domain;
	Participant_t		*pp;
	ChangeData_t		change;
	DiscoveredWriterData	*info = NULL, tinfo;
	Topic_t			*tp;
	DiscoveredWriter_t	*dwp;
	Reader_t		*mrp;
	UniQos_t		qos;
	InfoType_t		type;
	GUID_t			*guidp;
	int			error;

	if (t != NT_DATA_AVAILABLE)
		return;

	rp->r_status &= ~DDS_DATA_AVAILABLE_STATUS;
	for (;;) {
		if (info) {
			pid_writer_data_cleanup (info);
			xfree (info);
			info = NULL;
		}
		/*dtrc_print0 ("SEDP-Pub: get samples ");*/
		error = disc_get_data (rp, &change);
		if (error) {
			/*dtrc_print0 ("- none\r\n");*/
			break;
		}
		/*dtrc_print1 ("- valid(%u)\r\n", change.kind);*/
		if (change.kind != ALIVE) {
			error = hc_get_key (rp->r_cache, change.h, &tinfo, 0);
			if (error)
				continue;

			guidp = &tinfo.proxy.guid;
			type = EI_DELETE;
			hc_inst_free (rp->r_cache, change.h);
		}
		else {
			info = change.data;
			if (!info->topic_name || !info->type_name) {
				hc_inst_free (rp->r_cache, change.h);
				continue;
			}
			type = EI_NEW;
			guidp = &info->proxy.guid;
		}
			pp = entity_participant (change.writer);
		if (!pp ||				/* Not found. */
		    pp == &dp->participant ||		/* Own sent info. */
		    entity_ignored (pp->p_flags)) {	/* Ignored. */
			if (pp != &dp->participant && !cdd)
				warn_printf ("sedp_publication_rx: invalid change.writer field!\r\n");

			hc_inst_free (rp->r_cache, change.h);
			dtrc_print0 ("SEDP-Pub: unneeded!\r\n");
			continue;	/* Filter out unneeded info. */
		}

		/* Publication from remote participant. */
		if (type == EI_DELETE) {
			dwp = (DiscoveredWriter_t *) endpoint_lookup (pp,
							&guidp->entity_id);
			if (!dwp) {
				dtrc_print0 ("SEDP-Pub: DELETE && doesn't exist!\r\n");
				continue; /* If doesn't exist - no action. */
			}
			if (!dwp->dw_topic) {
				endpoint_delete (pp, &dwp->dw_ep);
				continue; /* Ignored topic -- only endpoint. */
			}
			if (sedp_log)
				log_printf (SEDP_ID, 0, "SEDP: Deleted %spublication (%s/%s) from peer!\r\n",
						(secure) ? "secure " : "",
						str_ptr (dwp->dw_topic->name),
						str_ptr (dwp->dw_topic->type->type_name));
			disc_publication_remove (pp, dwp);

			hc_inst_free (rp->r_cache, change.h);
			continue;
		}

		/* Do we know this topic? */
		tp = topic_lookup (&dp->participant, str_ptr (info->topic_name));
		if (tp && entity_ignored (tp->entity.flags)) {
			hc_inst_free (rp->r_cache, change.h);
			dtrc_print1 ("SEDP: ignored topic (%s)!\r\n", str_ptr (info->topic_name));
			continue;	/* Ignored topic. */
		}

		/* Do we know this endpoint already? */
		dwp = (DiscoveredWriter_t *) endpoint_lookup (pp, &guidp->entity_id);
		if (dwp) {
			if (entity_ignored (dwp->dw_flags) || cdd) {
				hc_inst_free (rp->r_cache, change.h);
				continue; /* Ignored endpoint. */
			}
			dtrc_print1 ("Already exists (%s)!\r\n", str_ptr (info->topic_name));
			type = EI_UPDATE;
			disc_publication_update (pp, dwp, info);
			if (sedp_log)
				log_printf (SEDP_ID, 0, "SEDP: Updated %spublication (%s/%s) from peer!\r\n",
						(secure) ? "secure " : "",
						str_ptr (info->topic_name),
						str_ptr (info->type_name));
			hc_inst_free (rp->r_cache, change.h);
		}
		else {
			/* Get QoS parameters. */
			qos_disc_writer_set (&qos, &info->qos);
			mrp = NULL;
			/* Create new endpoint. */
			dwp = (DiscoveredWriter_t *) endpoint_create (pp,
					pp, &guidp->entity_id, NULL);
			if (!dwp) {
				dtrc_print1 ("SEDP: Create endpoint (%s) not possible - exit!\r\n", str_ptr (info->topic_name));
				hc_inst_free (rp->r_cache, change.h);
				qos_disc_writer_restore (&info->qos, &qos);
				continue;  /* Can't create -- just ignore. */
			}
			disc_publication_add (pp, dwp, &qos, tp, mrp, info);
			hc_inst_free (rp->r_cache, change.h);
			if (sedp_log)
				log_printf (SEDP_ID, 0, "SEDP: New %spublication (%s/%s) from %s!\r\n",
						(secure) ? "secure " : "",
						str_ptr (info->topic_name),
						str_ptr (info->type_name),
						(cdd) ? "CDD" : "peer");

		}
	}
	if (info) {
		pid_writer_data_cleanup (info);
		xfree (info);
	}
}