示例#1
0
文件: ipcserver.c 项目: beekhof/libqb
static int32_t
s1_msg_process_fn(qb_ipcs_connection_t * c, void *data, size_t size)
{
	struct qb_ipc_request_header *hdr;
	struct my_req *req_pt;
	struct qb_ipc_response_header response;
	ssize_t res;
	struct iovec iov[2];
	char resp[100];
	int32_t sl;
	int32_t send_ten_events = QB_FALSE;

	hdr = (struct qb_ipc_request_header *)data;
	if (hdr->id == (QB_IPC_MSG_USER_START + 1)) {
		return 0;
	}

	req_pt = (struct my_req *)data;
	qb_log(LOG_DEBUG, "msg received (id:%d, size:%d, data:%s)",
	       req_pt->hdr.id, req_pt->hdr.size, req_pt->message);

	if (strcmp(req_pt->message, "kill") == 0) {
		exit(0);
	}
	response.size = sizeof(struct qb_ipc_response_header);
	response.id = 13;
	response.error = 0;

	sl = snprintf(resp, 100, "ACK %zd bytes", size) + 1;
	iov[0].iov_len = sizeof(response);
	iov[0].iov_base = &response;
	iov[1].iov_len = sl;
	iov[1].iov_base = resp;
	response.size += sl;

	send_ten_events = (strcmp(req_pt->message, "events") == 0);

	if (use_events && !send_ten_events) {
		res = qb_ipcs_event_sendv(c, iov, 2);
	} else {
		res = qb_ipcs_response_sendv(c, iov, 2);
	}
	if (res < 0) {
		errno = - res;
		qb_perror(LOG_ERR, "qb_ipcs_response_send");
	}
	if (send_ten_events) {
		int32_t i;
		qb_log(LOG_INFO, "request to send 10 events");
		for (i = 0; i < 10; i++) {
			res = qb_ipcs_event_sendv(c, iov, 2);
			qb_log(LOG_INFO, "sent event %d res:%d", i, res);
		}
	}
	return 0;
}
示例#2
0
ssize_t
crm_ipcs_send(qb_ipcs_connection_t *c, xmlNode *message, enum ipcs_send_flags flags)
{
    int rc;
    int lpc = 0;
    struct iovec iov[2];
    static uint32_t id = 0;
    const char *type = "Response";
    struct qb_ipc_response_header header;
    char *buffer = dump_xml_unformatted(message);

    iov[0].iov_len = sizeof(struct qb_ipc_response_header);
    iov[0].iov_base = &header;
    iov[1].iov_len = 1 + strlen(buffer);
    iov[1].iov_base = buffer;

    header.id = id++; /* We don't really use it, but doesn't hurt to set one */
    header.error = 0; /* unused */
    header.size = iov[0].iov_len + iov[1].iov_len;

    do {
        if(flags & ipcs_send_event) {
            rc = qb_ipcs_event_sendv(c, iov, 2);
            type = "Event";
            
        } else {
            rc = qb_ipcs_response_sendv(c, iov, 2);
        }

        if(rc != -EAGAIN) {
            break;
        } else if(lpc > 3 && (flags & ipcs_send_error)) {
            break;
        }

        crm_debug("Attempting resend %d of %s %d (%d bytes) to %p[%d]: %.120s",
                  ++lpc, type, header.id, header.size, c, crm_ipcs_client_pid(c), buffer);
        sleep(1);

        /* Only retry for important stuff, and even then only a limited amount for ipcs_send_error
         * Unless ipcs_send_info or ipcs_send_error is specified, we block by default
         */
    } while((flags & ipcs_send_info) == 0);

    if(rc < header.size) {
        do_crm_log((flags & ipcs_send_error)?LOG_ERR:LOG_INFO,
                   "%s %d failed, size=%d, to=%p[%d], rc=%d: %.120s",
                   type, header.id, header.size, c, crm_ipcs_client_pid(c), rc, buffer);
    } else {
        crm_trace("%s %d sent, %d bytes to %p: %.120s", type, header.id, rc, c, buffer);
    }
    free(buffer);
    return rc;
}
示例#3
0
文件: ipc.c 项目: credativ/pacemaker
ssize_t
crm_ipcs_sendv(crm_client_t * c, struct iovec * iov, enum crm_ipc_flags flags)
{
    ssize_t rc;
    static uint32_t id = 1;
    struct crm_ipc_response_header *header = iov[0].iov_base;

    if (c->flags & crm_client_flag_ipc_proxied) {
        /* _ALL_ replies to proxied connections need to be sent as events */
        if (is_not_set(flags, crm_ipc_server_event)) {
            flags |= crm_ipc_server_event;
            /* this flag lets us know this was originally meant to be a response.
             * even though we're sending it over the event channel. */
            flags |= crm_ipc_proxied_relay_response;
        }
    }

    header->flags |= flags;
    if (flags & crm_ipc_server_event) {
        header->qb.id = id++;   /* We don't really use it, but doesn't hurt to set one */

        if (flags & crm_ipc_server_free) {
            crm_trace("Sending the original to %p[%d]", c->ipcs, c->pid);
            c->event_queue = g_list_append(c->event_queue, iov);

        } else {
            struct iovec *iov_copy = calloc(2, sizeof(struct iovec));

            crm_trace("Sending a copy to %p[%d]", c->ipcs, c->pid);
            iov_copy[0].iov_len = iov[0].iov_len;
            iov_copy[0].iov_base = malloc(iov[0].iov_len);
            memcpy(iov_copy[0].iov_base, iov[0].iov_base, iov[0].iov_len);

            iov_copy[1].iov_len = iov[1].iov_len;
            iov_copy[1].iov_base = malloc(iov[1].iov_len);
            memcpy(iov_copy[1].iov_base, iov[1].iov_base, iov[1].iov_len);

            c->event_queue = g_list_append(c->event_queue, iov_copy);
        }

    } else {
        CRM_LOG_ASSERT(header->qb.id != 0);     /* Replying to a specific request */

        rc = qb_ipcs_response_sendv(c->ipcs, iov, 2);
        if (rc < header->qb.size) {
            crm_notice("Response %d to %p[%d] (%u bytes) failed: %s (%d)",
                       header->qb.id, c->ipcs, c->pid, header->qb.size, pcmk_strerror(rc), rc);

        } else {
            crm_trace("Response %d sent, %zd bytes to %p[%d]", header->qb.id, rc, c->ipcs, c->pid);
        }

        if (flags & crm_ipc_server_free) {
            free(iov[0].iov_base);
            free(iov[1].iov_base);
            free(iov);
        }
    }

    if (flags & crm_ipc_server_event) {
        rc = crm_ipcs_flush_events(c);
    } else {
        crm_ipcs_flush_events(c);
    }

    if (rc == -EPIPE || rc == -ENOTCONN) {
        crm_trace("Client %p disconnected", c->ipcs);
    }

    return rc;
}
示例#4
0
文件: ipc.c 项目: bcavanagh/pacemaker
ssize_t
crm_ipcs_send(qb_ipcs_connection_t *c, uint32_t request, xmlNode *message, enum crm_ipc_server_flags flags)
{
    int rc;
    int lpc = 0;
    int retries = 40;
    int level = LOG_CRIT;
    struct iovec iov[2];
    static uint32_t id = 1;
    const char *type = "Response";
    struct qb_ipc_response_header header;
    char *buffer = dump_xml_unformatted(message);
    struct timespec delay = { 0, 250000000 }; /* 250ms */

    memset(&iov, 0, 2 * sizeof(struct iovec));
    iov[0].iov_len = sizeof(struct qb_ipc_response_header);
    iov[0].iov_base = &header;
    iov[1].iov_len = 1 + strlen(buffer);
    iov[1].iov_base = buffer;

    if(flags & crm_ipc_server_event) {
        header.id = id++;    /* We don't really use it, but doesn't hurt to set one */
    } else {
        CRM_LOG_ASSERT (request != 0);
        header.id = request; /* Replying to a specific request */
    }

    header.error = 0; /* unused */
    header.size = iov[0].iov_len + iov[1].iov_len;

    if(flags & crm_ipc_server_error) {
        retries = 20;
        level = LOG_ERR;

    } else if(flags & crm_ipc_server_info) {
        retries = 10;
        level = LOG_INFO;
    }

    while(lpc < retries) {
        if(flags & crm_ipc_server_event) {
            type = "Event";
            rc = qb_ipcs_event_sendv(c, iov, 2);
            if(rc == -EPIPE || rc == -ENOTCONN) {
                crm_trace("Client %p disconnected", c);
                level = LOG_INFO;
            }
            
        } else {
            rc = qb_ipcs_response_sendv(c, iov, 2);
        }

        if(rc != -EAGAIN) {
            break;
        }

        lpc++;
        crm_debug("Attempting resend %d of %s %d (%d bytes) to %p[%d]: %.120s",
                  lpc, type, header.id, header.size, c, crm_ipcs_client_pid(c), buffer);
        nanosleep(&delay, NULL);
    }

    if(rc < header.size) {
        struct qb_ipcs_connection_stats_2 *stats = qb_ipcs_connection_stats_get_2(c, 0);
        do_crm_log(level,
                   "%s %d failed, size=%d, to=%p[%d], queue=%d, rc=%d: %.120s",
                   type, header.id, header.size, c, stats->client_pid, stats->event_q_length, rc, buffer);
        free(stats);

    } else {
        crm_trace("%s %d sent, %d bytes to %p[%d]: %.120s", type, header.id, rc,
                  c, crm_ipcs_client_pid(c), buffer);
    }
    free(buffer);
    return rc;
}