Motr  M0
cookie.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 
36 #ifndef __KERNEL__
37 #include <unistd.h> /* sbrk(0) */
38 #endif
39 #include "lib/types.h"
40 #include "lib/errno.h" /* -EPROTO */
41 #include "lib/cookie.h"
42 #include "ut/ut.h"
43 #include "lib/memory.h" /* M0_ALLOC_PTR */
44 #include "lib/arith.h" /* M0_IS_8ALIGNED */
45 
46 struct obj_struct {
47  uint64_t os_val;
48 };
49 
50 static uint64_t bss;
51 static const uint64_t readonly = 2;
52 static struct obj_struct obj_bss;
53 
54 static void test_init_apis(struct m0_cookie *cookie_test, struct obj_struct*
55  obj)
56 {
57  /* Test No.6: Testing of init-apis. */
58  m0_cookie_new(&obj->os_val);
59  M0_UT_ASSERT(obj->os_val > 0);
60  m0_cookie_init(cookie_test, &obj->os_val);
61  M0_UT_ASSERT(cookie_test->co_addr ==
62  (uint64_t)&obj->os_val);
63  M0_UT_ASSERT(cookie_test->co_generation == obj->os_val);
64 }
65 
66 static void test_valid_cookie(struct m0_cookie *cookie_test,
67  struct obj_struct* obj)
68 {
69  int flag;
70  uint64_t *addr_dummy;
71  struct obj_struct *obj_retrvd ;
72 
73  /* Test No.0: Testing m0_cookie_dereference for a valid cookie. */
74  flag = m0_cookie_dereference(cookie_test, &addr_dummy);
75  M0_UT_ASSERT(flag == 0);
76  M0_UT_ASSERT(addr_dummy == &obj->os_val);
77 
78  /* Test No.0: Testing of the macro m0_cookie_of(...) for a
79  * valid cookie. */
80  obj_retrvd = m0_cookie_of(cookie_test, struct obj_struct, os_val);
81  M0_UT_ASSERT(obj_retrvd == obj);
82 }
83 
84 static void test_m0_cookie_dereference(struct m0_cookie *cookie_test,
85  struct obj_struct *obj)
86 {
87  uint64_t *addr_dummy;
88  int flag;
89  char *fake_ptr;
90 
91  /* Test No.1: Testing m0_cookie_dereference when address in a
92  * cookie is a NULL pointer. */
93  cookie_test->co_addr = (uint64_t)NULL;
94  flag = m0_cookie_dereference(cookie_test, &addr_dummy);
95  M0_UT_ASSERT(flag == -EPROTO);
96 
97  /* Test No.2: Testing m0_cookie_dereference when address in a
98  * cookie is not greater than 4096. */
99  cookie_test->co_addr = 2048;
100  flag = m0_cookie_dereference(cookie_test, &addr_dummy);
101  M0_UT_ASSERT(flag == -EPROTO);
102 
103  /* Test No.3: Testing m0_cookie_dereference when address in a
104  * cookie is not aligned to 8-bytes. */
105  fake_ptr = (char *)&obj->os_val;
106  fake_ptr++;
107  cookie_test->co_addr = (uint64_t)fake_ptr;
108  flag = m0_cookie_dereference(cookie_test, &addr_dummy);
109  M0_UT_ASSERT(flag == -EPROTO);
110 
111  /* Test No.4: Testing m0_cookie_dereference for a stale cookie. */
112  m0_cookie_new(&obj->os_val);
113  M0_UT_ASSERT(obj->os_val != cookie_test->co_generation);
114 
115  /* Restoring an address in cookie, that got tampered in the last Test.
116  */
117  cookie_test->co_addr = (uint64_t)&obj->os_val;
118  flag = m0_cookie_dereference(cookie_test, &addr_dummy);
119  M0_UT_ASSERT(flag == -EPROTO);
120 }
121 
122 static void test_m0_cookie_of(struct m0_cookie *cookie_test,
123  struct obj_struct *obj)
124 {
125  struct obj_struct *obj_retrvd;
126 
127  /* Test No.1: Testing m0_cookie_of when address in a cookie is a
128  * NULL pointer. */
129  cookie_test->co_addr = (uint64_t)NULL;
130  obj_retrvd = m0_cookie_of(cookie_test, struct obj_struct, os_val);
131  M0_UT_ASSERT(obj_retrvd == NULL);
132 }
133 
134 static void addr_sanity(const uint64_t *addr, bool sane, bool aligned)
135 {
137  M0_UT_ASSERT(M0_IS_8ALIGNED(addr) == aligned);
138  M0_UT_ASSERT(m0_addr_is_sane_and_aligned(addr) == (sane && aligned));
139 }
140 
141 void test_cookie(void)
142 {
143  int insane_cnt = 0;
144  uint64_t automatic;
145  uint64_t *dynamic;
146  uint64_t i;
147  struct m0_cookie cookie_test;
148  struct obj_struct *obj_dynamic;
149  struct obj_struct obj_automatic;
150  struct obj_struct *obj_ptrs[3];
151  char not_aligned[sizeof(uint64_t) * 2];
152 
153  M0_ALLOC_PTR(dynamic);
154  M0_UT_ASSERT(dynamic != NULL);
155 
156  /* Address-sanity testing */
157  addr_sanity(NULL, false, true);
158  addr_sanity((uint64_t*)1, false, false);
159  addr_sanity((uint64_t*)8, false, true);
160  addr_sanity(&automatic, true, true);
161  addr_sanity(dynamic, true, true);
162  addr_sanity(&bss, true, true);
163  addr_sanity(&readonly, true, true);
164  addr_sanity((uint64_t *)&test_cookie, true,
166  for (i = 1; i < sizeof(uint64_t); ++i)
167  addr_sanity((const uint64_t *)&not_aligned[i], true, false);
168 
169  m0_free(dynamic);
170 
171  /*
172  * run through address space, checking that m0_addr_is_sane() doesn't
173  * crash.
174  */
175  for (i = 1; i <= 0xffff; i++) {
176  uint64_t word;
177  void *addr;
178  bool sane;
179 
180  word = (i & ~0xf) | (i << 16) | (i << 32) | (i << 48);
181  addr = (void *)word;
182  sane = m0_addr_is_sane(addr);
183  if (!sane)
184  insane_cnt++;
185  }
186 
187  /* check that at least one really invalid address was tested. */
188  M0_UT_ASSERT(insane_cnt > 0);
189 
190  /*Testing cookie-APIs*/
191  M0_ALLOC_PTR(obj_dynamic);
192  M0_UT_ASSERT(obj_dynamic != NULL);
193 
194  obj_ptrs[0] = obj_dynamic;
195  obj_ptrs[1] = &obj_automatic;
196  obj_ptrs[2] = &obj_bss;
197 
198  for (i = 0; i < 3; ++i) {
199  test_init_apis(&cookie_test, obj_ptrs[i]);
200  test_valid_cookie(&cookie_test, obj_ptrs[i]);
201  test_init_apis(&cookie_test, obj_ptrs[i]);
202  test_m0_cookie_dereference(&cookie_test, obj_ptrs[i]);
203  test_init_apis(&cookie_test, obj_ptrs[i]);
204  test_m0_cookie_of(&cookie_test, obj_ptrs[i]);
205  }
206 
207  m0_free(obj_dynamic);
208 }
209 M0_EXPORTED(test_cookie);
210 
211 /*
212  * Local variables:
213  * c-indentation-style: "K&R"
214  * c-basic-offset: 8
215  * tab-width: 8
216  * fill-column: 80
217  * scroll-step: 1
218  * End:
219  */
static uint64_t bss
Definition: cookie.c:50
#define NULL
Definition: misc.h:38
uint64_t os_val
Definition: cookie.c:47
static void test_m0_cookie_of(struct m0_cookie *cookie_test, struct obj_struct *obj)
Definition: cookie.c:122
static struct foo * obj
Definition: tlist.c:302
static char * addr
Definition: node_k.c:37
int i
Definition: dir.c:1033
void test_cookie(void)
Definition: cookie.c:141
Definition: xcode.h:73
static struct obj_struct obj_bss
Definition: cookie.c:52
static void test_m0_cookie_dereference(struct m0_cookie *cookie_test, struct obj_struct *obj)
Definition: cookie.c:84
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static bool flag
Definition: nucleus.c:266
static void test_init_apis(struct m0_cookie *cookie_test, struct obj_struct *obj)
Definition: cookie.c:54
#define M0_IS_8ALIGNED(val)
Definition: arith.h:190
void m0_free(void *data)
Definition: memory.c:146
#define M0_UT_ASSERT(a)
Definition: ut.h:46
static const uint64_t readonly
Definition: cookie.c:51
static void addr_sanity(const uint64_t *addr, bool sane, bool aligned)
Definition: cookie.c:134
static void test_valid_cookie(struct m0_cookie *cookie_test, struct obj_struct *obj)
Definition: cookie.c:66