Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | /*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
* GPL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
* libcfs/include/libcfs/libcfs_ioctl.h
*
* Low-level ioctl data structures. Kernel ioctl functions declared here,
* and user space functions are in libcfsutil_ioctl.h.
*
*/
#ifndef __LIBCFS_IOCTL_H__
#define __LIBCFS_IOCTL_H__
#define LIBCFS_IOCTL_VERSION 0x0001000a
struct libcfs_ioctl_data {
__u32 ioc_len;
__u32 ioc_version;
__u64 ioc_nid;
__u64 ioc_u64[1];
__u32 ioc_flags;
__u32 ioc_count;
__u32 ioc_net;
__u32 ioc_u32[7];
__u32 ioc_inllen1;
char *ioc_inlbuf1;
__u32 ioc_inllen2;
char *ioc_inlbuf2;
__u32 ioc_plen1; /* buffers in userspace */
char *ioc_pbuf1;
__u32 ioc_plen2; /* buffers in userspace */
char *ioc_pbuf2;
char ioc_bulk[0];
};
#define ioc_priority ioc_u32[0]
struct libcfs_ioctl_hdr {
__u32 ioc_len;
__u32 ioc_version;
};
struct libcfs_debug_ioctl_data {
struct libcfs_ioctl_hdr hdr;
unsigned int subs;
unsigned int debug;
};
#define LIBCFS_IOC_INIT(data) \
do { \
memset(&data, 0, sizeof(data)); \
data.ioc_version = LIBCFS_IOCTL_VERSION; \
data.ioc_len = sizeof(data); \
} while (0)
struct libcfs_ioctl_handler {
struct list_head item;
int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_data *data);
};
#define DECLARE_IOCTL_HANDLER(ident, func) \
struct libcfs_ioctl_handler ident = { \
/* .item = */ LIST_HEAD_INIT(ident.item), \
/* .handle_ioctl = */ func \
}
/* FIXME check conflict with lustre_lib.h */
#define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long)
/* ioctls for manipulating snapshots 30- */
#define IOC_LIBCFS_TYPE 'e'
#define IOC_LIBCFS_MIN_NR 30
/* libcfs ioctls */
#define IOC_LIBCFS_PANIC _IOWR('e', 30, long)
#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, long)
#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, long)
#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, long)
/* lnet ioctls */
#define IOC_LIBCFS_GET_NI _IOWR('e', 50, long)
#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, long)
#define IOC_LIBCFS_ADD_ROUTE _IOWR('e', 52, long)
#define IOC_LIBCFS_DEL_ROUTE _IOWR('e', 53, long)
#define IOC_LIBCFS_GET_ROUTE _IOWR('e', 54, long)
#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, long)
#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, long)
#define IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, long)
#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, long)
#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, long)
#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, long)
#define IOC_LIBCFS_PING _IOWR('e', 61, long)
#define IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, long)
#define IOC_LIBCFS_LNETST _IOWR('e', 63, long)
/* lnd ioctls */
#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, long)
#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, long)
#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, long)
#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, long)
#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, long)
#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, long)
#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, long)
/* ioctl 77 is free for use */
#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, long)
#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, long)
#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, long)
#define IOC_LIBCFS_MAX_NR 80
static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
{
int len = sizeof(*data);
len += cfs_size_round(data->ioc_inllen1);
len += cfs_size_round(data->ioc_inllen2);
return len;
}
static inline int libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data)
{
if (data->ioc_len > (1<<30)) {
CERROR("LIBCFS ioctl: ioc_len larger than 1<<30\n");
return 1;
}
if (data->ioc_inllen1 > (1<<30)) {
CERROR("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n");
return 1;
}
if (data->ioc_inllen2 > (1<<30)) {
CERROR("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n");
return 1;
}
if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
CERROR("LIBCFS ioctl: inlbuf1 pointer but 0 length\n");
return 1;
}
if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
CERROR("LIBCFS ioctl: inlbuf2 pointer but 0 length\n");
return 1;
}
if (data->ioc_pbuf1 && !data->ioc_plen1) {
CERROR("LIBCFS ioctl: pbuf1 pointer but 0 length\n");
return 1;
}
if (data->ioc_pbuf2 && !data->ioc_plen2) {
CERROR("LIBCFS ioctl: pbuf2 pointer but 0 length\n");
return 1;
}
if (data->ioc_plen1 && !data->ioc_pbuf1) {
CERROR("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n");
return 1;
}
if (data->ioc_plen2 && !data->ioc_pbuf2) {
CERROR("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n");
return 1;
}
if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_len) {
CERROR("LIBCFS ioctl: packlen != ioc_len\n");
return 1;
}
if (data->ioc_inllen1 &&
data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
CERROR("LIBCFS ioctl: inlbuf1 not 0 terminated\n");
return 1;
}
if (data->ioc_inllen2 &&
data->ioc_bulk[cfs_size_round(data->ioc_inllen1) +
data->ioc_inllen2 - 1] != '\0') {
CERROR("LIBCFS ioctl: inlbuf2 not 0 terminated\n");
return 1;
}
return 0;
}
int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);
int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);
int libcfs_ioctl_getdata(char *buf, char *end, void *arg);
int libcfs_ioctl_popdata(void *arg, void *buf, int size);
#endif /* __LIBCFS_IOCTL_H__ */
|