Motr  M0
packet.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-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 #include "lib/vec.h"
23 #include "lib/memory.h" /* M0_ALLOC_ARR */
24 #include "lib/misc.h"
25 #include "lib/arith.h" /* m0_align() */
26 #include "lib/finject.h" /* m0_fi_enable_once */
27 #include "ut/ut.h"
28 #include "motr/init.h"
29 #include "motr/magic.h"
30 #include "fop/fop.h"
31 #include "rpc/rpc.h"
32 #include "rpc/rpc_internal.h"
33 #include "rpc/rpc_opcodes.h"
34 #include "rpc/it/ping_fop.h"
35 #include "rpc/it/ping_fop_xc.h"
36 #include "rpc/it/ping_fop_xc.c"
37 #include "rpc/it/ping_fom.c"
38 #include "rpc/it/ping_fop.c" /* m0_fop_ping_fopt */
39 
40 #define cmp_field(obj1, obj2, field)((obj1)->field == (obj2)->field)
41 
42 static struct m0_rpc_machine rmachine;
43 
44 static struct m0_rpc_item *prepare_ping_fop_item(void);
45 static struct m0_rpc_item *prepare_ping_rep_fop_item(void);
46 static void fill_ping_fop_data(struct m0_fop_ping_arr *fp_arr);
47 static void populate_item(struct m0_rpc_item *item);
48 static void packet_compare(struct m0_rpc_packet *p1, struct m0_rpc_packet *p2);
49 static void item_compare(struct m0_rpc_item *item1, struct m0_rpc_item *item2);
50 static void fop_data_compare(struct m0_fop *fop1, struct m0_fop *fop2);
51 static void cmp_ping_fop_data(struct m0_fop_ping_arr *fp_arr1,
52  struct m0_fop_ping_arr *fp_arr2);
53 static void packet_fini(struct m0_rpc_packet *packet);
54 
55 static int packet_encdec_ut_init(void)
56 {
59  return 0;
60 }
61 
62 static int packet_encdec_ut_fini(void)
63 {
66  return 0;
67 }
68 
69 static void test_packet_encode_decode(void)
70 {
71  struct m0_rpc_item *item;
72  struct m0_rpc_packet packet;
73  struct m0_rpc_packet decoded_packet;
74  struct m0_bufvec bufvec;
75  m0_bcount_t bufvec_size;
76  int rc;
77 
79 
90  bufvec_size = m0_align(packet.rp_size, 8);
91  /* m0_alloc_aligned() (lib/linux_kernel/memory.c), supports
92  * alignment of PAGE_SHIFT only
93  */
94  rc = m0_bufvec_alloc_aligned(&bufvec, 1, bufvec_size, M0_SEG_SHIFT);
95  M0_UT_ASSERT(rc == 0);
97  rc = m0_rpc_packet_encode(&packet, &bufvec);
99  M0_UT_ASSERT(rc == 0);
100 
101  m0_fi_enable_once("item_decode", "rito_decode_nomem");
102  m0_rpc_packet_init(&decoded_packet, &rmachine);
103  rc = m0_rpc_packet_decode(&decoded_packet, &bufvec, 0, bufvec_size);
104  M0_UT_ASSERT(rc == -ENOMEM);
105 
106  m0_fi_enable_once("item_decode", "header_unpack");
107  m0_rpc_packet_init(&decoded_packet, &rmachine);
108  rc = m0_rpc_packet_decode(&decoded_packet, &bufvec, 0, bufvec_size);
109  M0_UT_ASSERT(rc == -EPROTO);
110 
111  m0_rpc_packet_init(&decoded_packet, &rmachine);
112  rc = m0_rpc_packet_decode(&decoded_packet, &bufvec, 0, bufvec_size);
113  M0_UT_ASSERT(rc == 0);
114 
115  packet_compare(&packet, &decoded_packet);
117  packet_fini(&decoded_packet);
118  m0_bufvec_free_aligned(&bufvec, M0_SEG_SHIFT);
119 }
120 
121 static struct m0_rpc_item* prepare_ping_fop_item(void)
122 {
123  struct m0_fop *ping_fop;
124  struct m0_fop_ping *ping_fop_data;
125  struct m0_rpc_item *item;
126 
127  ping_fop = m0_fop_alloc(&m0_fop_ping_fopt, NULL, &rmachine);
128  M0_UT_ASSERT(ping_fop != NULL);
129  ping_fop_data = m0_fop_data(ping_fop);
130  ping_fop_data->fp_arr.f_count = 1;
131  M0_ALLOC_ARR(ping_fop_data->fp_arr.f_data,
132  ping_fop_data->fp_arr.f_count);
133  M0_UT_ASSERT(ping_fop_data->fp_arr.f_data != NULL);
134  fill_ping_fop_data(&ping_fop_data->fp_arr);
135  item = &ping_fop->f_item;
137  return item;
138 }
139 
141 {
142  struct m0_fop *ping_fop_rep;
143  struct m0_fop_ping_rep *ping_fop_rep_data;
144  struct m0_rpc_item *item;
145 
146  ping_fop_rep = m0_fop_alloc(&m0_fop_ping_rep_fopt, NULL, &rmachine);
147  M0_UT_ASSERT(ping_fop_rep != NULL);
148  ping_fop_rep_data = m0_fop_data(ping_fop_rep);
149  ping_fop_rep_data->fpr_rc = 1001;
150  item = &ping_fop_rep->f_item;
152  return item;
153 }
154 
156 {
157  int i;
158 
159  M0_UT_ASSERT(fp_arr->f_count != 0);
161 
162  for (i = 0; i < fp_arr->f_count; ++i) {
163  fp_arr->f_data[i] = i % UINT64_MAX;
164  }
165 }
166 
167 static void populate_item(struct m0_rpc_item *item)
168 {
169  item->ri_header = (struct m0_rpc_item_header2) {
170  .osr_uuid.u_hi = 9876,
171  .osr_uuid.u_lo = 6789,
172  .osr_sender_id = 101,
173  .osr_session_id = 523,
174  .osr_xid = 212,
175  };
176 }
177 
178 static void packet_compare(struct m0_rpc_packet *p1, struct m0_rpc_packet *p2)
179 {
180  struct m0_rpc_item *item1;
181  struct m0_rpc_item *item2;
182  struct m0_fop *fop1;
183  struct m0_fop *fop2;
184 
185  M0_UT_ASSERT(cmp_field(p1, p2, rp_size));
186  M0_UT_ASSERT(memcmp(&p1->rp_ow, &p2->rp_ow, sizeof p1->rp_ow) == 0);
187 
188  for (item1 = m0_tlist_head(&packet_item_tl, &p1->rp_items),
189  item2 = m0_tlist_head(&packet_item_tl, &p2->rp_items);
190  item1 != NULL && item2 != NULL;
191  item1 = packet_item_tlist_next(&p1->rp_items, item1),
192  item2 = packet_item_tlist_next(&p2->rp_items, item2)) {
193  item_compare(item1, item2);
194  fop1 = m0_rpc_item_to_fop(item1);
195  fop2 = m0_rpc_item_to_fop(item2);
196  fop_data_compare(fop1, fop2);
197  }
198 }
199 
200 static void item_compare(struct m0_rpc_item *item1, struct m0_rpc_item *item2)
201 {
202 
203  struct m0_rpc_item_header2 *h1 = &item1->ri_header;
204  struct m0_rpc_item_header2 *h2 = &item2->ri_header;
205 
206  M0_UT_ASSERT(cmp_field(item1, item2, ri_type->rit_opcode));
207  M0_UT_ASSERT(memcmp(h1, h2, sizeof *h1) == 0);
208 }
209 
210 static void fop_data_compare(struct m0_fop *fop1, struct m0_fop *fop2)
211 {
212  struct m0_fop_ping *ping_data1;
213  struct m0_fop_ping *ping_data2;
214  struct m0_fop_ping_rep *ping_rep_data1;
215  struct m0_fop_ping_rep *ping_rep_data2;
216 
217  M0_UT_ASSERT(m0_fop_opcode(fop1) == m0_fop_opcode(fop2));
218 
219  switch (m0_fop_opcode(fop1)) {
220 
221  case M0_RPC_PING_OPCODE:
222  ping_data1 = m0_fop_data(fop1);
223  ping_data2 = m0_fop_data(fop2);
224  cmp_ping_fop_data(&ping_data1->fp_arr, &ping_data2->fp_arr);
225  break;
226 
228  ping_rep_data1 = m0_fop_data(fop1);
229  ping_rep_data2 = m0_fop_data(fop2);
230 
231  M0_UT_ASSERT(ping_rep_data1->fpr_rc == ping_rep_data2->fpr_rc);
232  break;
233 
234  }
235 }
236 
237 static void cmp_ping_fop_data(struct m0_fop_ping_arr *fp_arr1,
238  struct m0_fop_ping_arr *fp_arr2)
239 {
240  M0_UT_ASSERT(cmp_field(fp_arr1, fp_arr2, f_count));
241  M0_UT_ASSERT(fp_arr1->f_data != NULL);
242  M0_UT_ASSERT(fp_arr2->f_data != NULL);
243  M0_UT_ASSERT(m0_forall(i, fp_arr1->f_count,
244  fp_arr1->f_data[i] == fp_arr2->f_data[i]));
245 }
246 
247 static void packet_fini(struct m0_rpc_packet *packet)
248 {
250 
251  /* items will be freed as soon as they're removed
252  from packet, because this is last reference on them */
257 }
258 
260  .ts_name = "rpc-packet-encdec-ut",
261  .ts_init = packet_encdec_ut_init,
262  .ts_fini = packet_encdec_ut_fini,
263  .ts_tests = {
264  { "packet-encode-decode-test", test_packet_encode_decode},
265  { NULL, NULL}
266  }
267 };
268 M0_EXPORTED(packet_encdec_ut);
uint32_t m0_fop_opcode(const struct m0_fop *fop)
Definition: fop.c:226
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL void m0_ping_fop_init(void)
Definition: ping_fop.c:47
void * m0_tlist_head(const struct m0_tl_descr *d, const struct m0_tl *list)
Definition: tlist.c:187
#define NULL
Definition: misc.h:38
M0_INTERNAL int m0_rpc_packet_decode(struct m0_rpc_packet *p, struct m0_bufvec *bufvec, m0_bindex_t off, m0_bcount_t len)
Definition: packet.c:367
void m0_rpc_item_put(struct m0_rpc_item *item)
Definition: item.c:443
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
int32_t fpr_rc
Definition: ping_fop.h:58
uint64_t m0_bcount_t
Definition: types.h:77
uint32_t f_count
Definition: ping_fop.h:49
M0_INTERNAL void m0_rpc_packet_add_item(struct m0_rpc_packet *p, struct m0_rpc_item *item)
Definition: packet.c:141
Definition: ut.h:77
static void packet_compare(struct m0_rpc_packet *p1, struct m0_rpc_packet *p2)
Definition: packet.c:178
static struct m0_rpc_item * item
Definition: item.c:56
M0_INTERNAL void m0_sm_group_fini(struct m0_sm_group *grp)
Definition: sm.c:65
struct m0_sm_group rm_sm_grp
Definition: rpc_machine.h:82
int m0_bufvec_alloc_aligned(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size, unsigned shift)
Definition: vec.c:355
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
M0_INTERNAL void m0_rpc_packet_init(struct m0_rpc_packet *p, struct m0_rpc_machine *rmach)
Definition: packet.c:103
int i
Definition: dir.c:1033
struct m0_fop_type m0_fop_ping_rep_fopt
Definition: ping_fop.c:35
M0_INTERNAL void m0_rpc_packet_fini(struct m0_rpc_packet *p)
Definition: packet.c:122
M0_INTERNAL void m0_ping_fop_fini(void)
Definition: ping_fop.c:37
M0_INTERNAL void m0_sm_group_init(struct m0_sm_group *grp)
Definition: sm.c:53
static struct m0_rpc_machine rmachine
Definition: packet.c:42
struct m0_rpc_item_header2 ri_header
Definition: item.h:193
struct m0_fop_type m0_fop_ping_fopt
Definition: ping_fop.c:34
Definition: xcode.h:95
struct m0_rpc_packet_onwire_header rp_ow
uint64_t u_hi
Definition: types.h:36
M0_INTERNAL int m0_rpc_packet_encode(struct m0_rpc_packet *p, struct m0_bufvec *bufvec)
Definition: packet.c:221
struct m0_uint128 osr_uuid
Definition: onwire.h:95
struct m0_fop_ping_arr fp_arr
Definition: ping_fop.h:35
#define UINT64_MAX
Definition: types.h:44
#define cmp_field(obj1, obj2, field)
Definition: packet.c:40
static void fill_ping_fop_data(struct m0_fop_ping_arr *fp_arr)
Definition: packet.c:155
struct m0_ut_suite packet_encdec_ut
Definition: packet.c:259
static void item_compare(struct m0_rpc_item *item1, struct m0_rpc_item *item2)
Definition: packet.c:200
static void cmp_ping_fop_data(struct m0_fop_ping_arr *fp_arr1, struct m0_fop_ping_arr *fp_arr2)
Definition: packet.c:237
M0_INTERNAL void m0_bufvec_free_aligned(struct m0_bufvec *bufvec, unsigned shift)
Definition: vec.c:436
#define m0_forall(var, nr,...)
Definition: misc.h:112
uint64_t * f_data
Definition: ping_fop.h:50
const char * ts_name
Definition: ut.h:99
uint32_t f_count
Definition: ping_fop.h:35
static void fop_data_compare(struct m0_fop *fop1, struct m0_fop *fop2)
Definition: packet.c:210
static void test_packet_encode_decode(void)
Definition: packet.c:69
struct m0_tl rp_items
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
struct m0_fop * m0_rpc_item_to_fop(const struct m0_rpc_item *item)
Definition: fop.c:346
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
static int packet_encdec_ut_init(void)
Definition: packet.c:55
static void populate_item(struct m0_rpc_item *item)
Definition: packet.c:167
M0_INTERNAL void m0_rpc_packet_remove_all_items(struct m0_rpc_packet *p)
Definition: packet.c:190
static struct m0_rpc_item * prepare_ping_fop_item(void)
Definition: packet.c:121
struct m0_fop_ping_arr fp_arr
Definition: ping_fop.h:54
struct m0_rpc_item f_item
Definition: fop.h:83
int32_t rc
Definition: trigger_fop.h:47
static uint64_t m0_align(uint64_t val, uint64_t alignment)
Definition: arith.h:170
#define M0_UT_ASSERT(a)
Definition: ut.h:46
static void packet_fini(struct m0_rpc_packet *packet)
Definition: packet.c:247
static int packet_encdec_ut_fini(void)
Definition: packet.c:62
Definition: fop.h:79
Definition: vec.h:145
struct m0_fop * m0_fop_alloc(struct m0_fop_type *fopt, void *data, struct m0_rpc_machine *mach)
Definition: fop.c:96
static struct m0_rpc_item * prepare_ping_rep_fop_item(void)
Definition: packet.c:140