Motr  M0
active_record.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 
29 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_BE
30 #include "lib/trace.h"
31 
32 #include "lib/string.h" /* m0_streq */
33 #include "be/active_record.h"
34 #include "motr/magic.h"
35 #include "be/op.h"
36 #include "be/seg.h"
37 #include "be/seg0.h"
38 #include "be/domain.h"
39 #include "reqh/reqh.h"
40 #include "module/instance.h"
41 
42 M0_BE_LIST_DESCR_DEFINE(ard, "list of ar_domain_subsystem in ar_domain",
44  rds_link, rds_magic,
47 
48 M0_BE_LIST_DESCR_DEFINE(rds, "list of active_record in ar_domain_subsystem",
49  static, struct m0_be_active_record,
50  ar_link, ar_magic,
52 M0_BE_LIST_DEFINE(rds, static, struct m0_be_active_record);
53 
54 
55 /* ----------------------------------------------------------------------
56  * m0_be_active_record_domain
57  * ---------------------------------------------------------------------- */
58 
59 static int active_record0_init(struct m0_be_domain *dom, const char *suffix,
60  const struct m0_buf *data);
61 static void active_record0_fini(struct m0_be_domain *dom, const char *suffix,
62  const struct m0_buf *data);
63 
64 #define BE_ACTIVE_RECORD_ID "0000"
66  .b0_name = "M0_BE:ACTIVE_RECORD",
67  .b0_init = active_record0_init,
68  .b0_fini = active_record0_fini,
69 };
70 
71 static int active_record0_init(struct m0_be_domain *dom, const char *suffix,
72  const struct m0_buf *data)
73 {
75  *adom = *(struct m0_be_active_record_domain**)data->b_addr;
76  struct m0_reqh
77  *reqh = dom->bd_cfg.bc_engine.bec_reqh;
78  unsigned key;
79 
80  M0_ENTRY("suffix: %s, data: %p, adom: %p", suffix, data->b_addr, adom);
81 
83 
84  if (m0_reqh_lockers_get(reqh, key) == NULL)
85  m0_reqh_lockers_set(reqh, key, adom);
86 
87  return M0_RC(0);
88 }
89 
90 static void active_record0_fini(struct m0_be_domain *dom, const char *suffix,
91  const struct m0_buf *data)
92 {
93  M0_ENTRY();
94  M0_LEAVE();
95 }
96 
97 M0_INTERNAL void
99  struct m0_be_seg *seg)
100 {
102 
103  dom->ard_seg = seg;
104 
105  sub = ard_be_list_head(&dom->ard_list);
106  if (sub == NULL)
107  return;
108 
109  for (;;) {
110  M0_ASSERT(ard_be_list_is_empty(&sub->rds_list));
111  m0_mutex_init(&sub->rds_lock);
112  m0_chan_init(&sub->rds_chan, &sub->rds_lock);
113 
114  sub = ard_be_list_next(&dom->ard_list, sub);
115  if (sub == NULL)
116  break;
117  }
118 }
119 
120 M0_INTERNAL void
122 {
124 
125  sub = ard_be_list_head(&dom->ard_list);
126  if (sub == NULL)
127  return;
128 
129  for (;;) {
130  M0_ASSERT(rds_be_list_is_empty(&sub->rds_list));
132  m0_mutex_fini(&sub->rds_lock);
133 
134  sub = ard_be_list_next(&dom->ard_list, sub);
135  if (sub == NULL)
136  break;
137  }
138 }
139 
140 M0_INTERNAL bool
142 {
143  /* XXX: update later */
144  return dom->ard_seg != NULL;
145 }
146 
147 M0_INTERNAL int
149  struct m0_be_tx *tx,
150  struct m0_be_seg *seg,
151  const struct m0_buf *path)
152 {
153  struct m0_be_domain *bedom = seg->bs_domain;
154  struct m0_buf data = {};
155  int rc;
156  unsigned i;
157 
159  ard_be_list_create(&(*dom)->ard_list, tx);
160 
161  for (i = 0; !m0_buf_eq(&path[i], &M0_BUF_INIT0); ++i) {
163 
164  M0_BE_ALLOC_PTR_SYNC(sub, seg, tx);
165  strncpy(sub->rds_name, path[i].b_addr, path[i].b_nob);
166  rds_be_list_create(&sub->rds_list, tx);
167  ard_be_tlink_create(sub, tx);
168  ard_be_list_add(&(*dom)->ard_list, tx, sub);
169 
170  M0_BE_TX_CAPTURE_PTR(seg, tx, sub);
171  }
172 
174 
178  M0_ASSERT(rc == 0);
179 
180  return M0_RC(0);
181 }
182 
183 M0_INTERNAL int
185  struct m0_be_tx *tx)
186 {
188  struct m0_be_seg *seg = dom->ard_seg;
189  struct m0_be_domain *bedom = seg->bs_domain;
190  int rc;
191 
194  M0_ASSERT(rc == 0);
195 
196  for (;;) {
197  sub = ard_be_list_tail(&dom->ard_list);
198  if (sub == NULL)
199  break;
200 
201  /* no unrecovered records should be in lists */
202  M0_ASSERT(rds_be_list_is_empty(&sub->rds_list));
203 
204  ard_be_list_del(&dom->ard_list, tx, sub);
205  rds_be_list_destroy(&sub->rds_list, tx);
206  ard_be_tlink_destroy(sub, tx);
207  M0_BE_FREE_PTR_SYNC(sub, seg, tx);
208  }
209 
210  ard_be_list_destroy(&dom->ard_list, tx);
212 
213  return M0_RC(0);
214 }
215 
216 M0_INTERNAL void
219  uint8_t subsys_nr,
220  struct m0_be_tx_credit *accum)
221 {
223  struct m0_be_seg *seg = dom->ard_seg;
224  struct m0_be_domain *bedom = seg->bs_domain;
225  struct m0_buf data = {};
226 
227 
228  M0_ASSERT_INFO(M0_IN(op, (RDO_CREATE, RDO_DESTROY)), "op=%d", op);
229  switch(op) {
230  case RDO_CREATE:
232  BE_ACTIVE_RECORD_ID, &data, accum);
234  M0_BE_ALLOC_CREDIT_ARR(&sub, subsys_nr, dom->ard_seg, accum);
235  ard_be_list_credit(M0_BLO_CREATE, 1, accum);
236  rds_be_list_credit(M0_BLO_CREATE, subsys_nr, accum);
237  ard_be_list_credit(M0_BLO_ADD, subsys_nr, accum);
239  subsys_nr);
241  break;
242  case RDO_DESTROY:
244  BE_ACTIVE_RECORD_ID, accum);
246  ard_be_list_credit(M0_BLO_DESTROY, 1, accum);
247 
248  M0_BE_FREE_CREDIT_ARR(&sub, subsys_nr, dom->ard_seg, accum);
249  rds_be_list_credit(M0_BLO_DESTROY, subsys_nr, accum);
250  ard_be_list_credit(M0_BLO_DEL, subsys_nr, accum);
251  break;
252  }
253 }
254 
255 /* ----------------------------------------------------------------------
256  * m0_be_active_record
257  * ---------------------------------------------------------------------- */
258 
259 M0_INTERNAL void
261  struct m0_be_active_record_domain *ar_dom)
262 {
263  rec->ar_dom = ar_dom;
264 }
265 
266 M0_INTERNAL void
268 {
269 }
270 
271 M0_INTERNAL bool
273 {
274  return rec->ar_dom != NULL;
275 }
276 
277 M0_INTERNAL int
279  struct m0_be_tx *tx,
280  struct m0_be_active_record_domain *ar_dom)
281 {
282  M0_BE_ALLOC_PTR_SYNC(*rec, ar_dom->ard_seg, tx);
283  *(*rec) = (struct m0_be_active_record) {
284  .ar_tx_id = 0,
285  .ar_rec_type = ART_NORM,
286  .ar_dom = ar_dom,
287  };
288 
289  rds_be_tlink_create(*rec, tx);
290  M0_BE_TX_CAPTURE_PTR(ar_dom->ard_seg, tx, *rec);
291 
292  return M0_RC(0);
293 }
294 
295 M0_INTERNAL int
297  struct m0_be_tx *tx)
298 {
299  rds_be_tlink_destroy(rec, tx);
300  M0_BE_FREE_PTR_SYNC(rec, rec->ar_dom->ard_seg, tx);
301 
302  return M0_RC(0);
303 }
304 
305 M0_INTERNAL void
308  struct m0_be_tx_credit *accum)
309 {
311 
313  ARO_ADD)), "op=%d", op);
314  switch(op) {
315  case ARO_CREATE:
316  M0_BE_ALLOC_CREDIT_PTR(rec, rec->ar_dom->ard_seg, accum);
318  break;
319  case ARO_DESTROY:
320  M0_BE_FREE_CREDIT_PTR(rec, rec->ar_dom->ard_seg, accum);
321  break;
322  case ARO_DEL:
323  rds_be_list_credit(M0_BLO_DEL, 1, accum);
324  break;
325  case ARO_ADD:
326  rds_be_list_credit(M0_BLO_ADD, 1, accum);
327  break;
328  }
329 }
330 
333  const char *subsys)
334 {
336 
337  sub = ard_be_list_head(&dom->ard_list);
338  if (sub == NULL || m0_streq(subsys, sub->rds_name))
339  return sub;
340 
341  for (;;) {
342  sub = ard_be_list_next(&dom->ard_list, sub);
343  if (sub == NULL || m0_streq(subsys, sub->rds_name))
344  break;
345  }
346 
347  return sub;
348 }
349 
350 M0_INTERNAL int
351 m0_be_active_record_add(const char *subsys,
352  struct m0_be_active_record *rec,
353  struct m0_be_tx *tx)
354 {
357 
358  if (sub == NULL)
359  return M0_RC(-ENOENT);
360 
361  rds_be_list_add(&sub->rds_list, tx, rec);
362 
363  return M0_RC(0);
364 }
365 
366 M0_INTERNAL int
367 m0_be_active_record_del(const char *subsys,
368  struct m0_be_active_record *rec,
369  struct m0_be_tx *tx)
370 {
373 
374  if (sub == NULL)
375  return M0_RC(-ENOENT);
376 
377  rds_be_list_del(&sub->rds_list, tx, rec);
378 
379  return M0_RC(0);
380 }
381 
382 #undef M0_TRACE_SUBSYSTEM
383 
386 /*
387  * Local variables:
388  * c-indentation-style: "K&R"
389  * c-basic-offset: 8
390  * tab-width: 8
391  * fill-column: 80
392  * scroll-step: 1
393  * End:
394  */
395 /*
396  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
397  */
#define M0_BE_ALLOC_CREDIT_PTR(ptr, seg, accum)
Definition: alloc.h:355
struct m0_be_domain * bs_domain
Definition: seg.h:82
struct m0_be_list ard_list
Definition: active_record.h:72
#define M0_BE_ALLOC_PTR_SYNC(ptr, seg, tx)
Definition: alloc.h:339
void m0_be_0type_add_credit(struct m0_be_domain *dom, const struct m0_be_0type *zt, const char *suffix, const struct m0_buf *data, struct m0_be_tx_credit *credit)
Definition: seg0.c:139
#define NULL
Definition: misc.h:38
const char * b0_name
Definition: seg0.h:44
M0_BE_LIST_DESCR_DEFINE(ard, "list of ar_domain_subsystem in ar_domain", static, struct m0_be_active_record_domain_subsystem, rds_link, rds_magic, M0_BE_ACT_REC_DOM_MAGIC, M0_BE_ACT_REC_DOM_MAGIC)
M0_INTERNAL bool m0_be_active_record_domain__invariant(struct m0_be_active_record_domain *dom)
void * b_addr
Definition: buf.h:39
M0_INTERNAL bool m0_buf_eq(const struct m0_buf *x, const struct m0_buf *y)
Definition: buf.c:90
M0_LEAVE()
#define M0_BE_ALLOC_CREDIT_ARR(arr, nr, seg, accum)
Definition: alloc.h:363
void m0_be_0type_del_credit(struct m0_be_domain *dom, const struct m0_be_0type *zt, const char *suffix, struct m0_be_tx_credit *credit)
Definition: seg0.c:156
M0_INTERNAL void m0_be_active_record_domain_fini(struct m0_be_active_record_domain *dom)
m0_be_active_record_domain_op
Definition: active_record.h:76
M0_INTERNAL void m0_be_active_record_domain_init(struct m0_be_active_record_domain *dom, struct m0_be_seg *seg)
Definition: active_record.c:98
struct m0_bufvec data
Definition: di.c:40
unsigned i_actrec_dom_key
Definition: instance.h:139
M0_INTERNAL int m0_be_active_record_del(const char *subsys, struct m0_be_active_record *rec, struct m0_be_tx *tx)
#define M0_BE_TX_CAPTURE_PTR(seg, tx, ptr)
Definition: tx.h:505
M0_INTERNAL struct m0 * m0_get(void)
Definition: instance.c:41
#define M0_BE_TX_CREDIT_TYPE(type)
Definition: tx_credit.h:97
M0_BE_LIST_DEFINE(ard, static, struct m0_be_active_record_domain_subsystem)
return M0_RC(rc)
op
Definition: libdemo.c:64
#define M0_ENTRY(...)
Definition: trace.h:170
Definition: buf.h:37
M0_INTERNAL void m0_be_active_record_credit(struct m0_be_active_record *rec, enum m0_be_active_record_op op, struct m0_be_tx_credit *accum)
M0_INTERNAL int m0_be_active_record_destroy(struct m0_be_active_record *rec, struct m0_be_tx *tx)
int i
Definition: dir.c:1033
static struct m0_be_active_record_domain * dom
Definition: active_record.c:34
M0_INTERNAL int m0_be_active_record_add(const char *subsys, struct m0_be_active_record *rec, struct m0_be_tx *tx)
M0_INTERNAL void m0_be_tx_credit_mac(struct m0_be_tx_credit *c, const struct m0_be_tx_credit *c1, m0_bcount_t k)
Definition: tx_credit.c:88
struct m0_be_0type m0_be_active_record0
Definition: active_record.c:65
static void active_record0_fini(struct m0_be_domain *dom, const char *suffix, const struct m0_buf *data)
Definition: active_record.c:90
m0_bcount_t b_nob
Definition: buf.h:38
M0_INTERNAL void m0_chan_init(struct m0_chan *chan, struct m0_mutex *ch_guard)
Definition: chan.c:96
#define M0_ASSERT(cond)
static struct m0_be_active_record_domain_subsystem * be_active_record__subsystem_lookup(struct m0_be_active_record_domain *dom, const char *subsys)
M0_INTERNAL void m0_be_tx_credit_add(struct m0_be_tx_credit *c0, const struct m0_be_tx_credit *c1)
Definition: tx_credit.c:44
#define m0_streq(a, b)
Definition: string.h:34
#define M0_BUF_INIT0
Definition: buf.h:71
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
M0_INTERNAL int m0_be_active_record_domain__create(struct m0_be_active_record_domain **dom, struct m0_be_tx *tx, struct m0_be_seg *seg, const struct m0_buf *path)
Definition: reqh.h:94
struct m0_be_active_record_domain * ar_dom
Definition: active_record.h:49
#define M0_BE_FREE_PTR_SYNC(ptr, seg, tx)
Definition: alloc.h:345
Definition: seg.h:66
M0_INTERNAL void m0_be_active_record_domain_credit(struct m0_be_active_record_domain *dom, enum m0_be_active_record_domain_op op, uint8_t subsys_nr, struct m0_be_tx_credit *accum)
int m0_be_0type_add(struct m0_be_0type *zt, struct m0_be_domain *dom, struct m0_be_tx *tx, const char *suffix, const struct m0_buf *data)
Definition: seg0.c:79
#define BE_ACTIVE_RECORD_ID
Definition: active_record.c:64
M0_INTERNAL void m0_be_active_record_init(struct m0_be_active_record *rec, struct m0_be_active_record_domain *ar_dom)
struct m0_reqh reqh
Definition: rm_foms.c:48
#define M0_BUF_INIT_PTR(p)
Definition: buf.h:69
int m0_be_0type_del(struct m0_be_0type *zt, struct m0_be_domain *dom, struct m0_be_tx *tx, const char *suffix)
Definition: seg0.c:112
M0_INTERNAL int m0_be_active_record_domain_destroy(struct m0_be_active_record_domain *dom, struct m0_be_tx *tx)
m0_be_active_record_op
Definition: active_record.h:81
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
static struct m0_be_seg * seg
Definition: btree.c:40
#define M0_ASSERT_INFO(cond, fmt,...)
static int active_record0_init(struct m0_be_domain *dom, const char *suffix, const struct m0_buf *data)
Definition: active_record.c:71
M0_INTERNAL bool m0_be_active_record__invariant(struct m0_be_active_record *rec)
M0_INTERNAL void m0_chan_fini_lock(struct m0_chan *chan)
Definition: chan.c:112
struct m0_be_seg * ard_seg
Definition: active_record.h:73
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL void m0_be_active_record_fini(struct m0_be_active_record *rec)
#define M0_BE_FREE_CREDIT_ARR(arr, nr, seg, accum)
Definition: alloc.h:367
#define M0_BE_FREE_CREDIT_PTR(ptr, seg, accum)
Definition: alloc.h:359
Definition: tx.h:280
Definition: idx_mock.c:47
M0_INTERNAL int m0_be_active_record_create(struct m0_be_active_record **rec, struct m0_be_tx *tx, struct m0_be_active_record_domain *ar_dom)