Beispiel #1
0
  const json IPCClientPrivate::receiveOne()
  {
    char *data = new char[1<<20];
    ssize_t recv_size;

    if ((recv_size = qb_ipcc_event_recv(_qb_conn, data, 1<<20, 500)) < 0) {
      disconnect();
      throw IPCException(IPCException::ProtocolError, "Receive error");
    }

    if (recv_size < (ssize_t)sizeof(struct qb_ipc_response_header)) {
      disconnect();
      throw IPCException(IPCException::ProtocolError, "Message too small");
    }

    const struct qb_ipc_response_header *hdr = \
      (const struct qb_ipc_response_header *)data;

    if (hdr->size != recv_size) {
      disconnect();
      throw IPCException(IPCException::ProtocolError, "Invalid size in header");
    }

    const char *jdata = data + sizeof(struct qb_ipc_response_header);
    const size_t jsize = recv_size - sizeof(struct qb_ipc_response_header);
    const std::string json_string(jdata, jsize);
    const json jobj = json::parse(json_string);
    delete [] data;
    return std::move(jobj);
  }
Beispiel #2
0
long
crm_ipc_read(crm_ipc_t *client) 
{
    CRM_ASSERT(client != NULL);
    CRM_ASSERT(client->ipc != NULL);
    CRM_ASSERT(client->buffer != NULL);

    client->buffer[0] = 0;
    client->msg_size = qb_ipcc_event_recv(client->ipc, client->buffer, client->buf_size-1, 0);
    if(client->msg_size >= 0) {
        struct qb_ipc_response_header *header = (struct qb_ipc_response_header *)client->buffer;
        client->buffer[client->msg_size] = 0;

        crm_trace("Recieved %s event %d, size=%d, rc=%d, text: %.200s",
                  client->name, header->id, header->size, client->msg_size,
                  client->buffer+sizeof(struct qb_ipc_response_header));
    } else {
        crm_trace("No message from %s recieved: %s", client->name, pcmk_strerror(client->msg_size));
    }

    if(crm_ipc_connected(client) == FALSE || client->msg_size == -ENOTCONN) {
        crm_err("Connection to %s failed", client->name);
    }
    
    return client->msg_size;
}
Beispiel #3
0
long
crm_ipc_read(crm_ipc_t * client)
{
    struct crm_ipc_response_header *header = NULL;

    CRM_ASSERT(client != NULL);
    CRM_ASSERT(client->ipc != NULL);
    CRM_ASSERT(client->buffer != NULL);

    crm_ipc_init();

    client->buffer[0] = 0;
    client->msg_size = qb_ipcc_event_recv(client->ipc, client->buffer, client->buf_size - 1, 0);
    if (client->msg_size >= 0) {
        int rc = crm_ipc_decompress(client);

        if (rc != pcmk_ok) {
            return rc;
        }

        header = (struct crm_ipc_response_header *)(void*)client->buffer;
        if(header->version > PCMK_IPC_VERSION) {
            crm_err("Filtering incompatible v%d IPC message, we only support versions <= %d",
                    header->version, PCMK_IPC_VERSION);
            return -EBADMSG;
        }

        crm_trace("Received %s event %d, size=%u, rc=%d, text: %.100s",
                  client->name, header->qb.id, header->qb.size, client->msg_size,
                  client->buffer + hdr_offset);

    } else {
        crm_trace("No message from %s received: %s", client->name, pcmk_strerror(client->msg_size));
    }

    if (crm_ipc_connected(client) == FALSE || client->msg_size == -ENOTCONN) {
        crm_err("Connection to %s failed", client->name);
    }

    if (header) {
        /* Data excluding the header */
        return header->size_uncompressed;
    }
    return -ENOMSG;
}
Beispiel #4
0
long
crm_ipc_read(crm_ipc_t *client) 
{
    CRM_ASSERT(client != NULL);
    CRM_ASSERT(client->buffer != NULL);
    
    crm_trace("Message recieved on %s IPC connection", client->name);

    client->buffer[0] = 0;
    client->msg_size = qb_ipcc_event_recv(client->ipc, client->buffer, client->buf_size-1, -1);
    if(client->msg_size >= 0) {
        struct qb_ipc_response_header *header = (struct qb_ipc_response_header *)client->buffer;
        client->buffer[client->msg_size] = 0;

        crm_trace("Recieved response %d, size=%d, rc=%d, text: %.200s", header->id, header->size, client->msg_size, client->buffer+sizeof(struct qb_ipc_response_header));
    }

    if(crm_ipc_connected(client) == FALSE || client->msg_size == -ENOTCONN) {
        crm_err("Connection to %s failed", client->name);
    }
    
    return client->msg_size;
}
Beispiel #5
0
cs_error_t cmap_dispatch (
	cmap_handle_t handle,
        cs_dispatch_flags_t dispatch_types)
{
	int timeout = -1;
	cs_error_t error;
	int cont = 1; /* always continue do loop except when set to 0 */
	struct cmap_inst *cmap_inst;
	struct qb_ipc_response_header *dispatch_data;
	char dispatch_buf[IPC_DISPATCH_SIZE];
	struct res_lib_cmap_notify_callback *res_lib_cmap_notify_callback;
	struct cmap_track_inst *cmap_track_inst;
	struct cmap_notify_value old_val;
	struct cmap_notify_value new_val;

	error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
	if (error != CS_OK) {
		return (error);
	}

	/*
	 * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
	 * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
	 */
	if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
		timeout = 0;
	}

	dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
	do {
		error = qb_to_cs_error(qb_ipcc_event_recv (
			cmap_inst->c,
			dispatch_buf,
			IPC_DISPATCH_SIZE,
			timeout));

		if (error == CS_ERR_BAD_HANDLE) {
			error = CS_OK;
			goto error_put;
		}
		if (error == CS_ERR_TRY_AGAIN) {
			if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
				/*
				 * Don't mask error
				 */
				goto error_put;
			}
			error = CS_OK;
			if (dispatch_types == CS_DISPATCH_ALL) {
				break; /* exit do while cont is 1 loop */
			} else {
				continue; /* next poll */
			}
		}

		if (error != CS_OK) {
			goto error_put;
		}

		/*
		 * Dispatch incoming message
		 */
		switch (dispatch_data->id) {
		case MESSAGE_RES_CMAP_NOTIFY_CALLBACK:
			res_lib_cmap_notify_callback = (struct res_lib_cmap_notify_callback *)dispatch_data;

			error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
					res_lib_cmap_notify_callback->track_inst_handle,
					(void *)&cmap_track_inst));
			if (error == CS_ERR_BAD_HANDLE) {
				/*
				 * User deleted tracker -> ignore error
				 */
				 break;
			}
			if (error != CS_OK) {
				goto error_put;
			}

			new_val.type = res_lib_cmap_notify_callback->new_value_type;
			old_val.type = res_lib_cmap_notify_callback->old_value_type;
			new_val.len = res_lib_cmap_notify_callback->new_value_len;
			old_val.len = res_lib_cmap_notify_callback->old_value_len;
			new_val.data = res_lib_cmap_notify_callback->new_value;
			old_val.data = (((const char *)res_lib_cmap_notify_callback->new_value) + new_val.len);

			cmap_track_inst->notify_fn(handle,
					cmap_track_inst->track_handle,
					res_lib_cmap_notify_callback->event,
					(char *)res_lib_cmap_notify_callback->key_name.value,
					new_val,
					old_val,
					cmap_track_inst->user_data);

			(void)hdb_handle_put(&cmap_track_handle_t_db, res_lib_cmap_notify_callback->track_inst_handle);
			break;
		default:
			error = CS_ERR_LIBRARY;
			goto error_put;
			break;
		}
		if (cmap_inst->finalize) {
			/*
			 * If the finalize has been called then get out of the dispatch.
			 */
			error = CS_ERR_BAD_HANDLE;
			goto error_put;
		}

		/*
		 * Determine if more messages should be processed
		 */
		if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
			cont = 0;
		}
	} while (cont);

error_put:
	(void)hdb_handle_put (&cmap_handle_t_db, handle);

	return (error);
}
Beispiel #6
0
static void
do_echo(qb_ipcc_connection_t *conn)
{
	struct my_req req;
	struct my_res res;
	char *newline;
	int32_t rc;
	int32_t send_ten_events;

	while (1) {
		printf("SEND (q or Q to quit) : ");
		if (fgets(req.message, 256, stdin) == NULL) {
			continue;
		}
		newline = strrchr(req.message, '\n');
		if (newline) {
			*newline = '\0';
		}

		if (strcasecmp(req.message, "q") == 0) {
			break;
		} else {
			req.hdr.id = QB_IPC_MSG_USER_START + 3;
			req.hdr.size = sizeof(struct my_req);
			rc = qb_ipcc_send(conn, &req, req.hdr.size);
			if (rc < 0) {
				perror("qb_ipcc_send");
				exit(0);
			}
		}

		send_ten_events = (strcasecmp(req.message, "events") == 0);

		if (rc > 0) {
			if (use_events && !send_ten_events) {
				printf("waiting for event recv\n");
				rc = qb_ipcc_event_recv(conn, &res, sizeof(res), -1);
			} else {
				printf("waiting for recv\n");
				rc = qb_ipcc_recv(conn, &res, sizeof(res), -1);
			}
			printf("recv %d\n", rc);
			if (rc < 0) {
				perror("qb_ipcc_recv");
				exit(0);
			}
			if (send_ten_events) {
				int32_t i;
				printf("waiting for 10 events\n");
				for (i = 0; i < 10; i++) {
					rc = qb_ipcc_event_recv(conn, &res, sizeof(res), -1);
					if (rc < 0) {
						perror("qb_ipcc_event_recv");
					} else {
						printf("got event %d rc:%d\n", i, rc);
					}
				}
			}
			printf("Response[%d]: %s \n", res.hdr.id, res.message);
		}
	}
}
Beispiel #7
0
cs_error_t
corosync_cfg_dispatch (
	corosync_cfg_handle_t cfg_handle,
	cs_dispatch_flags_t dispatch_flags)
{
	int timeout = -1;
	cs_error_t error;
	int cont = 1; /* always continue do loop except when set to 0 */
	struct cfg_inst *cfg_inst;
	struct res_lib_cfg_testshutdown *res_lib_cfg_testshutdown;
	corosync_cfg_callbacks_t callbacks;
	struct qb_ipc_response_header *dispatch_data;
	char dispatch_buf[IPC_DISPATCH_SIZE];

	error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle,
		(void *)&cfg_inst));
	if (error != CS_OK) {
		return (error);
	}

	/*
	 * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
	 * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
	 */
	if (dispatch_flags == CS_DISPATCH_ALL || dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) {
		timeout = 0;
	}

	dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
	do {
		error = qb_to_cs_error (qb_ipcc_event_recv (
			cfg_inst->c,
			dispatch_buf,
			IPC_DISPATCH_SIZE,
			timeout));
		if (error == CS_ERR_BAD_HANDLE) {
			error = CS_OK;
			goto error_put;
		}
		if (error == CS_ERR_TRY_AGAIN) {
			if (dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) {
				/*
				 * Don't mask error
				 */
				goto error_put;
			}
			error = CS_OK;
			if (dispatch_flags == CS_DISPATCH_ALL) {
				break; /* exit do while cont is 1 loop */
			} else {
				continue; /* next poll */
			}
		}
		if (error != CS_OK) {
			goto error_put;
		}

		/*
		 * Make copy of callbacks, message data, unlock instance, and call callback
		 * A risk of this dispatch method is that the callback routines may
		 * operate at the same time that cfgFinalize has been called in another thread.
		 */
		memcpy (&callbacks, &cfg_inst->callbacks, sizeof (corosync_cfg_callbacks_t));

		/*
		 * Dispatch incoming response
		 */
		switch (dispatch_data->id) {
		case MESSAGE_RES_CFG_TESTSHUTDOWN:
			if (callbacks.corosync_cfg_shutdown_callback == NULL) {
				break;
			}

			res_lib_cfg_testshutdown = (struct res_lib_cfg_testshutdown *)dispatch_data;
			callbacks.corosync_cfg_shutdown_callback(cfg_handle, res_lib_cfg_testshutdown->flags);
			break;
		default:
			error = CS_ERR_LIBRARY;
			goto error_nounlock;
			break;
		}
		if (cfg_inst->finalize) {
			/*
			 * If the finalize has been called then get out of the dispatch.
			 */
			error = CS_ERR_BAD_HANDLE;
			goto error_put;
		}

		/*
		 * Determine if more messages should be processed
		 */
		if (dispatch_flags == CS_DISPATCH_ONE || dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) {
			cont = 0;
		}
	} while (cont);

error_put:
	(void)hdb_handle_put (&cfg_hdb, cfg_handle);
error_nounlock:
	return (error);
}
Beispiel #8
0
cs_error_t votequorum_dispatch (
	votequorum_handle_t handle,
	cs_dispatch_flags_t dispatch_types)
{
	int timeout = -1;
	cs_error_t error;
	int cont = 1; /* always continue do loop except when set to 0 */
	struct votequorum_inst *votequorum_inst;
	votequorum_callbacks_t callbacks;
	struct qb_ipc_response_header *dispatch_data;
	struct res_lib_votequorum_notification *res_lib_votequorum_notification;
	struct res_lib_votequorum_expectedvotes_notification *res_lib_votequorum_expectedvotes_notification;
	char dispatch_buf[IPC_DISPATCH_SIZE];
	votequorum_ring_id_t ring_id;

	if (dispatch_types != CS_DISPATCH_ONE &&
		dispatch_types != CS_DISPATCH_ALL &&
		dispatch_types != CS_DISPATCH_BLOCKING &&
		dispatch_types != CS_DISPATCH_ONE_NONBLOCKING) {

		return (CS_ERR_INVALID_PARAM);
	}

	error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle,
		(void *)&votequorum_inst));
	if (error != CS_OK) {
		return (error);
	}

	/*
	 * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
	 * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
	 */
	if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
		timeout = 0;
	}

	dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
	do {
		error = qb_to_cs_error (qb_ipcc_event_recv (
			votequorum_inst->c,
			dispatch_buf,
			IPC_DISPATCH_SIZE,
			timeout));
		if (error == CS_ERR_BAD_HANDLE) {
			error = CS_OK;
			goto error_put;
		}
		if (error == CS_ERR_TRY_AGAIN) {
			if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
				/*
				 * Don't mask error
				 */
				goto error_put;
			}
			error = CS_OK;
			if (dispatch_types == CS_DISPATCH_ALL) {
				break; /* exit do while cont is 1 loop */
			} else {
				continue; /* next poll */
			}
		}
		if (error != CS_OK) {
			goto error_put;
		}

		/*
		 * Make copy of callbacks, message data, unlock instance, and call callback
		 * A risk of this dispatch method is that the callback routines may
		 * operate at the same time that votequorum_finalize has been called in another thread.
		 */
		memcpy (&callbacks, &votequorum_inst->callbacks, sizeof (votequorum_callbacks_t));

		/*
		 * Dispatch incoming message
		 */
		switch (dispatch_data->id) {

		case MESSAGE_RES_VOTEQUORUM_NOTIFICATION:
			if (callbacks.votequorum_notify_fn == NULL) {
				break;
			}
			res_lib_votequorum_notification = (struct res_lib_votequorum_notification *)dispatch_data;
			marshall_from_mar_votequorum_ring_id (&ring_id, &res_lib_votequorum_notification->ring_id);

			callbacks.votequorum_notify_fn ( handle,
							 res_lib_votequorum_notification->context,
							 res_lib_votequorum_notification->quorate,
							 ring_id,
							 res_lib_votequorum_notification->node_list_entries,
							 (votequorum_node_t *)res_lib_votequorum_notification->node_list );
				;
			break;

		case MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION:
			if (callbacks.votequorum_expectedvotes_notify_fn == NULL) {
				break;
			}
			res_lib_votequorum_expectedvotes_notification = (struct res_lib_votequorum_expectedvotes_notification *)dispatch_data;

			callbacks.votequorum_expectedvotes_notify_fn ( handle,
								       res_lib_votequorum_expectedvotes_notification->context,
								       res_lib_votequorum_expectedvotes_notification->expected_votes);
			break;

		default:
			error = CS_ERR_LIBRARY;
			goto error_put;
			break;
		}
		if (votequorum_inst->finalize) {
			/*
			 * If the finalize has been called then get out of the dispatch.
			 */
			error = CS_ERR_BAD_HANDLE;
			goto error_put;
		}

		/*
		 * Determine if more messages should be processed
		 */
		if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
			cont = 0;
		}
	} while (cont);


error_put:
	hdb_handle_put (&votequorum_handle_t_db, handle);
	return (error);
}