4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "lvm-wrappers.h"
28 static const char _c
[] =
29 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#";
31 static int _built_inverse
;
32 static char _inverse_c
[256];
34 int lvid_create(union lvid
*lvid
, struct id
*vgid
)
36 memcpy(lvid
->id
, vgid
, sizeof(*lvid
->id
));
37 return id_create(&lvid
->id
[1]);
40 void uuid_from_num(char *uuid
, uint32_t num
)
44 for (i
= ID_LEN
; i
; i
--) {
45 uuid
[i
- 1] = _c
[num
% (sizeof(_c
) - 1)];
46 num
/= sizeof(_c
) - 1;
50 int lvid_from_lvnum(union lvid
*lvid
, struct id
*vgid
, uint32_t lv_num
)
54 memcpy(lvid
->id
, vgid
, sizeof(*lvid
->id
));
56 for (i
= ID_LEN
; i
; i
--) {
57 lvid
->id
[1].uuid
[i
- 1] = _c
[lv_num
% (sizeof(_c
) - 1)];
58 lv_num
/= sizeof(_c
) - 1;
61 lvid
->s
[sizeof(lvid
->s
) - 1] = '\0';
66 int lvnum_from_lvid(union lvid
*lvid
)
71 for (i
= 0; i
< ID_LEN
; i
++) {
72 lv_num
*= sizeof(_c
) - 1;
73 if ((c
= strchr(_c
, lvid
->id
[1].uuid
[i
])))
74 lv_num
+= (int) (c
- _c
);
82 int lvid_in_restricted_range(union lvid
*lvid
)
86 for (i
= 0; i
< ID_LEN
- 3; i
++)
87 if (lvid
->id
[1].uuid
[i
] != '0')
90 for (i
= ID_LEN
- 3; i
< ID_LEN
; i
++)
91 if (!isdigit(lvid
->id
[1].uuid
[i
]))
98 int id_create(struct id
*id
)
101 size_t len
= sizeof(id
->uuid
);
103 memset(id
->uuid
, 0, len
);
104 if (!read_urandom(&id
->uuid
, len
)) {
109 * Skip out the last 2 chars in randomized creation for LVM1
110 * backwards compatibility.
112 for (i
= 0; i
< len
; i
++)
113 id
->uuid
[i
] = _c
[id
->uuid
[i
] % (sizeof(_c
) - 3)];
119 * The only validity check we have is that
120 * the uuid just contains characters from
121 * '_c'. A checksum would have been nice :(
123 static void _build_inverse(void)
130 memset(_inverse_c
, 0, sizeof(_inverse_c
));
132 for (ptr
= _c
; *ptr
; ptr
++)
133 _inverse_c
[(int) *ptr
] = (char) 0x1;
136 int id_valid(struct id
*id
)
142 for (i
= 0; i
< ID_LEN
; i
++)
143 if (!_inverse_c
[id
->uuid
[i
]]) {
144 log_error("UUID contains invalid character");
151 int id_equal(const struct id
*lhs
, const struct id
*rhs
)
153 return !memcmp(lhs
->uuid
, rhs
->uuid
, sizeof(lhs
->uuid
));
156 #define GROUPS (ID_LEN / 4)
158 int id_write_format(const struct id
*id
, char *buffer
, size_t size
)
162 static unsigned group_size
[] = { 6, 4, 4, 4, 4, 4, 6 };
164 assert(ID_LEN
== 32);
166 /* split into groups separated by dashes */
167 if (size
< (32 + 6 + 1)) {
168 log_error("Couldn't write uuid, buffer too small.");
172 for (i
= 0, tot
= 0; i
< 7; i
++) {
173 memcpy(buffer
, id
->uuid
+ tot
, group_size
[i
]);
174 buffer
+= group_size
[i
];
175 tot
+= group_size
[i
];
183 int id_read_format(struct id
*id
, const char *buffer
)
187 /* just strip out any dashes */
190 if (*buffer
== '-') {
196 log_error("Too many characters to be uuid.");
200 id
->uuid
[out
++] = *buffer
++;
204 log_error("Couldn't read uuid: incorrect number of "