Exemplo n.º 1
0
static int kvp_on_msg(void *msg, int len)
{
	struct hv_kvp_msg *message = (struct hv_kvp_msg *)msg;
	struct hv_kvp_msg_enumerate *data;
	int	error = 0;

	if (len < sizeof(*message))
		return -EINVAL;

	/*
	 * If we are negotiating the version information
	 * with the daemon; handle that first.
	 */

	if (kvp_transaction.state < HVUTIL_READY) {
		return kvp_handle_handshake(message);
	}

	/* We didn't send anything to userspace so the reply is spurious */
	if (kvp_transaction.state < HVUTIL_USERSPACE_REQ)
		return -EINVAL;

	kvp_transaction.state = HVUTIL_USERSPACE_RECV;

	/*
	 * Based on the version of the daemon, we propagate errors from the
	 * daemon differently.
	 */

	data = &message->body.kvp_enum_data;

	switch (dm_reg_value) {
	case KVP_OP_REGISTER:
		/*
		 * Null string is used to pass back error condition.
		 */
		if (data->data.key[0] == 0)
			error = HV_S_CONT;
		break;

	case KVP_OP_REGISTER1:
		/*
		 * We use the message header information from
		 * the user level daemon to transmit errors.
		 */
		error = message->error;
		break;
	}

	/*
	 * Complete the transaction by forwarding the key value
	 * to the host. But first, cancel the timeout.
	 */
	if (cancel_delayed_work_sync(&kvp_timeout_work)) {
		kvp_respond_to_host(message, error);
		hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);
	}

	return 0;
}
Exemplo n.º 2
0
static void
kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
    struct hv_kvp_msg *message;
    struct hv_kvp_msg_enumerate *data;
    int	error = 0;

    message = (struct hv_kvp_msg *)msg->data;

    /*
     * If we are negotiating the version information
     * with the daemon; handle that first.
     */

    if (in_hand_shake) {
        if (kvp_handle_handshake(message))
            in_hand_shake = false;
        return;
    }

    /*
     * Based on the version of the daemon, we propagate errors from the
     * daemon differently.
     */

    data = &message->body.kvp_enum_data;

    switch (dm_reg_value) {
    case KVP_OP_REGISTER:
        /*
         * Null string is used to pass back error condition.
         */
        if (data->data.key[0] == 0)
            error = HV_S_CONT;
        break;

    case KVP_OP_REGISTER1:
        /*
         * We use the message header information from
         * the user level daemon to transmit errors.
         */
        error = message->error;
        break;
    }

    /*
     * Complete the transaction by forwarding the key value
     * to the host. But first, cancel the timeout.
     */
    if (cancel_delayed_work_sync(&kvp_work))
        kvp_respond_to_host(message, error);
}