mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2025-05-25 09:50:22 +00:00

(Logical change 1.55) git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@180 fd59a12c-fef9-0310-b244-a6a79926bd2f
439 lines
13 KiB
C
439 lines
13 KiB
C
/*
|
|
* Copyright (c) 2004 Mark Haverkamp
|
|
* Copyright (c) 2004 Open Source Development Lab
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* This software licensed under BSD license, the text of which follows:
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* - Neither the name of the MontaVista Software, Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#define DEBUG
|
|
#include <sys/types.h>
|
|
#include <malloc.h>
|
|
#include <errno.h>
|
|
#include "../include/ais_types.h"
|
|
#include "../include/ais_msg.h"
|
|
#include "../include/list.h"
|
|
#include "../include/queue.h"
|
|
#include "aispoll.h"
|
|
#include "mempool.h"
|
|
#include "parse.h"
|
|
#include "main.h"
|
|
#include "print.h"
|
|
#include "gmi.h"
|
|
#include "evt.h"
|
|
|
|
static int message_handler_req_lib_activatepoll (struct conn_info *conn_info,
|
|
void *message);
|
|
static int lib_evt_open_channel(struct conn_info *conn_info, void *message);
|
|
static int lib_evt_close_channel(struct conn_info *conn_info, void *message);
|
|
static int lib_evt_channel_subscribe(struct conn_info *conn_info,
|
|
void *message);
|
|
static int lib_evt_channel_unsubscribe(struct conn_info *conn_info,
|
|
void *message);
|
|
static int lib_evt_event_publish(struct conn_info *conn_info, void *message);
|
|
static int lib_evt_event_clear_retentiontime(struct conn_info *conn_info,
|
|
void *message);
|
|
static int evt_conf_change(
|
|
struct sockaddr_in *member_list, int member_list_entries,
|
|
struct sockaddr_in *left_list, int left_list_entries,
|
|
struct sockaddr_in *joined_list, int joined_list_entries);
|
|
static int evt_init(struct conn_info *conn_info, void *msg);
|
|
static int evt_exit(struct conn_info *conn_info);
|
|
static int evt_exec_init(void);
|
|
|
|
static struct libais_handler evt_libais_handlers[] = {
|
|
{
|
|
.libais_handler_fn = message_handler_req_lib_activatepoll,
|
|
.response_size = sizeof(struct res_lib_activatepoll),
|
|
.response_id = MESSAGE_RES_LIB_ACTIVATEPOLL,
|
|
.gmi_prio = GMI_PRIO_RECOVERY
|
|
},
|
|
{
|
|
.libais_handler_fn = lib_evt_open_channel,
|
|
.response_size = sizeof(struct res_evt_channel_open),
|
|
.response_id = MESSAGE_RES_EVT_OPEN_CHANNEL,
|
|
.gmi_prio = GMI_PRIO_MED
|
|
},
|
|
{
|
|
.libais_handler_fn = lib_evt_close_channel,
|
|
.response_size = sizeof(struct res_evt_channel_close),
|
|
.response_id = MESSAGE_RES_EVT_CLOSE_CHANNEL,
|
|
.gmi_prio = GMI_PRIO_RECOVERY
|
|
},
|
|
{
|
|
.libais_handler_fn = lib_evt_channel_subscribe,
|
|
.response_size = sizeof(struct res_evt_channel_subscribe),
|
|
.response_id = MESSAGE_RES_EVT_SUBSCRIBE,
|
|
.gmi_prio = GMI_PRIO_RECOVERY
|
|
},
|
|
{
|
|
.libais_handler_fn = lib_evt_channel_unsubscribe,
|
|
.response_size = sizeof(struct res_evt_channel_unsubscribe),
|
|
.response_id = MESSAGE_RES_EVT_UNSUBSCRIBE,
|
|
.gmi_prio = GMI_PRIO_RECOVERY
|
|
},
|
|
{
|
|
.libais_handler_fn = lib_evt_event_publish,
|
|
.response_size = sizeof(struct res_evt_event_publish),
|
|
.response_id = MESSAGE_RES_EVT_PUBLISH,
|
|
.gmi_prio = GMI_PRIO_LOW
|
|
},
|
|
{
|
|
.libais_handler_fn = lib_evt_event_clear_retentiontime,
|
|
.response_size = sizeof(struct res_evt_event_clear_retentiontime),
|
|
.response_id = MESSAGE_REQ_EVT_CLEAR_RETENTIONTIME,
|
|
.gmi_prio = GMI_PRIO_RECOVERY
|
|
},
|
|
};
|
|
|
|
|
|
static int evt_remote_evt(void *msg, struct in_addr source_addr);
|
|
static int evt_remote_chan_op(void *msg, struct in_addr source_addr);
|
|
|
|
static int (*evt_exec_handler_fns[]) (void *m, struct in_addr s) = {
|
|
evt_remote_evt,
|
|
evt_remote_chan_op
|
|
};
|
|
|
|
struct service_handler evt_service_handler = {
|
|
.libais_handlers = evt_libais_handlers,
|
|
.libais_handlers_count = sizeof(evt_libais_handlers) /
|
|
sizeof(struct libais_handler),
|
|
.aisexec_handler_fns = evt_exec_handler_fns,
|
|
.aisexec_handler_fns_count = sizeof(evt_exec_handler_fns) /
|
|
sizeof(int (*)),
|
|
.confchg_fn = evt_conf_change,
|
|
.libais_init_fn = evt_init,
|
|
.libais_exit_fn = evt_exit,
|
|
.aisexec_init_fn = evt_exec_init
|
|
};
|
|
|
|
|
|
/*
|
|
* Take the filters we received from the application via the library and
|
|
* make them into a real SaEvtEventFilterArrayT
|
|
*/
|
|
static SaErrorT evtfilt_to_aisfilt(struct req_evt_channel_subscribe *req,
|
|
SaEvtEventFilterArrayT **evtfilters)
|
|
{
|
|
|
|
SaEvtEventFilterArrayT *filta = (SaEvtEventFilterArrayT *)req->ics_filter_data;
|
|
SaEvtEventFilterArrayT *filters;
|
|
SaEvtEventFilterT *filt = (void *)filta + sizeof(SaEvtEventFilterArrayT);
|
|
SaUint8T *str = (void *)filta + sizeof(SaEvtEventFilterArrayT) +
|
|
(sizeof(SaEvtEventFilterT) * filta->filtersNumber);
|
|
int i;
|
|
|
|
filters = malloc(sizeof(SaEvtEventFilterArrayT));
|
|
if (!filters) {
|
|
return SA_ERR_NO_MEMORY;
|
|
}
|
|
|
|
filters->filtersNumber = filta->filtersNumber;
|
|
filters->filters = malloc(sizeof(SaEvtEventFilterT) *
|
|
filta->filtersNumber);
|
|
|
|
for (i = 0; i < filters->filtersNumber; i++) {
|
|
filters->filters[i].filter.pattern =
|
|
malloc(filt[i].filter.patternSize);
|
|
/*
|
|
* TODO: Back out of previous allocs if malloc fails
|
|
*/
|
|
filters->filters[i].filter.patternSize =
|
|
filt[i].filter.patternSize;
|
|
memcpy(filters->filters[i].filter.pattern,
|
|
str, filters->filters[i].filter.patternSize);
|
|
str += filters->filters[i].filter.patternSize;
|
|
}
|
|
|
|
*evtfilters = filters;
|
|
|
|
return SA_OK;
|
|
}
|
|
|
|
|
|
static int message_handler_req_lib_activatepoll(struct conn_info *conn_info,
|
|
void *message)
|
|
{
|
|
struct res_lib_activatepoll res;
|
|
|
|
res.header.error = SA_OK;
|
|
res.header.size = sizeof (struct res_lib_activatepoll);
|
|
res.header.id = MESSAGE_RES_LIB_ACTIVATEPOLL;
|
|
libais_send_response(conn_info, &res, sizeof(res));
|
|
|
|
return (0);
|
|
}
|
|
|
|
static int evt_init(struct conn_info *conn_info, void *msg)
|
|
{
|
|
struct res_lib_init res;
|
|
|
|
|
|
res.header.size = sizeof (struct res_lib_init);
|
|
res.header.id = MESSAGE_RES_INIT;
|
|
res.header.error = SA_OK;
|
|
|
|
log_printf(LOG_LEVEL_DEBUG,
|
|
"Got request to initalize cluster event service.\n");
|
|
if (!conn_info->authenticated) {
|
|
log_printf(LOG_LEVEL_DEBUG,
|
|
"event service: Not authenticated\n");
|
|
res.header.error = SA_ERR_SECURITY;
|
|
libais_send_response(conn_info, &res, sizeof(res));
|
|
return -1;
|
|
}
|
|
|
|
conn_info->service = SOCKET_SERVICE_EVT;
|
|
libais_send_response (conn_info, &res, sizeof(res));
|
|
list_init (&conn_info->conn_list);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lib_evt_open_channel(struct conn_info *conn_info, void *message)
|
|
{
|
|
struct req_evt_channel_open *req;
|
|
struct res_evt_channel_open res;
|
|
|
|
req = message;
|
|
|
|
|
|
log_printf(LOG_LEVEL_DEBUG, "Open channel request\n");
|
|
log_printf(LOG_LEVEL_DEBUG,
|
|
"size %d, id %d, handle 0x%x, to 0x%llx\n",
|
|
req->ico_head.size,
|
|
req->ico_head.id,
|
|
req->ico_c_handle,
|
|
req->ico_timeout);
|
|
log_printf(LOG_LEVEL_DEBUG, "flags %x, channel name(%d) %s\n",
|
|
req->ico_open_flag,
|
|
req->ico_channel_name.length,
|
|
req->ico_channel_name.value);
|
|
|
|
/*
|
|
* TODO: Add open code here
|
|
*/
|
|
|
|
res.ico_head.size = sizeof(res);
|
|
res.ico_head.id = MESSAGE_RES_EVT_OPEN_CHANNEL;
|
|
res.ico_head.error = SA_OK;
|
|
res.ico_channel_handle = req->ico_c_handle; /* TODO: fix this */
|
|
libais_send_response (conn_info, &res, sizeof(res));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lib_evt_close_channel(struct conn_info *conn_info, void *message)
|
|
{
|
|
struct req_evt_channel_close *req;
|
|
struct res_evt_channel_close res;
|
|
|
|
req = message;
|
|
|
|
log_printf(LOG_LEVEL_DEBUG, "Close channel request\n");
|
|
log_printf(LOG_LEVEL_DEBUG, "size %d, id %d, handle 0x%x\n",
|
|
req->icc_head.size,
|
|
req->icc_head.id,
|
|
req->icc_channel_handle);
|
|
|
|
/*
|
|
* TODO: Add close code here
|
|
*/
|
|
|
|
res.icc_head.size = sizeof(res);
|
|
res.icc_head.id = MESSAGE_RES_EVT_CLOSE_CHANNEL;
|
|
res.icc_head.error = SA_OK;
|
|
libais_send_response (conn_info, &res, sizeof(res));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lib_evt_channel_subscribe(struct conn_info *conn_info, void *message)
|
|
{
|
|
struct req_evt_channel_subscribe *req;
|
|
struct res_evt_channel_subscribe res;
|
|
SaEvtEventFilterArrayT *filters;
|
|
SaErrorT error = SA_OK;
|
|
int i;
|
|
|
|
req = message;
|
|
|
|
log_printf(LOG_LEVEL_DEBUG, "Subscribe channel request\n");
|
|
log_printf(LOG_LEVEL_DEBUG, "size %d, id %d\n",
|
|
req->ics_head.size,
|
|
req->ics_head.id);
|
|
log_printf(LOG_LEVEL_DEBUG, "subscription Id: 0x%x\n", req->ics_sub_id);
|
|
error = evtfilt_to_aisfilt(req, &filters);
|
|
|
|
if (error == SA_OK) {
|
|
log_printf(LOG_LEVEL_DEBUG, "Subscribe filters count %d\n",
|
|
filters->filtersNumber);
|
|
for (i = 0; i < filters->filtersNumber; i++) {
|
|
log_printf(LOG_LEVEL_DEBUG, "sz %d, type %d, <%s>\n",
|
|
filters->filters[i].filterType,
|
|
filters->filters[i].filter.patternSize,
|
|
filters->filters[i].filter.pattern);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* TODO: add subscribe code here.
|
|
* TODO: remove filters for now to avoid a leak.
|
|
*/
|
|
for (i = 0; i < filters->filtersNumber; i++) {
|
|
free(filters->filters[i].filter.pattern);
|
|
}
|
|
free(filters->filters);
|
|
free(filters);
|
|
|
|
res.ics_head.size = sizeof(res);
|
|
res.ics_head.id = MESSAGE_RES_EVT_SUBSCRIBE;
|
|
res.ics_head.error = error;
|
|
libais_send_response (conn_info, &res, sizeof(res));
|
|
|
|
return 0;
|
|
}
|
|
static int lib_evt_channel_unsubscribe(struct conn_info *conn_info,
|
|
void *message)
|
|
{
|
|
struct req_evt_channel_unsubscribe *req;
|
|
struct res_evt_channel_unsubscribe res;
|
|
SaErrorT error = SA_OK;
|
|
|
|
req = message;
|
|
|
|
log_printf(LOG_LEVEL_DEBUG, "Unsubscribe channel request\n");
|
|
log_printf(LOG_LEVEL_DEBUG, "size %d, id %d\n",
|
|
req->icu_head.size,
|
|
req->icu_head.id);
|
|
log_printf(LOG_LEVEL_DEBUG, "subscription Id: 0x%x\n", req->icu_sub_id);
|
|
|
|
/*
|
|
* TODO: Add unsubscribe code here
|
|
*/
|
|
|
|
|
|
res.icu_head.size = sizeof(res);
|
|
res.icu_head.id = MESSAGE_RES_EVT_UNSUBSCRIBE;
|
|
res.icu_head.error = error;
|
|
libais_send_response (conn_info, &res, sizeof(res));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lib_evt_event_publish(struct conn_info *conn_info, void *message)
|
|
{
|
|
struct lib_event_data *req;
|
|
struct res_evt_event_publish res;
|
|
SaEvtEventIdT event_id = 0x5a5a5a5a5a5a5a5aull;
|
|
SaErrorT error = SA_OK;
|
|
|
|
req = message;
|
|
|
|
log_printf(LOG_LEVEL_DEBUG, "Publish event request\n");
|
|
log_printf(LOG_LEVEL_DEBUG, "size %d, id %d\n",
|
|
req->led_head.size,
|
|
req->led_head.id);
|
|
|
|
/*
|
|
* TODO: Add publish code here
|
|
*/
|
|
|
|
res.iep_head.size = sizeof(res);
|
|
res.iep_head.id = MESSAGE_RES_EVT_PUBLISH;
|
|
res.iep_head.error = error;
|
|
res.iep_event_id = event_id;
|
|
libais_send_response (conn_info, &res, sizeof(res));
|
|
|
|
return 0;
|
|
}
|
|
static int lib_evt_event_clear_retentiontime(struct conn_info *conn_info, void *message)
|
|
{
|
|
struct req_evt_event_clear_retentiontime *req;
|
|
struct res_evt_event_clear_retentiontime res;
|
|
SaErrorT error = SA_OK;
|
|
|
|
req = message;
|
|
|
|
log_printf(LOG_LEVEL_DEBUG, "Clear event retentiontime request\n");
|
|
log_printf(LOG_LEVEL_DEBUG,
|
|
"size %d, id %d, event ID 0x%llx, chan handle 0x%x\n",
|
|
req->iec_head.size,
|
|
req->iec_head.id,
|
|
req->iec_event_id,
|
|
req->iec_channel_handle);
|
|
|
|
/*
|
|
* TODO: Add clear retention time code here
|
|
*/
|
|
|
|
res.iec_head.size = sizeof(res);
|
|
res.iec_head.id = MESSAGE_REQ_EVT_CLEAR_RETENTIONTIME;
|
|
res.iec_head.error = error;
|
|
libais_send_response (conn_info, &res, sizeof(res));
|
|
|
|
return 0;
|
|
}
|
|
static int evt_conf_change(
|
|
struct sockaddr_in *member_list, int member_list_entries,
|
|
struct sockaddr_in *left_list, int left_list_entries,
|
|
struct sockaddr_in *joined_list, int joined_list_entries)
|
|
{
|
|
log_printf(LOG_LEVEL_DEBUG, "Evt conf change\n");
|
|
|
|
return 0;
|
|
}
|
|
static int evt_exit(struct conn_info *conn_info)
|
|
{
|
|
log_printf(LOG_LEVEL_DEBUG, "Evt exit request\n");
|
|
|
|
/*
|
|
* Delete track entry if there is one
|
|
*/
|
|
list_del (&conn_info->conn_list);
|
|
|
|
return 0;
|
|
}
|
|
static int evt_exec_init(void)
|
|
{
|
|
log_printf(LOG_LEVEL_DEBUG, "Evt exec exit request\n");
|
|
return 0;
|
|
}
|
|
|
|
static int evt_remote_evt(void *msg, struct in_addr source_addr)
|
|
{
|
|
log_printf(LOG_LEVEL_DEBUG, "Remote event data received");
|
|
return 0;
|
|
}
|
|
static int evt_remote_chan_op(void *msg, struct in_addr source_addr)
|
|
{
|
|
log_printf(LOG_LEVEL_DEBUG, "Remote channel operation request\n");
|
|
return 0;
|
|
}
|