Motr  M0
device_foms.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_SSS
23 #include "lib/trace.h"
24 
25 #include "lib/assert.h"
26 #include "lib/misc.h"
27 #include "lib/memory.h"
28 #include "lib/tlist.h"
29 #include "lib/finject.h" /* M0_FI_ENABLED */
30 #include "conf/diter.h"
31 #include "conf/obj.h"
32 #include "conf/obj_ops.h" /* M0_CONF_DIRNEXT */
33 #include "conf/helpers.h" /* m0_conf_sdev_get */
34 #include "fop/fop.h"
35 #include "fop/fom_generic.h"
36 #include "pool/pool.h"
37 #include "pool/pool_machine.h"
38 #include "reqh/reqh.h"
39 #include "sss/device_fops.h"
40 #include "sss/device_foms.h"
41 #ifndef __KERNEL__
42  #include "motr/setup.h" /* m0_cs_storage_devs_get */
43  #include "ioservice/storage_dev.h"
44 #endif
45 
46 extern struct m0_reqh_service_type m0_ios_type;
47 
48 static int sss_device_fom_create(struct m0_fop *fop,
49  struct m0_fom **out,
50  struct m0_reqh *reqh);
51 static int sss_device_fom_tick(struct m0_fom *fom);
52 static void sss_device_fom_fini(struct m0_fom *fom);
53 static size_t sss_device_fom_home_locality(const struct m0_fom *fom);
54 
86 };
87 
91 struct m0_sss_dfom {
93  struct m0_fom ssm_fom;
106  struct m0_fid ssm_fid;
110  struct {
112  struct m0_chan chan;
113  struct m0_clink clink;
114  struct m0_ha_nvec nvec;
115  struct m0_ha_note note;
116  } ssm_ha;
117 };
118 
121  .fo_home_locality = sss_device_fom_home_locality,
122  .fo_fini = sss_device_fom_fini
123 };
124 
127 };
128 
130  [SSS_DFOM_SWITCH]= {
132  .sd_name = "SSS_DFOM_SWITCH",
133  .sd_allowed = M0_BITS(SSS_DFOM_SDEV_OPENING,
140  },
142  .sd_name = "SSS_DFOM_DISK_OPENING",
143  .sd_allowed = M0_BITS(SSS_DFOM_DISK_HA_STATE_GET,
145  },
147  .sd_name = "SSS_DFOM_DISK_HA_STATE_GET",
148  .sd_allowed = M0_BITS(SSS_DFOM_DISK_OPENED,
150  },
152  .sd_name = "SSS_DFOM_DISK_OPENED",
154  },
155  [SSS_DFOM_FS_OPENED]= {
156  .sd_name = "SSS_DFOM_FS_OPENED",
158  },
159  [SSS_DFOM_SDEV_ITER]= {
160  .sd_name = "SSS_DFOM_SDEV_ITER",
161  .sd_allowed = M0_BITS(SSS_DFOM_SWITCH, M0_FOPH_FAILURE),
162  },
164  .sd_name = "SSS_DFOM_SDEV_OPENING",
166  },
168  .sd_name = "SSS_DFOM_ATTACH_STOB",
169  .sd_allowed = M0_BITS(M0_FOPH_TXN_INIT),
170  },
172  .sd_name = "SSS_DFOM_ATTACH_POOL_MACHINE",
173  .sd_allowed = M0_BITS(M0_FOPH_SUCCESS, M0_FOPH_FAILURE),
174  },
176  .sd_name = "SSS_DFOM_DETACH_STOB",
177  .sd_allowed = M0_BITS(SSS_DFOM_DETACH_STOB_WAIT),
178  },
180  .sd_name = "SSS_DFOM_DETACH_STOB_WAIT",
181  .sd_allowed = M0_BITS(M0_FOPH_TXN_INIT),
182  },
184  .sd_name = "SSS_DFOM_DETACH_POOL_MACHINE",
185  .sd_allowed = M0_BITS(M0_FOPH_SUCCESS, M0_FOPH_FAILURE),
186  },
187  [SSS_DFOM_FORMAT]= {
188  .sd_name = "SSS_DFOM_FORMAT",
189  .sd_allowed = M0_BITS(M0_FOPH_SUCCESS, M0_FOPH_FAILURE),
190  },
191 };
192 
194  .scf_name = "sss-device-fom-sm",
195  .scf_nr_states = ARRAY_SIZE(sss_device_fom_phases_desc),
196  .scf_state = sss_device_fom_phases_desc
197 };
198 
199 static int sss_device_fom_create(struct m0_fop *fop,
200  struct m0_fom **out,
201  struct m0_reqh *reqh)
202 {
203  struct m0_sss_dfom *dfom = NULL;
204  struct m0_fop *rep_fop = NULL;
205 
206  M0_ENTRY();
207  M0_PRE(fop != NULL);
208  M0_PRE(out != NULL);
210  M0_PRE(reqh != NULL);
211 
212  if (!M0_FI_ENABLED("fom_alloc_fail"))
213  M0_ALLOC_PTR(dfom);
214  if (!M0_FI_ENABLED("fop_alloc_fail"))
216  if (dfom == NULL || rep_fop == NULL)
217  goto err;
218 
221 
222  *out = &dfom->ssm_fom;
223  M0_LOG(M0_DEBUG, "fom %p", dfom);
224  return M0_RC(0);
225 
226 err:
227  m0_free(rep_fop);
228  m0_free(dfom);
229  return M0_ERR(-ENOMEM);
230 }
231 
232 static void sss_device_fom_fini(struct m0_fom *fom)
233 {
234  struct m0_sss_dfom *dfom;
235 
236  M0_ENTRY();
237  M0_LOG(M0_DEBUG, "fom %p", fom);
238  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
239  m0_fom_fini(fom);
240  m0_free(dfom);
241  M0_LEAVE();
242 }
243 
244 #ifndef __KERNEL__
245 
251 {
252  struct m0_sss_dfom *dfom = container_of(clink, struct m0_sss_dfom,
253  ssm_clink);
254  struct m0_confc_ctx *confc_ctx = &dfom->ssm_confc_ctx;
255 
256  if (m0_confc_ctx_is_completed(confc_ctx)) {
259  m0_fom_wakeup(&dfom->ssm_fom);
260  }
261  return true;
262 }
263 
264 static inline uint32_t sss_dfom_device_cmd(struct m0_sss_dfom *dfom)
265 {
267 }
268 
274 static void sss_device_fom_switch(struct m0_fom *fom)
275 {
276  static const enum sss_device_fom_phases next_phase[][2] = {
282  SSS_DFOM_FORMAT },
283  };
284  uint32_t cmd;
285  struct m0_sss_dfom *dfom = container_of(fom, struct m0_sss_dfom,
286  ssm_fom);
287 
288  M0_ENTRY("fom %p, state %d", fom, m0_fom_phase(fom));
289  M0_PRE(fom != NULL);
292 
293  /* If non native sdev (by IO service) then ignore STOB stage */
294  if (dfom->ssm_stage == SSS_DEVICE_FOM_STAGE_STOB &&
295  !dfom->ssm_native_device) {
296  /*
297  * Foreign disk->sdev (i.e. not of current IO service)
298  * ==> do not proceed to STOB stage.
299  */
301  } else {
302  cmd = sss_dfom_device_cmd(dfom);
304  m0_fom_phase_set(fom, next_phase[cmd][dfom->ssm_stage]);
305  }
306  ++dfom->ssm_stage;
307 }
308 
309 static int sss_confc_ctx_init(struct m0_sss_dfom *dfom)
310 {
311  struct m0_confc_ctx *ctx = &dfom->ssm_confc_ctx;
312  struct m0_confc *confc = m0_reqh2confc(m0_fom_reqh(&dfom->ssm_fom));
313  int rc;
314 
316  M0_POST(ergo(rc == 0, confc == ctx->fc_confc));
317  return M0_RC(rc);
318 }
319 
321  struct m0_fid *fid)
322 {
323  struct m0_confc_ctx *ctx = &dfom->ssm_confc_ctx;
324  int rc;
325 
326  rc = sss_confc_ctx_init(dfom);
327  if (rc == 0) {
329  m0_clink_add_lock(&ctx->fc_mach.sm_chan, &dfom->ssm_clink);
331  }
332  return M0_RC(rc);
333 }
334 
336 {
337  struct m0_sss_dfom *dfom;
338  struct m0_fid *disk_fid;
339 
340  M0_ENTRY();
341  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
342  disk_fid = &m0_sss_fop_to_dev_req(fom->fo_fop)->ssd_fid;
343  return M0_RC(sss_device_fom_conf_obj_open(dfom, disk_fid));
344 }
345 
347 {
348  struct m0_sss_dfom *dfom;
349 
350  M0_ENTRY();
351  dfom = container_of(link, struct m0_sss_dfom, ssm_ha.clink);
352  /*
353  * Here we just wake the fom up doing nothing else. It's not possible to
354  * finalise HA retrieval context right here as long as we are in the
355  * chan callback.
356  *
357  * Context finalisation as well as state acceptance are going to be done
358  * later. See sss_disk_info_use().
359  */
360  m0_fom_wakeup(&dfom->ssm_fom);
361  M0_LEAVE();
362  return true;
363 }
364 
365 static void sss_device_fom_ha_init(struct m0_sss_dfom *dfom,
366  struct m0_fid *fid)
367 {
369  m0_chan_init(&dfom->ssm_ha.chan, &dfom->ssm_ha.chan_lock);
370  m0_clink_init(&dfom->ssm_ha.clink,
372  m0_clink_add_lock(&dfom->ssm_ha.chan, &dfom->ssm_ha.clink);
373 
374  dfom->ssm_ha.note.no_id = *fid;
376  dfom->ssm_ha.nvec.nv_nr = 1;
377  dfom->ssm_ha.nvec.nv_note = &dfom->ssm_ha.note;
378 }
379 
380 static void sss_device_fom_ha_fini(struct m0_sss_dfom *dfom)
381 {
383  m0_clink_fini(&dfom->ssm_ha.clink);
385  m0_chan_fini(&dfom->ssm_ha.chan);
388 }
389 
390 static void sss_device_fom_ha_update(struct m0_sss_dfom *dfom)
391 {
392  struct m0_conf_obj *obj = dfom->ssm_confc_ctx.fc_result;
393  struct m0_sss_device_fop_rep *rep =
395 
396  M0_PRE(obj != NULL);
397  M0_PRE(m0_fid_eq(&obj->co_id, &dfom->ssm_ha.note.no_id));
399  M0_PRE(rep->ssdp_ha_state == M0_NC_UNKNOWN);
400 
401  rep->ssdp_ha_state = obj->co_ha_state;
402  m0_ha_state_accept(&dfom->ssm_ha.nvec, false);
403  /*
404  * Now we need to make sure the state has been successfully applied to
405  * the object we are to deal with later. This implies the dfom operates
406  * with a confc registered as an HA client, i.e. m0_ha_client_add() was
407  * done for the confc instance.
408  */
409  M0_POST(obj->co_ha_state == dfom->ssm_ha.note.no_state);
410 }
411 
416 {
417  struct m0_sss_dfom *dfom;
418  struct m0_fid *disk_fid;
419  int rc;
420 
421  M0_ENTRY();
422  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
423  disk_fid = &m0_sss_fop_to_dev_req(fom->fo_fop)->ssd_fid;
424  sss_device_fom_ha_init(dfom, disk_fid);
425  rc = m0_ha_state_get(&dfom->ssm_ha.nvec, &dfom->ssm_ha.chan);
426  if (rc != 0)
428  return M0_RC(rc);
429 }
430 
431 static int sss_disk_info_use(struct m0_sss_dfom *dfom)
432 {
433  struct m0_confc_ctx *ctx = &dfom->ssm_confc_ctx;
434  struct m0_conf_drive *disk;
435  int rc;
436 
437  if (sss_dfom_device_cmd(dfom) == M0_DEVICE_ATTACH) {
438  /* complete previous phase now with unlocked context */
441  }
442 
444  if (rc == 0) {
446  dfom->ssm_fid = disk->ck_sdev->sd_obj.co_id;
447  m0_confc_close(&disk->ck_obj);
448  }
450  return M0_RC(rc);
451 }
452 
458 {
459  struct m0_sss_dfom *dfom = container_of(fom, struct m0_sss_dfom,
460  ssm_fom);
461  struct m0_confc_ctx *ctx = &dfom->ssm_confc_ctx;
463  int rc;
464 
465  M0_ENTRY();
466  M0_PRE(confc == ctx->fc_confc);
467 
468  rc = sss_disk_info_use(dfom) ?: sss_confc_ctx_init(dfom);
469  if (rc == 0) {
471  m0_clink_add_lock(&ctx->fc_mach.sm_chan, &dfom->ssm_clink);
473  }
474  return M0_RC(rc);
475 }
476 
477 static bool _obj_is_sdev(const struct m0_conf_obj *obj)
478 {
480 }
481 
482 static bool sss_device_find_has_svc(struct m0_fom *fom, struct m0_fid *svc_fid)
483 {
484  struct m0_reqh *reqh = m0_fom_reqh(fom);
485  struct m0_reqh_service *svc = m0_reqh_service_lookup(reqh, svc_fid);
486 
487  return svc != NULL && svc->rs_type == &m0_ios_type;
488 }
489 
496 {
497  struct m0_sss_dfom *dfom;
498  struct m0_conf_obj *obj;
499  struct m0_fid svc_fid;
500  int rc;
501 
502  M0_ENTRY();
503 
504  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
505 
506  while ((rc = m0_conf_diter_next(&dfom->ssm_it, _obj_is_sdev)) ==
507  M0_CONF_DIRNEXT) {
508  obj = m0_conf_diter_result(&dfom->ssm_it);
509  if (m0_fid_eq(&dfom->ssm_fid, &obj->co_id)) {
510  svc_fid = m0_conf_obj_grandparent(obj)->co_id;
512  &dfom->ssm_fom, &svc_fid);
513  rc = M0_CONF_DIREND;
514  break;
515  }
516  }
517 
518  /*
519  * If rc == M0_CONF_DIRMISS, then ios_start_disk_iter_cb() will be
520  * called once directory entry is loaded
521  */
522  if (rc != M0_CONF_DIRMISS) {
523  /* End of directory or error */
525  m0_clink_fini(&dfom->ssm_clink);
526  m0_conf_diter_fini(&dfom->ssm_it);
529  }
530  return M0_RC(rc);
531 }
532 
534 {
535  struct m0_sss_dfom *dfom = container_of(clink, struct m0_sss_dfom,
536  ssm_clink);
537  m0_fom_wakeup(&dfom->ssm_fom);
538  return true;
539 }
540 
542  struct m0_conf_obj **root_obj)
543 {
544  struct m0_confc_ctx *confc_ctx = &dfom->ssm_confc_ctx;
545  int rc;
546 
547  rc = m0_confc_ctx_error_lock(confc_ctx);
548  if (rc == 0)
549  *root_obj = m0_confc_ctx_result(confc_ctx);
550  return M0_RC(rc);
551 }
552 
554  struct m0_conf_obj *root_obj)
555 {
556  struct m0_confc *confc = m0_reqh2confc(m0_fom_reqh(&dfom->ssm_fom));
557  int rc;
558 
559  rc = m0_conf_diter_init(&dfom->ssm_it, confc, root_obj,
560  M0_CONF_ROOT_NODES_FID,
561  M0_CONF_NODE_PROCESSES_FID,
562  M0_CONF_PROCESS_SERVICES_FID,
563  M0_CONF_SERVICE_SDEVS_FID);
564  m0_confc_close(root_obj);
565  if (rc == 0) {
567  m0_clink_add_lock(&dfom->ssm_it.di_wait, &dfom->ssm_clink);
569  }
570  return M0_RC(rc);
571 }
572 
578 {
579  struct m0_sss_dfom *dfom = container_of(fom, struct m0_sss_dfom,
580  ssm_fom);
581  struct m0_conf_obj *root_obj = NULL;
582  int rc;
583 
584  M0_ENTRY();
585 
586  rc = sss_device_fom_root_info_use(dfom, &root_obj) ?:
587  sss_device_fom_sdev_iter_init(dfom, root_obj) ?:
589  if (!M0_IN(rc, (0, M0_CONF_DIRMISS, M0_CONF_DIREND)))
591  return M0_RC(rc);
592 }
593 
595 {
596  struct m0_sss_dfom *dfom;
597 
598  M0_ENTRY();
599  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
600  return M0_RC(sss_device_fom_conf_obj_open(dfom, &dfom->ssm_fid));
601 }
602 
603 static int sss_device_stob_attach(struct m0_fom *fom)
604 {
605  struct m0_sss_dfom *dfom;
606  struct m0_storage_devs *devs = m0_cs_storage_devs_get();
607  struct m0_storage_dev *dev;
608  struct m0_storage_dev *dev_new = NULL;
609  struct m0_confc_ctx *confc_ctx;
610  struct m0_conf_sdev *sdev;
611  int rc;
612 
613  M0_ENTRY();
614  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
615  confc_ctx = &dfom->ssm_confc_ctx;
616  rc = m0_confc_ctx_error_lock(confc_ctx);
617  if (rc != 0)
618  goto out;
619  sdev = M0_CONF_CAST(m0_confc_ctx_result(confc_ctx),
620  m0_conf_sdev);
621  M0_LOG(M0_DEBUG, "sdev fid"FID_F"device index:%d",
622  FID_P(&sdev->sd_obj.co_id), (int)sdev->sd_dev_idx);
623  m0_storage_devs_lock(devs);
624  dev = m0_storage_devs_find_by_cid(devs, sdev->sd_dev_idx);
626  if (dev != NULL) {
627  rc = M0_ERR(-EEXIST);
628  goto confc_close;
629  }
630  /*
631  * Enclose domain creation into m0_fom_block_{enter,leave}()
632  * block since it is possibly long operation.
633  */
635  rc = m0_storage_dev_new_by_conf(devs, sdev, false, &dev_new);
637  if (rc == 0) {
638  m0_storage_devs_lock(devs);
639  /*
640  * There is a race window where the devs is unlocked above.
641  * But current fom is the only place where a storage device
642  * can be attached "on fly". Therefore, there is no user that
643  * would try to create and attach storage device with the
644  * same cid.
645  */
646  m0_storage_dev_attach(dev_new, devs);
648  }
649 confc_close:
650  m0_confc_close(&sdev->sd_obj);
651 out:
653  return M0_RC(rc);
654 }
655 
657 {
658  struct m0_sss_dfom *dfom = container_of(fom, struct m0_sss_dfom,
659  ssm_fom);
660  M0_ENTRY();
662  &fom->fo_tx.tx_betx,
663  &dfom->ssm_fid,
664  M0_PNDS_ONLINE));
665 }
666 
668 {
669  struct m0_sss_dfom *dfom = container_of(fom, struct m0_sss_dfom,
670  ssm_fom);
671  M0_ENTRY();
673  &fom->fo_tx.tx_betx,
674  &dfom->ssm_fid,
675  M0_PNDS_OFFLINE));
676 }
677 
678 /*
679  * Find and detach m0_storage_dev object. If arm_wakeup is true the fom
680  * is armed to wakeup when stob detach operation is completed.
681  */
682 static int sss_device_stob_detach(struct m0_fom *fom, bool arm_wakeup)
683 {
684  struct m0_sss_dfom *dfom;
685  struct m0_storage_devs *devs = m0_cs_storage_devs_get();
686  struct m0_storage_dev *dev;
687  int rc;
689  struct m0_conf_sdev *sdev;
690 
691  M0_ENTRY();
692  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
693  rc = m0_conf_sdev_get(confc, &dfom->ssm_fid, &sdev);
694  if (rc != 0)
695  return M0_ERR(rc);
696  M0_LOG(M0_DEBUG, "sdev="FID_F" dev_id=%u", FID_P(&sdev->sd_obj.co_id),
697  sdev->sd_dev_idx);
698  m0_storage_devs_lock(devs);
699  dev = m0_storage_devs_find_by_cid(devs, sdev->sd_dev_idx);
700  if (dev == NULL)
701  rc = M0_ERR(-ENOENT);
702  else {
703  if (arm_wakeup) {
706  &fom->fo_cb);
708  }
710  }
712  m0_confc_close(&sdev->sd_obj);
713  return M0_RC(rc);
714 }
715 
716 static int sss_device_format(struct m0_fom *fom)
717 {
718  struct m0_sss_dfom *dfom;
719  struct m0_storage_devs *devs = m0_cs_storage_devs_get();
720  struct m0_storage_dev *dev;
721  int rc;
723  struct m0_conf_sdev *sdev;
724 
725  M0_ENTRY();
726  dfom = container_of(fom, struct m0_sss_dfom, ssm_fom);
727  rc = m0_conf_sdev_get(confc, &dfom->ssm_fid, &sdev);
728  if (rc != 0)
729  return M0_ERR(rc);
730  M0_LOG(M0_DEBUG, "sdev="FID_F" dev_id=%u", FID_P(&sdev->sd_obj.co_id),
731  sdev->sd_dev_idx);
732  m0_storage_devs_lock(devs);
733  dev = m0_storage_devs_find_by_cid(devs, sdev->sd_dev_idx);
734  /*
735  * Note. If device not attached yet then dev equal NULL.
736  */
737  rc = m0_storage_dev_format(dev, sdev->sd_dev_idx);
739  m0_confc_close(&sdev->sd_obj);
740  return M0_RC(rc);
741 }
742 
752 static int sss_device_fom_tick(struct m0_fom *fom)
753 {
754  struct m0_sss_device_fop_rep *rep;
755  struct m0_sss_dfom *dfom = container_of(fom,
756  struct m0_sss_dfom, ssm_fom);
757 
758  M0_ENTRY("fom %p, state %d", fom, m0_fom_phase(fom));
759  M0_PRE(fom != NULL);
760 
761  /* first handle generic phase */
762  if (m0_fom_phase(fom) < M0_FOPH_NR) {
764  /* If stage "work with stob" then goto custom phases */
765  if (dfom->ssm_stage == SSS_DEVICE_FOM_STAGE_STOB) {
768  return M0_FSO_AGAIN;
769  }
770  }
771  return m0_fom_tick_generic(fom);
772  }
773 
774  rep = m0_sss_fop_to_dev_rep(fom->fo_rep_fop);
775 
776  switch (m0_fom_phase(fom)) {
777 
779  rep->ssdp_rc = sss_device_fom_disk_opening(fom);
780  m0_fom_phase_moveif(fom, rep->ssdp_rc,
783  return rep->ssdp_rc == 0 ? M0_FSO_WAIT : M0_FSO_AGAIN;
784 
786  if (sss_dfom_device_cmd(dfom) != M0_DEVICE_ATTACH) {
788  return M0_FSO_AGAIN;
789  }
791  m0_fom_phase_moveif(fom, rep->ssdp_rc,
793  return rep->ssdp_rc == 0 ? M0_FSO_WAIT : M0_FSO_AGAIN;
794 
796  rep->ssdp_rc = sss_device_fom_disk_opened(fom);
797  m0_fom_phase_moveif(fom, rep->ssdp_rc,
799  return rep->ssdp_rc == 0 ? M0_FSO_WAIT : M0_FSO_AGAIN;
800 
801  case SSS_DFOM_FS_OPENED:
802  rep->ssdp_rc = sss_device_fom_fs_opened(fom);
803  if (!M0_IN(rep->ssdp_rc, (M0_CONF_DIRMISS, M0_CONF_DIREND)))
805  return rep->ssdp_rc == M0_CONF_DIRMISS ? M0_FSO_WAIT :
806  M0_FSO_AGAIN;
807 
808  case SSS_DFOM_SDEV_ITER:
809  rep->ssdp_rc = sss_device_fom_sdev_iter(fom);
810  if (!M0_IN(rep->ssdp_rc, (M0_CONF_DIRMISS, M0_CONF_DIREND)))
812  return rep->ssdp_rc == M0_CONF_DIRMISS ? M0_FSO_WAIT :
813  M0_FSO_AGAIN;
814 
815  case SSS_DFOM_SWITCH:
817  return M0_FSO_AGAIN;
818 
820  rep->ssdp_rc = sss_device_fom_sdev_opening(fom);
821  m0_fom_phase_moveif(fom, rep->ssdp_rc,
823  return rep->ssdp_rc == 0 ? M0_FSO_WAIT : M0_FSO_AGAIN;
824 
826  rep->ssdp_rc = sss_device_stob_attach(fom);
828  return M0_FSO_AGAIN;
829 
832  if (rep->ssdp_rc != 0)
833  sss_device_stob_detach(fom, false);
836  return M0_FSO_AGAIN;
837 
839  /* calls m0_fom_wait_on() inside */
840  rep->ssdp_rc = sss_device_stob_detach(fom, true);
842  return rep->ssdp_rc == 0 ? M0_FSO_WAIT : M0_FSO_AGAIN;
843 
846  return M0_FSO_AGAIN;
847 
852  return M0_FSO_AGAIN;
853 
854  case SSS_DFOM_FORMAT:
855  rep->ssdp_rc = sss_device_format(fom);
858  return M0_FSO_AGAIN;
859 
860  default:
861  M0_IMPOSSIBLE("Invalid phase");
862  }
863  return M0_FSO_AGAIN;
864 }
865 #else
866 static int sss_device_fom_tick(struct m0_fom *fom)
867 {
868  struct m0_sss_device_fop_rep *rep;
869 
870  if (m0_fom_phase(fom) < M0_FOPH_NR)
871  return m0_fom_tick_generic(fom);
872 
873  rep = m0_sss_fop_to_dev_rep(fom->fo_rep_fop);
874  rep->ssdp_rc = M0_ERR(-ENOENT);
876  return M0_FSO_AGAIN;
877 }
878 #endif
879 
880 static size_t sss_device_fom_home_locality(const struct m0_fom *fom)
881 {
882  return 1;
883 }
884 
887 #undef M0_TRACE_SUBSYSTEM
888 
889 /*
890  * Local variables:
891  * c-indentation-style: "K&R"
892  * c-basic-offset: 8
893  * tab-width: 8
894  * fill-column: 80
895  * scroll-step: 1
896  * End:
897  */
const struct m0_conf_obj_type * m0_conf_obj_type(const struct m0_conf_obj *obj)
Definition: obj.c:363
struct m0_fid co_id
Definition: obj.h:208
M0_INTERNAL int m0_ha_state_get(struct m0_ha_nvec *note, struct m0_chan *chan)
Definition: note.c:74
M0_INTERNAL struct m0_storage_dev * m0_storage_devs_find_by_cid(struct m0_storage_devs *devs, uint64_t cid)
Definition: storage_dev.c:152
static int sss_device_fom_conf_obj_open(struct m0_sss_dfom *dfom, struct m0_fid *fid)
Definition: device_foms.c:320
static void sss_device_fom_ha_init(struct m0_sss_dfom *dfom, struct m0_fid *fid)
Definition: device_foms.c:365
void m0_fom_phase_moveif(struct m0_fom *fom, int32_t rc, int phase0, int phase1)
Definition: fom.c:1710
struct m0_fop_type m0_sss_fop_device_rep_fopt
Definition: device_fops.c:40
struct m0_conf_obj * cc_root
Definition: confc.h:404
M0_INTERNAL void m0_fom_wakeup(struct m0_fom *fom)
Definition: fom.c:532
#define M0_PRE(cond)
M0_INTERNAL struct m0_reqh_service * m0_reqh_service_lookup(const struct m0_reqh *reqh, const struct m0_fid *fid)
Definition: reqh_service.c:551
static int sss_device_fom_root_info_use(struct m0_sss_dfom *dfom, struct m0_conf_obj **root_obj)
Definition: device_foms.c:541
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
struct m0_fop * fo_fop
Definition: fom.h:490
static int sss_device_fom_sdev_opening(struct m0_fom *fom)
Definition: device_foms.c:594
M0_INTERNAL void m0_fom_block_enter(struct m0_fom *fom)
Definition: fom.c:538
#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
M0_INTERNAL void m0_clink_del(struct m0_clink *link)
Definition: chan.c:267
static int sss_device_fom_create(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: device_foms.c:199
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
struct m0_chan chan
Definition: device_foms.c:112
#define ergo(a, b)
Definition: misc.h:293
static int sss_device_fom_fs_opened(struct m0_fom *fom)
Definition: device_foms.c:577
M0_INTERNAL struct m0_conf_obj * m0_confc_ctx_result(struct m0_confc_ctx *ctx)
Definition: confc.c:771
Definition: sm.h:350
M0_INTERNAL void m0_storage_dev_attach(struct m0_storage_dev *dev, struct m0_storage_devs *devs)
Definition: storage_dev.c:633
struct m0_chan di_wait
Definition: diter.h:212
int(* fo_tick)(struct m0_fom *fom)
Definition: fom.h:663
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
static bool sss_device_fom_conf_obj_ha_state_cb(struct m0_clink *link)
Definition: device_foms.c:346
struct m0_sss_dfom::@504 ssm_ha
int(* fto_create)(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: fom.h:650
struct m0_conf_obj * fc_result
Definition: confc.h:574
const struct m0_conf_obj_type M0_CONF_SDEV_TYPE
Definition: sdev.c:122
static int sss_device_stob_attach(struct m0_fom *fom)
Definition: device_foms.c:603
static void sss_device_fom_fini(struct m0_fom *fom)
Definition: device_foms.c:232
struct m0_ha_note note
Definition: device_foms.c:115
M0_INTERNAL int32_t m0_confc_ctx_error_lock(const struct m0_confc_ctx *ctx)
Definition: confc.c:765
M0_INTERNAL void m0_fom_wait_on(struct m0_fom *fom, struct m0_chan *chan, struct m0_fom_callback *cb)
Definition: fom.c:1490
#define M0_BITS(...)
Definition: misc.h:236
M0_INTERNAL void m0_chan_lock(struct m0_chan *ch)
Definition: chan.c:68
#define container_of(ptr, type, member)
Definition: misc.h:33
M0_INTERNAL void m0_confc_open_by_fid(struct m0_confc_ctx *ctx, const struct m0_fid *fid)
Definition: confc.c:930
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
static int sss_device_stob_detach(struct m0_fom *fom, bool arm_wakeup)
Definition: device_foms.c:682
static int sss_device_format(struct m0_fom *fom)
Definition: device_foms.c:716
struct m0_fop_getxattr_rep * rep
Definition: dir.c:455
static struct foo * obj
Definition: tlist.c:302
m0_fom_phase
Definition: fom.h:372
M0_INTERNAL struct m0_sss_device_fop * m0_sss_fop_to_dev_req(struct m0_fop *fop)
Definition: device_fops.c:114
#define m0_confc_open(ctx, origin,...)
Definition: confc.h:678
struct m0_fom_type ft_fom_type
Definition: fop.h:232
static int sss_device_fom_disk_opening(struct m0_fom *fom)
Definition: device_foms.c:335
struct m0_fid fid
Definition: di.c:46
return M0_RC(rc)
static void sss_device_fom_switch(struct m0_fom *fom)
Definition: device_foms.c:274
enum sss_device_fom_stage ssm_stage
Definition: device_foms.c:95
M0_INTERNAL bool m0_sss_fop_is_dev_req(const struct m0_fop *fop)
Definition: device_fops.c:108
M0_INTERNAL int m0_storage_dev_new_by_conf(struct m0_storage_devs *devs, struct m0_conf_sdev *sdev, bool force, struct m0_storage_dev **dev)
Definition: storage_dev.c:590
#define M0_ENTRY(...)
Definition: trace.h:170
struct m0_fid ssm_fid
Definition: device_foms.c:106
static struct m0_fom_ops sss_device_fom_ops
Definition: device_foms.c:119
void m0_fom_init(struct m0_fom *fom, const struct m0_fom_type *fom_type, const struct m0_fom_ops *ops, struct m0_fop *fop, struct m0_fop *reply, struct m0_reqh *reqh)
Definition: fom.c:1372
uint32_t sd_dev_idx
Definition: obj.h:635
struct m0_fop_type * f_type
Definition: fop.h:81
struct m0_clink ssm_clink
Definition: device_foms.c:99
int32_t nv_nr
Definition: note.h:196
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL struct m0_confc * m0_reqh2confc(struct m0_reqh *reqh)
Definition: reqh.c:753
const struct m0_sm_conf sss_device_fom_conf
Definition: device_foms.c:193
M0_INTERNAL void m0_confc_ctx_fini(struct m0_confc_ctx *ctx)
Definition: confc.c:716
M0_INTERNAL void m0_storage_devs_lock(struct m0_storage_devs *devs)
Definition: storage_dev.c:71
int m0_fom_tick_generic(struct m0_fom *fom)
Definition: fom_generic.c:848
void m0_fom_fini(struct m0_fom *fom)
Definition: fom.c:1324
struct m0_sm_state_descr sss_device_fom_phases_desc[]
Definition: device_foms.c:129
struct m0_fid ssd_fid
Definition: device_fops.h:168
M0_INTERNAL void m0_chan_init(struct m0_chan *chan, struct m0_mutex *ch_guard)
Definition: chan.c:96
#define M0_ASSERT(cond)
const char * scf_name
Definition: sm.h:352
static struct m0_confc * confc
Definition: file.c:94
const struct m0_fom_type_ops sss_device_fom_type_ops
Definition: device_foms.c:125
static bool sss_device_find_has_svc(struct m0_fom *fom, struct m0_fid *svc_fid)
Definition: device_foms.c:482
struct m0_conf_obj * m0_conf_obj_grandparent(const struct m0_conf_obj *obj)
Definition: obj.c:384
void m0_fom_phase_move(struct m0_fom *fom, int32_t rc, int phase)
Definition: fom.c:1699
M0_INTERNAL bool m0_confc_ctx_is_completed(const struct m0_confc_ctx *ctx)
Definition: confc.c:742
struct m0_reqh_service_type m0_ios_type
Definition: io_service.c:112
static int sss_disk_info_use(struct m0_sss_dfom *dfom)
Definition: device_foms.c:431
M0_INTERNAL void m0_fom_block_leave(struct m0_fom *fom)
Definition: fom.c:582
M0_INTERNAL int m0_confc_ctx_init(struct m0_confc_ctx *ctx, struct m0_confc *confc)
Definition: confc.c:643
static int sss_device_fom_disk_ha_state_get(struct m0_fom *fom)
Definition: device_foms.c:415
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
#define M0_POST(cond)
M0_INTERNAL int m0_conf_diter_next(struct m0_conf_diter *it, bool(*filter)(const struct m0_conf_obj *obj))
Definition: diter.c:532
Definition: reqh.h:94
Definition: dump.c:103
Definition: chan.h:229
static int sss_device_fom_sdev_iter(struct m0_fom *fom)
Definition: device_foms.c:495
#define M0_CONF_CAST(ptr, type)
Definition: obj.h:780
struct m0_conf_sdev * ck_sdev
Definition: obj.h:710
static struct m0_clink clink[RDWR_REQUEST_MAX]
struct m0_mutex chan_lock
Definition: device_foms.c:111
#define FID_P(f)
Definition: fid.h:77
M0_INTERNAL struct m0_storage_devs * m0_cs_storage_devs_get(void)
Definition: setup.c:1783
M0_INTERNAL int m0_storage_dev_format(struct m0_storage_dev *dev, uint64_t cid)
Definition: storage_dev.c:767
struct m0_fid no_id
Definition: note.h:180
static int sss_device_fom_sdev_iter_init(struct m0_sss_dfom *dfom, struct m0_conf_obj *root_obj)
Definition: device_foms.c:553
M0_INTERNAL void m0_chan_unlock(struct m0_chan *ch)
Definition: chan.c:73
struct m0_clink clink
Definition: device_foms.c:113
struct m0_fop * m0_fop_reply_alloc(struct m0_fop *req, struct m0_fop_type *rept)
Definition: fop.c:129
static uint32_t sss_dfom_device_cmd(struct m0_sss_dfom *dfom)
Definition: device_foms.c:264
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
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
M0_INTERNAL struct m0_conf_obj * m0_conf_diter_result(const struct m0_conf_diter *it)
Definition: diter.c:576
Definition: fom.h:481
#define m0_conf_diter_init(iter, confc, origin,...)
Definition: diter.h:235
struct m0_reqh reqh
Definition: rm_foms.c:48
M0_INTERNAL struct m0_sss_device_fop_rep * m0_sss_fop_to_dev_rep(struct m0_fop *fop)
Definition: device_fops.c:129
static int sss_device_fom_tick(struct m0_fom *fom)
Definition: device_foms.c:752
static bool _obj_is_sdev(const struct m0_conf_obj *obj)
Definition: device_foms.c:477
M0_INTERNAL void m0_storage_dev_detach(struct m0_storage_dev *dev)
Definition: storage_dev.c:652
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
Definition: fid.h:38
static bool sss_device_fom_sdev_iter_cb(struct m0_clink *clink)
Definition: device_foms.c:533
static int sss_confc_ctx_init(struct m0_sss_dfom *dfom)
Definition: device_foms.c:309
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL int m0_pool_device_state_update(struct m0_reqh *reqh, struct m0_be_tx *tx, struct m0_fid *dev_fid, enum m0_pool_nd_state new_state)
Definition: pool.c:2068
struct m0_fom ssm_fom
Definition: device_foms.c:93
M0_INTERNAL void m0_conf_diter_fini(struct m0_conf_diter *it)
Definition: diter.c:313
static struct m0_net_test_service svc
Definition: service.c:34
static size_t sss_device_fom_home_locality(const struct m0_fom *fom)
Definition: device_foms.c:880
struct m0_conf_obj sd_obj
Definition: obj.h:616
static void sss_device_fom_ha_fini(struct m0_sss_dfom *dfom)
Definition: device_foms.c:380
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
static struct m0_fop * fop
Definition: item.c:57
struct m0_chan isd_detached_chan
Definition: storage_dev.h:106
M0_INTERNAL void m0_storage_devs_unlock(struct m0_storage_devs *devs)
Definition: storage_dev.c:77
sss_device_fom_phases
Definition: device_foms.h:224
M0_INTERNAL void m0_confc_close(struct m0_conf_obj *obj)
Definition: confc.c:921
M0_INTERNAL void m0_chan_fini(struct m0_chan *chan)
Definition: chan.c:104
struct m0_fop * fo_rep_fop
Definition: fom.h:492
struct m0_confc_ctx ssm_confc_ctx
Definition: device_foms.c:97
Definition: nucleus.c:42
static int sss_device_pool_machine_detach(struct m0_fom *fom)
Definition: device_foms.c:667
#define out(...)
Definition: gen.c:41
void m0_fom_phase_set(struct m0_fom *fom, int phase)
Definition: fom.c:1688
#define M0_FID0
Definition: fid.h:93
static int sss_device_pool_machine_attach(struct m0_fom *fom)
Definition: device_foms.c:656
struct m0_ha_note * nv_note
Definition: note.h:197
M0_INTERNAL void m0_ha_state_accept(const struct m0_ha_nvec *note, bool ignore_same_state)
Definition: note.c:189
struct m0_ha_nvec nvec
Definition: device_foms.c:114
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
bool ssm_native_device
Definition: device_foms.c:108
sss_device_fom_stage
Definition: device_foms.c:75
static int sss_device_fom_disk_opened(struct m0_fom *fom)
Definition: device_foms.c:457
int32_t rc
Definition: trigger_fop.h:47
static bool sss_dfom_confc_ctx_check_cb(struct m0_clink *clink)
Definition: device_foms.c:250
#define ARRAY_SIZE(a)
Definition: misc.h:45
static void sss_device_fom_ha_update(struct m0_sss_dfom *dfom)
Definition: device_foms.c:390
struct m0_conf_diter ssm_it
Definition: device_foms.c:101
Definition: fop.h:79
struct m0_conf_obj ck_obj
Definition: obj.h:707
#define FID_F
Definition: fid.h:75
M0_INTERNAL struct m0_reqh * m0_fom_reqh(const struct m0_fom *fom)
Definition: fom.c:283
struct m0_fop * rep_fop
Definition: dir.c:334
#define M0_IMPOSSIBLE(fmt,...)
uint32_t no_state
Definition: note.h:182