Motr  M0
uuid.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 
23 #include "lib/uuid.h"
24 #include "lib/atomic.h"
25 #include "lib/errno.h"
26 #include "lib/time.h"
27 #include "lib/string.h" /* isxdigit */
28 #include "lib/misc.h" /* ARRAY_SIZE, m0_strtou64 */
29 
30 #ifdef __KERNEL__
31 # include <linux/uuid.h> /* generate_random_uuid */
32 #else
33 # include <uuid/uuid.h> /* generate_uuid */
34 #endif
35 
36 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB
37 #include "lib/trace.h"
38 
39 M0_BASSERT(sizeof (struct m0_uint128) == sizeof (char[16]));
40 #ifndef __KERNEL__
41 M0_BASSERT(sizeof (struct m0_uint128) == sizeof (uuid_t));
42 #endif
43 
44 M0_INTERNAL void m0_uuid_generate(struct m0_uint128 *u)
45 {
46 #ifdef __KERNEL__
47  generate_random_uuid((unsigned char *)u);
48 #else
49  uuid_generate((unsigned char *)u);
50 #endif
51 }
52 
58 static int parse_hex(const char *str, int len, uint64_t *val)
59 {
60  int i;
61  char buf[17];
62 
63  M0_ASSERT(len < ARRAY_SIZE(buf));
64  for (i = 0; i < len; ++i) {
65  if (*str == '\0')
66  return M0_ERR(-EINVAL);
67  if (!isxdigit(*str))
68  return M0_ERR(-EINVAL);
69  buf[i] = *str++;
70  }
71  buf[i] = '\0';
72  *val = m0_strtou64(buf, NULL, 16);
73 
74  return 0;
75 }
76 
77 M0_INTERNAL int m0_uuid_parse(const char *str, struct m0_uint128 *val)
78 {
79  uint64_t h1;
80  uint64_t h2;
81  uint64_t h3;
82  uint64_t h4;
83  uint64_t h5;
84 
85  val->u_hi = val->u_lo = 0;
86  if (parse_hex(&str[0], 8, &h1) < 0 || str[8] != '-' ||
87  parse_hex(&str[9], 4, &h2) < 0 || str[13] != '-' ||
88  parse_hex(&str[14], 4, &h3) < 0 || str[18] != '-' ||
89  parse_hex(&str[19], 4, &h4) < 0 || str[23] != '-' ||
90  parse_hex(&str[24], 12, &h5) < 0 || str[36] != '\0') {
91  if (parse_hex(&str[0], 8, &h1) < 0 ||
92  parse_hex(&str[8], 4, &h2) < 0 ||
93  parse_hex(&str[12], 4, &h3) < 0 ||
94  parse_hex(&str[16], 4, &h4) < 0 ||
95  parse_hex(&str[20], 12, &h5) < 0 || str[32] != '\0') {
96  return M0_ERR(-EINVAL);
97  }
98  }
99 
100  val->u_hi = h1 << 32 | h2 << 16 | h3;
101  val->u_lo = h4 << 48 | h5;
102  /* no validation of adherence to standard version formats */
103  return 0;
104 }
105 M0_EXPORTED(m0_uuid_parse);
106 
107 M0_INTERNAL void m0_uuid_format(const struct m0_uint128 *val,
108  char *buf, size_t len)
109 {
110  static const char *fmt = "%08x-%04x-%04x-%04x-%012lx";
111  uint32_t h1;
112  uint32_t h2;
113  uint32_t h3;
114  uint32_t h4;
115  uint64_t h5;
116 
117  M0_ASSERT(len > M0_UUID_STRLEN);
118  h1 = val->u_hi >> 32;
119  h2 = (val->u_hi >> 16) & 0xffff;
120  h3 = val->u_hi & 0xffff;
121  h4 = val->u_lo >> 48;
122  h5 = val->u_lo & 0xffffffffffff;
123  sprintf(buf, fmt, h1, h2, h3, h4, h5);
124 }
125 
126 M0_INTERNAL struct m0_uint128 m0_node_uuid;
127 
132 {
133  char buf[M0_UUID_STRLEN + 1];
134  struct m0_uint128 *uuid = &m0_node_uuid;
135  int rc;
136 
137  M0_SET0(uuid);
139  if (rc == 0) {
140  rc = m0_uuid_parse(buf, uuid);
141  if (rc == 0) {
143  M0_LOG(M0_NOTICE, "Node uuid: %s", (char *)buf);
144  } else
145  M0_LOG(M0_ERROR, "Unable to parse node UUID string");
146  } else
147  M0_LOG(M0_ERROR, "Unable to fetch node UUID string");
148  return M0_RC(rc);
149 }
150 
151 #undef M0_TRACE_SUBSYSTEM
152 
153 /*
154  * Local variables:
155  * c-indentation-style: "K&R"
156  * c-basic-offset: 8
157  * tab-width: 8
158  * fill-column: 80
159  * scroll-step: 1
160  * End:
161  */
struct m0_uint128 uuid[1000]
Definition: uuid.c:73
#define NULL
Definition: misc.h:38
Definition: idx_mock.c:52
M0_INTERNAL void m0_uuid_generate(struct m0_uint128 *u)
Definition: uuid.c:44
union @126 u
#define M0_LOG(level,...)
Definition: trace.h:167
M0_BASSERT(sizeof(struct m0_uint128)==sizeof(char[16]))
#define M0_SET0(obj)
Definition: misc.h:64
Definition: sock.c:887
return M0_RC(rc)
M0_INTERNAL int m0_uuid_parse(const char *str, struct m0_uint128 *val)
Definition: uuid.c:77
int i
Definition: dir.c:1033
static int parse_hex(const char *str, int len, uint64_t *val)
Definition: uuid.c:58
return M0_ERR(-EOPNOTSUPP)
int m0_node_uuid_string_get(char buf[M0_UUID_STRLEN+1])
Definition: kuuid.c:51
#define M0_ASSERT(cond)
uint64_t m0_strtou64(const char *str, char **endptr, int base)
Definition: kmisc.c:26
char * fmt(const char *format,...) __attribute__((format(printf
M0_INTERNAL void m0_uuid_format(const struct m0_uint128 *val, char *buf, size_t len)
Definition: uuid.c:107
int m0_node_uuid_init(void)
Definition: uuid.c:131
M0_INTERNAL struct m0_uint128 m0_node_uuid
Definition: uuid.c:126
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45