1 /*
2 * Copyright (C) 2008-2013 Codership Oy <info@codership.com>
3 *
4 * $Id$
5 */
6 /*
7 * Interface to membership messages - implementation
8 *
9 */
10
11 #include <string.h>
12 #include <errno.h>
13 #include <stddef.h>
14 #include <galerautils.h>
15
16 #define GCS_COMP_MSG_ACCESS
17 #include "gcs_comp_msg.hpp"
18
19 static inline int
comp_msg_size(int memb_num)20 comp_msg_size (int memb_num)
21 { return (sizeof(gcs_comp_msg_t) + memb_num * sizeof(gcs_comp_memb_t)); }
22
23 /*! Allocates membership object and zeroes it */
24 gcs_comp_msg_t*
gcs_comp_msg_new(bool prim,bool bootstrap,int my_idx,int memb_num,int error)25 gcs_comp_msg_new (bool prim, bool bootstrap, int my_idx, int memb_num, int error)
26 {
27 gcs_comp_msg_t* ret;
28
29 assert ((memb_num > 0 && my_idx >= 0) || (memb_num == 0 && my_idx == -1));
30
31 ret = static_cast<gcs_comp_msg_t*>(gu_calloc (1, comp_msg_size(memb_num)));
32
33 if (NULL != ret) {
34 ret->primary = prim;
35 ret->bootstrap = bootstrap;
36 ret->my_idx = my_idx;
37 ret->memb_num = memb_num;
38 ret->error = error;
39 }
40
41 return ret;
42 }
43
44 gcs_comp_msg_t*
gcs_comp_msg_leave(int error)45 gcs_comp_msg_leave (int error)
46 {
47 return gcs_comp_msg_new (false, false, -1, 0, error);
48 }
49
50 /*! Destroys component message */
51 void
gcs_comp_msg_delete(gcs_comp_msg_t * comp)52 gcs_comp_msg_delete (gcs_comp_msg_t* comp)
53 {
54 gu_free (comp);
55 }
56
57 /*! Returns total size of the component message */
58 int
gcs_comp_msg_size(const gcs_comp_msg_t * comp)59 gcs_comp_msg_size (const gcs_comp_msg_t* comp)
60 {
61 assert (comp);
62 return comp_msg_size (comp->memb_num);
63 }
64
65 /*! Adds a member to the component message
66 * Returns an index of the member or negative error code */
67 int
gcs_comp_msg_add(gcs_comp_msg_t * comp,const char * id,gcs_segment_t const segment)68 gcs_comp_msg_add (gcs_comp_msg_t* comp, const char* id,
69 gcs_segment_t const segment)
70 {
71 size_t id_len;
72 int i;
73
74 assert (comp);
75 assert (id);
76
77 /* check id length */
78 id_len = strlen (id);
79 if (!id_len) return -EINVAL;
80 if (id_len > GCS_COMP_MEMB_ID_MAX_LEN) return -ENAMETOOLONG;
81
82 int free_slot = -1;
83
84 /* find the free id slot and check for id uniqueness */
85 for (i = 0; i < comp->memb_num; i++) {
86 if (0 == comp->memb[i].id[0] && free_slot < 0) free_slot = i;
87 if (0 == strcmp (comp->memb[i].id, id)) return -ENOTUNIQ;
88 }
89
90 if (free_slot < 0) return -1;
91
92 memcpy (comp->memb[free_slot].id, id, id_len);
93 comp->memb[free_slot].segment = segment;
94
95 return free_slot;
96 }
97
98 /*! Creates a copy of the component message */
99 gcs_comp_msg_t*
gcs_comp_msg_copy(const gcs_comp_msg_t * comp)100 gcs_comp_msg_copy (const gcs_comp_msg_t* comp)
101 {
102 size_t size = gcs_comp_msg_size(comp);
103 gcs_comp_msg_t* ret = static_cast<gcs_comp_msg_t*>(gu_malloc (size));
104
105 if (ret) memcpy (ret, comp, size);
106
107 return ret;
108 }
109
110 /*! Returns member ID by index, NULL if none */
111 const gcs_comp_memb_t*
gcs_comp_msg_member(const gcs_comp_msg_t * comp,int idx)112 gcs_comp_msg_member (const gcs_comp_msg_t* comp, int idx)
113 {
114 if (0 <= idx && idx < comp->memb_num)
115 return &comp->memb[idx];
116 else
117 return NULL;
118 }
119
120 /*! Returns member index by ID, -1 if none */
121 int
gcs_comp_msg_idx(const gcs_comp_msg_t * comp,const char * id)122 gcs_comp_msg_idx (const gcs_comp_msg_t* comp, const char* id)
123 {
124 size_t id_len = strlen(id);
125 int idx = comp->memb_num;
126
127 if (id_len > 0 && id_len <= GCS_COMP_MEMB_ID_MAX_LEN)
128 for (idx = 0; idx < comp->memb_num; idx++)
129 if (0 == strcmp (comp->memb[idx].id, id)) break;
130
131 if (comp->memb_num == idx)
132 return -1;
133 else
134 return idx;
135 }
136
137 /*! Returns primary status of the component */
138 bool
gcs_comp_msg_primary(const gcs_comp_msg_t * comp)139 gcs_comp_msg_primary (const gcs_comp_msg_t* comp)
140 {
141 return comp->primary;
142 }
143
144 /*! Retruns bootstrap flag of the component */
145 bool
gcs_comp_msg_bootstrap(const gcs_comp_msg_t * comp)146 gcs_comp_msg_bootstrap(const gcs_comp_msg_t* comp)
147 {
148 return comp->bootstrap;
149 }
150
151 /*! Returns our own index in the membership */
152 int
gcs_comp_msg_self(const gcs_comp_msg_t * comp)153 gcs_comp_msg_self (const gcs_comp_msg_t* comp)
154 {
155 return comp->my_idx;
156 }
157
158 /*! Returns number of members in the component */
159 int
gcs_comp_msg_num(const gcs_comp_msg_t * comp)160 gcs_comp_msg_num (const gcs_comp_msg_t* comp)
161 {
162 return comp->memb_num;
163 }
164
165
gcs_comp_msg_error(const gcs_comp_msg_t * comp)166 int gcs_comp_msg_error(const gcs_comp_msg_t* comp)
167 {
168 return comp->error;
169 }
170