Motr  M0
format.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-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_LIB
23 #include "lib/trace.h"
24 
25 #include "lib/assert.h" /* M0_PRE */
26 #include "lib/types.h" /* PRIx64 */
27 #include "lib/errno.h"
28 #include "lib/hash_fnc.h" /* m0_hash_fnc_fnv1 */
29 #include "lib/misc.h"
30 #include "motr/magic.h"
31 #include "motr/iem.h" /* M0_MOTR_IEM_DESC */
32 #include "format/format.h"
33 
40 M0_INTERNAL void m0_format_header_pack(struct m0_format_header *dest,
41  const struct m0_format_tag *src)
42 {
43  dest->hd_magic = M0_FORMAT_HEADER_MAGIC;
44  dest->hd_bits = (uint64_t)src->ot_version << 48 |
45  (uint64_t)src->ot_type << 32 |
46  (uint64_t)src->ot_size;
47 }
48 
49 M0_INTERNAL void m0_format_header_unpack(struct m0_format_tag *dest,
50  const struct m0_format_header *src)
51 {
52  *dest = (struct m0_format_tag){
53  .ot_version = src->hd_bits >> 48,
54  .ot_type = src->hd_bits >> 32 & 0x0000ffff,
55  .ot_size = src->hd_bits & 0xffffffff
56  };
57 }
58 
60  const void *buffer,
61  uint32_t size)
62 {
63  footer->ft_magic = M0_FORMAT_FOOTER_MAGIC;
64  footer->ft_checksum = m0_hash_fnc_fnv1(buffer, size);
65 }
66 
67 static int get_footer_from_buf(const void *buffer,
68  const struct m0_format_footer **footer,
69  uint32_t *footer_offset)
70 {
71  const struct m0_format_header *header = buffer;
72 
73  struct m0_format_tag tag;
74 
75  M0_PRE(buffer != NULL);
76 
77  if (header->hd_magic != M0_FORMAT_HEADER_MAGIC)
78  return M0_ERR_INFO(-EPROTO, "format header magic mismatch for"
79  " the buffer %p, expected %"PRIx64
80  ", got %"PRIx64,
81  buffer, (uint64_t)M0_FORMAT_HEADER_MAGIC,
82  header->hd_magic);
83 
85  /* M0_LOG(M0_DEBUG, "format header of %p buffer: version %hu, type %hu" */
86  /* ", footer_offset %u", buffer, tag.ot_version, */
87  /* tag.ot_version, tag.ot_footer_offset); */
88 
89  *footer = buffer + tag.ot_footer_offset;
90  *footer_offset = tag.ot_footer_offset;
91 
92  return 0;
93 }
94 
95 M0_INTERNAL void m0_format_footer_update(const void *buffer)
96 {
97  struct m0_format_footer *footer;
98  uint32_t footer_offset;
99  int rc;
100 
101  if (buffer == NULL)
102  return;
103 
105  (const struct m0_format_footer **)&footer,
106  &footer_offset);
107  M0_ASSERT_INFO(rc == 0, "failed to update footer, invalid struct at"
108  " addr %p - no valid header found", buffer);
109  if (rc != 0)
110  return;
111 
112  m0_format_footer_generate(footer, buffer, footer_offset);
113 }
114 
115 static void format_iem_post(const char *msg, bool iem)
116 {
117  if (iem)
120  M0_MOTR_IEM_EVENT_MD_ERROR, "%s", msg);
121  else
122  M0_LOG(M0_ERROR, "%s", msg);
123 }
124 
126  const struct m0_format_footer *footer,
127  const void *buffer,
128  uint32_t size,
129  bool iem)
130 {
131  uint64_t checksum;
132 
133  M0_PRE(footer != NULL);
134 
135  if (footer->ft_magic != M0_FORMAT_FOOTER_MAGIC) {
136  format_iem_post("Observed data accessibility issue. "
137  "Contact Seagate support.", iem);
138  return M0_ERR(-EPROTO);
139  }
140  checksum = m0_hash_fnc_fnv1(buffer, size);
141  if (footer->ft_checksum != checksum) {
142  format_iem_post("Observed data accessibility issue. "
143  "Contact Seagate support.", iem);
144  return M0_ERR(-EPROTO);
145  }
146  return M0_RC(0);
147 }
148 
149 M0_INTERNAL int m0_format_footer_verify(const void *buffer, bool iem)
150 {
151  const struct m0_format_footer *footer;
152  uint32_t footer_offset;
153  int rc;
154 
155  M0_ASSERT(buffer != NULL);
156  rc = get_footer_from_buf(buffer, &footer, &footer_offset);
157  if (rc != 0) {
158  format_iem_post("Observed data accessibility issue. "
159  "Contact Seagate support.", iem);
160  return M0_ERR(rc);
161  }
163  footer_offset, iem);
164 }
165 
167 #undef M0_TRACE_SUBSYSTEM
168 
169 /*
170  * Local variables:
171  * c-indentation-style: "K&R"
172  * c-basic-offset: 8
173  * tab-width: 8
174  * fill-column: 80
175  * scroll-step: 1
176  * End:
177  */
178 /*
179  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
180  */
M0_INTERNAL void m0_format_footer_generate(struct m0_format_footer *footer, const void *buffer, uint32_t size)
Definition: format.c:59
#define M0_PRE(cond)
M0_INTERNAL void m0_format_header_pack(struct m0_format_header *dest, const struct m0_format_tag *src)
Definition: format.c:40
M0_INTERNAL void m0_format_header_unpack(struct m0_format_tag *dest, const struct m0_format_header *src)
Definition: format.c:49
#define NULL
Definition: misc.h:38
static uint64_t tag(uint8_t code, uint64_t id)
Definition: addb2.c:1047
#define M0_LOG(level,...)
Definition: trace.h:167
#define PRIx64
Definition: types.h:61
static int get_footer_from_buf(const void *buffer, const struct m0_format_footer **footer, uint32_t *footer_offset)
Definition: format.c:67
return M0_RC(rc)
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
return M0_ERR(-EOPNOTSUPP)
#define M0_ASSERT(cond)
M0_INTERNAL uint64_t m0_hash_fnc_fnv1(const void *buffer, m0_bcount_t len)
Definition: hash_fnc.c:84
M0_INTERNAL int m0_format_footer_verify_generic(const struct m0_format_footer *footer, const void *buffer, uint32_t size, bool iem)
Definition: format.c:125
M0_INTERNAL int m0_format_footer_verify(const void *buffer, bool iem)
Definition: format.c:149
#define M0_MOTR_IEM_DESC(_sev_id, _mod_id, _evt_id, _desc,...)
Definition: iem.h:103
M0_INTERNAL void m0_format_footer_update(const void *buffer)
Definition: format.c:95
Definition: addb2.c:200
m0_bcount_t size
Definition: di.c:39
#define M0_ASSERT_INFO(cond, fmt,...)
struct m0_pdclust_src_addr src
Definition: fd.c:108
static void format_iem_post(const char *msg, bool iem)
Definition: format.c:115
int32_t rc
Definition: trigger_fop.h:47
int const char void * buffer
Definition: dir.c:435