1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
7 * Copyright (c) 2006 Cluster File Systems, Inc.
8 * Author: Nikita Danilov <nikita@clusterfs.com>
10 * This file is part of the Lustre file system, http://www.lustre.org
11 * Lustre is a trademark of Cluster File Systems, Inc.
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.
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.
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.
37 #include <sys/types.h>
43 #include <libcfs/libcfs.h>
47 * Maximal format name length.
52 struct iam_uapi_info {
57 char iui_fmt_name[DX_FMT_NAME_LEN];
66 struct iam_uapi_op iui_op;
71 IAM_IOC_INIT = _IOW('i', 1, struct iam_uapi_info),
72 IAM_IOC_GETINFO = _IOR('i', 2, struct iam_uapi_info),
73 IAM_IOC_INSERT = _IOR('i', 3, struct iam_uapi_op),
74 IAM_IOC_LOOKUP = _IOWR('i', 4, struct iam_uapi_op),
75 IAM_IOC_DELETE = _IOR('i', 5, struct iam_uapi_op),
76 IAM_IOC_IT_START = _IOR('i', 6, struct iam_uapi_it),
77 IAM_IOC_IT_NEXT = _IOW('i', 7, struct iam_uapi_it),
78 IAM_IOC_IT_STOP = _IOR('i', 8, struct iam_uapi_it),
80 IAM_IOC_POLYMORPH = _IOR('i', 9, unsigned long)
83 static void usage(void)
85 printf("usage: iam_ut [-v] [-h] file\n");
88 static int doop(int fd, const void *key, const void *rec,
89 int cmd, const char *name)
93 struct iam_uapi_op op = {
97 result = ioctl(fd, cmd, &op);
99 fprintf(stderr, "ioctl(%s): %i/%i (%m)\n", name, result, errno);
103 static int doit(int fd, const void *key, const void *rec,
104 int cmd, const char *name)
108 struct iam_uapi_it it = {
116 assert((void *)&it == (void *)&it.iui_op);
118 result = ioctl(fd, cmd, &it);
120 fprintf(stderr, "ioctl(%s): %i/%i (%m)\n", name, result, errno);
122 result = it.iui_state;
126 static int insert(int fd, const void *key, const void *rec)
128 return doop(fd, key, rec, IAM_IOC_INSERT, "IAM_IOC_INSERT");
131 static int lookup(int fd, const void *key, void *rec)
133 return doop(fd, key, rec, IAM_IOC_LOOKUP, "IAM_IOC_LOOKUP");
136 static int delete(int fd, const void *key, void *rec)
138 return doop(fd, key, rec, IAM_IOC_DELETE, "IAM_IOC_DELETE");
141 static int rec_is_nul_term(int recsize)
143 return recsize == 255;
146 static void print_rec(const unsigned char *rec, int nr)
150 for (i = 0; i < nr; ++i) {
151 printf("%c", rec[i]);
152 if (rec_is_nul_term(nr) && rec[i] == 0)
156 for (i = 0; i < nr; ++i) {
157 printf("%x", rec[i]);
158 if (rec_is_nul_term(nr) && rec[i] == 0)
174 unsigned char hex2dec(unsigned char hex)
176 if ('0' <= hex && hex <= '9') {
178 } else if ('a' <= hex && hex <= 'f') {
179 return hex - 'a' + 10;
180 } else if ('A' <= hex && hex <= 'F') {
181 return hex - 'A' + 10;
183 fprintf(stderr, "Wrong hex digit '%c'\n", hex);
188 unsigned char *packdigit(unsigned char *number)
193 area = calloc(strlen(number) / 2 + 2, sizeof area[0]);
195 for (scan = area; *number; number += 2, scan++)
196 *scan = (hex2dec(number[0]) << 4) | hex2dec(number[1]);
201 int main(int argc, char **argv)
214 void *(*copier)(void *, void *, size_t);
224 struct iam_uapi_info ua;
226 setbuf(stdout, NULL);
227 setbuf(stderr, NULL);
235 opt = getopt(argc, argv, "vilk:K:N:r:R:dsSnP:");
242 key_opt = packdigit(optarg);
252 rec_opt = packdigit(optarg);
281 mode = strtoul(optarg, NULL, 0);
282 rc = ioctl(0, IAM_IOC_POLYMORPH, mode);
284 perror("IAM_IOC_POLYMORPH");
289 fprintf(stderr, "Unable to parse options.");
297 rc = ioctl(0, IAM_IOC_INIT, &ua);
299 fprintf(stderr, "ioctl(IAM_IOC_INIT): %i (%m)\n", rc);
303 rc = ioctl(0, IAM_IOC_GETINFO, &ua);
305 fprintf(stderr, "ioctl(IAM_IOC_GETATTR): %i (%m)\n", rc);
309 keysize = ua.iui_keysize;
310 recsize = ua.iui_recsize;
312 printf("keysize: %i, recsize: %i, ptrsize: %i, "
313 "height: %i, name: %s\n",
314 keysize, recsize, ua.iui_ptrsize,
315 ua.iui_height, ua.iui_fmt_name);
317 key = calloc(keysize + 1, sizeof key[0]);
318 rec = calloc(recsize + 1, sizeof rec[0]);
320 if (key == NULL || rec == NULL) {
321 fprintf(stderr, "cannot allocate memory\n");
326 copier = keynul ? &strncpy : &memcpy;
327 copier(key, key_opt ? : "RIVERRUN", keysize + 1);
332 copier = recnul ? &strncpy : &memcpy;
333 copier(rec, rec_opt ? : "PALEFIRE", recsize + 1);
339 if (op == OP_INSERT) {
340 rc = doop(0, key, rec, IAM_IOC_INSERT, "IAM_IOC_INSERT");
342 } else if (op == OP_DELETE) {
343 rc = doop(0, key, rec, IAM_IOC_DELETE, "IAM_IOC_DELETE");
345 } else if (op == OP_LOOKUP) {
346 rc = doop(0, key, rec, IAM_IOC_LOOKUP, "IAM_IOC_LOOKUP");
348 print_rec(rec, recsize);
350 } else if (op == OP_IT_START) {
351 rc = doop(0, key, rec, IAM_IOC_IT_START, "IAM_IOC_IT_START");
353 print_rec(key, keysize);
354 print_rec(rec, recsize);
357 } else if (op == OP_IT_STOP) {
358 rc = doop(0, key, rec, IAM_IOC_IT_STOP, "IAM_IOC_IT_STOP");
360 } else if (op == OP_IT_NEXT) {
361 rc = doop(0, key, rec, IAM_IOC_IT_NEXT, "IAM_IOC_IT_NEXT");
363 print_rec(key, keysize);
364 print_rec(rec, recsize);
369 rc = insert(0, key, rec);
375 rc = insert(0, "DAEDALUS", "FINNEGAN");
381 rc = insert(0, "DAEDALUS", "FINNEGAN");
382 if (errno != EEXIST) {
384 fprintf(stderr, "Duplicate key not detected!\n");
391 rc = lookup(0, "RIVERRUN", rec);
397 print_rec(rec, recsize);
399 for (i = 0; i < N; ++i) {
400 memset(key, 0, keysize + 1);
401 memset(rec, 0, recsize + 1);
402 snprintf(key, keysize + 1, "y-%x-x", i);
403 snprintf(rec, recsize + 1, "p-%x-q", 1000 - i);
404 rc = insert(0, key, rec);
410 printf("key %#x inserted\n", i);