Motr  M0
dtx.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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 
30 #include "lib/assert.h"
31 #include "lib/memory.h"
32 #include "lib/errno.h" /* ENOMEM, ENOSYS */
33 
34 #include "dtm/catalogue.h"
35 #include "dtm/dtm_internal.h"
36 #include "dtm/history.h"
37 #include "dtm/dtm.h"
38 #include "dtm/dtx.h"
39 
40 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_DTM
41 #include "lib/trace.h"
42 
44  struct m0_dtm_dtx *pa_dtx;
46 };
47 
48 static const struct m0_dtm_history_ops dtx_ops;
49 static const struct m0_dtm_history_ops dtx_srv_ops;
50 static struct m0_dtm_controlh *dtx_get(struct m0_dtm_dtx *dtx,
51  struct m0_dtm_remote *rem);
52 static struct m0_dtm_history *dtx_srv_alloc(struct m0_dtm *dtm,
53  const struct m0_uint128 *id,
54  void *datum);
55 static struct m0_dtm_history *pa_history(struct m0_dtm_dtx_party *pa);
56 
57 M0_INTERNAL int m0_dtm_dtx_init(struct m0_dtm_dtx *dtx,
58  const struct m0_uint128 *id,
59  struct m0_dtm *dtm, uint32_t nr_max)
60 {
61  dtx->dt_id = *id;
62  dtx->dt_dtm = dtm;
63  dtx->dt_nr_max = nr_max;
64  dtx->dt_nr = dtx->dt_nr_fixed = 0;
65  M0_ALLOC_ARR(dtx->dt_party, nr_max);
66  return dtx->dt_party == NULL ? -ENOMEM : 0;
67 }
68 
69 M0_INTERNAL void m0_dtm_dtx_fini(struct m0_dtm_dtx *dtx)
70 {
71  if (dtx->dt_party != NULL) {
72  uint32_t i;
73 
74  for (i = 0; i < dtx->dt_nr; ++i)
76  m0_free(dtx->dt_party);
77  }
78 }
79 
80 M0_INTERNAL void m0_dtm_dtx_add(struct m0_dtm_dtx *dtx,
81  struct m0_dtm_oper *oper)
82 {
83  oper_for(oper, i) {
84  if (oper_update_unique(oper, i))
86  oper);
87  } oper_endfor;
88 }
89 
90 M0_INTERNAL void m0_dtm_dtx_close(struct m0_dtm_dtx *dtx)
91 {
92  uint32_t i;
93 
94  for (i = 0; i < dtx->dt_nr; ++i) {
95  struct m0_dtm_history *history = pa_history(&dtx->dt_party[i]);
96  struct m0_dtm_update *update;
97 
98  update = up_update(history_latest(history));
99  M0_ASSERT(update != NULL);
102  }
103 }
104 
105 static void dtx_noop(void *unused)
106 {}
107 
108 static int dtx_find(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht,
109  const struct m0_uint128 *id,
110  struct m0_dtm_history **out)
111 {
112  M0_IMPOSSIBLE("Looking for dtx?");
113  return M0_ERR(-ENOSYS);
114 }
115 
116 static const struct m0_dtm_history_type_ops dtx_htype_ops = {
117  .hito_find = &dtx_find
118 };
119 
120 enum {
123 };
124 
125 M0_INTERNAL const struct m0_dtm_history_type m0_dtm_dtx_htype = {
127  .hit_rem_id = M0_DTM_HTYPE_DTX_SRV,
128  .hit_name = "dtx-party",
129  .hit_ops = &dtx_htype_ops
130 };
131 
132 static const struct m0_uint128 *dtx_id(const struct m0_dtm_history *history)
133 {
134  struct m0_dtm_dtx_party *pa;
135 
136  pa = M0_AMB(pa, history, pa_ch.ch_history);
137  return &pa->pa_dtx->dt_id;
138 }
139 
140 static void dtx_fixed(struct m0_dtm_history *history)
141 {
142  struct m0_dtm_dtx_party *pa;
143  struct m0_dtm_dtx *dx;
144 
145  pa = M0_AMB(pa, history, pa_ch.ch_history);
146  dx = pa->pa_dtx;
148  if (++dx->dt_nr_fixed == dx->dt_nr) {
149  }
150 }
151 
152 static const struct m0_dtm_history_ops dtx_ops = {
154  .hio_id = &dtx_id,
155  .hio_persistent = (void *)&dtx_noop,
156  .hio_fixed = &dtx_fixed,
158 };
159 
160 static struct m0_dtm_history *pa_history(struct m0_dtm_dtx_party *pa)
161 {
162  return &pa->pa_ch.ch_history;
163 }
164 
165 static struct m0_dtm_controlh *dtx_get(struct m0_dtm_dtx *dtx,
166  struct m0_dtm_remote *rem)
167 {
168  uint32_t i;
169  struct m0_dtm_dtx_party *pa;
170  struct m0_dtm_history *history;
171 
172  for (i = 0, pa = dtx->dt_party; i < dtx->dt_nr; ++i, ++pa) {
173  if (pa_history(pa)->h_rem == rem)
174  return &pa->pa_ch;
175  }
176  M0_ASSERT(dtx->dt_nr < dtx->dt_nr_max);
177  m0_dtm_controlh_init(&pa->pa_ch, dtx->dt_dtm);
178  history = pa_history(pa);
179  history->h_rem = rem;
180  history->h_ops = &dtx_ops;
181  history->h_hi.hi_flags |= M0_DHF_OWNED;
182  pa->pa_dtx = dtx;
183  dtx->dt_nr++;
184  return &pa->pa_ch;
185 }
186 
187 static int dtx_srv_find(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht,
188  const struct m0_uint128 *id,
189  struct m0_dtm_history **out)
190 {
192  id, &dtx_srv_alloc, NULL, out);
193 }
194 
197 };
198 
199 M0_INTERNAL const struct m0_dtm_history_type m0_dtm_dtx_srv_htype = {
201  .hit_rem_id = M0_DTM_HTYPE_DTX,
202  .hit_name = "distributed transaction service side",
203  .hit_ops = &dtx_srv_htype_ops
204 };
205 
206 static const struct m0_uint128 *dtx_srv_id(const struct m0_dtm_history *history)
207 {
208  struct m0_dtm_dtx_srv *dtx;
209 
210  dtx = M0_AMB(dtx, history, ds_history);
211  return &dtx->ds_id;
212 }
213 
214 static const struct m0_dtm_history_ops dtx_srv_ops = {
216  .hio_id = &dtx_srv_id,
217  .hio_persistent = (void *)&dtx_noop,
218  .hio_fixed = (void *)&dtx_noop,
219  .hio_update = &m0_dtm_controlh_update
220 };
221 
222 static struct m0_dtm_history *dtx_srv_alloc(struct m0_dtm *dtm,
223  const struct m0_uint128 *id,
224  void *datum)
225 {
226  struct m0_dtm_dtx_srv *dtx;
227  struct m0_dtm_history *history;
228 
229  M0_ALLOC_PTR(dtx);
230  if (dtx != NULL) {
231  history = &dtx->ds_history;
232  dtx->ds_id = *id;
233  m0_dtm_history_init(&dtx->ds_history, dtm);
234  history->h_ops = &dtx_srv_ops;
235  } else
236  history = NULL;
237  return history;
238 }
239 
242 #undef M0_TRACE_SUBSYSTEM
243 
244 /*
245  * Local variables:
246  * c-indentation-style: "K&R"
247  * c-basic-offset: 8
248  * tab-width: 8
249  * fill-column: 80
250  * scroll-step: 1
251  * End:
252  */
253 /*
254  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
255  */
struct m0_dtm_dtx_party * dt_party
Definition: dtx.h:50
uint64_t id
Definition: cob.h:2380
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
static struct m0_dtm_controlh * dtx_get(struct m0_dtm_dtx *dtx, struct m0_dtm_remote *rem)
Definition: dtx.c:165
static int dtx_srv_find(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht, const struct m0_uint128 *id, struct m0_dtm_history **out)
Definition: dtx.c:187
static void dtx_fixed(struct m0_dtm_history *history)
Definition: dtx.c:140
M0_INTERNAL void m0_dtm_controlh_fini(struct m0_dtm_controlh *ch)
Definition: history.c:340
#define NULL
Definition: misc.h:38
M0_INTERNAL const struct m0_dtm_history_type m0_dtm_dtx_htype
Definition: dtx.c:125
#define oper_for(o, update)
Definition: dtm_internal.h:77
static const struct m0_uint128 * dtx_srv_id(const struct m0_dtm_history *history)
Definition: dtx.c:206
uint64_t hi_flags
Definition: nucleus.h:65
struct m0_dtm_remote * h_rem
Definition: history.h:59
M0_INTERNAL void m0_dtm_controlh_init(struct m0_dtm_controlh *ch, struct m0_dtm *dtm)
Definition: history.c:328
uint8_t hit_id
Definition: history.h:88
M0_INTERNAL const struct m0_dtm_history_type m0_dtm_dtx_srv_htype
Definition: dtx.c:199
struct m0_dtm_hi h_hi
Definition: history.h:56
struct m0_dtm_catalogue d_cat[M0_DTM_HISTORY_TYPE_NR]
Definition: dtm.h:541
#define oper_endfor
Definition: dtm_internal.h:83
struct m0_uint128 ds_id
Definition: dtx.h:54
M0_INTERNAL struct m0_dtm_update * up_update(struct m0_dtm_up *up)
Definition: update.c:228
struct m0_dtm_dtx * pa_dtx
Definition: dtx.c:44
static const struct m0_uint128 * dtx_id(const struct m0_dtm_history *history)
Definition: dtx.c:132
int(* hio_update)(struct m0_dtm_history *history, uint8_t id, struct m0_dtm_update *update)
Definition: history.h:83
struct m0_dtm_history ch_history
Definition: history.h:102
int i
Definition: dir.c:1033
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL bool oper_update_unique(const struct m0_dtm_oper *oper, const struct m0_dtm_update *update)
Definition: operation.c:270
uint32_t dt_nr
Definition: dtx.h:47
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
Definition: dtx.h:44
M0_INTERNAL int m0_dtm_catalogue_find(struct m0_dtm_catalogue *cat, struct m0_dtm *dtm, const struct m0_uint128 *id, m0_dtm_catalogue_alloc_t *alloc, void *datum, struct m0_dtm_history **out)
Definition: catalogue.c:92
static const struct m0_dtm_history_type_ops dtx_htype_ops
Definition: dtx.c:116
#define M0_ASSERT(cond)
static int dtx_find(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht, const struct m0_uint128 *id, struct m0_dtm_history **out)
Definition: dtx.c:108
static void dtx_noop(void *unused)
Definition: dtx.c:105
struct m0_dtm * dt_dtm
Definition: dtx.h:45
uint32_t dt_nr_max
Definition: dtx.h:48
static struct m0_dtm_history * pa_history(struct m0_dtm_dtx_party *pa)
Definition: dtx.c:160
M0_INTERNAL void m0_dtm_dtx_close(struct m0_dtm_dtx *dtx)
Definition: dtx.c:90
struct m0_dtm_controlh pa_ch
Definition: dtx.c:45
M0_INTERNAL int m0_dtm_dtx_init(struct m0_dtm_dtx *dtx, const struct m0_uint128 *id, struct m0_dtm *dtm, uint32_t nr_max)
Definition: dtx.c:57
#define UPDATE_REM(update)
Definition: dtm_internal.h:105
static const struct m0_dtm_history_type_ops dtx_srv_htype_ops
Definition: dtx.c:195
struct m0_dtm_history ds_history
Definition: dtx.h:55
uint32_t dt_nr_fixed
Definition: dtx.h:49
M0_INTERNAL bool m0_dtm_history_invariant(const struct m0_dtm_history *history)
Definition: history.c:71
static struct m0_dtm_history * dtx_srv_alloc(struct m0_dtm *dtm, const struct m0_uint128 *id, void *datum)
Definition: dtx.c:222
static struct m0_dtm_dtx dx
Definition: dtx.c:53
int(* hito_find)(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht, const struct m0_uint128 *id, struct m0_dtm_history **out)
Definition: history.h:95
const struct m0_dtm_history_type * hio_type
Definition: history.h:79
M0_INTERNAL void m0_dtm_controlh_fuse_close(struct m0_dtm_update *update)
Definition: history.c:406
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL int m0_dtm_controlh_update(struct m0_dtm_history *history, uint8_t id, struct m0_dtm_update *update)
Definition: history.c:393
static const struct m0_dtm_history_ops dtx_ops
Definition: dtx.c:48
M0_INTERNAL void m0_dtm_history_init(struct m0_dtm_history *history, struct m0_dtm *dtm)
Definition: history.c:51
Definition: dtm.h:529
void(* hio_fixed)(struct m0_dtm_history *history)
Definition: history.h:82
#define out(...)
Definition: gen.c:41
M0_INTERNAL void m0_dtm_controlh_add(struct m0_dtm_controlh *ch, struct m0_dtm_oper *oper)
Definition: history.c:352
void m0_free(void *data)
Definition: memory.c:146
M0_INTERNAL void m0_dtm_dtx_fini(struct m0_dtm_dtx *dtx)
Definition: dtx.c:69
M0_INTERNAL void m0_dtm_dtx_add(struct m0_dtm_dtx *dtx, struct m0_dtm_oper *oper)
Definition: dtx.c:80
struct m0_uint128 dt_id
Definition: dtx.h:46
static const struct m0_dtm_history_ops dtx_srv_ops
Definition: dtx.c:49
const struct m0_dtm_history_ops * h_ops
Definition: history.h:65
#define M0_IMPOSSIBLE(fmt,...)
M0_INTERNAL struct m0_dtm_up * history_latest(struct m0_dtm_history *history)
Definition: history.c:205