~ubuntu-branches/ubuntu/precise/corosync/precise-proposed

« back to all changes in this revision

Viewing changes to services/evs.c

  • Committer: Bazaar Package Importer
  • Author(s): Ante Karamatic
  • Date: 2009-08-21 09:29:56 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090821092956-w9qxxxx3zeoh8dem
Tags: 1.0.0-4ubuntu2
* debian/control:
  - 'Ubuntu Developers' instead of 'Ubuntu Core Developers'
    as maintainer
  - Bump debhelper dependecy to 7

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (c) 2004-2006 MontaVista Software, Inc.
3
 
 * Copyright (c) 2006-2008 Red Hat, Inc.
 
3
 * Copyright (c) 2006-2009 Red Hat, Inc.
4
4
 *
5
5
 * All rights reserved.
6
6
 *
7
7
 * Author: Steven Dake (sdake@redhat.com)
8
8
 *
9
9
 * This software licensed under BSD license, the text of which follows:
10
 
 * 
 
10
 *
11
11
 * Redistribution and use in source and binary forms, with or without
12
12
 * modification, are permitted provided that the following conditions are met:
13
13
 *
32
32
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33
33
 * THE POSSIBILITY OF SUCH DAMAGE.
34
34
 */
 
35
 
 
36
#include <config.h>
 
37
 
35
38
#include <sys/types.h>
36
39
#include <sys/socket.h>
37
40
#include <sys/un.h>
43
46
#include <stdlib.h>
44
47
#include <stdio.h>
45
48
#include <errno.h>
46
 
#include <signal.h>
47
49
#include <time.h>
48
50
#include <netinet/in.h>
49
51
#include <arpa/inet.h>
50
52
 
51
53
#include <corosync/swab.h>
52
 
#include <corosync/saAis.h>
53
 
#include <corosync/ipc_gen.h>
 
54
#include <corosync/corotypes.h>
 
55
#include <corosync/coroipc_types.h>
 
56
#include <corosync/corodefs.h>
 
57
#include <corosync/mar_gen.h>
54
58
#include <corosync/lcr/lcr_comp.h>
55
59
#include <corosync/engine/coroapi.h>
 
60
#include <corosync/engine/logsys.h>
 
61
#include <corosync/list.h>
 
62
 
 
63
#include <corosync/evs.h>
56
64
#include <corosync/ipc_evs.h>
57
 
#include <corosync/list.h>
58
 
#include <corosync/engine/logsys.h>
59
65
 
60
 
LOGSYS_DECLARE_SUBSYS ("EVS", LOG_INFO);
 
66
LOGSYS_DECLARE_SUBSYS ("EVS");
61
67
 
62
68
enum evs_exec_message_req_types {
63
69
        MESSAGE_REQ_EXEC_EVS_MCAST = 0
71
77
 
72
78
static void evs_confchg_fn (
73
79
        enum totem_configuration_type configuration_type,
74
 
        unsigned int *member_list, int member_list_entries,
75
 
        unsigned int *left_list, int left_list_entries,
76
 
        unsigned int *joined_list, int joined_list_entries,
77
 
        struct memb_ring_id *ring_id);
 
80
        const unsigned int *member_list, size_t member_list_entries,
 
81
        const unsigned int *left_list, size_t left_list_entries,
 
82
        const unsigned int *joined_list, size_t joined_list_entries,
 
83
        const struct memb_ring_id *ring_id);
78
84
 
79
 
static void message_handler_req_exec_mcast (void *msg, unsigned int nodeid);
 
85
static void message_handler_req_exec_mcast (const void *msg, unsigned int nodeid);
80
86
 
81
87
static void req_exec_mcast_endian_convert (void *msg);
82
88
 
83
 
static void message_handler_req_evs_join (void *conn, void *msg);
84
 
static void message_handler_req_evs_leave (void *conn, void *msg);
85
 
static void message_handler_req_evs_mcast_joined (void *conn, void *msg);
86
 
static void message_handler_req_evs_mcast_groups (void *conn, void *msg);
87
 
static void message_handler_req_evs_membership_get (void *conn, void *msg);
 
89
static void message_handler_req_evs_join (void *conn, const void *msg);
 
90
static void message_handler_req_evs_leave (void *conn, const void *msg);
 
91
static void message_handler_req_evs_mcast_joined (void *conn, const void *msg);
 
92
static void message_handler_req_evs_mcast_groups (void *conn, const void *msg);
 
93
static void message_handler_req_evs_membership_get (void *conn, const void *msg);
88
94
 
89
95
static int evs_lib_init_fn (void *conn);
90
96
static int evs_lib_exit_fn (void *conn);
95
101
        struct list_head list;
96
102
        void *conn;
97
103
};
98
 
        
 
104
 
99
105
static struct corosync_api_v1 *api;
100
106
 
101
107
static struct corosync_lib_handler evs_lib_engine[] =
102
108
{
103
109
        { /* 0 */
104
110
                .lib_handler_fn                         = message_handler_req_evs_join,
105
 
                .response_size                          = sizeof (struct res_lib_evs_join),
106
 
                .response_id                            = MESSAGE_RES_EVS_JOIN,
107
 
                .flow_control                           = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
 
111
                .flow_control                           = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
108
112
        },
109
113
        { /* 1 */
110
114
                .lib_handler_fn                         = message_handler_req_evs_leave,
111
 
                .response_size                          = sizeof (struct res_lib_evs_leave),
112
 
                .response_id                            = MESSAGE_RES_EVS_LEAVE,
113
 
                .flow_control                           = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
 
115
                .flow_control                           = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
114
116
        },
115
117
        { /* 2 */
116
118
                .lib_handler_fn                         = message_handler_req_evs_mcast_joined,
117
 
                .response_size                          = sizeof (struct res_lib_evs_mcast_joined),
118
 
                .response_id                            = MESSAGE_RES_EVS_MCAST_JOINED,
119
 
                .flow_control                           = COROSYNC_LIB_FLOW_CONTROL_REQUIRED
 
119
                .flow_control                           = CS_LIB_FLOW_CONTROL_REQUIRED
120
120
        },
121
121
        { /* 3 */
122
122
                .lib_handler_fn                         = message_handler_req_evs_mcast_groups,
123
 
                .response_size                          = sizeof (struct res_lib_evs_mcast_groups),
124
 
                .response_id                            = MESSAGE_RES_EVS_MCAST_GROUPS,
125
 
                .flow_control                           = COROSYNC_LIB_FLOW_CONTROL_REQUIRED
 
123
                .flow_control                           = CS_LIB_FLOW_CONTROL_REQUIRED
126
124
        },
127
125
        { /* 4 */
128
126
                .lib_handler_fn                         = message_handler_req_evs_membership_get,
129
 
                .response_size                          = sizeof (struct res_lib_evs_membership_get),
130
 
                .response_id                            = MESSAGE_RES_EVS_MEMBERSHIP_GET,
131
 
                .flow_control                           = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
 
127
                .flow_control                           = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
132
128
        }
133
129
};
134
130
 
143
139
struct corosync_service_engine evs_service_engine = {
144
140
        .name                   = "corosync extended virtual synchrony service",
145
141
        .id                     = EVS_SERVICE,
 
142
        .priority               = 1,
146
143
        .private_data_size      = sizeof (struct evs_pd),
147
 
        .flow_control           = COROSYNC_LIB_FLOW_CONTROL_REQUIRED, 
 
144
        .flow_control           = CS_LIB_FLOW_CONTROL_REQUIRED,
148
145
        .lib_init_fn            = evs_lib_init_fn,
149
146
        .lib_exit_fn            = evs_lib_exit_fn,
150
147
        .lib_engine             = evs_lib_engine,
153
150
        .exec_engine_count      = sizeof (evs_exec_engine) / sizeof (struct corosync_exec_handler),
154
151
        .confchg_fn             = evs_confchg_fn,
155
152
        .exec_init_fn           = evs_exec_init_fn,
156
 
        .exec_dump_fn           = NULL
 
153
        .exec_dump_fn           = NULL,
 
154
        .sync_mode              = CS_SYNC_V1
157
155
};
158
156
 
159
157
static DECLARE_LIST_INIT (confchg_notify);
192
190
        return (&evs_service_engine);
193
191
}
194
192
 
195
 
__attribute__ ((constructor)) static void evs_comp_register (void) {
 
193
#ifdef COROSYNC_SOLARIS
 
194
void corosync_lcr_component_register (void);
 
195
 
 
196
void corosync_lcr_component_register (void) {
 
197
#else
 
198
__attribute__ ((constructor)) static void corosync_lcr_component_register (void) {
 
199
#endif
196
200
        lcr_interfaces_set (&corosync_evs_ver0[0], &evs_service_engine_iface);
197
201
 
198
202
        lcr_component_register (&evs_comp_ver0);
201
205
static int evs_exec_init_fn (
202
206
        struct corosync_api_v1 *corosync_api)
203
207
{
 
208
#ifdef COROSYNC_SOLARIS
 
209
        logsys_subsys_init();
 
210
#endif
 
211
 
204
212
        api = corosync_api;
205
213
 
206
214
        return 0;
210
218
 
211
219
static void evs_confchg_fn (
212
220
        enum totem_configuration_type configuration_type,
213
 
        unsigned int *member_list, int member_list_entries,
214
 
        unsigned int *left_list, int left_list_entries,
215
 
        unsigned int *joined_list, int joined_list_entries,
216
 
        struct memb_ring_id *ring_id)
 
221
        const unsigned int *member_list, size_t member_list_entries,
 
222
        const unsigned int *left_list, size_t left_list_entries,
 
223
        const unsigned int *joined_list, size_t joined_list_entries,
 
224
        const struct memb_ring_id *ring_id)
217
225
{
218
226
        struct list_head *list;
219
227
        struct evs_pd *evs_pd;
223
231
         */
224
232
        res_evs_confchg_callback.header.size = sizeof (struct res_evs_confchg_callback);
225
233
        res_evs_confchg_callback.header.id = MESSAGE_RES_EVS_CONFCHG_CALLBACK;
226
 
        res_evs_confchg_callback.header.error = SA_AIS_OK;
 
234
        res_evs_confchg_callback.header.error = CS_OK;
227
235
 
228
236
        memcpy (res_evs_confchg_callback.member_list,
229
237
                member_list, member_list_entries * sizeof(*member_list));
242
250
         */
243
251
        for (list = confchg_notify.next; list != &confchg_notify; list = list->next) {
244
252
                evs_pd = list_entry (list, struct evs_pd, list);
245
 
                api->ipc_conn_send_response (evs_pd->conn,
 
253
                api->ipc_response_send (evs_pd->conn,
246
254
                        &res_evs_confchg_callback,
247
255
                        sizeof (res_evs_confchg_callback));
248
256
        }
252
260
{
253
261
        struct evs_pd *evs_pd = (struct evs_pd *)api->ipc_private_data_get (conn);
254
262
 
255
 
        log_printf (LOG_LEVEL_DEBUG, "Got request to initalize evs service.\n");
 
263
        log_printf (LOGSYS_LEVEL_DEBUG, "Got request to initalize evs service.\n");
256
264
 
257
265
        evs_pd->groups = NULL;
258
266
        evs_pd->group_entries = 0;
260
268
        list_init (&evs_pd->list);
261
269
        list_add (&evs_pd->list, &confchg_notify);
262
270
 
263
 
        api->ipc_conn_send_response (conn, &res_evs_confchg_callback,
 
271
        api->ipc_dispatch_send (conn, &res_evs_confchg_callback,
264
272
                sizeof (res_evs_confchg_callback));
265
273
 
266
274
        return (0);
274
282
        return (0);
275
283
}
276
284
 
277
 
static void message_handler_req_evs_join (void *conn, void *msg)
 
285
static void message_handler_req_evs_join (void *conn, const void *msg)
278
286
{
279
 
        evs_error_t error = EVS_OK;
280
 
        struct req_lib_evs_join *req_lib_evs_join = (struct req_lib_evs_join *)msg;
 
287
        cs_error_t error = CS_OK;
 
288
        const struct req_lib_evs_join *req_lib_evs_join = msg;
281
289
        struct res_lib_evs_join res_lib_evs_join;
282
290
        void *addr;
283
291
        struct evs_pd *evs_pd = (struct evs_pd *)api->ipc_private_data_get (conn);
284
292
 
285
293
        if (req_lib_evs_join->group_entries > 50) {
286
 
                error = EVS_ERR_TOO_MANY_GROUPS;
 
294
                error = CS_ERR_TOO_MANY_GROUPS;
287
295
                goto exit_error;
288
296
        }
289
297
 
290
 
        addr = realloc (evs_pd->groups, sizeof (struct evs_group) * 
 
298
        addr = realloc (evs_pd->groups, sizeof (struct evs_group) *
291
299
                (evs_pd->group_entries + req_lib_evs_join->group_entries));
292
300
        if (addr == NULL) {
293
 
                error = SA_AIS_ERR_NO_MEMORY;
 
301
                error = CS_ERR_NO_MEMORY;
294
302
                goto exit_error;
295
303
        }
296
304
        evs_pd->groups = addr;
306
314
        res_lib_evs_join.header.id = MESSAGE_RES_EVS_JOIN;
307
315
        res_lib_evs_join.header.error = error;
308
316
 
309
 
        api->ipc_conn_send_response (conn, &res_lib_evs_join,
 
317
        api->ipc_response_send (conn, &res_lib_evs_join,
310
318
                sizeof (struct res_lib_evs_join));
311
319
}
312
320
 
313
 
static void message_handler_req_evs_leave (void *conn, void *msg)
 
321
static void message_handler_req_evs_leave (void *conn, const void *msg)
314
322
{
315
 
        struct req_lib_evs_leave *req_lib_evs_leave = (struct req_lib_evs_leave *)msg;
 
323
        const struct req_lib_evs_leave *req_lib_evs_leave = msg;
316
324
        struct res_lib_evs_leave res_lib_evs_leave;
317
 
        evs_error_t error = EVS_OK;
 
325
        cs_error_t error = CS_OK;
318
326
        int error_index;
319
327
        int i, j;
320
328
        int found;
342
350
                        }
343
351
                }
344
352
                if (found == 0) {
345
 
                        error = EVS_ERR_NOT_EXIST;
 
353
                        error = CS_ERR_NOT_EXIST;
346
354
                        error_index = i;
347
355
                        break;
348
356
                }
352
360
        res_lib_evs_leave.header.id = MESSAGE_RES_EVS_LEAVE;
353
361
        res_lib_evs_leave.header.error = error;
354
362
 
355
 
        api->ipc_conn_send_response (conn, &res_lib_evs_leave,
 
363
        api->ipc_response_send (conn, &res_lib_evs_leave,
356
364
                sizeof (struct res_lib_evs_leave));
357
365
}
358
366
 
359
 
static void message_handler_req_evs_mcast_joined (void *conn, void *msg)
 
367
static void message_handler_req_evs_mcast_joined (void *conn, const void *msg)
360
368
{
361
 
        evs_error_t error = EVS_ERR_TRY_AGAIN;
362
 
        struct req_lib_evs_mcast_joined *req_lib_evs_mcast_joined = (struct req_lib_evs_mcast_joined *)msg;
 
369
        cs_error_t error = CS_ERR_TRY_AGAIN;
 
370
        const struct req_lib_evs_mcast_joined *req_lib_evs_mcast_joined = msg;
363
371
        struct res_lib_evs_mcast_joined res_lib_evs_mcast_joined;
364
372
        struct iovec req_exec_evs_mcast_iovec[3];
365
373
        struct req_exec_evs_mcast req_exec_evs_mcast;
366
 
        int send_ok = 0;
367
374
        int res;
368
375
        struct evs_pd *evs_pd = (struct evs_pd *)api->ipc_private_data_get (conn);
369
376
 
382
389
        req_exec_evs_mcast_iovec[1].iov_len = evs_pd->group_entries * sizeof (struct evs_group);
383
390
        req_exec_evs_mcast_iovec[2].iov_base = (char *)&req_lib_evs_mcast_joined->msg;
384
391
        req_exec_evs_mcast_iovec[2].iov_len = req_lib_evs_mcast_joined->msg_len;
385
 
// TODO this doesn't seem to work for some reason       
386
 
        send_ok = api->totem_send_ok (req_exec_evs_mcast_iovec, 3);
387
392
 
388
393
        res = api->totem_mcast (req_exec_evs_mcast_iovec, 3, TOTEM_AGREED);
389
394
                // TODO
390
395
        if (res == 0) {
391
 
                error = EVS_OK;
 
396
                error = CS_OK;
392
397
        }
393
398
 
394
399
        res_lib_evs_mcast_joined.header.size = sizeof (struct res_lib_evs_mcast_joined);
395
400
        res_lib_evs_mcast_joined.header.id = MESSAGE_RES_EVS_MCAST_JOINED;
396
401
        res_lib_evs_mcast_joined.header.error = error;
397
402
 
398
 
        api->ipc_conn_send_response (conn, &res_lib_evs_mcast_joined,
 
403
        api->ipc_response_send (conn, &res_lib_evs_mcast_joined,
399
404
                sizeof (struct res_lib_evs_mcast_joined));
400
405
}
401
406
 
402
 
static void message_handler_req_evs_mcast_groups (void *conn, void *msg)
 
407
static void message_handler_req_evs_mcast_groups (void *conn, const void *msg)
403
408
{
404
 
        evs_error_t error = EVS_ERR_TRY_AGAIN;
405
 
        struct req_lib_evs_mcast_groups *req_lib_evs_mcast_groups = (struct req_lib_evs_mcast_groups *)msg;
 
409
        cs_error_t error = CS_ERR_TRY_AGAIN;
 
410
        const struct req_lib_evs_mcast_groups *req_lib_evs_mcast_groups = msg;
406
411
        struct res_lib_evs_mcast_groups res_lib_evs_mcast_groups;
407
412
        struct iovec req_exec_evs_mcast_iovec[3];
408
413
        struct req_exec_evs_mcast req_exec_evs_mcast;
409
 
        char *msg_addr;
410
 
        int send_ok = 0;
 
414
        const char *msg_addr;
411
415
        int res;
412
416
 
413
417
        req_exec_evs_mcast.header.size = sizeof (struct req_exec_evs_mcast) +
419
423
        req_exec_evs_mcast.msg_len = req_lib_evs_mcast_groups->msg_len;
420
424
        req_exec_evs_mcast.group_entries = req_lib_evs_mcast_groups->group_entries;
421
425
 
422
 
        msg_addr = (char *)req_lib_evs_mcast_groups +
423
 
                sizeof (struct req_lib_evs_mcast_groups) + 
 
426
        msg_addr = (const char *)req_lib_evs_mcast_groups +
 
427
                sizeof (struct req_lib_evs_mcast_groups) +
424
428
                (sizeof (struct evs_group) * req_lib_evs_mcast_groups->group_entries);
425
429
 
426
430
        req_exec_evs_mcast_iovec[0].iov_base = (char *)&req_exec_evs_mcast;
427
431
        req_exec_evs_mcast_iovec[0].iov_len = sizeof (req_exec_evs_mcast);
428
432
        req_exec_evs_mcast_iovec[1].iov_base = (char *)&req_lib_evs_mcast_groups->groups;
429
433
        req_exec_evs_mcast_iovec[1].iov_len = sizeof (struct evs_group) * req_lib_evs_mcast_groups->group_entries;
430
 
        req_exec_evs_mcast_iovec[2].iov_base = msg_addr;
 
434
        req_exec_evs_mcast_iovec[2].iov_base = (void *) msg_addr; /* discard const */
431
435
        req_exec_evs_mcast_iovec[2].iov_len = req_lib_evs_mcast_groups->msg_len;
432
 
        
433
 
// TODO this is wacky
434
 
        send_ok = api->totem_send_ok (req_exec_evs_mcast_iovec, 3);
 
436
 
435
437
        res = api->totem_mcast (req_exec_evs_mcast_iovec, 3, TOTEM_AGREED);
436
438
        if (res == 0) {
437
 
                error = EVS_OK;
 
439
                error = CS_OK;
438
440
        }
439
441
 
440
442
        res_lib_evs_mcast_groups.header.size = sizeof (struct res_lib_evs_mcast_groups);
441
443
        res_lib_evs_mcast_groups.header.id = MESSAGE_RES_EVS_MCAST_GROUPS;
442
444
        res_lib_evs_mcast_groups.header.error = error;
443
445
 
444
 
        api->ipc_conn_send_response (conn, &res_lib_evs_mcast_groups,
 
446
        api->ipc_response_send (conn, &res_lib_evs_mcast_groups,
445
447
                sizeof (struct res_lib_evs_mcast_groups));
446
448
}
447
449
 
448
 
static void message_handler_req_evs_membership_get (void *conn, void *msg)
 
450
static void message_handler_req_evs_membership_get (void *conn, const void *msg)
449
451
{
450
452
        struct res_lib_evs_membership_get res_lib_evs_membership_get;
451
453
 
452
454
        res_lib_evs_membership_get.header.size = sizeof (struct res_lib_evs_membership_get);
453
455
        res_lib_evs_membership_get.header.id = MESSAGE_RES_EVS_MEMBERSHIP_GET;
454
 
        res_lib_evs_membership_get.header.error = EVS_OK;
 
456
        res_lib_evs_membership_get.header.error = CS_OK;
455
457
        res_lib_evs_membership_get.local_nodeid = api->totem_nodeid_get ();
456
458
        memcpy (&res_lib_evs_membership_get.member_list,
457
459
                &res_evs_confchg_callback.member_list,
460
462
        res_lib_evs_membership_get.member_list_entries =
461
463
                res_evs_confchg_callback.member_list_entries;
462
464
 
463
 
        api->ipc_conn_send_response (conn, &res_lib_evs_membership_get,
 
465
        api->ipc_response_send (conn, &res_lib_evs_membership_get,
464
466
                sizeof (struct res_lib_evs_membership_get));
465
467
}
466
468
 
474
476
}
475
477
 
476
478
static void message_handler_req_exec_mcast (
477
 
        void *msg,
 
479
        const void *msg,
478
480
        unsigned int nodeid)
479
481
{
480
 
        struct req_exec_evs_mcast *req_exec_evs_mcast = (struct req_exec_evs_mcast *)msg;
 
482
        const struct req_exec_evs_mcast *req_exec_evs_mcast = msg;
481
483
        struct res_evs_deliver_callback res_evs_deliver_callback;
482
 
        char *msg_addr;
 
484
        const char *msg_addr;
483
485
        struct list_head *list;
484
486
        int found = 0;
485
487
        int i, j;
486
488
        struct evs_pd *evs_pd;
 
489
        struct iovec iov[2];
487
490
 
488
491
        res_evs_deliver_callback.header.size = sizeof (struct res_evs_deliver_callback) +
489
492
                req_exec_evs_mcast->msg_len;
490
493
        res_evs_deliver_callback.header.id = MESSAGE_RES_EVS_DELIVER_CALLBACK;
491
 
        res_evs_deliver_callback.header.error = SA_AIS_OK;
 
494
        res_evs_deliver_callback.header.error = CS_OK;
492
495
        res_evs_deliver_callback.msglen = req_exec_evs_mcast->msg_len;
493
496
 
494
 
        msg_addr = (char *)req_exec_evs_mcast + sizeof (struct req_exec_evs_mcast) + 
 
497
        msg_addr = (const char *)req_exec_evs_mcast + sizeof (struct req_exec_evs_mcast) +
495
498
                (sizeof (struct evs_group) * req_exec_evs_mcast->group_entries);
496
499
 
497
500
        for (list = confchg_notify.next; list != &confchg_notify; list = list->next) {
515
518
 
516
519
                if (found) {
517
520
                        res_evs_deliver_callback.local_nodeid = nodeid;
518
 
                        api->ipc_conn_send_response (evs_pd->conn, &res_evs_deliver_callback,
519
 
                                sizeof (struct res_evs_deliver_callback));
520
 
                        api->ipc_conn_send_response (evs_pd->conn, msg_addr,
521
 
                                req_exec_evs_mcast->msg_len);
 
521
                        iov[0].iov_base = (void *)&res_evs_deliver_callback;
 
522
                        iov[0].iov_len = sizeof (struct res_evs_deliver_callback);
 
523
                        iov[1].iov_base = (void *) msg_addr; /* discard const */
 
524
                        iov[1].iov_len = req_exec_evs_mcast->msg_len;
 
525
 
 
526
                        api->ipc_dispatch_iov_send (
 
527
                                evs_pd->conn,
 
528
                                iov,
 
529
                                2);
522
530
                }
523
531
        }
524
532
}
525