Motr  M0
link_service.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2016-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 
30 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_HA
31 #include "lib/trace.h"
32 
33 #include "ha/link_service.h"
34 
35 #include "lib/tlist.h" /* M0_TL_DESCR_DEFINE */
36 #include "lib/misc.h" /* container_of */
37 #include "lib/types.h" /* m0_uint128_eq */
38 #include "lib/memory.h" /* M0_ALLOC_PTR */
39 #include "lib/mutex.h" /* m0_mutex */
40 
41 #include "motr/magic.h" /* M0_HA_LINK_SERVICE_MAGIC */
42 #include "reqh/reqh_service.h" /* m0_reqh_service */
43 
44 #include "ha/link.h" /* m0_ha_link */
45 
46 M0_TL_DESCR_DEFINE(ha_link_svc, "ha_link_service::hls_links", static,
47  struct m0_ha_link, hln_service_link, hln_service_magic,
50 M0_TL_DEFINE(ha_link_svc, static, struct m0_ha_link);
51 
54  struct m0_reqh *hls_reqh;
55  struct m0_tl hls_links;
58  uint64_t hls_magic;
59 };
60 
61 static const struct m0_bob_type ha_link_service_bob_type = {
62  .bt_name = "m0_ha_link_service",
63  .bt_magix_offset = M0_MAGIX_OFFSET(struct ha_link_service, hls_magic),
64  .bt_magix = M0_HALON_INTERFACE_MAGIC,
65 };
66 /*
67  * "static inline" because with just "static" ha_link_service_bob_check()
68  * is not used, but it's declared => compiler emits a warning.
69  */
71 
72 static struct ha_link_service *
74 {
75  return bob_of(service, struct ha_link_service, hls_service,
77 }
78 
80 {
82 
83  M0_ENTRY("service=%p hl_service=%p", service, hl_service);
84  m0_mutex_init(&hl_service->hls_lock);
85  ha_link_svc_tlist_init(&hl_service->hls_links);
86  ha_link_svc_tlist_init(&hl_service->hls_quiescing);
87  M0_LEAVE();
88 }
89 
91 {
93 
94  M0_ENTRY("service=%p hl_service=%p", service, hl_service);
95  ha_link_svc_tlist_fini(&hl_service->hls_quiescing);
96  ha_link_svc_tlist_fini(&hl_service->hls_links);
97  m0_mutex_fini(&hl_service->hls_lock);
98  ha_link_service_bob_fini(hl_service);
99  /* allocated in ha_link_service_allocate() */
100  m0_free(hl_service);
101  M0_LEAVE();
102 }
103 
105 {
106  M0_ENTRY();
107  return M0_RC(0);
108 }
109 
111  struct m0_fop *fop)
112 {
113  M0_ENTRY();
114  return M0_RC(0);
115 }
116 
118 {
119  M0_ENTRY();
120  M0_LEAVE();
121 }
122 
123 static struct m0_ha_link *
125  const struct m0_uint128 *link_id,
126  struct m0_uint128 *connection_id)
127 {
128  struct m0_ha_link *hl;
129 
130  M0_ENTRY("hl_service=%p link_id="U128X_F, hl_service, U128_P(link_id));
131  M0_PRE(m0_mutex_is_locked(&hl_service->hls_lock));
132  hl = m0_tl_find(ha_link_svc, ha_link, &hl_service->hls_links,
133  m0_uint128_eq(&ha_link->hln_service_link_id, link_id));
134  if (connection_id != NULL)
135  *connection_id = hl == NULL ? M0_UINT128(0, 0) :
137  M0_LEAVE("hl=%p link_id="U128X_F" connection_id="U128X_F, hl,
138  U128_P(link_id), U128_P(connection_id == NULL ?
139  &M0_UINT128(0, 0) : connection_id));
140  return hl;
141 }
142 
143 static void ha_link_service_get(struct ha_link_service *hl_service,
144  struct m0_ha_link *hl)
145 {
146  M0_PRE(hl != NULL);
147  M0_ENTRY("hl_service=%p hl=%p hln_service_ref_counter=%"PRIu64,
148  hl_service, hl, hl->hln_service_ref_counter);
149  M0_PRE(m0_mutex_is_locked(&hl_service->hls_lock));
152 
154 }
155 
156 M0_INTERNAL struct m0_ha_link *
158  const struct m0_uint128 *link_id,
159  struct m0_uint128 *connection_id)
160 {
161  struct ha_link_service *hl_service = ha_link_service_container(service);
162  struct m0_ha_link *hl;
163 
164  M0_ENTRY("service=%p hl_service=%p link_id="U128X_F,
165  service, hl_service, U128_P(link_id));
166  m0_mutex_lock(&hl_service->hls_lock);
167  hl = ha_link_service_find(hl_service, link_id, connection_id);
168  if (hl != NULL)
169  ha_link_service_get(hl_service, hl);
170  m0_mutex_unlock(&hl_service->hls_lock);
171  M0_LEAVE("service=%p hl_service=%p link_id="U128X_F" hl=%p ",
172  service, hl_service, U128_P(link_id), hl);
173  return hl;
174 }
175 
177  struct m0_ha_link *hl)
178 {
179  struct ha_link_service *hl_service = ha_link_service_container(service);
180  uint64_t ref_counter;
181 
182  M0_ENTRY("service=%p hl_service=%p hl=%p", service, hl_service, hl);
183  m0_mutex_lock(&hl_service->hls_lock);
186  if (hl->hln_service_ref_counter == 0 && hl->hln_service_quiescing) {
187  hl->hln_service_released = true;
189  }
190  ref_counter = hl->hln_service_ref_counter;
191  m0_mutex_unlock(&hl_service->hls_lock);
192  M0_LEAVE("service=%p hl_service=%p hl=%p "
193  "hln_service_ref_counter=%"PRIu64,
194  service, hl_service, hl, ref_counter);
195 }
196 
198  struct m0_ha_link *hl,
199  struct m0_chan *chan)
200 {
201  struct ha_link_service *hl_service = ha_link_service_container(service);
202 
203  M0_ENTRY("service=%p hl_service=%p hl=%p", service, hl_service, hl);
204  m0_mutex_lock(&hl_service->hls_lock);
206  ha_link_service_get(hl_service, hl);
207  ha_link_svc_tlist_move_tail(&hl_service->hls_quiescing, hl);
208  hl->hln_service_quiescing = true;
209  m0_mutex_unlock(&hl_service->hls_lock);
211  M0_LEAVE("service=%p hl_service=%p hl=%p", service, hl_service, hl);
212 }
213 
214 M0_INTERNAL void
216  struct m0_ha_link *hl,
217  const struct m0_uint128 *link_id,
218  const struct m0_uint128 *connection_id)
219 {
220  struct ha_link_service *hl_service = ha_link_service_container(service);
221 
222  M0_ENTRY("service=%p hl=%p hl_service=%p", service, hl, hl_service);
223  hl->hln_service_ref_counter = 0;
224  hl->hln_service_link_id = *link_id;
225  hl->hln_service_connection_id = *connection_id;
226  hl->hln_service_quiescing = false;
227  hl->hln_service_released = false;
228  m0_mutex_lock(&hl_service->hls_lock);
229  M0_PRE(ha_link_service_find(hl_service, link_id, NULL) == NULL);
230  ha_link_svc_tlink_init_at_tail(hl, &hl_service->hls_links);
231  m0_mutex_unlock(&hl_service->hls_lock);
232  M0_LEAVE();
233 }
234 
236  struct m0_ha_link *hl)
237 {
238  struct ha_link_service *hl_service = ha_link_service_container(service);
239 
240  M0_ENTRY("service=%p hl=%p hl_service=%p", service, hl, hl_service);
243  m0_mutex_lock(&hl_service->hls_lock);
244  ha_link_svc_tlink_del_fini(hl);
245  m0_mutex_unlock(&hl_service->hls_lock);
246  M0_LEAVE();
247 }
248 
251  .rso_fop_accept = ha_link_service_fop_accept,
252  .rso_stop = ha_link_service_stop,
253  .rso_fini = ha_link_service_fini,
254 };
255 
257  const struct m0_reqh_service_type *stype);
258 
261 };
262 
264  .rst_name = "ha-link-service",
265  .rst_ops = &ha_link_stype_ops,
266  .rst_level = M0_HA_LINK_SVC_LEVEL,
267  .rst_keep_alive = true,
268 };
269 
271  const struct m0_reqh_service_type *stype)
272 {
273  struct ha_link_service *hl_service;
274 
275  M0_ENTRY();
277 
278  M0_ALLOC_PTR(hl_service);
279  if (hl_service == NULL)
280  return M0_RC(-ENOMEM);
281 
282  ha_link_service_bob_init(hl_service);
283  ha_link_service_init(&hl_service->hls_service);
284  *service = &hl_service->hls_service;
285  (*service)->rs_ops = &ha_link_service_ops;
286 
287  return M0_RC(0);
288 }
289 
290 M0_INTERNAL int m0_ha_link_service_init(struct m0_reqh_service **hl_service,
291  struct m0_reqh *reqh)
292 {
293  M0_ENTRY("reqh=%p", reqh);
295  reqh, NULL, NULL));
296 }
297 
298 M0_INTERNAL void m0_ha_link_service_fini(struct m0_reqh_service *hl_service)
299 {
300  M0_ENTRY("hl_service=%p", hl_service);
301  m0_reqh_service_quit(hl_service);
302  M0_LEAVE();
303 }
304 
305 M0_INTERNAL int m0_ha_link_service_mod_init(void)
306 {
308 }
309 
310 M0_INTERNAL void m0_ha_link_service_mod_fini(void)
311 {
313 }
314 
315 #undef M0_TRACE_SUBSYSTEM
316 
319 /*
320  * Local variables:
321  * c-indentation-style: "K&R"
322  * c-basic-offset: 8
323  * tab-width: 8
324  * fill-column: 80
325  * scroll-step: 1
326  * End:
327  */
328 /*
329  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
330  */
static struct ha_link_service * ha_link_service_container(struct m0_reqh_service *service)
Definition: link_service.c:73
M0_INTERNAL void m0_ha_link_service_put(struct m0_reqh_service *service, struct m0_ha_link *hl)
Definition: link_service.c:176
#define M0_PRE(cond)
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
int(* rso_start)(struct m0_reqh_service *service)
Definition: reqh_service.h:360
static int ha_link_service_allocate(struct m0_reqh_service **service, const struct m0_reqh_service_type *stype)
Definition: link_service.c:270
#define NULL
Definition: misc.h:38
M0_INTERNAL bool m0_uint128_eq(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:39
M0_LEAVE()
M0_BOB_DEFINE(static inline, &ha_link_service_bob_type, ha_link_service)
M0_INTERNAL struct m0_ha_link * m0_ha_link_service_find_get(struct m0_reqh_service *service, const struct m0_uint128 *link_id, struct m0_uint128 *connection_id)
Definition: link_service.c:157
static const struct m0_reqh_service_type_ops ha_link_stype_ops
Definition: link_service.c:259
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
int m0_reqh_service_type_register(struct m0_reqh_service_type *rstype)
Definition: reqh_service.c:473
const char * bt_name
Definition: bob.h:73
return M0_RC(rc)
#define M0_ENTRY(...)
Definition: trace.h:170
static int ha_link_service_start(struct m0_reqh_service *service)
Definition: link_service.c:104
#define PRIu64
Definition: types.h:58
static const struct socktype stype[]
Definition: sock.c:1156
M0_INTERNAL void m0_reqh_service_quit(struct m0_reqh_service *svc)
Definition: reqh_service.c:588
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
Definition: mutex.c:95
#define U128_P(x)
Definition: types.h:45
const char * rst_name
Definition: reqh_service.h:447
Definition: tlist.h:251
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
M0_TL_DESCR_DEFINE(ha_link_svc, "ha_link_service::hls_links", static, struct m0_ha_link, hln_service_link, hln_service_magic, M0_HA_LINK_SERVICE_LINK_MAGIC, M0_HA_LINK_SERVICE_HEAD_MAGIC)
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
Definition: reqh.h:94
Definition: chan.h:229
static void ha_link_service_fini(struct m0_reqh_service *service)
Definition: link_service.c:90
M0_INTERNAL int m0_reqh_service_setup(struct m0_reqh_service **out, struct m0_reqh_service_type *stype, struct m0_reqh *reqh, struct m0_reqh_context *rctx, const struct m0_fid *fid)
Definition: reqh_service.c:565
M0_INTERNAL int m0_ha_link_service_init(struct m0_reqh_service **hl_service, struct m0_reqh *reqh)
Definition: link_service.c:290
M0_INTERNAL int m0_ha_link_service_mod_init(void)
Definition: link_service.c:305
static const struct m0_reqh_service_ops ha_link_service_ops
Definition: link_service.c:249
M0_INTERNAL void m0_chan_signal_lock(struct m0_chan *chan)
Definition: chan.c:165
#define U128X_F
Definition: types.h:42
M0_INTERNAL void m0_ha_link_service_register(struct m0_reqh_service *service, struct m0_ha_link *hl, const struct m0_uint128 *link_id, const struct m0_uint128 *connection_id)
Definition: link_service.c:215
struct m0_reqh reqh
Definition: rm_foms.c:48
#define M0_MAGIX_OFFSET(type, field)
Definition: misc.h:356
int(* rsto_service_allocate)(struct m0_reqh_service **service, const struct m0_reqh_service_type *stype)
Definition: reqh_service.h:435
static void ha_link_service_init(struct m0_reqh_service *service)
Definition: link_service.c:79
struct m0_reqh_service_type m0_ha_link_service_type
Definition: link_service.c:263
static struct m0_chan chan[RDWR_REQUEST_MAX]
M0_INTERNAL void m0_ha_link_service_fini(struct m0_reqh_service *hl_service)
Definition: link_service.c:298
M0_INTERNAL void m0_ha_link_service_quiesce(struct m0_reqh_service *service, struct m0_ha_link *hl, struct m0_chan *chan)
Definition: link_service.c:197
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static void ha_link_service_stop(struct m0_reqh_service *service)
Definition: link_service.c:117
static int ha_link_service_fop_accept(struct m0_reqh_service *service, struct m0_fop *fop)
Definition: link_service.c:110
M0_TL_DEFINE(ha_link_svc, static, struct m0_ha_link)
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
static struct m0_fop * fop
Definition: item.c:57
static void ha_link_service_get(struct ha_link_service *hl_service, struct m0_ha_link *hl)
Definition: link_service.c:143
#define M0_UINT128(hi, lo)
Definition: types.h:40
static struct m0_ha_link * ha_link_service_find(struct ha_link_service *hl_service, const struct m0_uint128 *link_id, struct m0_uint128 *connection_id)
Definition: link_service.c:124
#define m0_tl_find(name, var, head,...)
Definition: tlist.h:757
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
M0_INTERNAL void m0_ha_link_service_deregister(struct m0_reqh_service *service, struct m0_ha_link *hl)
Definition: link_service.c:235
void m0_reqh_service_type_unregister(struct m0_reqh_service_type *rstype)
Definition: reqh_service.c:490
static struct m0_reqh_service * service[REQH_IN_UT_MAX]
Definition: long_lock_ut.c:46
Definition: fop.h:79
M0_INTERNAL void m0_ha_link_service_mod_fini(void)
Definition: link_service.c:310
const struct m0_reqh_service_ops * rs_ops
Definition: reqh_service.h:254
static const struct m0_bob_type ha_link_service_bob_type
Definition: link_service.c:61