1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
6 * This file is part of Portals, http://www.sf.net/projects/lustre/
8 * Portals is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Portals is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Portals; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <sys/types.h>
31 #include <sys/ioctl.h>
35 #include <portals/api-support.h>
36 #include <portals/ptlctl.h>
39 const char * dev_name;
43 static struct ioc_dev ioc_dev_list[10];
54 open_ioc_dev(int dev_id)
56 const char * dev_name;
58 if (dev_id < 0 || dev_id >= sizeof(ioc_dev_list))
61 dev_name = ioc_dev_list[dev_id].dev_name;
62 if (dev_name == NULL) {
63 fprintf(stderr, "unknown device id: %d\n", dev_id);
67 if (ioc_dev_list[dev_id].dev_fd < 0) {
68 int fd = open(dev_name, O_RDWR);
71 fprintf(stderr, "opening %s failed: %s\n"
72 "hint: the kernel modules may not be loaded\n",
73 dev_name, strerror(errno));
76 ioc_dev_list[dev_id].dev_fd = fd;
79 return ioc_dev_list[dev_id].dev_fd;
84 do_ioctl(int dev_id, int opc, void *buf)
88 fd = open_ioc_dev(dev_id);
92 rc = ioctl(fd, opc, buf);
102 if (!dump_filename) {
103 fprintf(stderr, "no dump filename\n");
105 fp = fopen(dump_filename, "a");
110 * The dump file should start with a description of which devices are
111 * used, but for now it will assumed whatever app reads the file will
112 * know what to do. */
114 dump(int dev_id, int opc, void *buf)
117 struct dump_hdr dump_hdr;
118 struct portal_ioctl_hdr * ioc_hdr = (struct portal_ioctl_hdr *) buf;
121 printf("dumping opc %x to %s\n", opc, dump_filename);
124 dump_hdr.magic = 0xdeadbeef;
125 dump_hdr.dev_id = dev_id;
128 fp = get_dump_file();
130 fprintf(stderr, "%s: %s\n", dump_filename,
135 rc = fwrite(&dump_hdr, sizeof(dump_hdr), 1, fp);
137 rc = fwrite(buf, ioc_hdr->ioc_len, 1, fp);
140 fprintf(stderr, "%s: %s\n", dump_filename,
148 /* register a device to send ioctls to. */
150 register_ioc_dev(int dev_id, const char * dev_name)
153 if (dev_id < 0 || dev_id >= sizeof(ioc_dev_list))
156 unregister_ioc_dev(dev_id);
158 ioc_dev_list[dev_id].dev_name = dev_name;
159 ioc_dev_list[dev_id].dev_fd = -1;
165 unregister_ioc_dev(int dev_id)
168 if (dev_id < 0 || dev_id >= sizeof(ioc_dev_list))
170 if (ioc_dev_list[dev_id].dev_name != NULL &&
171 ioc_dev_list[dev_id].dev_fd >= 0)
172 close(ioc_dev_list[dev_id].dev_fd);
174 ioc_dev_list[dev_id].dev_name = NULL;
175 ioc_dev_list[dev_id].dev_fd = -1;
178 /* If this file is set, then all ioctl buffers will be
179 appended to the file. */
181 set_ioctl_dump(char * file)
186 dump_filename = strdup(file);
191 l_ioctl(int dev_id, int opc, void *buf)
194 return dump(dev_id, opc, buf);
196 return do_ioctl(dev_id, opc, buf);
199 /* Read an ioctl dump file, and call the ioc_func for each ioctl buffer
200 * in the file. For example:
202 * parse_dump("lctl.dump", l_ioctl);
204 * Note: if using l_ioctl, then you also need to register_ioc_dev() for
205 * each device used in the dump.
208 parse_dump(char * dump_file, int (*ioc_func)(int dev_id, int opc, void *))
214 fd = syscall(SYS_open, dump_file, O_RDONLY);
216 #warning FIXME: cleanup fstat issue here
218 #define __SYS_fstat__ SYS_fstat
220 #define __SYS_fstat__ SYS_fstat64
222 if (syscall(__SYS_fstat__, fd, &st)) {
223 perror("stat fails");
227 if (st.st_size < 1) {
228 fprintf(stderr, "KML is empty\n");
232 buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE , fd, 0);
233 end = buf + st.st_size;
236 struct dump_hdr *dump_hdr = (struct dump_hdr *) buf;
237 struct portal_ioctl_hdr * data;
243 data = (struct portal_ioctl_hdr *) (buf + sizeof(*dump_hdr));
244 if (buf + data->ioc_len > end ) {
245 fprintf(stderr, "dump file overflow, %p + %d > %p\n", buf,
250 printf ("dump_hdr: %lx data: %lx\n",
251 (unsigned long)dump_hdr - (unsigned long)buf, (unsigned long)data - (unsigned long)buf);
253 printf("%d: opcode %x len: %d ver: %x ", line, dump_hdr->opc,
254 data->ioc_len, data->ioc_version);
257 memcpy(tmp, data, data->ioc_len);
259 rc = ioc_func(dump_hdr->dev_id, dump_hdr->opc, tmp);
261 printf("failed: %d\n", rc);
265 buf += data->ioc_len + sizeof(*dump_hdr);
271 jt_ioc_dump(int argc, char **argv)
274 fprintf(stderr, "usage: %s [hostname]\n", argv[0]);
277 printf("setting dumpfile to: %s\n", argv[1]);
279 set_ioctl_dump(argv[1]);