Whamcloud - gitweb
iam UT fixes:
[fs/lustre-release.git] / lustre / tests / iam_ut.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  iam_ut.c
5  *  iam unit-tests
6  *
7  *  Copyright (c) 2006 Cluster File Systems, Inc.
8  *   Author: Nikita Danilov <nikita@clusterfs.com>
9  *
10  *   This file is part of the Lustre file system, http://www.lustre.org
11  *   Lustre is a trademark of Cluster File Systems, Inc.
12  *
13  *   You may have signed or agreed to another license before downloading
14  *   this software.  If so, you are bound by the terms and conditions
15  *   of that agreement, and the following does not apply to you.  See the
16  *   LICENSE file included with this distribution for more information.
17  *
18  *   If you did not agree to a different license, then this copy of Lustre
19  *   is open source software; you can redistribute it and/or modify it
20  *   under the terms of version 2 of the GNU General Public License as
21  *   published by the Free Software Foundation.
22  *
23  *   In either case, Lustre is distributed in the hope that it will be
24  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *   license text for more details.
27  */
28
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <errno.h>
35
36 #include <sys/types.h>
37
38 #ifdef HAVE_ENDIAN_H
39 #include <endian.h>
40 #endif
41
42 #include <libcfs/libcfs.h>
43
44 enum {
45         /*
46          * Maximal format name length.
47          */
48         DX_FMT_NAME_LEN    = 16
49 };
50
51 struct iam_uapi_info {
52         __u16 iui_keysize;
53         __u16 iui_recsize;
54         __u16 iui_ptrsize;
55         __u16 iui_height;
56         char  iui_fmt_name[DX_FMT_NAME_LEN];
57 };
58
59 struct iam_uapi_op {
60         void *iul_key;
61         void *iul_rec;
62 };
63
64 enum iam_ioctl_cmd {
65         IAM_IOC_INIT     = _IOW('i', 1, struct iam_uapi_info),
66         IAM_IOC_GETINFO  = _IOR('i', 2, struct iam_uapi_info),
67         IAM_IOC_INSERT   = _IOR('i', 3, struct iam_uapi_op),
68         IAM_IOC_LOOKUP   = _IOWR('i', 4, struct iam_uapi_op),
69         IAM_IOC_DELETE   = _IOR('i', 5, struct iam_uapi_op)
70 };
71
72 static void usage(void)
73 {
74         printf("usage: iam_ut [-v] [-h] file\n");
75 }
76
77 static int doop(int fd, const void *key, const void *rec,
78                 int cmd, const char *name)
79 {
80         int result;
81
82         struct iam_uapi_op op = {
83                 .iul_key = key,
84                 .iul_rec = rec
85         };
86         result = ioctl(fd, cmd, &op);
87         if (result != 0)
88                 fprintf(stderr, "ioctl(%s): %i/%i (%m)\n", name, result, errno);
89         return result;
90 }
91
92 static int insert(int fd, const void *key, const void *rec)
93 {
94         return doop(fd, key, rec, IAM_IOC_INSERT, "IAM_IOC_INSERT");
95 }
96
97 static int lookup(int fd, const void *key, void *rec)
98 {
99         return doop(fd, key, rec, IAM_IOC_LOOKUP, "IAM_IOC_LOOKUP");
100 }
101
102 static int delete(int fd, const void *key, void *rec)
103 {
104         return doop(fd, key, rec, IAM_IOC_DELETE, "IAM_IOC_DELETE");
105 }
106
107 static void print_rec(const unsigned char *rec, int nr)
108 {
109         int i;
110
111         for (i = 0; i < nr; ++i)
112                 printf("%c", rec[i]);
113         printf("|    |");
114         for (i = 0; i < nr; ++i)
115                 printf("%x", rec[i]);
116         printf("\n");
117 }
118
119 enum op {
120         OP_TEST,
121         OP_INSERT,
122         OP_LOOKUP,
123         OP_DELETE
124 };
125
126 int main(int argc, char **argv)
127 {
128         int i;
129         int rc;
130         int opt;
131         int keysize;
132         int recsize;
133         int verbose = 0;
134
135         enum op op;
136
137         char *key;
138         char *rec;
139
140         char *key_opt;
141         char *rec_opt;
142
143         struct iam_uapi_info ua;
144
145         setbuf(stdout, NULL);
146         setbuf(stderr, NULL);
147
148         key_opt = NULL;
149         rec_opt = NULL;
150
151         op = OP_TEST;
152
153         do {
154                 opt = getopt(argc, argv, "vilk:r:d");
155                 switch (opt) {
156                 case 'v':
157                         verbose++;
158                 case -1:
159                         break;
160                 case 'k':
161                         key_opt = optarg;
162                         break;
163                 case 'r':
164                         rec_opt = optarg;
165                         break;
166                 case 'i':
167                         op = OP_INSERT;
168                         break;
169                 case 'l':
170                         op = OP_LOOKUP;
171                         break;
172                 case 'd':
173                         op = OP_DELETE;
174                         break;
175                 case '?':
176                 default:
177                         fprintf(stderr, "Unable to parse options.");
178                 case 'h':
179                         usage();
180                         return 0;
181                 }
182         } while (opt != -1);
183
184         rc = ioctl(0, IAM_IOC_INIT, &ua);
185         if (rc != 0) {
186                 fprintf(stderr, "ioctl(IAM_IOC_INIT): %i (%m)\n", rc);
187                 return 1;
188         }
189         rc = ioctl(0, IAM_IOC_GETINFO, &ua);
190         if (rc != 0) {
191                 fprintf(stderr, "ioctl(IAM_IOC_GETATTR): %i (%m)\n", rc);
192                 return 1;
193         }
194
195         keysize = ua.iui_keysize;
196         recsize = ua.iui_recsize;
197         if (verbose > 0)
198                 printf("keysize: %i, recsize: %i, ptrsize: %i, "
199                        "height: %i, name: %s\n",
200                        keysize, recsize, ua.iui_ptrsize,
201                        ua.iui_height, ua.iui_fmt_name);
202
203         key = calloc(keysize + 1, sizeof key[0]);
204         rec = calloc(recsize + 1, sizeof rec[0]);
205
206         if (key == NULL || rec == NULL) {
207                 fprintf(stderr, "cannot allocte memory\n");
208                 return 1;
209         }
210
211         strncpy(key, key_opt ? : "RIVERRUN", keysize + 1);
212         strncpy(rec, rec_opt ? : "PALEFIRE", recsize + 1);
213
214         if (op == OP_INSERT)
215                 return insert(0, key, rec);
216         else if (op == OP_DELETE)
217                 return delete(0, key, rec);
218         else if (op == OP_LOOKUP) {
219                 rc = lookup(0, key, rec);
220                 if (rc == 0)
221                         print_rec(rec, recsize);
222                 return rc;
223         }
224
225         rc = insert(0, key, rec);
226         if (rc != 0)
227                 return 1;
228
229         rc = insert(0, "DAEDALUS", "FINNEGAN");
230         if (rc != 0)
231                 return 1;
232
233         rc = insert(0, "DAEDALUS", "FINNEGAN");
234         if (errno != EEXIST) {
235                 if (rc == 0)
236                         fprintf(stderr, "Duplicate key not detected!\n");
237                 return 1;
238         }
239
240         rc = lookup(0, "RIVERRUN", rec);
241         if (rc != 0)
242                 return 1;
243
244         print_rec(rec, recsize);
245
246         for (i = 0; i < 0x10000; ++i) {
247                 memset(key, 0, keysize + 1);
248                 memset(rec, 0, recsize + 1);
249                 snprintf(key, keysize, "y-%x-x", i);
250                 snprintf(rec, recsize, "p-%x-q", 1000 - i);
251                 rc = insert(0, key, rec);
252                 if (rc != 0)
253                         return 1;
254                 if (verbose > 1)
255                         printf("key %#x inserted\n", i);
256         }
257
258         return 0;
259 }