Motr  M0
service_ctx.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2017-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 #include <unistd.h> /* sleep */
23 #include "reqh/reqh_service_internal.h" /* reqh_service_ctx_sm_lock */
24 #include "rpc/rpclib.h" /* m0_rpc_server_start */
25 #include "ut/misc.h" /* M0_UT_PATH */
26 #include "ut/ut.h"
27 
28 #define SERVER_LOG_FILE_NAME "reqh_service_ctx.log"
29 
30 static struct m0_rpc_server_ctx ut_sctx;
32 static struct m0_rpc_machine ut_rmach;
33 static const char *ut_ep_addr_remote = "0@lo:12345:34:999";
35 static struct m0_reqh ut_reqh;
36 
37 static char *sargs[] = {"m0d", "-T", "linux",
38  "-D", "cs_sdb", "-S", "cs_stob",
39  "-A", "linuxstob:cs_addb_stob",
40  "-e", M0_NET_XPRT_PREFIX_DEFAULT":0@lo:12345:34:1",
41  "-H", "0@lo:12345:34:1",
42  "-w", "10",
43  "-c", M0_SRC_PATH("reqh/ut/service_ctx.xc")
44 };
45 
46 static void reqh_service_ctx_ut_test_helper(char *ut_argv[], int ut_argc,
47  void (*ut_body)(void))
48 {
49  ut_sctx = (struct m0_rpc_server_ctx) {
50  .rsx_argv = ut_argv,
51  .rsx_argc = ut_argc,
52  .rsx_log_file_name = SERVER_LOG_FILE_NAME
53  };
54 
58  ut_body();
60 }
61 
63 {
64  enum { NR_TMS = 1 };
65  int rc;
66  uint32_t bufs_nr;
67 
69  M0_ASSERT(rc == 0);
72  bufs_nr, NR_TMS);
73  M0_ASSERT(rc == 0);
75  .rhia_dtm = (void *)1,
76  .rhia_db = NULL,
77  .rhia_mdstore = (void *)1,
78  .rhia_fid = &g_process_fid ) ?:
84  return rc;
85 }
86 
88 {
93 }
94 
95 static struct m0_reqh_service_ctx *
96 reqh_service_ctx_ut__find(struct m0_fid *fid, int stype, const char *ep)
97 {
99  struct m0_reqh_service_ctx *ctx;
100 
102  M0_UT_ASSERT(ctx != NULL);
103  M0_UT_ASSERT(ep == NULL ||
104  m0_streq(m0_rpc_link_end_point(&ctx->sc_rlink), ep));
105  return ctx;
106 }
107 
109 {
110  struct m0_fid fid = M0_FID_TINIT('s', 1, 27);
111 
112  return reqh_service_ctx_ut__find(&fid, M0_CST_DS1, ut_ep_addr_remote);
113 }
114 
115 static struct m0_semaphore g_sem;
116 
117 static bool ut_dead_end__cb(struct m0_clink *clink)
118 {
120  return true;
121 }
122 
123 static void ut_dead_end__connecting(void)
124 {
126  struct m0_clink clink;
127  /*
128  * Need to do nothing here but just wait. Connecting is to fail
129  * natural way due to "0@lo:12345:34:999" endpoint unavailable.
130  */
133  m0_clink_add_lock(&ctx->sc_rlink.rlk_wait, &clink);
138 }
139 
140 /*
141  * The test imitates situations when service context shuts down concurrently
142  * with context connection.
143  *
144  * We are to start without "0@lo:12345:34:999" remote end and then see if we can
145  * shutdown reqh smooth.
146  */
147 static void test_dead_end_connect(void)
148 {
151 }
152 
154 {
155  int state;
156  /*
157  * Make sure the context gets online. As the context may be already
158  * connected to the moment, attaching clink may be a trap. So we are
159  * going to wait in a plain cycle.
160  */
161  do {
162  sleep(1);
164  state = CTX_STATE(ctx);
165  M0_UT_ASSERT(M0_IN(state, (M0_RSC_ONLINE, M0_RSC_CONNECTING)));
167  } while (state != M0_RSC_ONLINE);
168 }
169 
171 {
173  struct m0_reqh_service_ctx *ctx;
174 
175  m0_tl_for(pools_common_svc_ctx, &pc->pc_svc_ctxs, ctx) {
177  } m0_tl_endfor;
178 }
179 
180 /*
181  * The case is about initiate disconnection when remote end is already dead, and
182  * shut down pool contexts immediately while disconnecting.
183  */
184 static void ut_dead_end__disconnecting(void)
185 {
187 
191 }
192 
193 /*
194  * The case is about initiate disconnection when remote end is already dead, and
195  * shut down pool contexts having corresponding context already offline.
196  */
197 static void ut_dead_end__disconnected(void)
198 {
200  struct m0_clink clink;
201 
205  m0_clink_add_lock(&ctx->sc_rlink.rlk_wait, &clink);
212 }
213 
214 /*
215  * The test imitates situations when service context shuts down concurrently
216  * with disconnection.
217  *
218  * This time a separate rpc machine is launched to let "0@lo:12345:34:999"
219  * remote end be connectable. The remote end will be stopped in the course of
220  * the test, and then we see if we can shutdown reqh smooth.
221  */
222 static void test_dead_end_disconnect(void)
223 {
227 
231 }
232 
234  .ts_name = "reqh-service-ctx-ut",
235  .ts_init = NULL,
236  .ts_fini = NULL,
237  .ts_tests = {
238  { "dead-end-conn", test_dead_end_connect },
239  { "dead-end-disc", test_dead_end_disconnect },
240  { NULL, NULL },
241  },
242  .ts_owners = "Igor Vartanov",
243 };
244 M0_EXPORTED(reqh_service_ut);
245 
246 /*
247  * Local variables:
248  * c-indentation-style: "K&R"
249  * c-basic-offset: 8
250  * tab-width: 8
251  * fill-column: 80
252  * scroll-step: 1
253  * End:
254  */
static void reqh_service_ctx_ut__wait_all_online(void)
Definition: service_ctx.c:170
void m0_rpc_machine_fini(struct m0_rpc_machine *machine)
Definition: rpc_machine.c:233
void m0_net_domain_fini(struct m0_net_domain *dom)
Definition: domain.c:71
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
struct m0_ut_suite reqh_service_ctx_ut
Definition: service_ctx.c:233
static bool ut_dead_end__cb(struct m0_clink *clink)
Definition: service_ctx.c:117
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
#define SERVER_LOG_FILE_NAME
Definition: service_ctx.c:28
#define M0_REQH_INIT(reqh,...)
Definition: reqh.h:262
char ** rsx_argv
Definition: rpclib.h:77
int m0_rpc_server_start(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:50
static void ut_dead_end__connecting(void)
Definition: service_ctx.c:123
static struct m0_reqh_service_ctx * reqh_service_ctx_ut__find(struct m0_fid *fid, int stype, const char *ep)
Definition: service_ctx.c:96
static const char * ut_ep_addr_remote
Definition: service_ctx.c:33
static void reqh_service_ctx_ut_test_helper(char *ut_argv[], int ut_argc, void(*ut_body)(void))
Definition: service_ctx.c:46
static struct m0_rpc_machine ut_rmach
Definition: service_ctx.c:32
static void reqh_service_ctx_sm_unlock(struct m0_reqh_service_ctx *ctx)
#define M0_SRC_PATH(name)
Definition: misc.h:48
Definition: ut.h:77
M0_INTERNAL void m0_reqh_fini(struct m0_reqh *reqh)
Definition: reqh.c:320
static struct m0_net_buffer_pool ut_buf_pool
Definition: service_ctx.c:34
M0_INTERNAL struct m0_reqh_service_ctx * m0_pools_common_service_ctx_find(const struct m0_pools_common *pc, const struct m0_fid *id, enum m0_conf_service_type type)
Definition: pool.c:1095
static struct m0_pools_common pc
Definition: iter_ut.c:59
#define m0_tl_endfor
Definition: tlist.h:700
struct m0_fid fid
Definition: di.c:46
Definition: sock.c:754
static void test_dead_end_connect(void)
Definition: service_ctx.c:147
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
static const struct socktype stype[]
Definition: sock.c:1156
static void ut_dead_end__disconnecting(void)
Definition: service_ctx.c:184
#define M0_NET_XPRT_PREFIX_DEFAULT
Definition: net.h:98
#define M0_ASSERT(cond)
static struct m0_net_domain ut_client_net_dom
Definition: service_ctx.c:31
M0_INTERNAL int m0_rpc_net_buffer_pool_setup(struct m0_net_domain *ndom, struct m0_net_buffer_pool *app_pool, uint32_t bufs_nr, uint32_t tm_nr)
Definition: rpc.c:229
static struct m0_reqh_service_ctx * reqh_service_ctx_ut__find_remote(void)
Definition: service_ctx.c:108
struct m0_ut_suite reqh_service_ut
Definition: service.c:117
#define m0_streq(a, b)
Definition: string.h:34
static char * sargs[]
Definition: service_ctx.c:37
M0_INTERNAL uint32_t m0_rpc_bufs_nr(uint32_t len, uint32_t tms_nr)
Definition: rpc.c:271
int m0_net_xprt_nr(void)
Definition: net.c:168
M0_INTERNAL int m0_rpc_machine_init(struct m0_rpc_machine *machine, struct m0_net_domain *net_dom, const char *ep_addr, struct m0_reqh *reqh, struct m0_net_buffer_pool *receive_pool, uint32_t colour, m0_bcount_t msg_size, uint32_t queue_len)
Definition: rpc_machine.c:123
struct m0_net_xprt * m0_net_xprt_default_get(void)
Definition: net.c:151
struct m0_net_xprt ** rsx_xprts
Definition: rpclib.h:69
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
Definition: reqh.h:94
static struct m0_rpc_server_ctx ut_sctx
Definition: service_ctx.c:30
static struct m0_clink clink[RDWR_REQUEST_MAX]
struct m0_tl pc_svc_ctxs
Definition: pool.h:172
static struct fdmi_ctx ctx
Definition: main.c:80
static struct m0_reqh ut_reqh
Definition: service_ctx.c:35
static void test_dead_end_disconnect(void)
Definition: service_ctx.c:222
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
static int reqh_service_ctx_ut__remote_rmach_init(void)
Definition: service_ctx.c:62
const char * ts_name
Definition: ut.h:99
static void reqh_service_ctx_sm_lock(struct m0_reqh_service_ctx *ctx)
int m0_net_domain_init(struct m0_net_domain *dom, const struct m0_net_xprt *xprt)
Definition: domain.c:36
int rsx_xprts_nr
Definition: rpclib.h:71
Definition: fid.h:38
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
struct m0_net_xprt ** m0_net_all_xprt_get(void)
Definition: net.c:161
static void ut_dead_end__disconnected(void)
Definition: service_ctx.c:197
static void reqh_service_ctx_ut__remote_rmach_fini(void)
Definition: service_ctx.c:87
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
void m0_rpc_server_stop(struct m0_rpc_server_ctx *sctx)
Definition: rpclib.c:85
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
Definition: nucleus.c:42
M0_INTERNAL void m0_reqh_service_disconnect(struct m0_reqh_service_ctx *ctx)
Definition: reqh_service.c:781
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
struct m0_pools_common cc_pools_common
Definition: setup.h:356
void m0_rpc_net_buffer_pool_cleanup(struct m0_net_buffer_pool *app_pool)
Definition: rpc.c:264
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
static struct m0_semaphore g_sem
Definition: service_ctx.c:115
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
struct m0_fid g_process_fid
Definition: ut.c:689
#define M0_UT_ASSERT(a)
Definition: ut.h:46
struct m0_motr rsx_motr_ctx
Definition: rpclib.h:84
#define CTX_STATE(ctx)
static void reqh_service_ctx_ut__wait_online(struct m0_reqh_service_ctx *ctx)
Definition: service_ctx.c:153