Motr  M0
client.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_DIX
31 #include "lib/trace.h"
32 #include "lib/ext.h" /* struct m0_ext */
33 #include "sm/sm.h"
34 #include "pool/pool.h" /* m0_pools_common, m0_pool_version_find */
35 #include "dix/layout.h"
36 #include "dix/req.h"
37 #include "dix/meta.h"
38 #include "dix/client.h"
39 #include "dix/client_internal.h"
40 
41 static struct m0_sm_state_descr dix_cli_states[] = {
42  [DIXCLI_INIT] = {
44  .sd_name = "init",
45  .sd_allowed = M0_BITS(DIXCLI_STARTING,
47  },
48  [DIXCLI_BOOTSTRAP] = {
49  .sd_name = "bootstrap_mode",
50  .sd_allowed = M0_BITS(DIXCLI_STARTING, DIXCLI_FINAL)
51  },
52  [DIXCLI_STARTING] = {
53  .sd_name = "starting",
54  .sd_allowed = M0_BITS(DIXCLI_READY, DIXCLI_FAILURE)
55  },
56  [DIXCLI_READY] = {
57  .sd_name = "ready",
58  .sd_allowed = M0_BITS(DIXCLI_FINAL)
59  },
60  [DIXCLI_FINAL] = {
61  .sd_name = "final",
62  .sd_flags = M0_SDF_TERMINAL,
63  },
64  [DIXCLI_FAILURE] = {
65  .sd_name = "failure",
66  .sd_flags = M0_SDF_TERMINAL | M0_SDF_FAILURE
67  }
68 };
69 
70 static struct m0_sm_trans_descr dix_cli_trans[] = {
71  { "start", DIXCLI_INIT, DIXCLI_STARTING },
72  { "bootstrap", DIXCLI_INIT, DIXCLI_BOOTSTRAP },
73  { "ready", DIXCLI_STARTING, DIXCLI_READY },
74  { "start-failure", DIXCLI_STARTING, DIXCLI_FAILURE },
75  { "start", DIXCLI_BOOTSTRAP, DIXCLI_STARTING },
76  { "bootstrap-exit", DIXCLI_BOOTSTRAP, DIXCLI_FINAL },
77  { "stop", DIXCLI_READY, DIXCLI_FINAL },
78 };
79 
80 static const struct m0_sm_conf dix_cli_sm_conf = {
81  .scf_name = "dix_client",
82  .scf_nr_states = ARRAY_SIZE(dix_cli_states),
83  .scf_state = dix_cli_states,
84  .scf_trans_nr = ARRAY_SIZE(dix_cli_trans),
85  .scf_trans = dix_cli_trans
86 };
87 
88 static struct m0_sm_group *dix_cli_smgrp(const struct m0_dix_cli *cli)
89 {
90  return cli->dx_sm.sm_grp;
91 }
92 
93 M0_INTERNAL void m0_dix_cli_lock(struct m0_dix_cli *cli)
94 {
95  M0_ENTRY();
97 }
98 
99 M0_INTERNAL void m0_dix_cli_unlock(struct m0_dix_cli *cli)
100 {
101  M0_ENTRY();
103 }
104 
105 M0_INTERNAL bool m0_dix_cli_is_locked(const struct m0_dix_cli *cli)
106 {
107  return m0_mutex_is_locked(&dix_cli_smgrp(cli)->s_lock);
108 }
109 
110 static enum m0_dix_cli_state dix_cli_state(const struct m0_dix_cli *cli)
111 {
112  return cli->dx_sm.sm_state;
113 }
114 
115 static void dix_cli_failure(struct m0_dix_cli *cli, int32_t rc)
116 {
117  M0_PRE(rc != 0);
119 }
120 
121 static void dix_cli_state_set(struct m0_dix_cli *cli,
122  enum m0_dix_cli_state state)
123 {
124  M0_LOG(M0_DEBUG, "DIX client: %p, state change:[%s -> %s]\n",
125  cli, m0_sm_state_name(&cli->dx_sm, cli->dx_sm.sm_state),
126  m0_sm_state_name(&cli->dx_sm, state));
127  m0_sm_state_set(&cli->dx_sm, state);
128 }
129 
130 M0_INTERNAL int m0_dix_cli_init(struct m0_dix_cli *cli,
131  struct m0_sm_group *sm_group,
132  struct m0_pools_common *pc,
133  struct m0_layout_domain *ldom,
134  const struct m0_fid *pver)
135 {
136  M0_ENTRY();
137  M0_SET0(cli);
138  cli->dx_pc = pc;
139  cli->dx_ldom = ldom;
141  cli->dx_sync_rec_update = NULL;
142  cli->dx_dtms = NULL;
144  &(struct m0_ext) { .e_start = 0,
145  .e_end = IMASK_INF },
146  1, HASH_FNC_FNV1,
147  &cli->dx_pver->pv_id);
148  m0_sm_init(&cli->dx_sm, &dix_cli_sm_conf, DIXCLI_INIT, sm_group);
149  return M0_RC(0);
150 }
151 
152 static void dix_cli_ast_post(struct m0_dix_cli *cli,
153  void (*cb)(struct m0_sm_group *,
154  struct m0_sm_ast *))
155 {
156  struct m0_sm_ast *ast = &cli->dx_ast;
157 
158  ast->sa_cb = cb;
159  ast->sa_datum = cli;
161 }
162 
163 static void dix_meta_read_ast_cb(struct m0_sm_group *grp, struct m0_sm_ast *ast)
164 {
165  struct m0_dix_cli *cli = ast->sa_datum;
166  struct m0_dix_meta_req *mreq = &cli->dx_mreq;
167  struct m0_dix_ldesc *layout = &cli->dx_layout;
168  struct m0_dix_ldesc *ldescr = &cli->dx_ldescr;
169  int rc;
170 
171  (void)grp;
172  rc = m0_dix_meta_generic_rc(mreq) ?:
173  m0_dix_root_read_rep(mreq, layout, ldescr);
174  m0_dix_meta_req_fini(mreq);
175  if (rc == 0)
177  else
178  dix_cli_failure(cli, rc);
179 }
180 
181 static bool dix_cli_meta_read_clink_cb(struct m0_clink *cl)
182 {
183  struct m0_dix_cli *cli = container_of(cl, struct m0_dix_cli, dx_clink);
184 
185  m0_clink_fini(cl);
187  return true;
188 }
189 
191  struct m0_sm_ast *ast)
192 {
193  struct m0_dix_cli *cli = ast->sa_datum;
194  struct m0_dix_meta_req *mreq = &cli->dx_mreq;
195  struct m0_clink *cl = &cli->dx_clink;
196  int rc;
197 
198  M0_ENTRY();
200  m0_dix_meta_req_init(mreq, cli, dix_cli_smgrp(cli));
202  m0_clink_add_lock(&mreq->dmr_chan, cl);
203  cl->cl_is_oneshot = true;
204  rc = m0_dix_root_read(mreq);
205  if (rc != 0) {
206  m0_clink_del_lock(cl);
207  m0_clink_fini(cl);
208  m0_dix_meta_req_fini(mreq);
209  dix_cli_failure(cli, rc);
210  }
211  M0_LEAVE();
212 }
213 
214 M0_INTERNAL void m0_dix_cli_start(struct m0_dix_cli *cli)
215 {
216  M0_ENTRY();
218  M0_LEAVE();
219 }
220 
221 M0_INTERNAL int m0_dix_cli_start_sync(struct m0_dix_cli *cli)
222 {
223  int rc;
224 
225  M0_ENTRY();
226  m0_dix_cli_start(cli);
227  m0_dix_cli_lock(cli);
228  rc = m0_sm_timedwait(&cli->dx_sm,
230  M0_TIME_NEVER);
231  m0_dix_cli_unlock(cli);
232  if (rc == 0)
233  rc = cli->dx_sm.sm_rc;
234  return M0_RC(rc);
235 }
236 
237 M0_INTERNAL void m0_dix_cli_bootstrap(struct m0_dix_cli *cli)
238 {
239  M0_ENTRY();
243 }
244 
245 M0_INTERNAL void m0_dix_cli_bootstrap_lock(struct m0_dix_cli *cli)
246 {
248  m0_dix_cli_lock(cli);
250  m0_dix_cli_unlock(cli);
251 }
252 
253 M0_INTERNAL void m0_dix_cli_stop(struct m0_dix_cli *cli)
254 {
255  M0_ENTRY();
258  M0_LEAVE();
259 }
260 
261 M0_INTERNAL void m0_dix_cli_stop_lock(struct m0_dix_cli *cli)
262 {
263  m0_dix_cli_lock(cli);
264  m0_dix_cli_stop(cli);
265  m0_dix_cli_unlock(cli);
266 }
267 
268 M0_INTERNAL void m0_dix_cli_fini(struct m0_dix_cli *cli)
269 {
271  m0_dix_ldesc_fini(&cli->dx_root);
274  m0_sm_fini(&cli->dx_sm);
275  cli->dx_dtms = NULL;
276 }
277 
278 M0_INTERNAL void m0_dix_cli_fini_lock(struct m0_dix_cli *cli)
279 {
280  struct m0_sm_group *grp = dix_cli_smgrp(cli);
281 
284  m0_dix_cli_fini(cli);
286 }
287 
288 M0_INTERNAL int m0_dix__root_set(const struct m0_dix_cli *cli,
289  struct m0_dix *out)
290 {
291  out->dd_fid = m0_dix_root_fid;
292  return m0_dix_desc_set(out, &cli->dx_root);
293 }
294 
295 M0_INTERNAL int m0_dix__layout_set(const struct m0_dix_cli *cli,
296  struct m0_dix *out)
297 {
298  out->dd_fid = m0_dix_layout_fid;
299  return m0_dix_desc_set(out, &cli->dx_layout);
300 }
301 
302 M0_INTERNAL int m0_dix__ldescr_set(const struct m0_dix_cli *cli,
303  struct m0_dix *out)
304 {
305  out->dd_fid = m0_dix_ldescr_fid;
306  return m0_dix_desc_set(out, &cli->dx_ldescr);
307 }
308 
309 M0_INTERNAL struct m0_pool_version *m0_dix_pver(const struct m0_dix_cli *cli,
310  const struct m0_dix *dix)
311 {
313  return m0_pool_version_find(cli->dx_pc,
314  &dix->dd_layout.u.dl_desc.ld_pver);
315 }
316 
317 #undef M0_TRACE_SUBSYSTEM
318 
321 /*
322  * Local variables:
323  * c-indentation-style: "K&R"
324  * c-basic-offset: 8
325  * tab-width: 8
326  * fill-column: 80
327  * scroll-step: 1
328  * End:
329  */
330 /*
331  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
332  */
#define M0_PRE(cond)
M0_INTERNAL int m0_dix__layout_set(const struct m0_dix_cli *cli, struct m0_dix *out)
Definition: client.c:295
struct m0_dix_layout dd_layout
Definition: req.h:112
M0_INTERNAL void m0_sm_fail(struct m0_sm *mach, int fail_state, int32_t rc)
Definition: sm.c:468
M0_INTERNAL void m0_dix_cli_stop_lock(struct m0_dix_cli *cli)
Definition: client.c:261
static void dix_cli_state_set(struct m0_dix_cli *cli, enum m0_dix_cli_state state)
Definition: client.c:121
#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
static struct m0_sm_state_descr dix_cli_states[]
Definition: client.c:41
M0_INTERNAL int m0_dix__root_set(const struct m0_dix_cli *cli, struct m0_dix *out)
Definition: client.c:288
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
static enum m0_dix_cli_state dix_cli_state(const struct m0_dix_cli *cli)
Definition: client.c:110
void(* sa_cb)(struct m0_sm_group *grp, struct m0_sm_ast *)
Definition: sm.h:506
M0_INTERNAL int m0_dix_desc_set(struct m0_dix *dix, const struct m0_dix_ldesc *desc)
Definition: req.c:2596
Definition: sm.h:350
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
M0_INTERNAL struct m0_pool_version * m0_pool_version_find(struct m0_pools_common *pc, const struct m0_fid *id)
Definition: pool.c:586
M0_INTERNAL int m0_dix_root_read(struct m0_dix_meta_req *req)
Definition: meta.c:379
static struct m0_sm_group * grp
Definition: bytecount.c:38
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
M0_INTERNAL const struct m0_fid m0_dix_layout_fid
Definition: meta.c:45
struct m0_dix_meta_req dx_mreq
Definition: client.h:186
M0_INTERNAL void m0_sm_ast_post(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: sm.c:135
M0_INTERNAL void m0_dix_meta_req_init(struct m0_dix_meta_req *req, struct m0_dix_cli *cli, struct m0_sm_group *grp)
Definition: meta.c:259
M0_INTERNAL bool m0_dix_cli_is_locked(const struct m0_dix_cli *cli)
Definition: client.c:105
M0_INTERNAL const char * m0_sm_state_name(const struct m0_sm *mach, int state)
Definition: sm.c:781
M0_INTERNAL int m0_dix_root_read_rep(struct m0_dix_meta_req *req, struct m0_dix_ldesc *layout, struct m0_dix_ldesc *ldescr)
Definition: meta.c:443
static struct m0_sm_group * dix_cli_smgrp(const struct m0_dix_cli *cli)
Definition: client.c:88
#define M0_BITS(...)
Definition: misc.h:236
Definition: sm.h:504
struct m0_pool_version * dx_pver
Definition: client.h:190
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
void(* dx_sync_rec_update)(struct m0_dix_req *, struct m0_rpc_session *, struct m0_be_tx_remid *)
Definition: client.h:202
struct m0_clink dx_clink
Definition: client.h:184
static struct m0_pools_common pc
Definition: iter_ut.c:59
M0_INTERNAL int m0_sm_timedwait(struct m0_sm *mach, uint64_t states, m0_time_t deadline)
Definition: sm.c:387
return M0_RC(rc)
#define M0_ENTRY(...)
Definition: trace.h:170
static struct m0_sm_ast ast[NR]
Definition: locality.c:44
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
struct m0_dtm0_service * dx_dtms
Definition: client.h:195
M0_INTERNAL void m0_dix_cli_unlock(struct m0_dix_cli *cli)
Definition: client.c:99
void * sa_datum
Definition: sm.h:508
static struct m0_sm_trans_descr dix_cli_trans[]
Definition: client.c:70
struct m0_fid pv_id
Definition: pool.h:113
M0_INTERNAL void m0_dix_cli_fini(struct m0_dix_cli *cli)
Definition: client.c:268
M0_INTERNAL void m0_dix_cli_lock(struct m0_dix_cli *cli)
Definition: client.c:93
const char * scf_name
Definition: sm.h:352
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
Definition: mutex.c:95
struct m0_dix_ldesc dx_ldescr
Definition: client.h:194
M0_INTERNAL int m0_dix_cli_start_sync(struct m0_dix_cli *cli)
Definition: client.c:221
struct m0_fid pver
Definition: idx_dix.c:74
void m0_sm_state_set(struct m0_sm *mach, int state)
Definition: sm.c:478
struct m0_dix_ldesc dx_root
Definition: client.h:192
static void dix_cli_failure(struct m0_dix_cli *cli, int32_t rc)
Definition: client.c:115
M0_INTERNAL int m0_dix_ldesc_init(struct m0_dix_ldesc *ld, struct m0_ext *range, m0_bcount_t range_nr, enum m0_dix_hash_fnc_type htype, struct m0_fid *pver)
Definition: layout.c:171
struct m0_sm_group * sm_grp
Definition: sm.h:321
M0_INTERNAL void m0_dix_meta_req_fini(struct m0_dix_meta_req *req)
Definition: meta.c:285
M0_INTERNAL int m0_dix__ldescr_set(const struct m0_dix_cli *cli, struct m0_dix *out)
Definition: client.c:302
struct m0_sm dx_sm
Definition: client.h:183
uint32_t dl_type
Definition: layout.h:100
int32_t sm_rc
Definition: sm.h:336
M0_INTERNAL void m0_dix_cli_start(struct m0_dix_cli *cli)
Definition: client.c:214
static void dix_cli_start_ast_cb(struct m0_sm_group *grp M0_UNUSED, struct m0_sm_ast *ast)
Definition: client.c:190
struct m0_mutex s_lock
Definition: sm.h:514
struct m0_dix_ldesc dx_layout
Definition: client.h:193
union m0_dix_layout::@145 u
struct m0_layout_domain * dx_ldom
Definition: client.h:188
static const struct m0_sm_conf dix_cli_sm_conf
Definition: client.c:80
M0_INTERNAL int m0_dix_cli_init(struct m0_dix_cli *cli, struct m0_sm_group *sm_group, struct m0_pools_common *pc, struct m0_layout_domain *ldom, const struct m0_fid *pver)
Definition: client.c:130
M0_INTERNAL void m0_dix_ldesc_fini(struct m0_dix_ldesc *ld)
Definition: layout.c:197
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
uint32_t sd_flags
Definition: sm.h:378
struct m0_pools_common * dx_pc
Definition: client.h:187
M0_INTERNAL void m0_dix_cli_bootstrap_lock(struct m0_dix_cli *cli)
Definition: client.c:245
struct m0_sm_ast dx_ast
Definition: client.h:191
m0_dix_cli_state
Definition: client.h:172
Definition: ext.h:37
Definition: fid.h:38
M0_INTERNAL const struct m0_fid m0_dix_ldescr_fid
Definition: meta.c:46
M0_INTERNAL void m0_sm_init(struct m0_sm *mach, const struct m0_sm_conf *conf, uint32_t state, struct m0_sm_group *grp)
Definition: sm.c:313
static void dix_meta_read_ast_cb(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: client.c:163
M0_INTERNAL int m0_dix_meta_generic_rc(const struct m0_dix_meta_req *req)
Definition: meta.c:309
static void dix_cli_ast_post(struct m0_dix_cli *cli, void(*cb)(struct m0_sm_group *, struct m0_sm_ast *))
Definition: client.c:152
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
M0_INTERNAL void m0_dix_cli_bootstrap(struct m0_dix_cli *cli)
Definition: client.c:237
static bool dix_cli_meta_read_clink_cb(struct m0_clink *cl)
Definition: client.c:181
M0_INTERNAL struct m0_pool_version * m0_dix_pver(const struct m0_dix_cli *cli, const struct m0_dix *dix)
Definition: client.c:309
M0_INTERNAL void m0_dix_cli_fini_lock(struct m0_dix_cli *cli)
Definition: client.c:278
#define out(...)
Definition: gen.c:41
struct m0_chan dmr_chan
Definition: meta.h:97
uint32_t sm_state
Definition: sm.h:307
M0_INTERNAL const struct m0_fid m0_dix_root_fid
Definition: meta.c:44
M0_INTERNAL void m0_dix_cli_stop(struct m0_dix_cli *cli)
Definition: client.c:253
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
Definition: req.h:110
M0_INTERNAL void m0_sm_fini(struct m0_sm *mach)
Definition: sm.c:331
#define M0_UNUSED
Definition: misc.h:380