Motr  M0
confd.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_CONF
23 #include "lib/trace.h"
24 
25 #include "conf/confd.h"
26 #include "conf/obj_ops.h" /* m0_conf_obj_find */
27 #include "conf/onwire.h" /* m0_confx, m0_confx_obj */
28 #include "conf/preload.h" /* m0_confx_free */
29 #include "conf/dir.h" /* m0_conf_dir_tl */
30 #include "lib/errno.h" /* ENOMEM */
31 #include "lib/memory.h" /* M0_ALLOC_PTR */
32 #include "lib/string.h" /* m0_strdup */
33 #include "lib/fs.h" /* m0_file_read */
34 #include "motr/magic.h" /* M0_CONFD_MAGIC */
35 #include "motr/setup.h" /* m0_reqh_context */
36 
430 
439 static int confd_allocate(struct m0_reqh_service **service,
440  const struct m0_reqh_service_type *stype);
441 static int confd_cache_preload(struct m0_conf_cache *cache, const char *str);
442 
443 const struct m0_bob_type m0_confd_bob = {
444  .bt_name = "m0_confd",
445  .bt_magix_offset = M0_MAGIX_OFFSET(struct m0_confd, d_magic),
446  .bt_magix = M0_CONFD_MAGIC
447 };
448 
451 };
452 
454  .rst_name = "M0_CST_CONFD",
455  .rst_ops = &confd_stype_ops,
456  .rst_level = M0_RS_LEVEL_NORMAL,
457  .rst_typecode = M0_CST_CONFD,
458 };
459 
460 M0_INTERNAL int m0_confd_register(void)
461 {
463 }
464 
465 M0_INTERNAL void m0_confd_unregister(void)
466 {
468 }
469 
470 static int confd_start(struct m0_reqh_service *service);
471 static void confd_stop(struct m0_reqh_service *service);
472 static void confd_fini(struct m0_reqh_service *service);
473 
474 static const struct m0_reqh_service_ops confd_ops = {
476  .rso_start_async = m0_reqh_service_async_start_simple,
477  .rso_stop = confd_stop,
478  .rso_fini = confd_fini
479 };
480 
483  const struct m0_reqh_service_type *stype)
484 {
485  struct m0_confd *confd;
486 
487  M0_ENTRY();
489 
490  M0_ALLOC_PTR(confd);
491  if (confd == NULL)
492  return M0_ERR(-ENOMEM);
493 
494  m0_bob_init(&m0_confd_bob, confd);
495  *service = &confd->d_reqh;
496  (*service)->rs_ops = &confd_ops;
497  return M0_RC(0);
498 }
499 
501 static void confd_fini(struct m0_reqh_service *service)
502 {
503  struct m0_confd *confd = bob_of(service, struct m0_confd, d_reqh,
504  &m0_confd_bob);
505  M0_ENTRY();
506 
507  m0_bob_fini(&m0_confd_bob, confd);
508  m0_free(confd);
509 
510  M0_LEAVE();
511 }
512 
513 M0_INTERNAL int m0_confd_cache_create(struct m0_conf_cache **out,
514  struct m0_mutex *cache_lock,
515  const char *confstr)
516 {
517  int rc;
518 
519  M0_ENTRY();
520  M0_PRE(confstr != NULL);
521 
522  M0_ALLOC_PTR(*out);
523  if (*out == NULL)
524  return M0_ERR(-ENOMEM);
525  m0_conf_cache_init(*out, cache_lock);
527  rc = confd_cache_preload(*out, confstr);
529  if (rc == 0)
530  return M0_RC(0);
532  m0_free0(out);
533  return M0_ERR(rc);
534 }
535 
536 M0_INTERNAL void m0_confd_cache_destroy(struct m0_conf_cache *cache)
537 {
538  M0_ENTRY();
540  m0_free(cache);
541  M0_LEAVE();
542 }
543 
545 {
546  struct m0_confd *confd = bob_of(service, struct m0_confd, d_reqh,
547  &m0_confd_bob);
548  char *path = NULL;
549  char *confstr = NULL;
550  int rc;
551 
552  M0_ENTRY();
553  m0_mutex_init(&confd->d_cache_lock);
555  m0_file_read(path, &confstr) ?:
556  m0_confd_cache_create(&confd->d_cache, &confd->d_cache_lock,
557  confstr);
558  m0_free(confstr);
559  m0_free(path);
560  if (rc != 0) {
561  m0_mutex_fini(&confd->d_cache_lock);
562  return M0_ERR(rc);
563  }
564  return M0_RC(0);
565 }
566 
567 static void confd_stop(struct m0_reqh_service *service)
568 {
569  struct m0_confd *confd = bob_of(service, struct m0_confd, d_reqh,
570  &m0_confd_bob);
571  M0_ENTRY();
572  M0_PRE(confd->d_cache != NULL);
574  m0_mutex_fini(&confd->d_cache_lock);
575  M0_LEAVE();
576 }
577 
578 static int confd_cache_preload(struct m0_conf_cache *cache, const char *str)
579 {
580  struct m0_confx *enc;
581  int i;
582  int rc;
583  struct m0_conf_obj *obj;
584 
585  M0_ENTRY();
586  M0_PRE(m0_mutex_is_locked(cache->ca_lock));
587 
588  rc = m0_confstr_parse(str, &enc);
589  if (rc != 0)
590  return M0_ERR(rc);
591 
592  for (i = 0; i < enc->cx_nr && rc == 0; ++i) {
593  struct m0_conf_obj *obj;
594  const struct m0_confx_obj *xobj = M0_CONFX_AT(enc, i);
595 
597  m0_conf_obj_fill(obj, xobj);
598  }
599 
600  /* Check for orphan configuration object. */
601  m0_tl_for(m0_conf_cache, &cache->ca_registry, obj) {
603  obj->co_parent != NULL ||
604  m0_tlink_is_in(&m0_conf_dir_tl, obj)),
605  FID_F" is not part of configuration tree.",
606  FID_P(&obj->co_id));
607  } m0_tlist_endfor;
608 
609  /*
610  * Now having cache updated, reset version number to M0_CONF_VER_UNKNOWN
611  * to let confd update it properly somewhat later when processing next
612  * configuration read request. See confx_populate().
613  */
614  cache->ca_ver = M0_CONF_VER_UNKNOWN;
615  m0_confx_free(enc);
616  return M0_RC(rc);
617 }
618 
619 static bool nil(const char *s)
620 {
621  return s == NULL || *s == '\0';
622 }
623 
625  char **dbpath)
626 {
627  M0_ENTRY();
628 
629  *dbpath = NULL;
631  *dbpath = m0_buf_strdup(&service->rs_ss_param);
632  if (nil(*dbpath)) {
633  m0_free(*dbpath);
634  *dbpath = m0_strdup((char*)service->rs_reqh_ctx->rc_confdb);
635  }
636 
637  if (*dbpath == NULL)
638  return M0_ERR(-ENOMEM);
639  if (**dbpath == '\0')
640  return M0_ERR(-EPROTO);
641  return M0_RC(0);
642 }
643 
645 #undef M0_TRACE_SUBSYSTEM
const struct m0_conf_obj_type * m0_conf_obj_type(const struct m0_conf_obj *obj)
Definition: obj.c:363
Definition: beck.c:235
static bool nil(const char *s)
Definition: confd.c:619
#define M0_PRE(cond)
M0_INTERNAL bool m0_buf_is_set(const struct m0_buf *buf)
Definition: buf.c:127
M0_INTERNAL void m0_confx_free(struct m0_confx *enc)
Definition: preload.c:33
int(* rso_start)(struct m0_reqh_service *service)
Definition: reqh_service.h:360
#define m0_strdup(s)
Definition: string.h:43
#define NULL
Definition: misc.h:38
M0_LEAVE()
M0_INTERNAL int m0_file_read(const char *path, char **out)
Definition: fs.c:61
const char * rc_confdb
Definition: setup.h:301
struct m0_reqh_service d_reqh
Definition: confd.h:153
static void confd_stop(struct m0_reqh_service *service)
Definition: confd.c:567
const struct m0_conf_obj_type M0_CONF_ROOT_TYPE
Definition: root.c:214
#define M0_CONFX_AT(cx, idx)
Definition: onwire.h:271
int m0_reqh_service_type_register(struct m0_reqh_service_type *rstype)
Definition: reqh_service.c:473
static struct foo * obj
Definition: tlist.c:302
const char * bt_name
Definition: bob.h:73
M0_INTERNAL int m0_confd_register(void)
Definition: confd.c:460
struct m0_mutex d_cache_lock
Definition: confd.h:156
struct m0_reqh_service_type m0_confd_stype
Definition: confd.c:453
return M0_RC(rc)
M0_INTERNAL void m0_confd_unregister(void)
Definition: confd.c:465
struct m0_buf rs_ss_param
Definition: reqh_service.h:281
M0_INTERNAL int m0_conf_obj_fill(struct m0_conf_obj *dest, const struct m0_confx_obj *src)
Definition: obj_ops.c:232
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL int m0_confd_service_to_filename(struct m0_reqh_service *service, char **dbpath)
Definition: confd.c:624
static const struct m0_reqh_service_ops confd_ops
Definition: confd.c:474
int i
Definition: dir.c:1033
M0_INTERNAL void m0_bob_init(const struct m0_bob_type *bt, void *bob)
Definition: bob.c:61
return M0_ERR(-EOPNOTSUPP)
uint32_t cx_nr
Definition: onwire.h:259
static const struct socktype stype[]
Definition: sock.c:1156
#define m0_free0(pptr)
Definition: memory.h:77
static int confd_start(struct m0_reqh_service *service)
Definition: confd.c:544
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
Definition: mutex.c:95
const char * rst_name
Definition: reqh_service.h:447
const struct m0_bob_type m0_confd_bob
Definition: confd.c:443
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
M0_INTERNAL void m0_bob_fini(const struct m0_bob_type *bt, void *bob)
Definition: bob.c:68
struct m0_reqh_context * rs_reqh_ctx
Definition: reqh_service.h:271
M0_INTERNAL int m0_confd_cache_create(struct m0_conf_cache **out, struct m0_mutex *cache_lock, const char *confstr)
Definition: confd.c:513
M0_INTERNAL void m0_conf_cache_init(struct m0_conf_cache *cache, struct m0_mutex *lock)
Definition: cache.c:66
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
M0_INTERNAL void m0_confd_cache_destroy(struct m0_conf_cache *cache)
Definition: confd.c:536
M0_INTERNAL int m0_conf_obj_find(struct m0_conf_cache *cache, const struct m0_fid *id, struct m0_conf_obj **out)
Definition: obj_ops.c:136
static int confd_cache_preload(struct m0_conf_cache *cache, const char *str)
Definition: confd.c:578
#define FID_P(f)
Definition: fid.h:77
static const struct m0_reqh_service_type_ops confd_stype_ops
Definition: confd.c:449
int m0_reqh_service_async_start_simple(struct m0_reqh_service_start_async_ctx *asc)
Definition: reqh_service.c:601
struct m0_conf_cache * d_cache
Definition: confd.h:163
M0_INTERNAL bool m0_tlink_is_in(const struct m0_tl_descr *d, const void *obj)
Definition: tlist.c:103
static void confd_fini(struct m0_reqh_service *service)
Definition: confd.c:501
M0_INTERNAL char * m0_buf_strdup(const struct m0_buf *buf)
Definition: buf.c:140
#define M0_MAGIX_OFFSET(type, field)
Definition: misc.h:356
int(* rsto_service_allocate)(struct m0_reqh_service **service, const struct m0_reqh_service_type *stype)
Definition: reqh_service.h:435
M0_INTERNAL int m0_confstr_parse(const char *str, struct m0_confx **out)
Definition: preload.c:41
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
#define m0_tlist_endfor
Definition: tlist.h:448
#define M0_ASSERT_INFO(cond, fmt,...)
#define out(...)
Definition: gen.c:41
static int confd_allocate(struct m0_reqh_service **service, const struct m0_reqh_service_type *stype)
Definition: confd.c:482
M0_INTERNAL void m0_conf_cache_fini(struct m0_conf_cache *cache)
Definition: cache.c:183
M0_INTERNAL void m0_conf_cache_lock(struct m0_conf_cache *cache)
Definition: cache.c:50
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
static struct m0_addb2_source * s
Definition: consumer.c:39
void m0_reqh_service_type_unregister(struct m0_reqh_service_type *rstype)
Definition: reqh_service.c:490
static struct m0_reqh_service * service[REQH_IN_UT_MAX]
Definition: long_lock_ut.c:46
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL void m0_conf_cache_unlock(struct m0_conf_cache *cache)
Definition: cache.c:55
#define FID_F
Definition: fid.h:75
const struct m0_fid * m0_conf_objx_fid(const struct m0_confx_obj *obj)
Definition: obj_ops.c:266
const struct m0_reqh_service_ops * rs_ops
Definition: reqh_service.h:254