Motr  M0
confd_stob.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 "lib/assert.h"
26 #include "lib/misc.h" /* M0_SET0 */
27 #include "lib/memory.h" /* m0_alloc_align */
28 #include "lib/errno.h"
29 #include "lib/string.h" /* m0_aspritf */
30 #include "conf/confd.h"
31 #include "conf/confd_stob.h"
32 #include "fol/fol.h"
33 #include "stob/domain.h"
34 #include "stob/io.h"
35 #include "stob/stob.h"
36 #ifndef __KERNEL__
37  #include <sys/stat.h> /* fstat */
38 #endif
39 
45 enum {
46  M0_CONFD_STOB_DOMAIN_KEY = 0x33C0FDD077,
47 };
48 
49 
51  const char *location,
52  struct m0_fid *confd_fid)
53 {
54  int rc;
55  struct m0_stob_domain *dom;
56  struct m0_stob_id stob_id;
57 
58  M0_PRE(stob != NULL);
59  M0_PRE(location != NULL);
60  M0_PRE(confd_fid != NULL);
61 
62  M0_ENTRY();
63 
64  *stob = NULL;
65 
66  /*
67  * TODO FIXME Current workflow assumes that m0_confd_stob_fini() is
68  * called even if m0_confd_stob_init() fails. Therefore, there is no
69  * cleanup code for error flow in this function.
70  * There are two problems:
71  * 1. If m0_stob_find() fails m0_confd_stob_fini() doesn't finalise
72  * stob domain, because `stob` remains NULL;
73  * 2. There is case when m0_stob_domain_find_by_location() returns
74  * existing stob domain, but m0_confd_stob_fini() finalises it.
75  * This leads to possible double finalisation, because there is
76  * other user that originally initialises the domain.
77  *
78  * Possible fix:
79  * 1. Cleanup on fail and call m0_confd_stob_fini() only after
80  * successful initialisation;
81  * 2. Move stob domain init/fini to respective subsystem init/fini
82  * functions
83  */
84 
86  rc = dom != NULL ? 0 :
89  NULL, &dom);
90  if (rc != 0)
91  return M0_ERR(rc);
92 
93  m0_stob_id_make(confd_fid->f_container, confd_fid->f_key,
94  &dom->sd_id, &stob_id);
95  rc = m0_stob_find(&stob_id, stob);
96  if (rc == 0 && m0_stob_state_get(*stob) == CSS_UNKNOWN)
98  if (rc == 0 && m0_stob_state_get(*stob) == CSS_NOENT)
100 
101  return M0_RC(rc);
102 }
103 
105 {
106  struct m0_stob_domain *dom;
107 
108  M0_ENTRY();
109 
110  if (stob != NULL) {
112  m0_stob_put(stob);
114  }
115 
116  M0_LEAVE();
117 }
118 
119 /* TODO get length */
120 #ifndef __KERNEL__
122 {
123  struct stat statbuf;
124  int fd = m0_stob_fd(stob);
125 
126  return fstat(fd, &statbuf) == 0 ? statbuf.st_size : 0;
127 }
128 #else
130 {
131  return 0;
132 }
133 #endif
134 
135 int m0_confd_stob_read(struct m0_stob *stob, char **str)
136 {
137  int rc;
138  m0_bcount_t length;
139  struct m0_bufvec bv = M0_BUFVEC_INIT_BUF((void**)str, &length);
140 
141  M0_PRE(stob != NULL);
142  M0_PRE(str != NULL);
143 
144  length = confd_stob_length(stob);
145 
146  *str = m0_alloc_aligned(length + 1, m0_stob_block_shift(stob));
147  if (*str == NULL)
148  return M0_ERR(-ENOMEM);
149 
151  if (rc != 0) {
152  m0_free(*str);
153  return M0_ERR(rc);
154  }
155 
156  return M0_RC(0);
157 }
158 
160  struct m0_bufvec *bufvec)
161 {
162  M0_PRE(stob != NULL);
163  M0_PRE(bufvec != NULL);
164 
165  return m0_stob_io_bufvec_launch(stob, bufvec, SIO_WRITE, 0);
166 }
167 
168 int m0_confd_stob_write(struct m0_stob *stob, char *str)
169 {
170  m0_bcount_t length = strlen(str);
172  struct m0_bufvec bv = M0_BUFVEC_INIT_BUF((void**)&str, &length);
173 
174  M0_PRE(stob != NULL);
175  M0_PRE(str != NULL);
176  M0_PRE(m0_addr_is_aligned(str, shift));
177 
178  return m0_stob_io_bufvec_launch(stob, &bv, SIO_WRITE, 0);
179 }
180 
181 M0_INTERNAL int m0_conf_stob_location_generate(struct m0_fom *fom,
182  char **location)
183 {
184  int rc;
185  char *conf_path;
186  char *name;
187  const char stob_prefix[] = "linuxstob:";
188  const char stob_suffix[] = "confd";
189 
190  M0_PRE(fom != NULL);
191  M0_PRE(location != NULL);
192 
193  M0_ENTRY();
194 
195  rc = m0_confd_service_to_filename(fom->fo_service, &conf_path);
196  if (rc != 0) {
197  *location = NULL;
198  return M0_ERR(rc);
199  }
200 
201  /*
202  * Generate location to store configuration databases loaded using
203  * load FOP. The idea is that this a same folder as folder of
204  * configuration file provided to confd at startup.
205  */
206  name = strrchr(conf_path, '/');
207  if (name != NULL)
208  *name = '\0';
209  m0_asprintf(location, "%s%s/%s",
210  stob_prefix,
211  name == NULL ? "." : conf_path,
212  stob_suffix);
213  m0_free(conf_path);
214 
215  return *location == NULL ? M0_ERR(-ENOMEM) : M0_RC(rc);
216 }
217 
220 /*
221  * Local variables:
222  * c-indentation-style: "K&R"
223  * c-basic-offset: 8
224  * tab-width: 8
225  * fill-column: 80
226  * scroll-step: 1
227  * End:
228  */
#define M0_BUFVEC_INIT_BUF(addr_ptr, count_ptr)
Definition: vec.h:165
M0_INTERNAL struct m0_stob_domain * m0_stob_dom_get(struct m0_stob *stob)
Definition: stob.c:338
#define M0_PRE(cond)
M0_INTERNAL int m0_stob_io_bufvec_launch(struct m0_stob *stob, struct m0_bufvec *bufvec, int op_code, m0_bindex_t offset)
Definition: io.c:248
M0_INTERNAL int struct dentry struct kstat * stat
Definition: dir.c:1433
#define NULL
Definition: misc.h:38
Definition: io.h:230
M0_INTERNAL int m0_stob_locate(struct m0_stob *stob)
Definition: stob.c:128
static bool m0_addr_is_aligned(const void *addr, unsigned shift)
Definition: memory.h:107
M0_LEAVE()
uint64_t m0_bcount_t
Definition: types.h:77
static m0_bcount_t confd_stob_length(struct m0_stob *stob)
Definition: confd_stob.c:121
const char * location
Definition: storage.c:50
return M0_RC(rc)
M0_INTERNAL uint32_t m0_stob_block_shift(struct m0_stob *stob)
Definition: stob.c:270
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL struct m0_stob_domain * m0_stob_domain_find_by_location(const char *location)
Definition: domain.c:284
M0_INTERNAL int m0_confd_service_to_filename(struct m0_reqh_service *service, char **dbpath)
Definition: confd.c:624
return M0_ERR(-EOPNOTSUPP)
void m0_confd_stob_fini(struct m0_stob *stob)
Definition: confd_stob.c:104
M0_INTERNAL int m0_conf_stob_location_generate(struct m0_fom *fom, char **location)
Definition: confd_stob.c:181
const char * name
Definition: trace.c:110
Definition: stob.h:163
static struct m0_stob * stob
Definition: storage.c:39
int m0_confd_stob_init(struct m0_stob **stob, const char *location, struct m0_fid *confd_fid)
Definition: confd_stob.c:50
static struct m0_stob_domain * dom
Definition: storage.c:38
M0_INTERNAL void m0_stob_id_make(uint64_t container, uint64_t key, const struct m0_fid *dom_id, struct m0_stob_id *stob_id)
Definition: stob.c:343
int m0_confd_stob_bufvec_write(struct m0_stob *stob, struct m0_bufvec *bufvec)
Definition: confd_stob.c:159
uint64_t f_container
Definition: fid.h:39
Definition: dump.c:103
int m0_confd_stob_write(struct m0_stob *stob, char *str)
Definition: confd_stob.c:168
M0_INTERNAL void m0_stob_domain_fini(struct m0_stob_domain *dom)
Definition: domain.c:204
M0_INTERNAL int m0_stob_create(struct m0_stob *stob, struct m0_dtx *dtx, const char *str_cfg)
Definition: stob.c:154
Definition: fom.h:481
struct m0_fid sd_id
Definition: domain.h:96
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
Definition: stob.h:91
Definition: fid.h:38
M0_INTERNAL int m0_stob_domain_create_or_init(const char *location, const char *str_cfg_init, uint64_t dom_key, const char *str_cfg_create, struct m0_stob_domain **out)
Definition: domain.c:262
uint64_t f_key
Definition: fid.h:40
M0_INTERNAL int m0_stob_fd(struct m0_stob *stob)
Definition: stob.c:360
#define m0_asprintf(s, fmt,...)
Definition: string.h:44
struct m0t1fs_filedata * fd
Definition: dir.c:1030
M0_INTERNAL int m0_stob_find(const struct m0_stob_id *id, struct m0_stob **out)
Definition: stob.c:92
int m0_confd_stob_read(struct m0_stob *stob, char **str)
Definition: confd_stob.c:135
M0_INTERNAL void * m0_alloc_aligned(size_t size, unsigned shift)
Definition: memory.c:168
Definition: io.h:229
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL void m0_stob_put(struct m0_stob *stob)
Definition: stob.c:291
Definition: vec.h:145