Motr  M0
client_init.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 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 #include "lib/memory.h" /* m0_alloc, m0_free */
24 #include "lib/errno.h" /* ENOMEM */
25 #include "lib/uuid.h" /* m0_uuid_generate */
26 #include "lib/finject.h" /* M0_FI_ENABLED */
27 #include "lib/arith.h" /* M0_CNT_INC */
28 #include "lib/mutex.h" /* m0_mutex_lock */
29 #include "lib/time.h" /* m0_nanosleep */
30 #include "addb2/global.h"
31 #include "addb2/sys.h"
32 #include "fid/fid.h" /* m0_fid */
33 #include "conf/ha.h" /* m0_conf_ha_process_event_post */
34 #include "conf/helpers.h" /* m0_confc_root_open */
35 #include "conf/confc.h" /* m0_confc_state */
36 #include "rpc/rpclib.h" /* m0_rpc_client_connect */
37 #include "pool/pool.h" /* m0_pool_init */
38 #include "rm/rm_service.h" /* m0_rms_type */
39 #include "net/lnet/lnet_core_types.h" /* M0_NET_LNET_NIDSTR_SIZE */
40 #include "dtm0/service.h" /* m0_dtm0_service_find */
41 #include "dtm0/helper.h" /* m0_dtm_client_service_start */
42 
43 #include "motr/io.h" /* io_sm_conf */
44 #include "motr/client.h"
45 #include "motr/addb.h"
46 #include "motr/client_internal.h"
47 #include "motr/layout.h"
48 
49 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
50 #include "lib/trace.h" /* M0_LOG */
51 
52 /* BOB type for m0_ */
53 static const struct m0_bob_type m0c_bobtype;
55 
56 static const struct m0_bob_type m0c_bobtype = {
57  .bt_name = "m0c_bobtype",
58  .bt_magix_offset = offsetof(struct m0_client, m0c_magic),
59  .bt_magix = M0_M0C_MAGIC,
60  .bt_check = NULL,
61 };
62 
69 
94  IL_NET, /* TODO: break this out */
95  IL_RPC, /* TODO: break this out */
98  IL_CONFC, /* Creates confc and stashes in m0c */
104  IL_ROOT_FID, /* TODO: remove this m0t1fs ism */
109 };
110 
112 static int initlift_uninitialised(struct m0_sm *mach);
113 static int initlift_net(struct m0_sm *mach);
114 static int initlift_rpc(struct m0_sm *mach);
115 static int initlift_ast_thread(struct m0_sm *mach);
116 static int initlift_ha(struct m0_sm *mach);
117 static int initlift_confc(struct m0_sm *mach);
118 static int initlift_pools(struct m0_sm *mach);
119 static int initlift_pool_version(struct m0_sm *mach);
120 static int initlift_resource_manager(struct m0_sm *mach);
121 static int initlift_layouts(struct m0_sm *mach);
122 static int initlift_idx_service(struct m0_sm *mach);
123 static int initlift_rootfid(struct m0_sm *mach);
124 static int initlift_addb2(struct m0_sm *mach);
125 static int initlift_dtm0(struct m0_sm *mach);
126 
131  [IL_UNINITIALISED] = {
133  .sd_name = "uninitialised",
134  .sd_allowed = M0_BITS(IL_NET, IL_FAILED),
135  .sd_in = initlift_uninitialised,
136  },
137  [IL_NET] = {
138  .sd_name = "init/fini-net",
139  .sd_allowed = M0_BITS(IL_RPC, IL_UNINITIALISED),
140  .sd_in = initlift_net,
141  },
142  [IL_RPC] = {
143  .sd_name = "init/fini-rpc",
144  .sd_allowed = M0_BITS(IL_AST_THREAD, IL_NET),
145  .sd_in = initlift_rpc,
146  },
147  [IL_AST_THREAD] = {
148  .sd_name = "init/fini-ast-thread",
149  .sd_allowed = M0_BITS(IL_HA, IL_RPC),
150  .sd_in = initlift_ast_thread,
151  },
152  [IL_HA] = {
153  .sd_name = "init/fini-ha",
154  .sd_allowed = M0_BITS(IL_CONFC,
155  IL_AST_THREAD),
156  .sd_in = initlift_ha,
157  },
158  [IL_CONFC] = {
159  .sd_name = "init/fini-confc",
160  .sd_allowed = M0_BITS(IL_POOLS,
161  IL_HA),
162  .sd_in = initlift_confc,
163  },
164  [IL_POOLS] = {
165  .sd_name = "init/fini-pools",
166  .sd_allowed = M0_BITS(IL_POOL_VERSION,
167  IL_CONFC),
168  .sd_in = initlift_pools,
169  },
170  [IL_POOL_VERSION] = {
171  .sd_name = "init/fini-pool-version",
172  .sd_allowed = M0_BITS(IL_RESOURCE_MANAGER,
173  IL_POOLS),
174  .sd_in = initlift_pool_version,
175  },
176  [IL_RESOURCE_MANAGER] = {
177  .sd_name = "init/fini-resource-manager",
178  .sd_allowed = M0_BITS(IL_LAYOUT_DB,
180  .sd_in = initlift_resource_manager,
181  },
182  [IL_LAYOUT_DB] = {
183  .sd_name = "init/fini-layout-database",
184  .sd_allowed = M0_BITS(IL_IDX_SERVICE,
186  .sd_in = initlift_layouts,
187  },
188  [IL_IDX_SERVICE] = {
189  .sd_name = "init/fini-resource-manager",
190  .sd_allowed = M0_BITS(IL_ROOT_FID,
191  IL_LAYOUT_DB),
192  .sd_in = initlift_idx_service,
193  },
194  [IL_ROOT_FID] = {
195  .sd_name = "retrieve-root-fid",
196  .sd_allowed = M0_BITS(IL_ADDB2,
198  .sd_in = initlift_rootfid,
199  },
200  [IL_ADDB2] = {
201  .sd_name = "init/fini-addb2",
202  .sd_allowed = M0_BITS(IL_DTM0,
203  IL_ROOT_FID),
204  .sd_in = initlift_addb2,
205  },
206  [IL_DTM0] = {
207  .sd_name = "init/fini-dtm0",
208  .sd_allowed = M0_BITS(IL_INITIALISED,
209  IL_ADDB2),
210  .sd_in = initlift_dtm0,
211  },
212  [IL_INITIALISED] = {
213  .sd_name = "initialised",
214  .sd_allowed = M0_BITS(IL_DTM0),
215  },
216  [IL_FAILED] = {
217  .sd_name = "failed",
218  .sd_flags = M0_SDF_FAILURE | M0_SDF_FINAL,
219  }
220 };
221 
226  /* INIT section*/
227  {"initialising-network", IL_UNINITIALISED, IL_NET},
228  {"initialising-rpc-layer", IL_NET, IL_RPC},
229  {"initialising-ast-thread", IL_RPC,
230  IL_AST_THREAD},
231  {"connecting-to-ha", IL_AST_THREAD,
232  IL_HA},
233  {"connecting-to-confd", IL_HA,
234  IL_CONFC},
235  {"setting-up-pools", IL_CONFC,
236  IL_POOLS},
237  {"initialising-pool-version", IL_POOLS,
239  {"initialising-resource-manager",
242  {"initialising-layout-database",
244  IL_LAYOUT_DB},
245  {"initialising-index-service",
246  IL_LAYOUT_DB,
248  {"retrieving-root-fid", IL_IDX_SERVICE,
249  IL_ROOT_FID},
250  {"initialising-addb2", IL_ROOT_FID,
251  IL_ADDB2},
252  {"initialising-dtm0", IL_ADDB2, IL_DTM0},
253  {"initialised", IL_DTM0, IL_INITIALISED},
254 
255  /* FINI section*/
256  {"shutting-down", IL_INITIALISED,
257  IL_DTM0},
258  {"finalising-dtm0", IL_DTM0,
259  IL_ADDB2},
260 
261  {"finalising-addb2", IL_ADDB2,
262  IL_ROOT_FID},
263  {"finalising-root-fid", IL_ROOT_FID,
265  {"finalising-index-service", IL_IDX_SERVICE,
266  IL_LAYOUT_DB},
267  {"finalising-layout-database", IL_LAYOUT_DB,
269  {"finalising-resource-manager",
272  {"finalising-pool-version", IL_POOL_VERSION,
273  IL_POOLS},
274  {"finalising-pools", IL_POOLS,
275  IL_CONFC},
276  {"closing-stale-confc", IL_CONFC,
277  IL_HA},
278  {"closing-ha-session", IL_HA,
279  IL_AST_THREAD},
280  {"finalising-ast-thread", IL_AST_THREAD, IL_RPC},
281  {"finalising-rpc-layer", IL_RPC, IL_NET},
282  {"finalising-network", IL_NET, IL_UNINITIALISED},
283  {"initialisation-failed",
285  IL_FAILED},
286 };
287 
292  .scf_name = "initlift-conf",
293  .scf_nr_states = ARRAY_SIZE(initlift_phases),
294  .scf_state = initlift_phases,
295  .scf_trans = initlift_trans,
296  .scf_trans_nr = ARRAY_SIZE(initlift_trans),
297 };
298 
305 static bool m0c_invariant(struct m0_client *m0c)
306 {
307  return M0_RC(m0c != NULL && m0_client_bob_check(m0c));
308 }
309 
310 static struct m0_rconfc *rconfc(struct m0_client *m0c)
311 {
312  return &m0c->m0c_reqh.rh_rconfc;
313 }
314 
315 M0_INTERNAL struct m0_confc *m0_confc(struct m0_client *m0c)
316 {
317  return &rconfc(m0c)->rc_confc;
318 }
319 
320 static int client_fid_sscanf(const char *s,
321  struct m0_fid *fid,
322  const char *descr)
323 {
324  int rc = m0_fid_sscanf(s, fid);
325 
326  if (rc != 0)
327  return M0_ERR_INFO(rc, "can't m0_fid_sscanf() %s %s", descr, s);
328  return M0_RC(0);
329 }
330 
339 {
340  int rc;
341 
342  M0_PRE(m0c != NULL);
343  M0_PRE(M0_IN(m0c->m0c_initlift_direction,
344  (STARTUP, SHUTDOWN)));
345 
346  if (M0_FI_ENABLED("ut"))
347  /* no op, -1 means don't move */
348  return M0_RC(-1);
349 
350  rc = m0c->m0c_initlift_sm.sm_state + m0c->m0c_initlift_direction;
353 
354  return M0_RC(rc);
355 }
356 
364 {
365  M0_PRE(m0c != NULL);
366 
367  if (M0_FI_ENABLED("immediate_ret"))
368  /*
369  * no-op: this is used by m0_client_init/fini to kick the init
370  * process into action - for the unit tests, we don't want to do
371  * anything.
372  */
373  m0c->m0c_initlift_rc = 0;
374  else if (M0_FI_ENABLED("failure"))
375  m0c->m0c_initlift_rc = -EPROTO;
376  else
377  m0_sm_move(&m0c->m0c_initlift_sm, 0,
379 }
380 
388 static void initlift_fail(int rc, struct m0_client *m0c)
389 {
390  M0_PRE(rc != 0);
391  M0_PRE(m0c != NULL);
392  M0_PRE(m0c->m0c_initlift_rc == 0);
393 
394  m0c->m0c_initlift_rc = rc;
395  m0c->m0c_initlift_direction = SHUTDOWN;
396 }
397 
398 static int initlift_uninitialised(struct m0_sm *mach)
399 {
400  struct m0_client *m0c;
401 
402  M0_ENTRY();
403  M0_PRE(mach != NULL);
404 
407 
408  if (m0c->m0c_initlift_direction == SHUTDOWN) {
409  if (m0c->m0c_initlift_rc != 0)
410  m0_sm_fail(&m0c->m0c_initlift_sm, IL_FAILED,
411  m0c->m0c_initlift_rc);
412  }
413 
414  return M0_RC(-1);
415 }
416 
423 static void client_net_fini(struct m0_client *m0c)
424 {
425  M0_ENTRY();
426 
427  M0_PRE(m0c != NULL);
428 
429  m0_net_domain_fini(&m0c->m0c_ndom);
430  m0c->m0c_xprt = NULL;
431  m0_free(m0c->m0c_laddr);
432  m0c->m0c_laddr = NULL;
433 
434  M0_LEAVE();
435 }
436 
448 static int client_net_init(struct m0_client *m0c)
449 {
450  struct m0_net_xprt *xprt;
451  struct m0_net_domain *ndom;
452  int rc;
453  char *laddr;
454  size_t laddr_len;
455 
456  M0_ENTRY();
457 
458  M0_PRE(m0c != NULL);
459  M0_PRE(m0c->m0c_config != NULL);
460  M0_PRE(m0c->m0c_config->mc_local_addr != NULL);
461 
462  laddr_len = strlen(m0c->m0c_config->mc_local_addr) + 1;
463  laddr = m0_alloc(laddr_len);
464  if (laddr == NULL)
465  return M0_ERR(-ENOMEM);
466  strncpy(laddr, m0c->m0c_config->mc_local_addr, laddr_len);
467  m0c->m0c_laddr = laddr;
468 
469  m0c->m0c_xprt = m0_net_xprt_default_get();
470  xprt = m0c->m0c_xprt;
471  ndom = &m0c->m0c_ndom;
472 
473  rc = m0_net_domain_init(ndom, xprt);
474  if (rc != 0) {
475  m0c->m0c_laddr = NULL;
476  m0_free(laddr);
477  }
478 
479  return M0_RC(rc);
480 }
481 
482 static int initlift_net(struct m0_sm *mach)
483 {
484  int rc;
485  struct m0_client *m0c;
486 
487  M0_ENTRY();
488  M0_PRE(mach != NULL);
489 
492 
493  if (m0c->m0c_initlift_direction == STARTUP) {
495  if (rc != 0)
496  initlift_fail(rc, m0c);
497  } else
499 
501 }
502 
509 static void rpc_fini(struct m0_client *m0c)
510 {
511  M0_ENTRY();
512 
513  M0_PRE(m0c != NULL);
514 
515  m0_rpc_machine_fini(&m0c->m0c_rpc_machine);
516  M0_SET0(&m0c->m0c_rpc_machine);
517  if (m0_reqh_state_get(&m0c->m0c_reqh) != M0_REQH_ST_STOPPED)
518  m0_reqh_services_terminate(&m0c->m0c_reqh);
519  m0_reqh_fini(&m0c->m0c_reqh);
520  M0_SET0(&m0c->m0c_reqh);
521  m0_rpc_net_buffer_pool_cleanup(&m0c->m0c_buffer_pool);
522 
523  M0_LEAVE();
524 }
525 
533 static int rpc_init(struct m0_client *m0c)
534 {
535  struct m0_rpc_machine *rpc_machine;
536  struct m0_reqh *reqh;
537  struct m0_net_domain *ndom;
538  const char *laddr;
539  struct m0_net_buffer_pool *buffer_pool;
540  struct m0_net_transfer_mc *tm;
541  int rc;
542  uint32_t bufs_nr;
543  uint32_t tms_nr;
544 
545  M0_ENTRY();
546  M0_PRE(m0c != NULL);
547 
548  rpc_machine = &m0c->m0c_rpc_machine;
549  reqh = &m0c->m0c_reqh;
550  ndom = &m0c->m0c_ndom;
551  laddr = m0c->m0c_laddr;
552  buffer_pool = &m0c->m0c_buffer_pool;
553 
554  tms_nr = 1;
555  bufs_nr = m0_rpc_bufs_nr(
556  m0c->m0c_config->mc_tm_recv_queue_min_len, tms_nr);
557 
558  rc = m0_rpc_net_buffer_pool_setup(ndom, buffer_pool,
559  bufs_nr, tms_nr);
560  if (rc != 0)
561  goto exit;
562 
563  rc = M0_REQH_INIT(reqh,
564  .rhia_dtm = (void*)1,
565  .rhia_db = (void*)1,
566  .rhia_mdstore = (void*)1,
567  .rhia_pc = &m0c->m0c_pools_common,
568  .rhia_fid = &m0c->m0c_process_fid);
569  if (rc != 0)
570  goto pool_fini;
571 
572  rc = m0_rpc_machine_init(rpc_machine, ndom, laddr, reqh,
573  buffer_pool, M0_BUFFER_ANY_COLOUR,
574  m0c->m0c_config->mc_max_rpc_msg_size,
575  m0c->m0c_config->mc_tm_recv_queue_min_len);
576  if (rc != 0)
577  goto reqh_fini;
578 
580  tm = &rpc_machine->rm_tm;
581  M0_ASSERT(tm->ntm_recv_pool == buffer_pool);
582  return M0_RC(rc);
583 
584 reqh_fini:
586 pool_fini:
587  m0_rpc_net_buffer_pool_cleanup(buffer_pool);
588 
589 exit:
590  M0_ASSERT(rc != 0);
591  initlift_fail(rc, m0c);
592 
593  return M0_RC(rc);
594 }
595 
596 static int initlift_rpc(struct m0_sm *mach)
597 {
598  struct m0_client *m0c;
599 
600  M0_ENTRY();
601  M0_PRE(mach != NULL);
602 
605 
606  if (m0c->m0c_initlift_direction == STARTUP)
607  rpc_init(m0c);
608  else
609  rpc_fini(m0c);
610 
612 }
613 
618 static void ast_thread(struct m0_client *m0c)
619 {
620  M0_PRE(m0c != NULL);
621 
622  while (1) {
623  /*
624  * See commit 19b74c444 for details on why it is changed
625  * to m0_chan_wait
626  */
627  m0_chan_wait(&m0c->m0c_sm_group.s_clink);
628  m0_sm_group_lock(&m0c->m0c_sm_group);
629  m0_sm_asts_run(&m0c->m0c_sm_group);
630  m0_sm_group_unlock(&m0c->m0c_sm_group);
631  if (!m0c->m0c_astthread_active &&
632  m0_atomic64_get(&m0c->m0c_pending_io_nr) == 0) {
633  m0_chan_signal_lock(&m0c->m0c_io_wait);
634  return;
635  }
636  }
637 }
638 
639 static int initlift_ast_thread(struct m0_sm *mach)
640 {
641  int rc;
642  struct m0_client *m0c;
643  struct m0_clink w;
644 
645  M0_ENTRY();
646  M0_PRE(mach != NULL);
647  m0c = bob_of(mach, struct m0_client, m0c_initlift_sm, &m0c_bobtype);
649  M0_PRE(m0_sm_group_is_locked(&m0c->m0c_sm_group));
650 
651  if (m0c->m0c_initlift_direction == STARTUP) {
652  m0c->m0c_astthread_active = true;
653  rc = M0_THREAD_INIT(&m0c->m0c_astthread, struct m0_client *,
654  NULL, &ast_thread, m0c,
655  "client:ast");
656 
657  if (rc != 0)
658  initlift_fail(rc, m0c);
659  } else {
660  /* Release the lock so that m0_clink_add_lock can use it */
661  m0_sm_group_unlock(&m0c->m0c_sm_group);
662 
663  m0_clink_init(&w, NULL);
664  m0_clink_add_lock(&m0c->m0c_io_wait, &w);
665 
666  m0c->m0c_astthread_active = false;
667  m0_chan_signal_lock(&m0c->m0c_sm_group.s_chan);
668  m0_chan_wait(&w);
669  m0_thread_join(&m0c->m0c_astthread);
670 
671  m0_clink_del_lock(&w);
672  m0_clink_fini(&w);
673 
674  /* Re-acquire the lock */
675  m0_sm_group_lock(&m0c->m0c_sm_group);
676 
677  M0_SET0(&m0c->m0c_astthread);
678  }
679 
681 }
682 
684 static void ha_process_event(struct m0_client *m0c,
685  enum m0_conf_ha_process_event event)
686 {
687  if (M0_FI_ENABLED("no-link"))
688  return;
689 
690  /*
691  * Don't post an event if HA link is not connect.
692  * HA link can be NULL in UT as client UT doesn't run through
693  * all steps of initialisation (for example, those setps involving
694  * interactions with services such as HA initialisation).
695  */
696  if (m0c->m0c_motr_ha.mh_link == NULL)
697  return;
698 
699  m0_conf_ha_process_event_post(&m0c->m0c_motr_ha.mh_ha,
700  m0c->m0c_motr_ha.mh_link,
701  &m0c->m0c_process_fid,
702  m0_process(), event,
703 #ifdef __KERNEL__
705 #else
707 #endif
708 }
709 
715 static int ha_init(struct m0_client *m0c)
716 {
717  int rc;
718  struct m0_motr_ha *motr_ha = &m0c->m0c_motr_ha;
719 
720  M0_ENTRY();
721 
722  if (M0_FI_ENABLED("skip-ha-init"))
723  return 0;
724 
725  motr_ha_cfg = (struct m0_motr_ha_cfg){
726  .mhc_dispatcher_cfg = {
727  .hdc_enable_note = true,
728  .hdc_enable_keepalive = true,
729  .hdc_enable_fvec = true,
730  },
731  .mhc_addr = m0c->m0c_config->mc_ha_addr,
732  .mhc_rpc_machine = &m0c->m0c_rpc_machine,
733  .mhc_reqh = &m0c->m0c_reqh,
734  .mhc_process_fid = m0c->m0c_process_fid,
735  };
736  rc = m0_motr_ha_init(motr_ha, &motr_ha_cfg);
737  M0_ASSERT(rc == 0);
738 
739  rc = m0_motr_ha_start(motr_ha);
740  M0_ASSERT(rc == 0);
741 
742  m0_motr_ha_connect(motr_ha);
744 
745  return M0_RC(0);
746 }
747 
751 static void ha_fini(struct m0_client *m0c)
752 {
753  M0_ENTRY();
754 
755  if (M0_FI_ENABLED("skip-ha-fini"))
756  return;
757 
758  /*
759  * Where is the best place to process HA_STOPPING event? We don't
760  * have umount-like operation as in m0t1fs.
761  */
763  m0_motr_ha_disconnect(&m0c->m0c_motr_ha);
764  m0_motr_ha_stop(&m0c->m0c_motr_ha);
765  m0_motr_ha_fini(&m0c->m0c_motr_ha);
766  M0_LEAVE();
767 }
768 
769 static int initlift_ha(struct m0_sm *mach)
770 {
771  int rc;
772  struct m0_client *m0c;
773 
774  M0_ENTRY();
775  M0_PRE(mach != NULL);
776 
779 
780  if (m0c->m0c_initlift_direction == STARTUP) {
781  rc = ha_init(m0c);
782  if (rc != 0)
783  initlift_fail(rc, m0c);
784  } else
785  ha_fini(m0c);
786 
788 }
789 
790 static bool rconfc_expired_cb(struct m0_clink *clink)
791 {
792  struct m0_client *m0c = M0_AMB(m0c, clink, m0c_conf_exp);
793  struct m0_confc *confc = m0_confc(m0c);
794 
795  M0_PRE(confc != NULL);
796 
797  M0_ENTRY();
798  if (m0c->m0c_reqh.rh_rconfc.rc_stopping)
799  return true;
800 
801  m0_mutex_lock(&m0c->m0c_confc_state.cus_lock);
802  m0c->m0c_confc_state.cus_state = M0_CC_REVOKED;
803  m0_mutex_unlock(&m0c->m0c_confc_state.cus_lock);
804 
805  M0_LEAVE();
806  return true;
807 }
808 
809 static bool rconfc_ready_cb(struct m0_clink *clink)
810 {
812 
813  M0_ENTRY();
814  m0_mutex_lock(&m0c->m0c_confc_state.cus_lock);
815  m0c->m0c_confc_state.cus_state = M0_CC_GETTING_READY;
816  m0_mutex_unlock(&m0c->m0c_confc_state.cus_lock);
817  M0_LEAVE();
818  return true;
819 }
820 
821 static void rconfc_fatal_cb(struct m0_rconfc *rconfc)
822 {
823  struct m0_reqh *reqh = M0_AMB(reqh, rconfc, rh_rconfc);
824  struct m0_client *m0c = M0_AMB(m0c, reqh, m0c_reqh);
825 
826  M0_ENTRY("rconfc %p", rconfc);
827  M0_LOG(M0_ERROR, "rconfc encounters fatal error and can't be started");
828  m0_mutex_lock(&m0c->m0c_confc_state.cus_lock);
829  m0c->m0c_confc_state.cus_state = M0_CC_FAILED;
830  m0_mutex_unlock(&m0c->m0c_confc_state.cus_lock);
831  M0_LEAVE();
832 }
833 
834 static void io_ref_cb(struct m0_ref *ref)
835 {
836  struct m0_client *m0c = M0_AMB(m0c, ref, m0c_ongoing_io);
837  struct m0_clink *pc_clink = &m0c->m0c_pools_common.pc_conf_ready_async;
838 
839  M0_ENTRY("client %p", m0c);
840 
841  m0_mutex_lock(&m0c->m0c_confc_state.cus_lock);
842  if (m0_ref_read(ref) == 0 &&
843  m0c->m0c_confc_state.cus_state == M0_CC_GETTING_READY) {
844  m0_pool_versions_stale_mark(&m0c->m0c_pools_common,
845  &m0c->m0c_confc_state);
846  if (m0c->m0c_pools_common.pc_confc != NULL)
848 
849  m0c->m0c_confc_state.cus_state = M0_CC_READY;
850  }
851  m0_mutex_unlock(&m0c->m0c_confc_state.cus_lock);
852 
853  m0_chan_lock(&m0c->m0c_conf_ready_chan);
854  m0_chan_broadcast(&m0c->m0c_conf_ready_chan);
855  m0_chan_unlock(&m0c->m0c_conf_ready_chan);
856 }
857 
858 static bool confc_ready_async_cb(struct m0_clink *clink)
859 {
861 
862  if (m0_ref_read(&m0c->m0c_ongoing_io) == 0 &&
863  m0c->m0c_confc_state.cus_state == M0_CC_GETTING_READY)
864  io_ref_cb(&m0c->m0c_ongoing_io);
865  return true;
866 }
867 
868 M0_INTERNAL int m0__io_ref_get(struct m0_client *m0c)
869 {
870  struct m0_clink clink;
871  struct m0_confc *confc = m0_confc(m0c);
872 
873  M0_PRE(confc != NULL);
874  M0_ENTRY("m0c=%p", m0c);
875  while (1) {
876  m0_mutex_lock(&m0c->m0c_confc_state.cus_lock);
877  if (M0_IN(m0c->m0c_confc_state.cus_state,
879  break;
881  m0_clink_add(&m0c->m0c_conf_ready_chan, &clink);
882 
883  m0_mutex_unlock(&m0c->m0c_confc_state.cus_lock);
884  /* Wait till configuration is updated. */
886 
889  }
890  if (m0c->m0c_confc_state.cus_state == M0_CC_READY)
891  m0_ref_get(&m0c->m0c_ongoing_io);
892  m0_mutex_unlock(&m0c->m0c_confc_state.cus_lock);
893  return M0_RC(m0c->m0c_confc_state.cus_state == M0_CC_READY ?
894  0 : -ESTALE);
895 }
896 
897 M0_INTERNAL void m0__io_ref_put(struct m0_client *m0c)
898 {
899  struct m0_confc *confc = m0_confc(m0c);
900  M0_PRE(confc != NULL);
901 
902  m0_ref_put(&m0c->m0c_ongoing_io);
903  M0_POST(m0_ref_read(&m0c->m0c_ongoing_io) >= 0);
904 }
905 
906 static int confc_init(struct m0_client *m0c)
907 {
908  int rc;
909  struct m0_reqh *reqh;
910  struct m0_confc_args *confc_args;
911  struct m0_rconfc *rconfcp;
912 
913  confc_args = &(struct m0_confc_args){
914  .ca_profile = m0c->m0c_config->mc_profile,
915  .ca_rmach = &m0c->m0c_rpc_machine,
916  .ca_group = &m0c->m0c_sm_group,
917  };
918  reqh = &m0c->m0c_reqh;
919  rconfcp = rconfc(m0c);
920 
921  /*
922  * confc needs the ast thread to make progress, and we block
923  * it with this lock.
924  */
925  m0_sm_group_unlock(&m0c->m0c_sm_group);
926 
927  rc = m0_reqh_conf_setup(reqh, confc_args);
928  if (rc != 0)
929  goto err_exit;
930 
931  m0_clink_init(&m0c->m0c_conf_exp, rconfc_expired_cb);
932  m0_clink_init(&m0c->m0c_conf_ready, rconfc_ready_cb);
933  m0_clink_init(&m0c->m0c_conf_ready_async, confc_ready_async_cb);
934  m0_clink_add_lock(&reqh->rh_conf_cache_exp, &m0c->m0c_conf_exp);
935  m0_clink_add_lock(&reqh->rh_conf_cache_ready, &m0c->m0c_conf_ready);
937  &m0c->m0c_conf_ready_async);
938  m0_ref_init(&m0c->m0c_ongoing_io, 0, io_ref_cb);
939 
940  rc = m0_rconfc_start_sync(rconfcp);
941  if (rc != 0)
942  goto err_rconfc_stop;
943 
945  if (rc != 0)
946  goto err_rconfc_stop;
947 
949  if (rc != 0)
950  goto err_conf_close;
951 
953  if (rc != 0)
954  goto err_conf_close;
955 
956  /* Set rconfc_fatal_cb */
957  m0_rconfc_lock(rconfcp);
959  m0_rconfc_unlock(rconfcp);
960 
961  /* re-acquire the lock */
962  m0_sm_group_lock(&m0c->m0c_sm_group);
963  return M0_RC(0);
964 
965 err_conf_close:
967 
968 err_rconfc_stop:
969  m0_rconfc_stop_sync(rconfcp);
970  m0_rconfc_fini(rconfcp);
971  m0_clink_del_lock(&m0c->m0c_conf_exp);
972  m0_clink_del_lock(&m0c->m0c_conf_ready);
973  m0_clink_del_lock(&m0c->m0c_conf_ready_async);
974  m0_clink_fini(&m0c->m0c_conf_exp);
975  m0_clink_fini(&m0c->m0c_conf_ready);
976  m0_clink_fini(&m0c->m0c_conf_ready_async);
977 
978 err_exit:
979  /* re-acquire the lock */
980  m0_sm_group_lock(&m0c->m0c_sm_group);
981 
982  return M0_RC(rc);
983 }
984 
985 static void confc_fini(struct m0_client *m0c)
986 {
987  /*
988  * Motr-1580:
989  * conf_root has to be closed in the shutdown path.
990  * This is needed if client init fails for some reason.
991  */
992  if (conf_root) {
994  conf_root = NULL;
995  }
996 
997  m0_sm_group_unlock(&m0c->m0c_sm_group);
1000  m0_clink_del_lock(&m0c->m0c_conf_exp);
1001  m0_clink_del_lock(&m0c->m0c_conf_ready);
1002  m0_clink_del_lock(&m0c->m0c_conf_ready_async);
1003  m0_clink_fini(&m0c->m0c_conf_exp);
1004  m0_clink_fini(&m0c->m0c_conf_ready);
1005  m0_sm_group_lock(&m0c->m0c_sm_group);
1006  m0_clink_fini(&m0c->m0c_conf_ready_async);
1007 }
1008 
1009 static int initlift_confc(struct m0_sm *mach)
1010 {
1011  int rc;
1012  struct m0_client *m0c;
1013 
1014  M0_ENTRY();
1015  M0_PRE(mach != NULL);
1018  M0_PRE(m0_sm_group_is_locked(&m0c->m0c_sm_group));
1019 
1020  if (m0c->m0c_initlift_direction == STARTUP) {
1021  rc = confc_init(m0c);
1022  if (rc != 0)
1023  initlift_fail(rc, m0c);
1024  } else {
1025  confc_fini(m0c);
1026  }
1027 
1029 }
1030 
1031 static int pools_init(struct m0_client *m0c)
1032 {
1033  int rc;
1034  struct m0_pools_common *pools = &m0c->m0c_pools_common;
1035 
1036  m0_sm_group_unlock(&m0c->m0c_sm_group);
1037 
1038  rc = m0_pools_common_init(pools, &m0c->m0c_rpc_machine);
1039  if (rc != 0)
1040  goto err_exit;
1041  M0_ASSERT(ergo(m0c->m0c_config->mc_is_oostore,
1042  pools->pc_md_redundancy > 0));
1043 
1044  rc = m0_pools_setup(pools, &m0c->m0c_profile_fid, NULL, NULL);
1045  if (rc != 0)
1046  goto err_pools_common_fini;
1047 
1049  if (rc != 0)
1050  goto err_pools_destroy;
1051 
1053 
1054  m0_sm_group_lock(&m0c->m0c_sm_group);
1055  return M0_RC(0);
1056 
1057 err_pools_destroy:
1058  m0_pools_destroy(pools);
1059 err_pools_common_fini:
1060  m0_pools_common_fini(pools);
1061 err_exit:
1062  m0_sm_group_lock(&m0c->m0c_sm_group);
1063  return M0_RC(rc);
1064 }
1065 
1066 static void pools_fini(struct m0_client *m0c)
1067 {
1068  struct m0_pools_common *pools = &m0c->m0c_pools_common;
1069 
1071  m0_pools_destroy(pools);
1072  m0_pools_common_fini(pools);
1073 }
1074 
1075 static int initlift_pools(struct m0_sm *mach)
1076 {
1077  int rc;
1078  struct m0_client *m0c;
1079 
1080  M0_ENTRY();
1081  M0_PRE(mach != NULL);
1082 
1085 
1086  if (m0c->m0c_initlift_direction == STARTUP) {
1087  rc = pools_init(m0c);
1088  if (rc != 0)
1089  initlift_fail(rc, m0c);
1090  } else
1091  pools_fini(m0c);
1092 
1094 }
1095 
1096 /* Finds the pool and pool version to use. */
1097 static int initlift_pool_version(struct m0_sm *mach)
1098 {
1099  int rc;
1100  struct m0_client *m0c;
1101  struct m0_pools_common *pools;
1102 
1103  M0_ENTRY();
1104  M0_PRE(mach != NULL);
1105 
1106  m0c = bob_of(mach, struct m0_client, m0c_initlift_sm, &m0c_bobtype);
1108  pools = &m0c->m0c_pools_common;
1109 
1110  if (m0c->m0c_initlift_direction == STARTUP) {
1111  /* Confc needs the lock to proceed. */
1112  m0_sm_group_unlock(&m0c->m0c_sm_group);
1113 
1114  rc = m0_pool_versions_setup(pools);
1115  if (rc != 0) {
1116  m0_sm_group_lock(&m0c->m0c_sm_group);
1117  initlift_fail(rc, m0c);
1118  goto exit;
1119  }
1120 
1121  m0_sm_group_lock(&m0c->m0c_sm_group);
1122  } else /* SHUTDOWN */
1123  m0_pool_versions_destroy(pools);
1124 
1125 exit:
1127 }
1128 
1129 static int service_start(struct m0_reqh *reqh, struct m0_fid *sfid,
1130  struct m0_reqh_service_type *stype,
1131  struct m0_reqh_service **service)
1132 {
1133  return m0_reqh_service_setup(service, stype, reqh, NULL, sfid);
1134 }
1135 
1137 {
1138  int rc = 0;
1139  struct m0_client *m0c;
1140  struct m0_reqh_service *service;
1141  struct m0_reqh *reqh;
1142  struct m0_fid sfid;
1143  struct m0_fid fake_pfid
1145 
1146  M0_ENTRY();
1147  M0_PRE(mach != NULL);
1148 
1149  m0c = bob_of(mach, struct m0_client, m0c_initlift_sm, &m0c_bobtype);
1151  reqh = &m0c->m0c_reqh;
1152 
1153  /*
1154  * @todo Use fake process fid for init script based cluster setup.
1155  * Init script based setup not adding client process
1156  * to configuration and also not passing client process
1157  * FID to mount.
1158  */
1159  if (!m0_fid_eq(&reqh->rh_fid, &fake_pfid)) {
1161  /* confd quorum is not possible. */
1162  rc = M0_ERR(-EINVAL);
1163  initlift_fail(rc, m0c);
1164  goto exit;
1165  }
1166 
1167  /* Confc needs the lock to proceed. */
1168  m0_sm_group_unlock(&m0c->m0c_sm_group);
1170  &reqh->rh_fid, M0_CST_RMS,
1171  &sfid);
1172  m0_sm_group_lock(&m0c->m0c_sm_group);
1173  if (rc != 0) {
1174  initlift_fail(rc, m0c);
1175  goto exit;
1176  }
1177  } else {
1178  m0_uuid_generate((struct m0_uint128 *)&sfid);
1180  }
1181 
1182  if (m0c->m0c_initlift_direction == STARTUP) {
1183  rc = service_start(reqh, &sfid, &m0_rms_type, &service);
1184  if (rc != 0)
1185  initlift_fail(rc, m0c);
1186  } else {
1187  /* reqh_services_terminate is handled by rpc_fini.
1188  * Reqh services are terminated not in reverse order because
1189  * m0_reqh_services_terminate() terminates all services
1190  * including rpc_service. Rpc_service starts in
1191  * rpc_init() implicitly.
1192  */
1193  }
1194 
1195 exit:
1197 }
1198 
1199 static int initlift_layouts(struct m0_sm *mach)
1200 {
1201  int rc;
1202  struct m0_client *m0c;
1203  struct m0_reqh *reqh;
1204 
1205  M0_ENTRY();
1206  M0_PRE(mach != NULL);
1207 
1208  m0c = bob_of(mach, struct m0_client, m0c_initlift_sm, &m0c_bobtype);
1210  reqh = &m0c->m0c_reqh;
1211 
1212  if (m0c->m0c_initlift_direction == STARTUP) {
1214  if (rc != 0)
1215  initlift_fail(rc, m0c);
1216  } else {
1218  }
1219 
1221 }
1222 
1223 static int initlift_idx_service(struct m0_sm *mach)
1224 {
1225  int rc = 0;
1226  struct m0_client *m0c;
1227  struct m0_idx_service *service;
1228  struct m0_idx_service_ctx *ctx;
1229 
1230  M0_ENTRY();
1231  M0_PRE(mach != NULL);
1232 
1233  m0c = bob_of(mach, struct m0_client, m0c_initlift_sm, &m0c_bobtype);
1235  ctx = &m0c->m0c_idx_svc_ctx;
1236 
1237  if (m0c->m0c_initlift_direction == STARTUP) {
1239  m0c->m0c_config->mc_idx_service_id,
1240  m0c->m0c_config->mc_idx_service_conf);
1241  service = ctx->isc_service;
1242  M0_ASSERT(service != NULL &&
1243  service->is_svc_ops != NULL &&
1244  service->is_svc_ops->iso_init != NULL);
1245 
1246  /* Confc needs the lock to proceed. */
1247  m0_sm_group_unlock(&m0c->m0c_sm_group);
1248  rc = service->is_svc_ops->iso_init((void *)ctx);
1249  m0_sm_group_lock(&m0c->m0c_sm_group);
1250 
1251  if (rc != 0)
1252  initlift_fail(rc, m0c);
1253  } else {
1254  service = ctx->isc_service;
1255  M0_ASSERT(service != NULL &&
1256  service->is_svc_ops != NULL &&
1257  service->is_svc_ops->iso_fini != NULL);
1258  service->is_svc_ops->iso_fini((void *)ctx);
1259  }
1260 
1262 }
1263 
1264 /* Default root fid and name_len for oostore mode */
1265 #ifdef CLIENT_FOR_M0T1FS
1266 
1267 M0_INTERNAL const struct m0_fid M0_CLIENT_ROOT_FID = {
1268  .f_container = 1ULL,
1269  .f_key = 1ULL
1270 };
1271 
1272 #define M0_M0T1FS_NAME_LEN (256)
1273 
1274 #endif
1275 
1282 static int rootfid_lookup(struct m0_client *m0c)
1283 {
1284 #ifdef CLIENT_FOR_M0T1FS
1285  int rc;
1286  struct m0_fop *fop;
1287  struct m0_rpc_session *session;
1288  struct m0_fop_statfs_rep *statfs_rep;
1289  struct m0_fop_statfs *statfs;
1290  struct m0_fop *rep_fop = NULL;
1291  struct m0_reqh_service_ctx *ctx;
1292  struct m0_pools_common *pc;
1293 
1294  M0_ENTRY();
1295  M0_PRE(m0c != NULL);
1296  M0_PRE(m0_sm_group_is_locked(&m0c->m0c_sm_group));
1297 
1298  /*
1299  * As the root fid in oostore mode is always set to be M0_CLIENT_ROOT_FID,
1300  * no neeed to send a request to mds to query it.
1301  */
1302  if (m0c->m0c_config->mc_is_oostore) {
1303  m0c->m0_namelen = M0_M0T1FS_NAME_LEN;
1304  m0c->m0c_root_fid = M0_CLIENT_ROOT_FID;
1305  return M0_RC(0);
1306  }
1307 
1308  /* Layout data is stored on mds0 */
1309  pc = &m0c->m0c_pools_common;
1310  ctx = pc->pc_mds_map[0];
1311  M0_ASSERT(ctx != NULL);
1312 
1313  /* Wait till the connection is ready. */
1315  session = &ctx->sc_rlink.rlk_sess;
1316  M0_ASSERT(session != NULL);
1317 
1318  /* Allocate a fop */
1320  if (fop == NULL) {
1321  rc = -ENOMEM;
1322  M0_LOG(M0_ERROR, "m0_fop_alloc() failed with %d", rc);
1323  return M0_RC(rc);
1324  }
1325 
1326  /* populate the request values */
1327  statfs = m0_fop_data(fop);
1328  statfs->f_flags = 0;
1329 
1330  rc = m0_rpc_post_sync(fop, session, NULL, 0 /* deadline */);
1331  if (rc != 0) {
1332  M0_LOG(M0_ERROR, "m0_rpc_post_sync(%x) failed with %d",
1333  m0_fop_opcode(fop), rc);
1334  goto out;
1335  }
1336 
1337  /* Retrieve and unpack the reply */
1340  statfs_rep = m0_fop_data(rep_fop);
1341  rc = statfs_rep->f_rc;
1342  if (rc != 0) {
1343  M0_LOG(M0_ERROR, "remote statfs fop (%x) failed with %d",
1344  m0_fop_opcode(fop), rc);
1345  goto out;
1346  }
1347 
1348  /* Unpack the reply */
1349  m0c->m0_namelen = statfs_rep->f_namelen;
1350  M0_LOG(M0_DEBUG, "Got mdservice root "FID_F,
1351  FID_P(&statfs_rep->f_root));
1352 
1353  m0c->m0c_root_fid = statfs_rep->f_root;
1354 
1355 out:
1356  /* We are done with the reply */
1357  if (rep_fop != NULL)
1359 
1360  /* We are done with the request */
1362 
1363  return M0_RC(rc);
1364 #endif
1365 }
1366 
1367 static int initlift_rootfid(struct m0_sm *mach)
1368 {
1369  int rc;
1370  struct m0_client *m0c;
1371 
1372  M0_ENTRY();
1373  M0_PRE(mach != NULL);
1374 
1377 
1378  if (m0c->m0c_initlift_direction == STARTUP) {
1379  rc = rootfid_lookup(m0c);
1380  if (rc != 0)
1381  initlift_fail(rc, m0c);
1382  } else {
1383  m0c->m0_namelen = 0;
1384  M0_SET0(&m0c->m0c_root_fid);
1385  }
1386 
1388 }
1389 
1390 static int initlift_addb2(struct m0_sm *mach)
1391 {
1392  int rc = 0;
1393  struct m0_client *m0c;
1394  struct m0_addb2_sys *sys = m0_addb2_global_get();
1395 
1396  M0_ENTRY();
1397  M0_PRE(mach != NULL);
1398 
1399  m0c = bob_of(mach, struct m0_client, m0c_initlift_sm, &m0c_bobtype);
1401 
1402  if (M0_FI_ENABLED("no-addb2"))
1404 
1405  if (m0c->m0c_initlift_direction == STARTUP) {
1406 #ifndef __KERNEL__
1407  /*
1408  * When reaching here, m0t1fs has started ADDB 'sys' if client
1409  * is in kernel mode. TODO: client is the 'only' interface
1410  * motr and m0t1fs is built on top of client in the future. We
1411  * will sort this out later.
1412  */
1415  if (rc != 0) {
1416  initlift_fail(rc, m0c);
1418  }
1419 #endif
1420 
1422  sys, &m0c->m0c_pools_common.pc_svc_ctxs);
1423 
1424  if (rc != 0)
1425  initlift_fail(rc, m0c);
1426  } else {
1427 #ifndef __KERNEL__
1430 #endif
1431  }
1432 
1434 }
1435 
1436 static int initlift_dtm0(struct m0_sm *mach)
1437 {
1438  int rc = 0;
1439  struct m0_client *m0c;
1440 
1441  M0_ENTRY();
1442  M0_PRE(mach != NULL);
1443 
1446 
1447  if (m0c->m0c_initlift_direction == STARTUP) {
1448  rc = m0_dtm0_domain_init(&m0c->m0c_dtm0_domain, NULL);
1449  if (rc != 0) {
1450  initlift_fail(rc, m0c);
1452  }
1453  } else {
1454  m0_dtm0_domain_fini(&m0c->m0c_dtm0_domain);
1455  }
1456 
1458 }
1459 
1460 M0_INTERNAL void m0_client_global_fini(void)
1461 {
1462  M0_ENTRY();
1463 
1466 
1472 
1473  M0_LEAVE();
1474 }
1475 
1479 #ifndef __KERNEL__
1480 #include <unistd.h>
1481 #endif
1482 static int get_online_cpus(void)
1483 {
1484  int cpus;
1485 
1486 #ifdef __KERNEL__
1487  cpus = num_online_cpus();
1488 #else
1489  cpus = sysconf(_SC_NPROCESSORS_ONLN);
1490 #endif
1491 
1492  return (cpus / 2) ?: 1;
1493 }
1494 
1495 M0_INTERNAL int m0_client_global_init(void)
1496 {
1497  int cpus;
1498  int rc;
1499 
1500  M0_ENTRY();
1501 
1506 
1507  /*
1508  * Limit the number of concurrent parity calculations
1509  * to avoid starving other threads (especially LNet) out.
1510  *
1511  * Note: the exact threshold number may come from configuration
1512  * database later where it can be specified per-node.
1513  */
1514  cpus = get_online_cpus();
1515  M0_LOG(M0_INFO, "motr: max CPUs for parity calcs: %d\n", cpus);
1516  m0_semaphore_init(&cpus_sem, cpus);
1517 
1519 
1526 
1527  return M0_RC(rc);
1528 }
1529 
1530 #define NOT_EMPTY(x) (x != NULL && *x != '\0')
1531 
1533 int m0_client_init(struct m0_client **m0c_p,
1534  struct m0_config *conf, bool init_m0)
1535 {
1536  int rc;
1537  struct m0_client *m0c;
1538  struct m0_fid cli_svc_fid;
1539 
1540  M0_PRE(m0c_p != NULL);
1541  M0_PRE(*m0c_p == NULL);
1542  M0_PRE(conf != NULL);
1543  M0_PRE(NOT_EMPTY(conf->mc_local_addr));
1544  M0_PRE(NOT_EMPTY(conf->mc_ha_addr));
1545  M0_PRE(NOT_EMPTY(conf->mc_profile));
1546  M0_PRE(NOT_EMPTY(conf->mc_process_fid));
1547  M0_PRE(conf->mc_tm_recv_queue_min_len != 0);
1548  M0_PRE(conf->mc_max_rpc_msg_size != 0);
1549 
1550  /* Initialise Motr if needed at the very beginning. */
1551 #ifndef __KERNEL__
1552  if (init_m0) {
1555  if (rc != 0)
1556  return M0_RC(rc);
1557  }
1558 #endif
1559 
1560  /* Can't call M0_ENTRY before m0 is initialised. */
1561  M0_ENTRY();
1562 
1563  /* initialise this m0_ instance */
1564  M0_ALLOC_PTR(m0c);
1565  if (m0c == NULL)
1566  return M0_ERR(-ENOMEM);
1567  m0_client_bob_init(m0c);
1568 
1569  /* Set configuration parameters */
1570  m0c->m0c_config = conf;
1571 
1572  /* Parse some parameters in m0_config for future uses. */
1573  rc = client_fid_sscanf(conf->mc_process_fid, &m0c->m0c_process_fid,
1574  "process fid");
1575  if (rc != 0)
1576  goto err_exit;
1577 
1578  rc = client_fid_sscanf(conf->mc_profile, &m0c->m0c_profile_fid,
1579  "profile");
1580  if (rc != 0)
1581  goto err_exit;
1582 
1583  /* Set motr instance. */
1584  m0c->m0c_motr = &m0_client_motr_instance;
1585 
1586  /* Initialise configuration state lock */
1587  m0_mutex_init(&m0c->m0c_confc_state.cus_lock);
1588  m0_chan_init(&m0c->m0c_conf_ready_chan, &m0c->m0c_confc_state.cus_lock);
1589 
1590  /*
1591  * Initialise those types specific to IO operations, this is needed
1592  * to get rootfid in the Client initlift trip.
1593  */
1595 
1596  /* Initialise state machine group */
1597  m0_sm_group_init(&m0c->m0c_sm_group);
1598  m0_chan_init(&m0c->m0c_io_wait, &m0c->m0c_sm_group.s_lock);
1599 
1600  /* Move the initlift in its direction of travel */
1601  m0_sm_group_lock(&m0c->m0c_sm_group);
1602 
1603  m0_sm_init(&m0c->m0c_initlift_sm, &initlift_conf,
1604  IL_UNINITIALISED, &m0c->m0c_sm_group);
1605  m0c->m0c_initlift_direction = STARTUP;
1607 
1608  /*
1609  * If Client initialisation successes, close the configuration fs
1610  * object(cached) now as it may become invalid at some point of time.
1611  */
1612  rc = m0c->m0c_initlift_rc;
1613  if (rc == 0) {
1615  conf_root = NULL;
1616 
1617  /*
1618  * m0t1fs posts the `STARTED` event during `mount`, client
1619  * doesn't have corresponding `mount` operation, instead
1620  * client posts this event when all initialisation steps
1621  * are completed successfully.
1622  */
1624  /*
1625  For m0crate, s3servers and other client apps,
1626  M0_NC_DTM_RECOVERING state is transient, sending
1627  M0_CONF_HA_PROCESS_DTM_RECOVERED just after
1628  M0_CONF_HA_PROCESS_STARTED.
1629 
1630  ha_process_event(m0c, M0_CONF_HA_PROCESS_DTM_RECOVERED);
1631  */
1632  }
1633 
1634  m0_sm_group_unlock(&m0c->m0c_sm_group);
1635 
1636  /* Check the stashed first failure (may be 0) */
1637  if (rc != 0)
1638  goto err_exit;
1639 
1640  /* Do post checks if all initialisation steps success. */
1643  /* This is a sanity test, not a side-effect of m0_client_init */
1645  &M0_ID_APP) < 0);
1646 
1647  /* Extra initialisation work for composite layout. */
1649 
1650  /* Init the hash-table for RM contexts */
1651  rm_ctx_htable_init(&m0c->m0c_rm_ctxs, M0_RM_HBUCKET_NR);
1652 
1653  if (ENABLE_DTM0) {
1654  struct m0_reqh_service *reqh_svc;
1655 
1657  &m0c->m0c_reqh.rh_fid,
1658  M0_CST_DTM0, &cli_svc_fid);
1659  M0_ASSERT(rc == 0);
1660 
1661  if (m0_dtm0_in_ut()) {
1662  /* When in UT, m0c_reqh.rh_fid is the same as the
1663  * server process fid. It causes the client to use
1664  * the server-side service fid. Hard-coding of the client
1665  * service fid resolves this problem.
1666  * TODO: When in UT, walk over the list of processes in
1667  * the conf cache and get the service with "volatile"
1668  * property from there. It will help to get rid of the
1669  * hard-coded service fid.
1670  */
1671  cli_svc_fid = M0_FID_INIT(0x7300000000000001, 0x1a);
1672  }
1673 
1674  rc = m0_dtm_client_service_start(&m0c->m0c_reqh, &cli_svc_fid,
1675  &reqh_svc);
1676  M0_ASSERT(rc == 0);
1677 
1678  m0c->m0c_dtms = m0_dtm0_service_find(&m0c->m0c_reqh);
1679  M0_ASSERT(m0c->m0c_dtms != NULL);
1680  }
1681  if (conf->mc_is_addb_init) {
1682  char buf[64];
1683  /* Default client addb record file size set to 128M */
1685  if (conf->mc_addb_size != 0) {
1686  if (conf->mc_addb_size > MAX_ADDB2_RECORD_SIZE)
1687  M0_LOG(M0_WARN, "ADDB size is more than recommended");
1688  size = conf->mc_addb_size;
1689  M0_LOG(M0_DEBUG, "ADDB size = %" PRIu64 "", size);
1690  }
1691  sprintf(buf, "linuxstob:./addb_%d", (int)m0_pid());
1692  M0_LOG(M0_DEBUG, "addb size=%llu\n", (unsigned long long)size);
1693  rc = m0_reqh_addb2_init(&m0c->m0c_reqh, buf,
1694  0xaddbf11e, true, true, size);
1695  }
1696  /* publish the allocated client instance */
1697  *m0c_p = m0c;
1698  return M0_RC(rc);
1699 
1700 err_exit:
1701  m0_free(m0c);
1702 #ifndef __KERNEL__
1703  if (init_m0)
1704  m0_fini();
1705 #endif
1706  return M0_RC(rc);
1707 
1708 }
1709 M0_EXPORTED(m0_client_init);
1710 
1711 void m0_client_fini(struct m0_client *m0c, bool fini_m0)
1712 {
1713  M0_ENTRY();
1714 
1717  M0_PRE(m0c != NULL);
1718  M0_PRE(ergo(ENABLE_DTM0, m0c->m0c_dtms != NULL));
1719 
1720  if (m0c->m0c_dtms != NULL)
1721  m0_dtm_client_service_stop(&m0c->m0c_dtms->dos_generic);
1722 
1723  if (m0c->m0c_config->mc_is_addb_init) {
1725  m0_reqh_addb2_fini(&m0c->m0c_reqh);
1726  }
1727 
1728  /* Finalize hash-table for RM contexts */
1729  rm_ctx_htable_fini(&m0c->m0c_rm_ctxs);
1730 
1731  /* shut down this client instance */
1732  m0_sm_group_lock(&m0c->m0c_sm_group);
1733 
1734  /*
1735  * As explained in m0_client_init(), client doesn't have `umount`
1736  * so it posts the `STOPPING` event here.
1737  */
1739 
1740  m0c->m0c_initlift_direction = SHUTDOWN;
1741  if (m0c->m0c_initlift_sm.sm_state == IL_INITIALISED)
1742  /* Kick the initlift in its direction of travel */
1744 
1745  m0_sm_group_unlock(&m0c->m0c_sm_group);
1746  m0_chan_fini_lock(&m0c->m0c_io_wait);
1747 
1748  m0_chan_fini_lock(&m0c->m0c_conf_ready_chan);
1749  m0_mutex_fini(&m0c->m0c_confc_state.cus_lock);
1750 
1751 
1752  /* finalise the m0_ instance */
1753  m0_sm_group_fini(&m0c->m0c_sm_group);
1754 
1755  m0_client_bob_fini(m0c);
1756 #ifndef __KERNEL__
1757  if (fini_m0)
1758  m0_fini();
1759 #endif
1760  m0_free(m0c);
1761 
1762  M0_LEAVE();
1763 }
1764 M0_EXPORTED(m0_client_fini);
1765 
1766 void m0_process_fid(const struct m0_client *m0c,
1767  struct m0_fid *proc_fid)
1768 {
1769  M0_PRE(m0c != NULL && proc_fid != NULL);
1770 
1771  /* TODO: check if the process fid is a valid one for client. */
1772  *proc_fid = m0c->m0c_process_fid;
1773 }
1774 M0_EXPORTED(m0_process_fid);
1775 
1776 #ifdef REALM_SUPPORTED
1777 /* for now, this only lets you open the uber realm for an instance */
1778 void m0_realm_open(struct m0_realm *realm,
1779  uint64_t wcount, uint64_t rcount,
1780  struct m0_op **op)
1781 {
1782  /* TODO: how to set the id of the realm to open?
1783  * if not, why does the uber realm have one? */
1784 }
1785 #endif
1786 
1787 #undef M0_TRACE_SUBSYSTEM
1788 
1789 /*
1790  * Local variables:
1791  * c-indentation-style: "K&R"
1792  * c-basic-offset: 8
1793  * tab-width: 8
1794  * fill-column: 80
1795  * scroll-step: 1
1796  * End:
1797  */
1798 /*
1799  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
1800  */
M0_INTERNAL int m0_uint128_cmp(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:45
M0_INTERNAL uint64_t m0_process(void)
Definition: kthread.c:295
static void confc_fini(struct m0_client *m0c)
Definition: client_init.c:985
static int initlift_pool_version(struct m0_sm *mach)
Definition: client_init.c:1097
uint32_t m0_fop_opcode(const struct m0_fop *fop)
Definition: fop.c:226
M0_INTERNAL void m0_chan_wait(struct m0_clink *link)
Definition: chan.c:336
M0_INTERNAL void m0_pools_common_fini(struct m0_pools_common *pc)
Definition: pool.c:1549
static void io_ref_cb(struct m0_ref *ref)
Definition: client_init.c:834
struct m0_reqh_service * reqh_svc
Definition: rm_foms.c:49
#define M0_PRE(cond)
void m0_rpc_machine_fini(struct m0_rpc_machine *machine)
Definition: rpc_machine.c:233
M0_INTERNAL void m0_sm_conf_init(struct m0_sm_conf *conf)
Definition: sm.c:340
static void rpc_fini(struct m0_client *m0c)
Definition: client_init.c:509
M0_INTERNAL void m0_sm_fail(struct m0_sm *mach, int fail_state, int32_t rc)
Definition: sm.c:468
M0_INTERNAL void m0_reqh_services_terminate(struct m0_reqh *reqh)
Definition: reqh.c:675
static int initlift_pools(struct m0_sm *mach)
Definition: client_init.c:1075
static int initlift_ha(struct m0_sm *mach)
Definition: client_init.c:769
uint32_t f_namelen
Definition: md_fops.h:278
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
void m0_net_domain_fini(struct m0_net_domain *dom)
Definition: domain.c:71
struct m0_sm_trans_descr initlift_trans[]
Definition: client_init.c:225
initlift_states
Definition: client_init.c:92
void m0_addb2_sys_net_stop(struct m0_addb2_sys *sys)
Definition: sys.c:322
M0_INTERNAL int m0_motr_ha_start(struct m0_motr_ha *mha)
Definition: ha.c:549
m0_conf_ha_process_event
Definition: ha.h:49
M0_INTERNAL int m0_sm_addb2_init(struct m0_sm_conf *conf, uint64_t id, uint64_t counter)
Definition: sm.c:846
#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 struct m0_dtm0_service * m0_dtm0_service_find(const struct m0_reqh *reqh)
Definition: service.c:406
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
M0_INTERNAL void m0_dtm_client_service_stop(struct m0_reqh_service *svc)
Definition: service.c:139
void m0_addb2_sys_sm_stop(struct m0_addb2_sys *sys)
Definition: sys.c:384
static int initlift_confc(struct m0_sm *mach)
Definition: client_init.c:1009
void m0_fini(void)
Definition: init.c:318
#define ergo(a, b)
Definition: misc.h:293
int m0_thread_join(struct m0_thread *q)
Definition: kthread.c:169
M0_INTERNAL int m0_conf_full_load(struct m0_conf_root *r)
Definition: helpers.c:165
#define M0_REQH_INIT(reqh,...)
Definition: reqh.h:262
M0_INTERNAL void m0_uuid_generate(struct m0_uint128 *u)
Definition: uuid.c:44
Definition: sm.h:350
void m0_addb2_sys_sm_start(struct m0_addb2_sys *sys)
Definition: sys.c:377
struct m0_chan rh_conf_cache_ready_async
Definition: reqh.h:227
struct m0_conf_root * conf_root
Definition: client_init.c:68
struct m0_conf_obj rt_obj
Definition: obj.h:372
static struct m0_motr_ha_cfg motr_ha_cfg
Definition: client_init.c:714
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
M0_INTERNAL void m0_reqh_layouts_cleanup(struct m0_reqh *reqh)
Definition: reqh.c:169
uint8_t ft_id
Definition: fid.h:101
const struct m0_conf_obj_type M0_CONF_SERVICE_TYPE
Definition: service.c:156
M0_BOB_DEFINE(static, &m0c_bobtype, m0_client)
#define M0_FID_INIT(container, key)
Definition: fid.h:84
struct m0_clink m0c_conf_ready
struct m0_fop_type m0_fop_statfs_fopt
Definition: md_fops.c:64
void m0_process_fid(const struct m0_client *m0c, struct m0_fid *proc_fid)
Definition: client_init.c:1766
static int initlift_layouts(struct m0_sm *mach)
Definition: client_init.c:1199
M0_INTERNAL void m0_idx_service_config(struct m0_client *m0c, int svc_id, void *svc_conf)
Definition: idx.c:654
static struct m0 m0_client_motr_instance
Definition: client_init.c:1532
void m0_client_fini(struct m0_client *m0c, bool fini_m0)
Definition: client_init.c:1711
struct m0_clink m0c_conf_exp
static int service_start(struct m0_reqh *reqh, struct m0_fid *sfid, struct m0_reqh_service_type *stype, struct m0_reqh_service **service)
Definition: client_init.c:1129
static struct m0_clovis * m0c
Definition: main.c:25
struct m0_sm_conf io_sm_conf
Definition: io_req.c:141
M0_INTERNAL void m0_rconfc_stop_sync(struct m0_rconfc *rconfc)
Definition: rconfc.c:2995
struct m0_chan rh_conf_cache_ready
Definition: reqh.h:205
M0_INTERNAL int m0_dtm0_domain_init(struct m0_dtm0_domain *dod, struct m0_dtm0_domain_cfg *dod_cfg)
Definition: domain.c:183
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
M0_INTERNAL void m0_rconfc_fatal_cb_set(struct m0_rconfc *rconfc, m0_rconfc_cb_t cb)
Definition: rconfc.c:3067
Definition: conf.py:1
static struct m0_addb2_mach * mach
Definition: storage.c:42
#define M0_BITS(...)
Definition: misc.h:236
static void ast_thread(struct m0_client *m0c)
Definition: client_init.c:618
uint64_t m0_bcount_t
Definition: types.h:77
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
Definition: thread.h:139
int m0_init(struct m0 *instance)
Definition: init.c:310
M0_INTERNAL void m0_chan_lock(struct m0_chan *ch)
Definition: chan.c:68
static struct m0_rpc_session session
Definition: formation2.c:38
#define M0_SET0(obj)
Definition: misc.h:64
int m0_client_init(struct m0_client **m0c_p, struct m0_config *conf, bool init_m0)
Definition: client_init.c:1533
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
const struct m0_uint128 M0_UBER_REALM
Definition: client.c:85
M0_INTERNAL int m0_pools_setup(struct m0_pools_common *pc, const struct m0_fid *profile, struct m0_sm_group *sm_grp, struct m0_dtm *dtm)
Definition: pool.c:1810
static int initlift_net(struct m0_sm *mach)
Definition: client_init.c:482
M0_INTERNAL void m0_reqh_service_connect_wait(struct m0_reqh_service_ctx *ctx)
Definition: reqh_service.c:822
M0_INTERNAL void m0_reqh_fini(struct m0_reqh *reqh)
Definition: reqh.c:320
M0_INTERNAL int m0_motr_ha_init(struct m0_motr_ha *mha, struct m0_motr_ha_cfg *mha_cfg)
Definition: ha.c:509
M0_INTERNAL int m0_reqh_addb2_init(struct m0_reqh *reqh, const char *location, uint64_t key, bool mkfs, bool force, m0_bcount_t size)
Definition: reqh.c:341
M0_INTERNAL void m0_sm_group_fini(struct m0_sm_group *grp)
Definition: sm.c:65
static bool rconfc_expired_cb(struct m0_clink *clink)
Definition: client_init.c:790
const char * bt_name
Definition: bob.h:73
Definition: sock.c:887
static struct m0_pools_common pc
Definition: iter_ut.c:59
const struct m0_uint128 M0_ID_APP
Definition: client.c:92
struct m0_fid fid
Definition: di.c:46
M0_INTERNAL void m0_motr_ha_disconnect(struct m0_motr_ha *mha)
Definition: ha.c:578
static int initlift_resource_manager(struct m0_sm *mach)
Definition: client_init.c:1136
#define NOT_EMPTY(x)
Definition: client_init.c:1530
M0_INTERNAL int m0_confc_root_open(struct m0_confc *confc, struct m0_conf_root **root)
Definition: helpers.c:219
return M0_RC(rc)
op
Definition: libdemo.c:64
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL void m0_idx_services_register(void)
Definition: idx.c:683
M0_INTERNAL void m0__io_ref_put(struct m0_client *m0c)
Definition: client_init.c:897
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
struct m0_semaphore cpus_sem
Definition: io_req.c:45
void m0_fop_put0_lock(struct m0_fop *fop)
Definition: fop.c:213
static void ha_process_event(struct m0_client *m0c, enum m0_conf_ha_process_event event)
Definition: client_init.c:684
#define PRIu64
Definition: types.h:58
static void rconfc_fatal_cb(struct m0_rconfc *rconfc)
Definition: client_init.c:821
struct m0_sm_conf initlift_conf
Definition: client_init.c:291
Definition: client.h:641
M0_INTERNAL void m0_ref_put(struct m0_ref *ref)
Definition: refs.c:38
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
struct m0_reqh_service_ctx ** pc_mds_map
Definition: pool.h:180
void m0_ref_init(struct m0_ref *ref, int init_num, void(*release)(struct m0_ref *ref))
Definition: refs.c:24
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_ref_get(struct m0_ref *ref)
Definition: refs.c:32
M0_INTERNAL bool m0_pools_common_conf_ready_async_cb(struct m0_clink *clink)
Definition: pool.c:1358
M0_INTERNAL void m0_pool_versions_stale_mark(struct m0_pools_common *pc, struct m0_confc_update_state *s)
Definition: pool.c:811
Definition: trace.h:482
static int confc_init(struct m0_client *m0c)
Definition: client_init.c:906
uint32_t pc_md_redundancy
Definition: pool.h:210
M0_INTERNAL struct m0_confc * m0_reqh2confc(struct m0_reqh *reqh)
Definition: reqh.c:753
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
Definition: refs.h:34
static const struct socktype stype[]
Definition: sock.c:1156
struct m0_sm_state_descr initlift_phases[]
Definition: client_init.c:130
#define ENABLE_DTM0
Definition: config.h:36
const struct m0_fid_type cot_ftype
Definition: obj.h:314
M0_INTERNAL int m0_client_global_init(void)
Definition: client_init.c:1495
M0_INTERNAL int m0_reqh_conf_setup(struct m0_reqh *reqh, struct m0_confc_args *args)
Definition: reqh.c:729
void m0_realm_open(struct m0_realm *realm, uint64_t wcount, uint64_t rcount, struct m0_op **op)
struct m0_net_transfer_mc rm_tm
Definition: rpc_machine.h:88
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
struct crate_conf * conf
static struct m0_confc * confc
Definition: file.c:94
M0_INTERNAL void m0_sm_group_init(struct m0_sm_group *grp)
Definition: sm.c:53
M0_INTERNAL void m0_pools_common_service_ctx_connect_sync(struct m0_pools_common *pc)
Definition: pool.c:1608
static const struct m0_bob_type m0c_bobtype
Definition: client_init.c:53
static int initlift_ast_thread(struct m0_sm *mach)
Definition: client_init.c:639
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
struct m0_reqh m0c_reqh
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
struct m0_sm_conf entity_conf
Definition: client.c:213
M0_INTERNAL int m0_dtm_client_service_start(struct m0_reqh *reqh, struct m0_fid *cli_srv_fid, struct m0_reqh_service **out)
Definition: service.c:113
M0_INTERNAL uint32_t m0_rpc_bufs_nr(uint32_t len, uint32_t tms_nr)
Definition: rpc.c:271
static int client_net_init(struct m0_client *m0c)
Definition: client_init.c:448
Definition: instance.h:80
static int initlift_dtm0(struct m0_sm *mach)
Definition: client_init.c:1436
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
M0_INTERNAL void m0_pools_service_ctx_destroy(struct m0_pools_common *pc)
Definition: pool.c:1617
struct m0_fop * m0_fop_get(struct m0_fop *fop)
Definition: fop.c:162
struct m0_rpc_item * ri_reply
Definition: item.h:163
M0_INTERNAL int m0_reqh_mdpool_layout_build(struct m0_reqh *reqh)
Definition: reqh.c:145
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
static int initlift_idx_service(struct m0_sm *mach)
Definition: client_init.c:1223
void * m0_alloc(size_t size)
Definition: memory.c:126
static char * proc_fid
Definition: m0hsm.c:45
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
int m0_rpc_post_sync(struct m0_fop *fop, struct m0_rpc_session *session, const struct m0_rpc_item_ops *ri_ops, m0_time_t deadline)
Definition: rpclib.c:284
static int m0_rconfc_start_sync(struct m0_rconfc *rconfc)
Definition: rconfc.h:502
M0_INTERNAL int m0_conf_confc_ha_update(struct m0_confc *confc)
Definition: helpers.c:658
uint64_t f_container
Definition: fid.h:39
#define M0_POST(cond)
M0_INTERNAL void m0_sm_addb2_fini(struct m0_sm_conf *conf)
Definition: sm.c:870
M0_INTERNAL void m0_rconfc_lock(struct m0_rconfc *rconfc)
Definition: rconfc.c:2841
Definition: reqh.h:94
static void ha_fini(struct m0_client *m0c)
Definition: client_init.c:751
M0_INTERNAL void m0_motr_ha_connect(struct m0_motr_ha *mha)
Definition: ha.c:567
M0_INTERNAL bool m0_confc_is_inited(const struct m0_confc *confc)
Definition: confc.c:448
static struct m0_clink clink[RDWR_REQUEST_MAX]
M0_INTERNAL int m0_reqh_service_setup(struct m0_reqh_service **out, struct m0_reqh_service_type *stype, struct m0_reqh *reqh, struct m0_reqh_context *rctx, const struct m0_fid *fid)
Definition: reqh_service.c:565
M0_INTERNAL int m0_fid_sscanf(const char *s, struct m0_fid *fid)
Definition: fid.c:227
static struct fdmi_ctx ctx
Definition: main.c:80
int m0_addb2_sys_net_start_with(struct m0_addb2_sys *sys, struct m0_tl *head)
Definition: sys.c:329
static void initlift_move_next_floor(struct m0_client *m0c)
Definition: client_init.c:363
#define FID_P(f)
Definition: fid.h:77
M0_INTERNAL void m0_chan_unlock(struct m0_chan *ch)
Definition: chan.c:73
M0_INTERNAL void m0_chan_signal_lock(struct m0_chan *chan)
Definition: chan.c:165
M0_INTERNAL void m0_rconfc_fini(struct m0_rconfc *rconfc)
Definition: rconfc.c:3009
M0_INTERNAL int m0__io_ref_get(struct m0_client *m0c)
Definition: client_init.c:868
static int rootfid_lookup(struct m0_client *m0c)
Definition: client_init.c:1282
M0_INTERNAL int m0_reqh_state_get(struct m0_reqh *reqh)
Definition: reqh.c:398
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
static bool rconfc_ready_cb(struct m0_clink *clink)
Definition: client_init.c:809
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
static int initlift_rootfid(struct m0_sm *mach)
Definition: client_init.c:1367
static int initlift_get_next_floor(struct m0_client *m0c)
Definition: client_init.c:338
M0_INTERNAL int m0_conf_process2service_get(struct m0_confc *confc, const struct m0_fid *process_fid, enum m0_conf_service_type stype, struct m0_fid *sfid)
Definition: helpers.c:518
struct m0_reqh_service_type m0_rms_type
Definition: rm_service.c:69
Definition: ha.h:54
static void pools_fini(struct m0_client *m0c)
Definition: client_init.c:1066
M0_INTERNAL void m0_reqh_start(struct m0_reqh *reqh)
Definition: reqh.c:711
struct m0_clink m0c_conf_ready_async
static int rpc_init(struct m0_client *m0c)
Definition: client_init.c:533
M0_INTERNAL void m0_rconfc_unlock(struct m0_rconfc *rconfc)
Definition: rconfc.c:2855
M0_INTERNAL int64_t m0_ref_read(const struct m0_ref *ref)
Definition: refs.c:44
M0_INTERNAL struct m0_confc * m0_confc(struct m0_client *m0c)
Definition: client_init.c:315
struct m0_ref m0c_ongoing_io
M0_INTERNAL void m0_client_global_fini(void)
Definition: client_init.c:1460
struct m0_reqh reqh
Definition: rm_foms.c:48
int m0_net_domain_init(struct m0_net_domain *dom, const struct m0_net_xprt *xprt)
Definition: domain.c:36
M0_INTERNAL int m0_pools_common_init(struct m0_pools_common *pc, struct m0_rpc_machine *rmach)
Definition: pool.c:1425
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
Definition: fid.h:38
struct m0_ha_dispatcher_cfg mhc_dispatcher_cfg
Definition: ha.h:47
struct m0_confc rc_confc
Definition: rconfc.h:235
static int initlift_addb2(struct m0_sm *mach)
Definition: client_init.c:1390
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 int initlift_uninitialised(struct m0_sm *mach)
Definition: client_init.c:398
struct m0_chan rh_conf_cache_exp
Definition: reqh.h:194
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_clink_add(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:228
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
static struct m0_realm realm
Definition: sync.c:87
static bool confc_ready_async_cb(struct m0_clink *clink)
Definition: client_init.c:858
M0_INTERNAL void m0_conf_ha_process_event_post(struct m0_ha *ha, struct m0_ha_link *hl, const struct m0_fid *process_fid, uint64_t pid, enum m0_conf_ha_process_event event, enum m0_conf_ha_process_type type)
Definition: ha.c:45
M0_INTERNAL int m0_pools_service_ctx_create(struct m0_pools_common *pc)
Definition: pool.c:1535
static int client_fid_sscanf(const char *s, struct m0_fid *fid, const char *descr)
Definition: client_init.c:320
M0_INTERNAL struct m0_addb2_sys * m0_addb2_global_get(void)
Definition: global.c:99
static void client_net_fini(struct m0_client *m0c)
Definition: client_init.c:423
Definition: sm.h:301
struct m0_fop * m0_fop_alloc_at(struct m0_rpc_session *sess, struct m0_fop_type *fopt)
Definition: fop.c:122
m0_bcount_t size
Definition: di.c:39
void m0_addb2_force_all(void)
Definition: addb2.c:613
M0_INTERNAL void m0_sm_move(struct m0_sm *mach, int32_t rc, int state)
Definition: sm.c:485
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 int initlift_rpc(struct m0_sm *mach)
Definition: client_init.c:596
static struct m0_fop * fop
Definition: item.c:57
struct m0_fid f_root
Definition: md_fops.h:279
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
int m0_addb2_sys_net_start(struct m0_addb2_sys *sys)
Definition: sys.c:312
struct m0_fop * m0_rpc_item_to_fop(const struct m0_rpc_item *item)
Definition: fop.c:346
struct m0_fid rh_fid
Definition: reqh.h:177
static struct m0_rconfc * rconfc(struct m0_client *m0c)
Definition: client_init.c:310
M0_INTERNAL void m0_confc_close(struct m0_conf_obj *obj)
Definition: confc.c:921
struct m0_rconfc rh_rconfc
Definition: reqh.h:166
static void reqh_fini(void)
Definition: ms_fom_ut.c:351
M0_INTERNAL void m0_motr_ha_stop(struct m0_motr_ha *mha)
Definition: ha.c:560
M0_INTERNAL void m0_dtm0_domain_fini(struct m0_dtm0_domain *dod)
Definition: domain.c:203
const struct m0_conf_obj_type M0_CONF_PROCESS_TYPE
Definition: process.c:161
Definition: nucleus.c:42
M0_INTERNAL uint64_t m0_pid(void)
Definition: kthread.c:290
#define out(...)
Definition: gen.c:41
M0_INTERNAL void m0_client_init_io_op(void)
Definition: io.c:815
M0_INTERNAL int m0_pool_versions_setup(struct m0_pools_common *pc)
Definition: pool.c:1640
struct m0_net_xprt * xprt
Definition: module.c:61
M0_INTERNAL void m0_sm_conf_fini(struct m0_sm_conf *conf)
Definition: sm.c:376
M0_INTERNAL bool m0_sm_conf_is_initialized(const struct m0_sm_conf *conf)
Definition: sm.c:382
void m0_rpc_net_buffer_pool_cleanup(struct m0_net_buffer_pool *app_pool)
Definition: rpc.c:264
M0_INTERNAL void m0_pool_versions_destroy(struct m0_pools_common *pc)
Definition: pool.c:1876
int32_t f_rc
Definition: md_fops.h:270
M0_INTERNAL void m0_sm_asts_run(struct m0_sm_group *grp)
Definition: sm.c:150
static int ha_init(struct m0_client *m0c)
Definition: client_init.c:715
M0_INTERNAL void m0_motr_ha_fini(struct m0_motr_ha *mha)
Definition: ha.c:537
static int get_online_cpus(void)
Definition: client_init.c:1482
uint64_t f_flags
Definition: md_fops.h:266
const char * ca_profile
Definition: helpers.h:34
M0_INTERNAL void m0_reqh_addb2_fini(struct m0_reqh *reqh)
Definition: reqh.c:383
M0_INTERNAL void m0_chan_fini_lock(struct m0_chan *chan)
Definition: chan.c:112
void m0_free(void *data)
Definition: memory.c:146
static struct m0_addb2_source * s
Definition: consumer.c:39
static void initlift_fail(int rc, struct m0_client *m0c)
Definition: client_init.c:388
struct m0_rpc_item f_item
Definition: fop.h:83
static struct m0_reqh_service * service[REQH_IN_UT_MAX]
Definition: long_lock_ut.c:46
static int pools_init(struct m0_client *m0c)
Definition: client_init.c:1031
M0_INTERNAL void m0_chan_broadcast(struct m0_chan *chan)
Definition: chan.c:172
static struct m0_rpc_machine rpc_machine
Definition: service_ut.c:63
int32_t rc
Definition: trigger_fop.h:47
static bool m0c_invariant(struct m0_client *m0c)
Definition: client_init.c:305
struct m0_sm m0c_initlift_sm
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define offsetof(typ, memb)
Definition: misc.h:29
M0_INTERNAL bool m0_sm_group_is_locked(const struct m0_sm_group *grp)
Definition: sm.c:107
struct m0_sm_conf m0_op_conf
Definition: client.c:145
Definition: fop.h:79
M0_INTERNAL int m0__composite_container_init(struct m0_client *cinst)
#define FID_F
Definition: fid.h:75
Definition: trace.h:478
struct m0_fop * rep_fop
Definition: dir.c:334
M0_INTERNAL bool m0_dtm0_in_ut(void)
Definition: service.c:415
M0_INTERNAL void m0_fid_tassume(struct m0_fid *fid, const struct m0_fid_type *ft)
Definition: fid.c:146
M0_INTERNAL void m0_pools_destroy(struct m0_pools_common *pc)
Definition: pool.c:1887
struct m0_net_buffer_pool * ntm_recv_pool
Definition: net.h:896