1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/tests/iam_ut.c
41 * Author: Nikita Danilov <nikita@clusterfs.com>
52 #include <sys/types.h>
58 #include <libcfs/libcfs.h>
62 * Maximal format name length.
67 struct iam_uapi_info {
72 char iui_fmt_name[DX_FMT_NAME_LEN];
81 struct iam_uapi_op iui_op;
86 IAM_IOC_INIT = _IOW('i', 1, struct iam_uapi_info),
87 IAM_IOC_GETINFO = _IOR('i', 2, struct iam_uapi_info),
88 IAM_IOC_INSERT = _IOR('i', 3, struct iam_uapi_op),
89 IAM_IOC_LOOKUP = _IOWR('i', 4, struct iam_uapi_op),
90 IAM_IOC_DELETE = _IOR('i', 5, struct iam_uapi_op),
91 IAM_IOC_IT_START = _IOR('i', 6, struct iam_uapi_it),
92 IAM_IOC_IT_NEXT = _IOW('i', 7, struct iam_uapi_it),
93 IAM_IOC_IT_STOP = _IOR('i', 8, struct iam_uapi_it),
95 IAM_IOC_POLYMORPH = _IOR('i', 9, unsigned long)
98 static void usage(void)
100 printf("usage: iam_ut [-v] [-h] file\n");
103 static int doop(int fd, const void *key, const void *rec,
104 int cmd, const char *name)
108 struct iam_uapi_op op = {
112 result = ioctl(fd, cmd, &op);
114 fprintf(stderr, "ioctl(%s): %i/%i (%m)\n", name, result, errno);
118 static int doit(int fd, const void *key, const void *rec,
119 int cmd, const char *name)
123 struct iam_uapi_it it = {
131 assert((void *)&it == (void *)&it.iui_op);
133 result = ioctl(fd, cmd, &it);
135 fprintf(stderr, "ioctl(%s): %i/%i (%m)\n", name, result, errno);
137 result = it.iui_state;
141 static int insert(int fd, const void *key, const void *rec)
143 return doop(fd, key, rec, IAM_IOC_INSERT, "IAM_IOC_INSERT");
146 static int lookup(int fd, const void *key, void *rec)
148 return doop(fd, key, rec, IAM_IOC_LOOKUP, "IAM_IOC_LOOKUP");
151 static int delete(int fd, const void *key, void *rec)
153 return doop(fd, key, rec, IAM_IOC_DELETE, "IAM_IOC_DELETE");
156 static int rec_is_nul_term(int recsize)
158 return recsize == 255;
161 static void print_rec(const unsigned char *rec, int nr)
165 for (i = 0; i < nr; ++i) {
166 printf("%c", rec[i]);
167 if (rec_is_nul_term(nr) && rec[i] == 0)
171 for (i = 0; i < nr; ++i) {
172 printf("%x", rec[i]);
173 if (rec_is_nul_term(nr) && rec[i] == 0)
189 unsigned char hex2dec(unsigned char hex)
191 if ('0' <= hex && hex <= '9') {
193 } else if ('a' <= hex && hex <= 'f') {
194 return hex - 'a' + 10;
195 } else if ('A' <= hex && hex <= 'F') {
196 return hex - 'A' + 10;
198 fprintf(stderr, "Wrong hex digit '%c'\n", hex);
203 unsigned char *packdigit(unsigned char *number)
208 area = calloc(strlen(number) / 2 + 2, sizeof area[0]);
210 for (scan = area; *number; number += 2, scan++)
211 *scan = (hex2dec(number[0]) << 4) | hex2dec(number[1]);
216 int main(int argc, char **argv)
229 void *(*copier)(void *, void *, size_t);
239 struct iam_uapi_info ua;
241 setbuf(stdout, NULL);
242 setbuf(stderr, NULL);
250 opt = getopt(argc, argv, "vilk:K:N:r:R:dsSnP:");
257 key_opt = packdigit(optarg);
267 rec_opt = packdigit(optarg);
296 mode = strtoul(optarg, NULL, 0);
297 rc = ioctl(0, IAM_IOC_POLYMORPH, mode);
299 perror("IAM_IOC_POLYMORPH");
304 fprintf(stderr, "Unable to parse options.");
312 rc = ioctl(0, IAM_IOC_INIT, &ua);
314 fprintf(stderr, "ioctl(IAM_IOC_INIT): %i (%m)\n", rc);
318 rc = ioctl(0, IAM_IOC_GETINFO, &ua);
320 fprintf(stderr, "ioctl(IAM_IOC_GETATTR): %i (%m)\n", rc);
324 keysize = ua.iui_keysize;
325 recsize = ua.iui_recsize;
327 printf("keysize: %i, recsize: %i, ptrsize: %i, "
328 "height: %i, name: %s\n",
329 keysize, recsize, ua.iui_ptrsize,
330 ua.iui_height, ua.iui_fmt_name);
332 key = calloc(keysize + 1, sizeof key[0]);
333 rec = calloc(recsize + 1, sizeof rec[0]);
335 if (key == NULL || rec == NULL) {
336 fprintf(stderr, "cannot allocate memory\n");
341 copier = keynul ? &strncpy : &memcpy;
342 copier(key, key_opt ? : "RIVERRUN", keysize + 1);
347 copier = recnul ? &strncpy : &memcpy;
348 copier(rec, rec_opt ? : "PALEFIRE", recsize + 1);
354 if (op == OP_INSERT) {
355 rc = doop(0, key, rec, IAM_IOC_INSERT, "IAM_IOC_INSERT");
357 } else if (op == OP_DELETE) {
358 rc = doop(0, key, rec, IAM_IOC_DELETE, "IAM_IOC_DELETE");
360 } else if (op == OP_LOOKUP) {
361 rc = doop(0, key, rec, IAM_IOC_LOOKUP, "IAM_IOC_LOOKUP");
363 print_rec(rec, recsize);
365 } else if (op == OP_IT_START) {
366 rc = doop(0, key, rec, IAM_IOC_IT_START, "IAM_IOC_IT_START");
368 print_rec(key, keysize);
369 print_rec(rec, recsize);
372 } else if (op == OP_IT_STOP) {
373 rc = doop(0, key, rec, IAM_IOC_IT_STOP, "IAM_IOC_IT_STOP");
375 } else if (op == OP_IT_NEXT) {
376 rc = doop(0, key, rec, IAM_IOC_IT_NEXT, "IAM_IOC_IT_NEXT");
378 print_rec(key, keysize);
379 print_rec(rec, recsize);
384 rc = insert(0, key, rec);
390 rc = insert(0, "DAEDALUS", "FINNEGAN");
396 rc = insert(0, "DAEDALUS", "FINNEGAN");
397 if (errno != EEXIST) {
399 fprintf(stderr, "Duplicate key not detected!\n");
406 rc = lookup(0, "RIVERRUN", rec);
412 print_rec(rec, recsize);
414 for (i = 0; i < N; ++i) {
415 memset(key, 0, keysize + 1);
416 memset(rec, 0, recsize + 1);
417 snprintf(key, keysize + 1, "y-%x-x", i);
418 snprintf(rec, recsize + 1, "p-%x-q", 1000 - i);
419 rc = insert(0, key, rec);
425 printf("key %#x inserted\n", i);