Motr  M0
rm_service.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2015-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 
28 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_RM
29 #include "lib/trace.h"
30 
31 #include "lib/errno.h"
32 #include "lib/memory.h"
33 #include "lib/bob.h"
34 #include "fid/fid.h"
35 #include "motr/magic.h"
36 #include "reqh/reqh_service.h"
37 #include "reqh/reqh.h"
38 #include "rm/rm.h"
39 #include "rm/rm_service.h"
40 #include "rm/rm_internal.h"
41 #include "rm/rm_fops.h"
42 #include "rm/rm_rwlock.h" /* m0_rw_lockable_type_register */
43 #include "file/file.h"
44 
45 static int rms_allocate(struct m0_reqh_service **service,
46  const struct m0_reqh_service_type *stype);
47 static void rms_fini(struct m0_reqh_service *service);
48 
49 static int rms_start(struct m0_reqh_service *service);
50 static void rms_stop(struct m0_reqh_service *service);
51 
55 static const struct m0_reqh_service_type_ops rms_type_ops = {
57 };
58 
62 static const struct m0_reqh_service_ops rms_ops = {
64  .rso_start_async = m0_reqh_service_async_start_simple,
65  .rso_stop = rms_stop,
66  .rso_fini = rms_fini,
67 };
68 
70  .rst_name = "M0_CST_RMS",
71  .rst_ops = &rms_type_ops,
72  .rst_level = M0_RM_SVC_LEVEL,
73  .rst_typecode = M0_CST_RMS,
74 };
75 
76 static const struct m0_bob_type rms_bob = {
77  .bt_name = "rm service",
78  .bt_magix_offset = offsetof(struct m0_reqh_rm_service, rms_magic),
79  .bt_magix = M0_RM_SERVICE_MAGIC,
80  .bt_check = NULL
81 };
82 
84 
85 const static struct m0_fid_type owner_fid_type = {
86  .ft_id = 'O',
87  .ft_name = "rm owner fid"
88 };
89 
93 M0_INTERNAL int m0_rms_register(void)
94 {
95  M0_ENTRY();
96 
103  return M0_RC(m0_rm_fop_init());
104 }
105 
109 M0_INTERNAL void m0_rms_unregister(void)
110 {
111  M0_ENTRY();
112 
113  m0_rm_fop_fini();
116 
117  M0_LEAVE();
118 }
119 
121  const struct m0_reqh_service_type *stype)
122 {
123  struct m0_reqh_rm_service *rms;
124 
125  M0_ENTRY();
126 
127  M0_PRE(service != NULL && stype != NULL);
128 
129  M0_ALLOC_PTR(rms);
130  if (rms != NULL) {
131  m0_reqh_rm_service_bob_init(rms);
132  *service = &rms->rms_svc;
133  (*service)->rs_ops = &rms_ops;
134  return M0_RC(0);
135  } else
136  return M0_ERR(-ENOMEM);
137 }
138 
139 static void rms_fini(struct m0_reqh_service *service)
140 {
141  struct m0_reqh_rm_service *rms;
142 
143  M0_ENTRY();
144  M0_PRE(service != NULL);
145 
146  rms = bob_of(service, struct m0_reqh_rm_service, rms_svc, &rms_bob);
147  m0_reqh_rm_service_bob_fini(rms);
148  m0_free(rms);
149 
150  M0_LEAVE();
151 }
152 
153 static int rms_start(struct m0_reqh_service *service)
154 {
155  struct m0_reqh_rm_service *rms;
156 
157  M0_PRE(service != NULL);
158  M0_ENTRY();
159 
160  rms = bob_of(service, struct m0_reqh_rm_service, rms_svc, &rms_bob);
161 
162  m0_rm_domain_init(&rms->rms_dom);
163 
164  rms->rms_flock_rt.rt_name = "File Lock Resource Type";
165  rms->rms_rwlockable_rt.rt_name = "Read-Write Lockable Resource Type";
166 
170  return M0_RC(0);
171 }
172 
173 static void rms_resources_free(struct m0_rm_resource_type *rtype)
174 {
175  struct m0_rm_resource *resource;
176  struct m0_rm_remote *rem;
177  struct m0_rm_owner *owner;
178 
179  M0_PRE(rtype != NULL);
180 
181  m0_tl_for(res, &rtype->rt_resources, resource) {
182  m0_tl_for(m0_owners, &resource->r_local, owner) {
183  m0_rm_owner_windup(owner);
185  m0_rm_owner_fini(owner);
186  m0_free(owner);
187  } m0_tl_endfor;
188 
189  m0_tl_teardown(m0_remotes, &resource->r_remotes, rem) {
190  m0_rm_remote_fini(rem);
191  m0_free(rem);
192  }
193  m0_rm_resource_del(resource);
194  m0_rm_resource_free(resource);
195  } m0_tl_endfor;
196 }
197 
198 static void rms_stop(struct m0_reqh_service *service)
199 {
200  struct m0_reqh_rm_service *rms;
201 
202  M0_PRE(service != NULL);
203  M0_ENTRY();
204 
205  rms = bob_of(service, struct m0_reqh_rm_service, rms_svc, &rms_bob);
206 
211  m0_rm_domain_fini(&rms->rms_dom);
212 
213  M0_LEAVE();
214 }
215 
216 static struct m0_rm_owner *rmsvc_owner(const struct m0_rm_resource *res)
217 {
218  M0_PRE(res != NULL);
219  M0_PRE(m0_owners_tlist_length(&res->r_local) <= 1);
220 
221  return m0_owners_tlist_head(&res->r_local);
222 }
223 
225  struct m0_rm_owner **out,
226  struct m0_buf *resbuf)
227 {
228  int rc;
229  struct m0_reqh_rm_service *rms;
230  uint64_t rtype_id;
231  struct m0_rm_resource *resource;
232  struct m0_rm_owner *owner;
233  struct m0_rm_resource_type *rtype;
234  struct m0_bufvec_cursor cursor;
235  struct m0_rm_credit *ow_cr = NULL;
236  struct m0_bufvec datum_buf =
237  M0_BUFVEC_INIT_BUF(&resbuf->b_addr,
238  &resbuf->b_nob);
239 
240  M0_PRE(service != NULL);
241 
242  M0_ENTRY();
243 
244  rms = bob_of(service, struct m0_reqh_rm_service, rms_svc, &rms_bob);
245 
246  /* Find resource type id */
247  m0_bufvec_cursor_init(&cursor, &datum_buf);
248  rc = m0_bufvec_cursor_copyfrom(&cursor, &rtype_id, sizeof rtype_id);
249  if (rc < 0)
250  return M0_RC(rc);
251 
252  rtype = m0_rm_resource_type_lookup(&rms->rms_dom, rtype_id);
253  if (rtype == NULL)
254  return M0_ERR(-EINVAL);
255  M0_ASSERT(rtype->rt_ops != NULL);
256  rc = rtype->rt_ops->rto_decode(&cursor, &resource);
257  if (rc == 0) {
258  struct m0_rm_resource *resadd;
259 
260  resadd = m0_rm_resource_find(rtype, resource);
261  if (resadd == NULL) {
262  resource->r_type = rtype;
263  m0_rm_resource_add(rtype, resource);
264  } else {
265  m0_rm_resource_free(resource);
266  resource = resadd;
267  }
268  owner = rmsvc_owner(resource);
269  if (owner == NULL) {
270  M0_ALLOC_PTR(owner);
271  M0_ALLOC_PTR(ow_cr);
272  if (owner != NULL && ow_cr != NULL) {
273  /*
274  * RM service does not belong to any group at
275  * the moment. If we change this assumption,
276  * we need to introduce function to source
277  * the group id.
278  */
280  resource, NULL);
281  m0_rm_credit_init(ow_cr, owner);
282  ow_cr->cr_ops->cro_initial_capital(ow_cr);
283  rc = m0_rm_owner_selfadd(owner, ow_cr);
284  m0_rm_credit_fini(ow_cr);
285  m0_free(ow_cr);
286  if (rc != 0)
287  goto err_add;
288  } else {
289  rc = M0_ERR(-ENOMEM);
290  goto err_alloc;
291  }
292  }
293  *out = owner;
294  }
295  return M0_RC(rc);
296 
297 err_add:
298  m0_rm_owner_fini(owner);
299 err_alloc:
300  m0_free(ow_cr);
301  m0_free(owner);
302  m0_rm_resource_del(resource);
303  return M0_ERR(rc);
304 }
305 
306 M0_INTERNAL struct m0_rm_domain *
308 {
309  struct m0_reqh_rm_service *rms;
310 
311  M0_PRE(svc != NULL);
312  M0_PRE(svc->rs_type == &m0_rms_type);
313  rms = bob_of(svc, struct m0_reqh_rm_service, rms_svc, &rms_bob);
314  return &rms->rms_dom;
315 }
316 
318 #undef M0_TRACE_SUBSYSTEM
319 
320 /*
321  * Local variables:
322  * c-indentation-style: "K&R"
323  * c-basic-offset: 8
324  * tab-width: 8
325  * fill-column: 80
326  * scroll-step: 1
327  * End:
328  */
329 /*
330  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
331  */
const struct m0_rm_credit_ops * cr_ops
Definition: rm.h:502
static int rms_start(struct m0_reqh_service *service)
Definition: rm_service.c:153
#define M0_BUFVEC_INIT_BUF(addr_ptr, count_ptr)
Definition: vec.h:165
M0_INTERNAL void m0_rms_unregister(void)
Definition: rm_service.c:109
static int rms_allocate(struct m0_reqh_service **service, const struct m0_reqh_service_type *stype)
Definition: rm_service.c:120
M0_INTERNAL int m0_rm_owner_selfadd(struct m0_rm_owner *owner, struct m0_rm_credit *r)
Definition: rm.c:732
struct m0_rm_resource_type * r_type
Definition: rm.h:304
#define M0_PRE(cond)
int(* rso_start)(struct m0_reqh_service *service)
Definition: reqh_service.h:360
#define NULL
Definition: misc.h:38
M0_INTERNAL struct m0_rm_domain * m0_rm_svc_domain_get(const struct m0_reqh_service *svc)
Definition: rm_service.c:307
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
static void rms_resources_free(struct m0_rm_resource_type *rtype)
Definition: rm_service.c:173
void * b_addr
Definition: buf.h:39
M0_INTERNAL struct m0_rm_resource_type * m0_rm_resource_type_lookup(const struct m0_rm_domain *dom, const uint64_t rtype_id)
Definition: rm.c:327
M0_LEAVE()
M0_BOB_DEFINE(M0_INTERNAL, &rms_bob, m0_reqh_rm_service)
uint8_t ft_id
Definition: fid.h:101
struct m0_reqh_service rms_svc
Definition: rm_service.h:75
M0_INTERNAL void m0_rm_domain_init(struct m0_rm_domain *dom)
Definition: rm.c:215
static const struct m0_reqh_service_ops rms_ops
Definition: rm_service.c:62
int m0_reqh_service_type_register(struct m0_reqh_service_type *rstype)
Definition: reqh_service.c:473
const char * bt_name
Definition: bob.h:73
M0_INTERNAL int m0_rm_owner_timedwait(struct m0_rm_owner *owner, uint64_t state, const m0_time_t abs_timeout)
Definition: rm.c:892
#define m0_tl_endfor
Definition: tlist.h:700
M0_INTERNAL int m0_rm_svc_owner_create(struct m0_reqh_service *service, struct m0_rm_owner **out, struct m0_buf *resbuf)
Definition: rm_service.c:224
M0_INTERNAL void m0_file_lock_type_deregister(struct m0_rm_resource_type *flock_rt)
Definition: file.c:561
static struct m0_rm_owner * rmsvc_owner(const struct m0_rm_resource *res)
Definition: rm_service.c:216
return M0_RC(rc)
#define M0_ENTRY(...)
Definition: trace.h:170
Definition: buf.h:37
M0_INTERNAL int m0_file_lock_type_register(struct m0_rm_domain *dom, struct m0_rm_resource_type *flock_rt)
Definition: file.c:549
struct m0_rm_domain rms_dom
Definition: rm_service.h:78
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_copyfrom(struct m0_bufvec_cursor *scur, void *ddata, m0_bcount_t num_bytes)
Definition: vec.c:692
static const struct m0_bob_type rms_bob
Definition: rm_service.c:76
struct m0_tl r_local
Definition: rm.h:323
static const struct m0_reqh_service_type_ops rms_type_ops
Definition: rm_service.c:55
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_fid_type_register(const struct m0_fid_type *fidt)
Definition: fid.c:46
static const struct socktype stype[]
Definition: sock.c:1156
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
const struct m0_uint128 m0_rm_no_group
Definition: rm.c:211
m0_bcount_t b_nob
Definition: buf.h:38
#define M0_ASSERT(cond)
M0_INTERNAL void m0_rm_owner_init_rfid(struct m0_rm_owner *owner, const struct m0_uint128 *group, struct m0_rm_resource *res, struct m0_rm_remote *creditor)
Definition: rm.c:649
M0_INTERNAL void m0_rm_owner_fini(struct m0_rm_owner *owner)
Definition: rm.c:943
const char * rst_name
Definition: reqh_service.h:447
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
M0_INTERNAL void m0_bufvec_cursor_init(struct m0_bufvec_cursor *cur, const struct m0_bufvec *bvec)
Definition: vec.c:563
M0_INTERNAL void m0_rw_lockable_type_deregister(struct m0_rm_resource_type *rtype)
Definition: rm_rwlock.c:588
int(* rto_decode)(struct m0_bufvec_cursor *cur, struct m0_rm_resource **resource)
Definition: rm.h:468
M0_INTERNAL void m0_fid_type_unregister(const struct m0_fid_type *fidt)
Definition: fid.c:55
static const struct m0_fid_type owner_fid_type
Definition: rm_service.c:85
M0_INTERNAL void m0_rm_resource_free(struct m0_rm_resource *res)
Definition: rm.c:386
int m0_reqh_service_async_start_simple(struct m0_reqh_service_start_async_ctx *asc)
Definition: reqh_service.c:601
struct m0_reqh_service_type m0_rms_type
Definition: rm_service.c:69
const char * rt_name
Definition: rm.h:389
M0_INTERNAL void m0_rm_resource_add(struct m0_rm_resource_type *rtype, struct m0_rm_resource *res)
Definition: rm.c:337
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_rm_fop_init(void)
Definition: rm_fops.c:561
M0_INTERNAL void m0_rm_credit_init(struct m0_rm_credit *credit, struct m0_rm_owner *owner)
Definition: rm.c:964
M0_INTERNAL void m0_rm_remote_fini(struct m0_rm_remote *rem)
Definition: rm.c:1431
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL int m0_rms_register(void)
Definition: rm_service.c:93
Definition: rm.h:863
static void rms_stop(struct m0_reqh_service *service)
Definition: rm_service.c:198
M0_INTERNAL void m0_rm_owner_windup(struct m0_rm_owner *owner)
Definition: rm.c:930
static struct m0_net_test_service svc
Definition: service.c:34
const struct m0_rm_resource_type_ops * rt_ops
Definition: rm.h:388
void(* cro_initial_capital)(struct m0_rm_credit *self)
Definition: rm.h:671
struct m0_rm_resource_type rms_flock_rt
Definition: rm_service.h:81
#define out(...)
Definition: gen.c:41
M0_INTERNAL void m0_rm_credit_fini(struct m0_rm_credit *credit)
Definition: rm.c:985
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
struct m0_rm_resource_type rms_rwlockable_rt
Definition: rm_service.h:84
void m0_free(void *data)
Definition: memory.c:146
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 int m0_rw_lockable_type_register(struct m0_rm_domain *dom, struct m0_rm_resource_type *rtype)
Definition: rm_rwlock.c:575
M0_INTERNAL void m0_rm_domain_fini(struct m0_rm_domain *dom)
Definition: rm.c:227
#define offsetof(typ, memb)
Definition: misc.h:29
static void rms_fini(struct m0_reqh_service *service)
Definition: rm_service.c:139
M0_INTERNAL void m0_rm_resource_del(struct m0_rm_resource *res)
Definition: rm.c:361
Definition: vec.h:145
struct m0_tl r_remotes
Definition: rm.h:315
M0_INTERNAL void m0_rm_fop_fini(void)
Definition: rm_fops.c:547
struct m0_tl rt_resources
Definition: rm.h:409
M0_INTERNAL struct m0_rm_resource * m0_rm_resource_find(const struct m0_rm_resource_type *rt, const struct m0_rm_resource *res)
Definition: rm.c:243
const struct m0_reqh_service_ops * rs_ops
Definition: reqh_service.h:254