Motr  M0
helpers.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_SNSCM
24 
25 #include "lib/trace.h"
26 #include "lib/misc.h"
27 
28 #include "fid/fid.h"
29 
30 #include "cm/proxy.h"
31 
32 #include "sns/parity_repair.h"
33 #include "sns/cm/cm_utils.h"
34 #include "sns/cm/ag.h"
35 #include "sns/cm/file.h"
36 #include "pool/pool.h"
37 
38 M0_INTERNAL int m0_sns_cm_rebalance_ag_setup(struct m0_sns_cm_ag *sag,
39  struct m0_pdclust_layout *pl);
40 
41 static bool is_spare_relevant(const struct m0_sns_cm *scm,
42  struct m0_sns_cm_file_ctx *fctx,
43  uint64_t group, uint32_t spare,
44  uint32_t *incoming_unit);
45 
46 static int cob_to_proxy(struct m0_fid *cobfid, const struct m0_cm *cm,
47  struct m0_poolmach *pm, struct m0_cm_proxy **pxy)
48 {
49  struct m0_conf_obj *s;
50  struct m0_cm_proxy *p;
51  const char *ep;
52  int rc;
53 
54  M0_PRE(m0_fid_is_set(cobfid));
55  M0_PRE(cm != NULL && pm != NULL);
56 
57  ep = m0_sns_cm_tgt_ep(cm, pm->pm_pver, cobfid, &s);
58  p = m0_tl_find(proxy, p, &cm->cm_proxies,
59  m0_streq(ep, p->px_endpoint));
61  if (M0_IN(p->px_status, (M0_PX_STOP, M0_PX_FAILED))) {
62  rc = p->px_status == M0_PX_STOP ? -ESHUTDOWN : -EHOSTDOWN;
63  return M0_ERR(rc);
64  }
65  *pxy = p;
66 
67  return 0;
68 }
69 
70 static int rebalance_ag_in_cp_units(const struct m0_sns_cm *scm,
71  const struct m0_cm_ag_id *id,
72  struct m0_sns_cm_file_ctx *fctx,
73  uint32_t *in_cp_nr,
74  uint32_t *in_units_nr,
75  struct m0_cm_proxy_in_count *pcount)
76 {
77  struct m0_fid cobfid;
78  struct m0_fid gfid;
79  struct m0_pdclust_src_addr sa;
80  struct m0_pdclust_tgt_addr ta;
81  struct m0_cm_proxy *pxy;
82  const struct m0_cm *cm;
83  struct m0_pdclust_layout *pl;
84  struct m0_poolmach *pm;
85  uint32_t incps = 0;
86  uint32_t tgt_unit;
87  uint32_t tgt_unit_prev;
88  uint64_t unit;
89  uint64_t upg;
90  int rc = 0;
91 
92  M0_ENTRY();
93 
94  M0_SET0(&sa);
95  cm = &scm->sc_base;
96  agid2fid(id, &gfid);
97  sa.sa_group = agid2group(id);
99  pm = fctx->sf_pm;
100  upg = m0_sns_cm_ag_size(pl);
101  for (unit = 0; unit < upg; ++unit) {
102  sa.sa_unit = unit;
103  M0_SET0(&ta);
104  M0_SET0(&cobfid);
105  M0_ASSERT(pm != NULL);
106  m0_sns_cm_unit2cobfid(fctx, &sa, &ta, &cobfid);
107  if (!scm->sc_helpers->sch_is_cob_failed(pm, ta.ta_obj))
108  continue;
109  if (!m0_sns_cm_is_local_cob(cm, pm->pm_pver, &cobfid))
110  continue;
111  if (m0_pdclust_unit_classify(pl, unit) == M0_PUT_SPARE) {
112  if (is_spare_relevant(scm, fctx, sa.sa_group, unit,
113  &tgt_unit)) {
114  if (pcount != NULL) {
115  M0_SET0(&ta);
116  M0_SET0(&cobfid);
117  sa.sa_unit = tgt_unit;
118  m0_sns_cm_unit2cobfid(fctx, &sa, &ta,
119  &cobfid);
120  rc = cob_to_proxy(&cobfid, cm, pm, &pxy);
121  if (rc != 0)
122  return M0_ERR(rc);
123  M0_CNT_INC(pcount->p_count[pxy->px_id]);
124  }
125  M0_CNT_INC(incps);
126  }
127  continue;
128  }
131  sa.sa_group, unit, &tgt_unit,
132  &tgt_unit_prev);
134  if (rc != 0)
135  return M0_ERR(rc);
136  M0_SET0(&ta);
137  M0_SET0(&cobfid);
138  sa.sa_unit = tgt_unit;
139  m0_sns_cm_unit2cobfid(fctx, &sa, &ta, &cobfid);
140  if (!m0_sns_cm_is_local_cob(cm, pm->pm_pver, &cobfid)) {
141  if (pcount != NULL) {
142  rc = cob_to_proxy(&cobfid, cm, pm, &pxy);
143  if (rc != 0)
144  return M0_ERR(rc);
145  M0_CNT_INC(pcount->p_count[pxy->px_id]);
146  }
147  M0_CNT_INC(incps);
148  }
149  }
150 
151  *in_cp_nr = *in_units_nr = incps;
152 
153  M0_LEAVE("incps=%u", (unsigned)incps);
154  return M0_RC(rc);
155 }
156 
157 static uint64_t rebalance_ag_unit_start(const struct m0_pdclust_layout *pl)
158 {
159  return m0_sns_cm_ag_spare_unit_nr(pl, 0);
160 }
161 
162 static uint64_t rebalance_ag_unit_end(const struct m0_pdclust_layout *pl)
163 {
164  return m0_sns_cm_ag_size(pl);
165 }
166 
167 static int _tgt_check_and_change(struct m0_sns_cm_ag *sag, struct m0_poolmach *pm,
168  struct m0_pdclust_layout *pl,
169  uint64_t data_unit, uint32_t old_tgt_dev,
170  uint64_t *new_tgt_unit)
171 {
172  uint64_t group = agid2group(&sag->sag_base.cag_id);
173  uint32_t spare;
174  uint32_t spare_prev;
175  struct m0_sns_cm_file_ctx *fctx;
176  int rc;
177 
178  fctx = sag->sag_fctx;
181  group, data_unit, &spare,
182  &spare_prev);
184  if (rc == 0)
185  *new_tgt_unit = spare;
186 
187  return M0_RC(rc);
188 }
189 
191  struct m0_sns_cm_cp *scp)
192 {
193  struct m0_pdclust_layout *pl;
194  struct m0_fid cobfid;
195  struct m0_sns_cm_file_ctx *fctx;
196  struct m0_poolmach *pm;
197  uint64_t group = agid2group(&sag->sag_base.cag_id);
198  uint64_t data_unit;
199  uint64_t offset;
200  uint32_t dev_idx;
201  int rc = 0;
202 
203  fctx = sag->sag_fctx;
204  pm = fctx->sf_pm;
206  data_unit = scp->sc_base.c_ag_cp_idx;
207  dev_idx = m0_sns_cm_device_index_get(group, data_unit, fctx);
208  if (!m0_sns_cm_is_cob_rebalancing(pm, dev_idx)) {
209  rc = _tgt_check_and_change(sag, pm, pl, data_unit, dev_idx,
210  &data_unit);
211  if (rc != 0) {
212  M0_LOG(M0_DEBUG, "Target device %u not rebalancing,"
213  "no other rebalancing target found.",
214  (unsigned)dev_idx);
215  return M0_RC(rc);
216  }
217  scp->sc_base.c_ag_cp_idx = data_unit;
218  }
219 
221  if (rc == 0) {
224  /*
225  * Change the target cobfid and offset of the copy
226  * packet to write the data from spare unit back to
227  * previously failed data unit but now available data/
228  * parity unit in the aggregation group.
229  */
232  }
233 
234  return M0_RC(rc);
235 }
236 
237 static bool is_spare_relevant(const struct m0_sns_cm *scm,
238  struct m0_sns_cm_file_ctx *fctx,
239  uint64_t group, uint32_t spare,
240  uint32_t *incoming_unit)
241 {
242  struct m0_pdclust_src_addr sa;
243  struct m0_pdclust_tgt_addr ta;
244  struct m0_fid cobfid;
245  uint32_t dev_idx;
246  uint64_t data;
247  uint32_t spare_prev;
248  struct m0_poolmach *pm;
249  struct m0_pdclust_layout *pl;
250  struct m0_pdclust_instance *pi;
251  int rc;
252 
254  pi = fctx->sf_pi;
255  pm = fctx->sf_pm;
257  rc = m0_sns_repair_data_map(pm, pl, pi, group, spare, &data);
259  if (rc == 0) {
261  if (m0_sns_cm_is_cob_repaired(pm, dev_idx)) {
263  rc = m0_sns_repair_spare_map(pm, &fctx->sf_fid, pl, pi,
264  group, data, &spare,
265  &spare_prev);
267  if (rc == 0) {
268  sa.sa_unit = spare;
269  sa.sa_group = group;
270  m0_sns_cm_unit2cobfid(fctx, &sa, &ta, &cobfid);
272  pm->pm_pver,
273  &cobfid)) {
274  *incoming_unit = spare;
275  return true;
276  }
277  }
278  }
279  }
280  return false;
281 }
282 
284  struct m0_sns_cm_file_ctx *fctx,
285  uint64_t group)
286 {
287  uint32_t spare;
288  uint32_t spare_prev;
289  struct m0_pdclust_src_addr sa;
290  struct m0_pdclust_tgt_addr ta;
291  struct m0_fid cobfid;
292  uint64_t upg;
293  uint32_t i;
294  uint32_t tunit;
295  uint32_t in_unit;
296  struct m0_poolmach *pm;
297  struct m0_pdclust_layout *pl;
298  int rc;
299 
300  M0_PRE(fctx != NULL);
301 
303  upg = m0_sns_cm_ag_size(pl);
304  sa.sa_group = group;
305  pm = fctx->sf_pm;
306  for (i = 0; i < upg; ++i) {
307  sa.sa_unit = i;
308  m0_sns_cm_unit2cobfid(fctx, &sa, &ta, &cobfid);
309  if (m0_sns_cm_is_cob_rebalancing(pm, ta.ta_obj) &&
311  &cobfid)) {
312  tunit = sa.sa_unit;
313  if (m0_pdclust_unit_classify(pl, tunit) ==
314  M0_PUT_SPARE) {
315  if (!is_spare_relevant(scm, fctx, group, tunit,
316  &in_unit))
317  continue;
318  }
321  pl, fctx->sf_pi, group, tunit,
322  &spare, &spare_prev);
324  if (rc != 0)
325  return false;
326  tunit = spare;
327  sa.sa_unit = tunit;
328  m0_sns_cm_unit2cobfid(fctx, &sa, &ta, &cobfid);
330  &cobfid))
331  return true;
332  }
333  }
334 
335  return false;
336 }
337 
338 static int
340  struct m0_poolmach *pm, const struct m0_fid *cob_fid)
341 {
343 }
344 
345 static bool rebalance_is_cob_failed(struct m0_poolmach *pm,
346  uint32_t cob_index)
347 {
348  enum m0_pool_nd_state state_out = 0;
349  M0_PRE(pm != NULL);
350 
351  m0_poolmach_device_state(pm, cob_index, &state_out);
352  return !M0_IN(state_out, (M0_PNDS_ONLINE, M0_PNDS_OFFLINE,
354 }
355 
358  .sch_ag_unit_start = rebalance_ag_unit_start,
359  .sch_ag_unit_end = rebalance_ag_unit_end,
360  .sch_ag_is_relevant = rebalance_ag_is_relevant,
361  .sch_ag_setup = m0_sns_cm_rebalance_ag_setup,
362  .sch_cob_locate = rebalance_cob_locate,
363  .sch_is_cob_failed = rebalance_is_cob_failed
364 };
365 
366 #undef M0_TRACE_SUBSYSTEM
367 
370 /*
371  * Local variables:
372  * c-indentation-style: "K&R"
373  * c-basic-offset: 8
374  * tab-width: 8
375  * fill-column: 80
376  * scroll-step: 1
377  * End:
378  */
Definition: cm.h:205
static struct m0_addb2_philter p
Definition: consumer.c:40
#define M0_PRE(cond)
M0_INTERNAL void m0_sns_cm_unit2cobfid(struct m0_sns_cm_file_ctx *fctx, const struct m0_pdclust_src_addr *sa, struct m0_pdclust_tgt_addr *ta, struct m0_fid *cfid_out)
Definition: cm_utils.c:117
M0_INTERNAL void m0_sns_cm_cp_tgt_info_fill(struct m0_sns_cm_cp *scp, const struct m0_fid *cob_fid, uint64_t stob_offset, uint64_t ag_cp_idx)
Definition: cp.c:357
uint64_t sa_group
Definition: pdclust.h:241
M0_INTERNAL void agid2fid(const struct m0_cm_ag_id *id, struct m0_fid *fid)
Definition: ag.c:405
#define NULL
Definition: misc.h:38
const struct m0_sns_cm_helpers rebalance_helpers
Definition: helpers.c:356
M0_INTERNAL const char * m0_sns_cm_tgt_ep(const struct m0_cm *cm, const struct m0_pool_version *pv, const struct m0_fid *cob_fid, struct m0_conf_obj **hostage)
Definition: cm_utils.c:434
struct m0_pool_version * pm_pver
Definition: pool_machine.h:172
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
M0_INTERNAL bool m0_sns_cm_is_local_cob(const struct m0_cm *cm, const struct m0_pool_version *pv, const struct m0_fid *cob_fid)
Definition: cm_utils.c:449
M0_INTERNAL int m0_sns_repair_spare_map(struct m0_poolmach *pm, const struct m0_fid *fid, struct m0_pdclust_layout *pl, struct m0_pdclust_instance *pi, uint64_t group, uint64_t unit, uint32_t *spare_slot_out, uint32_t *spare_slot_out_prev)
M0_INTERNAL int m0_sns_cm_rebalance_ag_setup(struct m0_sns_cm_ag *sag, struct m0_pdclust_layout *pl)
Definition: ag.c:138
M0_INTERNAL int m0_sns_repair_spare_rebalancing(struct m0_poolmach *pm, const struct m0_fid *fid, struct m0_pdclust_layout *pl, struct m0_pdclust_instance *pi, uint64_t group, uint64_t unit, uint32_t *spare_slot_out, uint32_t *spare_slot_out_prev)
struct m0_bufvec data
Definition: di.c:40
struct m0_layout * sf_layout
Definition: file.h:74
uint64_t ta_obj
Definition: pdclust.h:256
struct m0_cm_ag_id cag_id
Definition: ag.h:72
M0_INTERNAL void m0_sns_cm_fctx_unlock(struct m0_sns_cm_file_ctx *fctx)
Definition: file.c:58
static struct m0_sns_cm * scm
Definition: cm.c:64
struct m0_fid sf_fid
Definition: file.h:63
M0_INTERNAL int m0_poolmach_device_state(struct m0_poolmach *pm, uint32_t device_index, enum m0_pool_nd_state *state_out)
Definition: pool_machine.c:816
uint64_t c_ag_cp_idx
Definition: cp.h:175
#define M0_SET0(obj)
Definition: misc.h:64
M0_INTERNAL int m0_sns_cm_ag_tgt_unit2cob(struct m0_sns_cm_ag *sag, uint64_t tgt_unit, struct m0_fid *cobfid)
Definition: cm_utils.c:381
struct m0_poolmach * sf_pm
Definition: file.h:70
uint32_t * p_count
Definition: proxy.h:154
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
M0_INTERNAL uint64_t m0_sns_cm_ag_unit2cobindex(struct m0_sns_cm_ag *sag, uint64_t unit)
Definition: cm_utils.c:143
static struct m0_cob_domain * cdom
Definition: xform.c:55
return M0_RC(rc)
static struct m0_cm * cm
Definition: cm.c:63
static bool is_spare_relevant(const struct m0_sns_cm *scm, struct m0_sns_cm_file_ctx *fctx, uint64_t group, uint32_t spare, uint32_t *incoming_unit)
Definition: helpers.c:237
Definition: sock.c:754
int(* sch_ag_in_cp_units)(const struct m0_sns_cm *scm, const struct m0_cm_ag_id *id, struct m0_sns_cm_file_ctx *fctx, uint32_t *in_cp_nr, uint32_t *in_units_nr, struct m0_cm_proxy_in_count *pcount)
Definition: cm.h:153
struct m0_tl cm_proxies
Definition: cm.h:246
M0_INTERNAL uint64_t agid2group(const struct m0_cm_ag_id *id)
Definition: ag.c:413
#define M0_ENTRY(...)
Definition: trace.h:170
static struct m0_sns_cm_ag * sag
Definition: cm.c:66
int i
Definition: dir.c:1033
struct m0_cm_cp sc_base
Definition: cp.h:39
M0_INTERNAL bool m0_sns_cm_is_cob_rebalancing(struct m0_poolmach *pm, uint32_t cob_index)
Definition: cm_utils.c:266
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL uint32_t m0_sns_cm_device_index_get(uint64_t group, uint64_t unit_number, struct m0_sns_cm_file_ctx *fctx)
Definition: cm_utils.c:126
static bool rebalance_is_cob_failed(struct m0_poolmach *pm, uint32_t cob_index)
Definition: helpers.c:345
#define M0_ASSERT(cond)
m0_pool_nd_state
Definition: pool_machine.h:57
M0_INTERNAL int m0_sns_cm_cob_locate(struct m0_cob_domain *cdom, const struct m0_fid *cob_fid)
Definition: cm_utils.c:157
#define m0_streq(a, b)
Definition: string.h:34
static uint64_t rebalance_ag_unit_end(const struct m0_pdclust_layout *pl)
Definition: helpers.c:162
static struct m0_fid cob_fid
Definition: net.c:116
M0_INTERNAL struct m0_pdclust_layout * m0_layout_to_pdl(const struct m0_layout *l)
Definition: pdclust.c:382
struct m0_pdclust_instance pi
Definition: fd.c:107
M0_INTERNAL bool m0_sns_cm_is_cob_repaired(struct m0_poolmach *pm, uint32_t cob_index)
Definition: cm_utils.c:246
M0_INTERNAL uint64_t m0_sns_cm_ag_spare_unit_nr(const struct m0_pdclust_layout *pl, uint64_t fidx)
Definition: cm_utils.c:362
M0_INTERNAL int m0_sns_repair_data_map(struct m0_poolmach *pm, struct m0_pdclust_layout *pl, struct m0_pdclust_instance *pi, uint64_t group_number, uint64_t spare_unit_number, uint64_t *data_unit_id_out)
static void group(void)
Definition: sm.c:386
static m0_bindex_t offset
Definition: dump.c:173
M0_INTERNAL void m0_sns_cm_fctx_lock(struct m0_sns_cm_file_ctx *fctx)
Definition: file.c:53
uint64_t px_id
Definition: proxy.h:63
M0_INTERNAL int m0_sns_cm_rebalance_tgt_info(struct m0_sns_cm_ag *sag, struct m0_sns_cm_cp *scp)
Definition: helpers.c:190
static int rebalance_cob_locate(struct m0_sns_cm *scm, struct m0_cob_domain *cdom, struct m0_poolmach *pm, const struct m0_fid *cob_fid)
Definition: helpers.c:339
uint64_t sa_unit
Definition: pdclust.h:243
struct m0_sns_cm_file_ctx * sag_fctx
Definition: ag.h:48
char * ep
Definition: sw.h:132
#define M0_CNT_INC(cnt)
Definition: arith.h:226
Definition: fid.h:38
M0_INTERNAL uint64_t m0_sns_cm_ag_size(const struct m0_pdclust_layout *pl)
Definition: cm_utils.c:239
static struct m0_sns_cm_cp scp
Definition: cm.c:65
Definition: cm.h:166
M0_INTERNAL enum m0_pdclust_unit_type m0_pdclust_unit_classify(const struct m0_pdclust_layout *pl, int unit)
Definition: pdclust.c:425
static int _tgt_check_and_change(struct m0_sns_cm_ag *sag, struct m0_poolmach *pm, struct m0_pdclust_layout *pl, uint64_t data_unit, uint32_t old_tgt_dev, uint64_t *new_tgt_unit)
Definition: helpers.c:167
static bool rebalance_ag_is_relevant(struct m0_sns_cm *scm, struct m0_sns_cm_file_ctx *fctx, uint64_t group)
Definition: helpers.c:283
M0_INTERNAL void m0_confc_close(struct m0_conf_obj *obj)
Definition: confc.c:921
struct m0_cm sc_base
Definition: cm.h:206
static int cob_to_proxy(struct m0_fid *cobfid, const struct m0_cm *cm, struct m0_poolmach *pm, struct m0_cm_proxy **pxy)
Definition: helpers.c:46
struct m0_pdclust_instance * sf_pi
Definition: file.h:77
static struct m0_sns_cm_file_ctx fctx
Definition: net.c:55
struct m0_cm_aggr_group sag_base
Definition: ag.h:46
struct m0_fid gfid
Definition: dir.c:626
#define m0_tl_find(name, var, head,...)
Definition: tlist.h:757
static struct m0_addb2_source * s
Definition: consumer.c:39
static int rebalance_ag_in_cp_units(const struct m0_sns_cm *scm, const struct m0_cm_ag_id *id, struct m0_sns_cm_file_ctx *fctx, uint32_t *in_cp_nr, uint32_t *in_units_nr, struct m0_cm_proxy_in_count *pcount)
Definition: helpers.c:70
bool(* sch_is_cob_failed)(struct m0_poolmach *pm, uint32_t cob_index)
Definition: cm.h:188
const struct m0_sns_cm_helpers * sc_helpers
Definition: cm.h:215
int32_t rc
Definition: trigger_fop.h:47
static uint64_t rebalance_ag_unit_start(const struct m0_pdclust_layout *pl)
Definition: helpers.c:157
Definition: ag.h:49