Whamcloud - gitweb
09302bdbd39d4306a072bfed2f35c0600f6304a7
[fs/lustre-release.git] / lustre / obdclass / uuid.c
1 /*
2  * Public include file for the UUID library
3  * 
4  * Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
5  * Copyright (C) 2002 Cluster File System
6  * - changed for use in lustre
7  *
8  * %Begin-Header%
9  * This file may be redistributed under the terms of the GNU 
10  * Library General Public License.
11  * %End-Header%
12  */
13 #define DEBUG_SUBSYSTEM S_CLASS
14
15 #ifndef __KERNEL__
16 # include <liblustre.h>
17 #endif
18
19 #include <obd_support.h>
20 #include <obd_class.h>
21
22 struct uuid {
23         __u32   time_low;
24         __u16   time_mid;
25         __u16   time_hi_and_version;
26         __u16   clock_seq;
27         __u8    node[6];
28 };
29
30 static void uuid_unpack(class_uuid_t in, struct uuid *uu)
31 {
32         __u8    *ptr = in;
33         __u32   tmp;
34
35         tmp = *ptr++;
36         tmp = (tmp << 8) | *ptr++;
37         tmp = (tmp << 8) | *ptr++;
38         tmp = (tmp << 8) | *ptr++;
39         uu->time_low = tmp;
40
41         tmp = *ptr++;
42         tmp = (tmp << 8) | *ptr++;
43         uu->time_mid = tmp;
44
45         tmp = *ptr++;
46         tmp = (tmp << 8) | *ptr++;
47         uu->time_hi_and_version = tmp;
48
49         tmp = *ptr++;
50         tmp = (tmp << 8) | *ptr++;
51         uu->clock_seq = tmp;
52
53         memcpy(uu->node, ptr, 6);
54 }
55
56 #if 0
57 static void uuid_pack(struct uuid *uu, class_uuid_t ptr)
58 {
59         __u32   tmp;
60         unsigned char   *out = ptr;
61
62         tmp = uu->time_low;
63         out[3] = (unsigned char) tmp;
64         tmp >>= 8;
65         out[2] = (unsigned char) tmp;
66         tmp >>= 8;
67         out[1] = (unsigned char) tmp;
68         tmp >>= 8;
69         out[0] = (unsigned char) tmp;
70
71         tmp = uu->time_mid;
72         out[5] = (unsigned char) tmp;
73         tmp >>= 8;
74         out[4] = (unsigned char) tmp;
75
76         tmp = uu->time_hi_and_version;
77         out[7] = (unsigned char) tmp;
78         tmp >>= 8;
79         out[6] = (unsigned char) tmp;
80
81         tmp = uu->clock_seq;
82         out[9] = (unsigned char) tmp;
83         tmp >>= 8;
84         out[8] = (unsigned char) tmp;
85
86         memcpy(out+10, uu->node, 6);
87 }
88
89 int class_uuid_parse(struct obd_uuid in, class_uuid_t uu)
90 {
91         struct uuid uuid;
92         int i;
93         char *cp, buf[3];
94
95         if (strlen(in) != 36)
96                 return -1;
97         for (i=0, cp = in; i <= 36; i++,cp++) {
98                 if ((i == 8) || (i == 13) || (i == 18) ||
99                     (i == 23))
100                         if (*cp == '-')
101                                 continue;
102                 if (i== 36)
103                         if (*cp == 0)
104                                 continue;
105                 if (!isxdigit(*cp))
106                         return -1;
107         }
108         uuid.time_low = simple_strtoul(in, NULL, 16);
109         uuid.time_mid = simple_strtoul(in+9, NULL, 16);
110         uuid.time_hi_and_version = simple_strtoul(in+14, NULL, 16);
111         uuid.clock_seq = simple_strtoul(in+19, NULL, 16);
112         cp = in+24;
113         buf[2] = 0;
114         for (i=0; i < 6; i++) {
115                 buf[0] = *cp++;
116                 buf[1] = *cp++;
117                 uuid.node[i] = simple_strtoul(buf, NULL, 16);
118         }
119
120         uuid_pack(&uuid, uu);
121         return 0;
122 }
123 #endif
124
125
126 void generate_random_uuid(unsigned char uuid_out[16]);
127
128 /* We need to have some extra twiddling here because some systems have
129  * no random state when they start up. */
130 void class_generate_random_uuid(class_uuid_t uuid)
131 {
132         struct timeval t;
133         int *i, j, k;
134
135         LASSERT(sizeof(class_uuid_t) % sizeof(*i) == 0);
136
137         j = jiffies;
138         do_gettimeofday(&t);
139         k = t.tv_usec;
140
141         generate_random_uuid(uuid);
142
143         for (i = (int *)uuid; (char *)i < (char *)uuid + sizeof(class_uuid_t); i++) {
144                 *i ^= j ^ k;
145                 j = ((j << 8) & 0xffffff00) | ((j >> 24) & 0x000000ff);
146                 k = ((k >> 8) & 0x00ffffff) | ((k << 24) & 0xff000000);
147         }
148 }
149
150 void class_uuid_unparse(class_uuid_t uu, struct obd_uuid *out)
151 {
152         struct uuid uuid;
153
154         uuid_unpack(uu, &uuid);
155         sprintf(out->uuid,
156                 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
157                 uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
158                 uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
159                 uuid.node[0], uuid.node[1], uuid.node[2],
160                 uuid.node[3], uuid.node[4], uuid.node[5]);
161 }