From 421d7a675265d697a1a9308aa9dac8030eab497a Mon Sep 17 00:00:00 2001 From: "robert.read" Date: Wed, 6 Aug 2008 00:23:21 +0000 Subject: [PATCH] Land b_head_libcfs onto HEAD (20080805_1722) b=16620 i=adilger i=shadow i=isaac First stage of Libcfs cleanup. This landing includes the patches from bugs 16159, 16420, 16445, 16478, and 16479. --- libcfs/autoconf/lustre-libcfs.m4 | 4 + libcfs/include/libcfs/Makefile.am | 8 +- libcfs/include/libcfs/darwin/darwin-prim.h | 1 - libcfs/include/libcfs/darwin/kp30.h | 4 - libcfs/include/libcfs/darwin/libcfs.h | 15 +- libcfs/include/libcfs/libcfs.h | 401 +----------- libcfs/include/libcfs/libcfs_debug.h | 330 ++++++++++ libcfs/include/libcfs/libcfs_hash.h | 116 ++++ libcfs/include/libcfs/libcfs_ioctl.h | 229 +++++++ libcfs/include/libcfs/libcfs_prim.h | 81 +++ libcfs/include/libcfs/libcfs_private.h | 262 +------- libcfs/include/libcfs/libcfs_time.h | 144 +++++ libcfs/include/libcfs/{types.h => libcfsutil.h} | 31 +- libcfs/include/libcfs/linux/kp30.h | 102 ++-- libcfs/include/libcfs/linux/libcfs.h | 106 +--- libcfs/include/libcfs/linux/linux-fs.h | 18 +- libcfs/include/libcfs/linux/linux-lock.h | 12 +- libcfs/include/libcfs/linux/linux-mem.h | 28 +- libcfs/include/libcfs/linux/linux-prim.h | 71 +-- libcfs/include/libcfs/linux/linux-tcpip.h | 11 +- libcfs/include/libcfs/linux/linux-time.h | 44 +- libcfs/include/libcfs/posix/.cvsignore | 2 + libcfs/include/libcfs/posix/Makefile.am | 1 + libcfs/include/libcfs/posix/libcfs.h | 245 ++++++++ libcfs/include/libcfs/posix/posix-types.h | 64 ++ libcfs/include/libcfs/posix/posix-wordsize.h | 149 +++++ libcfs/include/libcfs/user-lock.h | 64 +- libcfs/include/libcfs/user-mem.h | 105 ++++ libcfs/include/libcfs/user-prim.h | 194 +----- libcfs/include/libcfs/user-time.h | 33 +- libcfs/include/libcfs/util/.cvsignore | 2 + libcfs/include/libcfs/util/Makefile.am | 1 + libcfs/include/libcfs/util/libcfsutil_ioctl.h | 54 ++ libcfs/include/libcfs/util/parser.h | 115 ++++ libcfs/include/libcfs/util/platform.h | 268 ++++++++ libcfs/include/libcfs/winnt/kp30.h | 4 - libcfs/include/libcfs/winnt/libcfs.h | 1 + libcfs/include/libcfs/winnt/winnt-prim.h | 3 +- libcfs/libcfs/autoMakefile.am | 14 +- libcfs/libcfs/darwin/darwin-prim.c | 6 - libcfs/libcfs/darwin/darwin-utils.c | 4 +- libcfs/libcfs/debug.c | 327 ---------- libcfs/libcfs/linux/linux-prim.c | 151 +++++ libcfs/libcfs/posix/.cvsignore | 2 + libcfs/libcfs/posix/Makefile.am | 2 + libcfs/libcfs/posix/posix-debug.c | 364 +++++++++++ libcfs/libcfs/user-lock.c | 27 +- libcfs/libcfs/user-mem.c | 157 +++++ libcfs/libcfs/user-prim.c | 178 +++--- libcfs/libcfs/user-tcpip.c | 1 + libcfs/libcfs/util/.cvsignore | 3 + libcfs/libcfs/util/Makefile.am | 2 + libcfs/libcfs/util/l_ioctl.c | 391 ++++++++++++ libcfs/libcfs/util/parser.c | 771 ++++++++++++++++++++++++ libcfs/libcfs/winnt/winnt-sync.c | 21 - 55 files changed, 4055 insertions(+), 1689 deletions(-) create mode 100644 libcfs/include/libcfs/libcfs_debug.h create mode 100644 libcfs/include/libcfs/libcfs_hash.h create mode 100644 libcfs/include/libcfs/libcfs_ioctl.h create mode 100644 libcfs/include/libcfs/libcfs_prim.h create mode 100644 libcfs/include/libcfs/libcfs_time.h rename libcfs/include/libcfs/{types.h => libcfsutil.h} (70%) create mode 100644 libcfs/include/libcfs/posix/.cvsignore create mode 100644 libcfs/include/libcfs/posix/Makefile.am create mode 100644 libcfs/include/libcfs/posix/libcfs.h create mode 100644 libcfs/include/libcfs/posix/posix-types.h create mode 100644 libcfs/include/libcfs/posix/posix-wordsize.h create mode 100644 libcfs/include/libcfs/user-mem.h create mode 100644 libcfs/include/libcfs/util/.cvsignore create mode 100644 libcfs/include/libcfs/util/Makefile.am create mode 100644 libcfs/include/libcfs/util/libcfsutil_ioctl.h create mode 100644 libcfs/include/libcfs/util/parser.h create mode 100644 libcfs/include/libcfs/util/platform.h create mode 100644 libcfs/libcfs/posix/.cvsignore create mode 100644 libcfs/libcfs/posix/Makefile.am create mode 100644 libcfs/libcfs/posix/posix-debug.c create mode 100644 libcfs/libcfs/user-mem.c create mode 100644 libcfs/libcfs/util/.cvsignore create mode 100644 libcfs/libcfs/util/Makefile.am create mode 100644 libcfs/libcfs/util/l_ioctl.c create mode 100644 libcfs/libcfs/util/parser.c diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index f78c781..ae74dc0 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -502,9 +502,13 @@ libcfs/autoconf/Makefile libcfs/include/Makefile libcfs/include/libcfs/Makefile libcfs/include/libcfs/linux/Makefile +libcfs/include/libcfs/posix/Makefile +libcfs/include/libcfs/util/Makefile libcfs/libcfs/Makefile libcfs/libcfs/autoMakefile libcfs/libcfs/linux/Makefile +libcfs/libcfs/posix/Makefile +libcfs/libcfs/util/Makefile ]) case $lb_target_os in darwin) diff --git a/libcfs/include/libcfs/Makefile.am b/libcfs/include/libcfs/Makefile.am index 733fe3e..207e7f6 100644 --- a/libcfs/include/libcfs/Makefile.am +++ b/libcfs/include/libcfs/Makefile.am @@ -1,9 +1,11 @@ -SUBDIRS := linux +SUBDIRS := linux posix util if DARWIN SUBDIRS += darwin endif DIST_SUBDIRS := $(SUBDIRS) EXTRA_DIST := curproc.h libcfs_private.h libcfs.h list.h lltrace.h \ - portals_utils.h types.h user-lock.h user-prim.h user-time.h \ - user-tcpip.h user-bitops.h bitmap.h + portals_utils.h user-lock.h user-prim.h user-time.h \ + user-tcpip.h user-bitops.h bitmap.h user-mem.h\ + libcfs_prim.h libcfs_private.h libcfs_hash.h libcfs_time.h \ + libcfs_debug.h libcfsutil.h libcfs_ioctl.h diff --git a/libcfs/include/libcfs/darwin/darwin-prim.h b/libcfs/include/libcfs/darwin/darwin-prim.h index 02425b7..2f1fc74 100644 --- a/libcfs/include/libcfs/darwin/darwin-prim.h +++ b/libcfs/include/libcfs/darwin/darwin-prim.h @@ -232,7 +232,6 @@ void cfs_waitlink_init(struct cfs_waitlink *link); void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link); void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, struct cfs_waitlink *link); -void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq); void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link); int cfs_waitq_active(struct cfs_waitq *waitq); diff --git a/libcfs/include/libcfs/darwin/kp30.h b/libcfs/include/libcfs/darwin/kp30.h index c823787..63d52af 100644 --- a/libcfs/include/libcfs/darwin/kp30.h +++ b/libcfs/include/libcfs/darwin/kp30.h @@ -37,10 +37,6 @@ #ifndef __LIBCFS_DARWIN_KP30__ #define __LIBCFS_DARWIN_KP30__ -#ifndef __LIBCFS_KP30_H__ -#error Do not #include this file directly. #include instead -#endif - #ifdef __KERNEL__ #include diff --git a/libcfs/include/libcfs/darwin/libcfs.h b/libcfs/include/libcfs/darwin/libcfs.h index 233eae0..e3fdfd2 100644 --- a/libcfs/include/libcfs/darwin/libcfs.h +++ b/libcfs/include/libcfs/darwin/libcfs.h @@ -51,6 +51,7 @@ #include #include #include +#include #ifdef __KERNEL__ # include @@ -85,20 +86,6 @@ typedef unsigned long long cycles_t; #define __swab32s(x) do { *(x) = __swab32(*(x)); } while (0) #define __swab64s(x) do { *(x) = __swab64(*(x)); } while (0) -struct ptldebug_header { - __u32 ph_len; - __u32 ph_flags; - __u32 ph_subsys; - __u32 ph_mask; - __u32 ph_cpu_id; - __u32 ph_sec; - __u64 ph_usec; - __u32 ph_stack; - __u32 ph_pid; - __u32 ph_extern_pid; - __u32 ph_line_num; -} __attribute__((packed)); - #ifdef __KERNEL__ # include diff --git a/libcfs/include/libcfs/libcfs.h b/libcfs/include/libcfs/libcfs.h index d1e80be..36e0979 100644 --- a/libcfs/include/libcfs/libcfs.h +++ b/libcfs/include/libcfs/libcfs.h @@ -41,7 +41,9 @@ #define __attribute__(x) #endif -#if defined(__linux__) +#if !defined(__WINNT__) && !defined(__KERNEL__) +#include +#elif defined(__linux__) #include #elif defined(__APPLE__) #include @@ -53,19 +55,14 @@ #include "curproc.h" -#ifndef __KERNEL__ -#include -#endif - -/* Controlled via configure key */ -/* #define LIBCFS_DEBUG */ - #ifndef offsetof # define offsetof(typ,memb) ((unsigned long)((char *)&(((typ *)0)->memb))) #endif /* cardinality of array */ -#define sizeof_array(a) ((sizeof (a)) / (sizeof ((a)[0]))) +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) ((sizeof (a)) / (sizeof ((a)[0]))) +#endif #if !defined(container_of) /* given a pointer @ptr to the field @member embedded into type (usually @@ -99,161 +96,6 @@ #define LOWEST_BIT_SET(x) ((x) & ~((x) - 1)) -/* - * Debugging - */ -extern unsigned int libcfs_subsystem_debug; -extern unsigned int libcfs_stack; -extern unsigned int libcfs_debug; -extern unsigned int libcfs_printk; -extern unsigned int libcfs_console_ratelimit; -extern cfs_duration_t libcfs_console_max_delay; -extern cfs_duration_t libcfs_console_min_delay; -extern unsigned int libcfs_console_backoff; -extern unsigned int libcfs_debug_binary; -extern char debug_file_path[1024]; - -int libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys); -int libcfs_debug_str2mask(int *mask, const char *str, int is_subsys); - -/* Has there been an LBUG? */ -extern unsigned int libcfs_catastrophe; -extern unsigned int libcfs_panic_on_lbug; - -/* - * struct ptldebug_header is defined in libcfs//libcfs.h - */ - -#define PH_FLAG_FIRST_RECORD 1 - -/* Debugging subsystems (32 bits, non-overlapping) */ -/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */ -#define S_UNDEFINED 0x00000001 -#define S_MDC 0x00000002 -#define S_MDS 0x00000004 -#define S_OSC 0x00000008 -#define S_OST 0x00000010 -#define S_CLASS 0x00000020 -#define S_LOG 0x00000040 -#define S_LLITE 0x00000080 -#define S_RPC 0x00000100 -#define S_MGMT 0x00000200 -#define S_LNET 0x00000400 -#define S_LND 0x00000800 /* ALL LNDs */ -#define S_PINGER 0x00001000 -#define S_FILTER 0x00002000 -/* unused */ -#define S_ECHO 0x00008000 -#define S_LDLM 0x00010000 -#define S_LOV 0x00020000 -/* unused */ -/* unused */ -/* unused */ -/* unused */ -/* unused */ -#define S_LMV 0x00800000 /* b_new_cmd */ -/* unused */ -#define S_SEC 0x02000000 /* upcall cache */ -#define S_GSS 0x04000000 /* b_new_cmd */ -/* unused */ -#define S_MGC 0x10000000 -#define S_MGS 0x20000000 -#define S_FID 0x40000000 /* b_new_cmd */ -#define S_FLD 0x80000000 /* b_new_cmd */ -/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */ - -/* Debugging masks (32 bits, non-overlapping) */ -/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */ -#define D_TRACE 0x00000001 /* ENTRY/EXIT markers */ -#define D_INODE 0x00000002 -#define D_SUPER 0x00000004 -#define D_EXT2 0x00000008 /* anything from ext2_debug */ -#define D_MALLOC 0x00000010 /* print malloc, free information */ -#define D_CACHE 0x00000020 /* cache-related items */ -#define D_INFO 0x00000040 /* general information */ -#define D_IOCTL 0x00000080 /* ioctl related information */ -#define D_NETERROR 0x00000100 /* network errors */ -#define D_NET 0x00000200 /* network communications */ -#define D_WARNING 0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */ -#define D_BUFFS 0x00000800 -#define D_OTHER 0x00001000 -#define D_DENTRY 0x00002000 -#define D_NETTRACE 0x00004000 -#define D_PAGE 0x00008000 /* bulk page handling */ -#define D_DLMTRACE 0x00010000 -#define D_ERROR 0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */ -#define D_EMERG 0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */ -#define D_HA 0x00080000 /* recovery and failover */ -#define D_RPCTRACE 0x00100000 /* for distributed debugging */ -#define D_VFSTRACE 0x00200000 -#define D_READA 0x00400000 /* read-ahead */ -#define D_MMAP 0x00800000 -#define D_CONFIG 0x01000000 -#define D_CONSOLE 0x02000000 -#define D_QUOTA 0x04000000 -#define D_SEC 0x08000000 -/* keep these in sync with lnet/{utils,libcfs}/debug.c */ - -#define D_CANTMASK (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE) - -#ifndef DEBUG_SUBSYSTEM -# define DEBUG_SUBSYSTEM S_UNDEFINED -#endif - -#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600)) /* jiffies */ -#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */ -#define CDEBUG_DEFAULT_BACKOFF 2 -typedef struct { - cfs_time_t cdls_next; - int cdls_count; - cfs_duration_t cdls_delay; -} cfs_debug_limit_state_t; - -/* Controlled via configure key */ -/* #define CDEBUG_ENABLED */ - -#if defined(__KERNEL__) || (defined(__arch_lib__) && !defined(LUSTRE_UTILS)) - -#ifdef CDEBUG_ENABLED -#define __CDEBUG(cdls, mask, format, a...) \ -do { \ - CHECK_STACK(); \ - \ - if (((mask) & D_CANTMASK) != 0 || \ - ((libcfs_debug & (mask)) != 0 && \ - (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \ - libcfs_debug_msg(cdls, DEBUG_SUBSYSTEM, mask, \ - __FILE__, __FUNCTION__, __LINE__, \ - format, ## a); \ -} while (0) - -#define CDEBUG(mask, format, a...) __CDEBUG(NULL, mask, format, ## a) - -#define CDEBUG_LIMIT(mask, format, a...) \ -do { \ - static cfs_debug_limit_state_t cdls; \ - \ - __CDEBUG(&cdls, mask, format, ## a); \ -} while (0) - -#else /* CDEBUG_ENABLED */ -#define CDEBUG(mask, format, a...) (void)(0) -#define CDEBUG_LIMIT(mask, format, a...) (void)(0) -#warning "CDEBUG IS DISABLED. THIS SHOULD NEVER BE DONE FOR PRODUCTION!" -#endif - -#else - -#define CDEBUG(mask, format, a...) \ -do { \ - if (((mask) & D_CANTMASK) != 0) \ - fprintf(stderr, "(%s:%d:%s()) " format, \ - __FILE__, __LINE__, __FUNCTION__, ## a); \ -} while (0) - -#define CDEBUG_LIMIT CDEBUG - -#endif /* !__KERNEL__ */ /* * Lustre Error Checksum: calculates checksum @@ -262,69 +104,6 @@ do { \ #define LERRCHKSUM(hexnum) (((hexnum) & 0xf) ^ ((hexnum) >> 4 & 0xf) ^ \ ((hexnum) >> 8 & 0xf)) -#define CWARN(format, a...) CDEBUG_LIMIT(D_WARNING, format, ## a) -#define CERROR(format, a...) CDEBUG_LIMIT(D_ERROR, format, ## a) -#define CEMERG(format, a...) CDEBUG_LIMIT(D_EMERG, format, ## a) - -#define LCONSOLE(mask, format, a...) CDEBUG(D_CONSOLE | (mask), format, ## a) -#define LCONSOLE_INFO(format, a...) CDEBUG_LIMIT(D_CONSOLE, format, ## a) -#define LCONSOLE_WARN(format, a...) CDEBUG_LIMIT(D_CONSOLE | D_WARNING, format, ## a) -#define LCONSOLE_ERROR_MSG(errnum, format, a...) CDEBUG_LIMIT(D_CONSOLE | D_ERROR, \ - "%x-%x: " format, errnum, LERRCHKSUM(errnum), ## a) -#define LCONSOLE_ERROR(format, a...) LCONSOLE_ERROR_MSG(0x00, format, ## a) - -#define LCONSOLE_EMERG(format, a...) CDEBUG(D_CONSOLE | D_EMERG, format, ## a) - -#ifdef CDEBUG_ENABLED - -#define GOTO(label, rc) \ -do { \ - long GOTO__ret = (long)(rc); \ - CDEBUG(D_TRACE,"Process leaving via %s (rc=%lu : %ld : %lx)\n", \ - #label, (unsigned long)GOTO__ret, (signed long)GOTO__ret,\ - (signed long)GOTO__ret); \ - goto label; \ -} while (0) -#else -#define GOTO(label, rc) do { ((void)(rc)); goto label; } while (0) -#endif - -/* Controlled via configure key */ -/* #define CDEBUG_ENTRY_EXIT */ - -#ifdef CDEBUG_ENTRY_EXIT - -/* - * if rc == NULL, we need to code as RETURN((void *)NULL), otherwise - * there will be a warning in osx. - */ -#define RETURN(rc) \ -do { \ - typeof(rc) RETURN__ret = (rc); \ - CDEBUG(D_TRACE, "Process leaving (rc=%lu : %ld : %lx)\n", \ - (long)RETURN__ret, (long)RETURN__ret, (long)RETURN__ret);\ - EXIT_NESTING; \ - return RETURN__ret; \ -} while (0) - -#define ENTRY \ -ENTRY_NESTING; \ -do { \ - CDEBUG(D_TRACE, "Process entered\n"); \ -} while (0) - -#define EXIT \ -do { \ - CDEBUG(D_TRACE, "Process leaving\n"); \ - EXIT_NESTING; \ -} while(0) -#else /* !CDEBUG_ENTRY_EXIT */ - -#define RETURN(rc) return (rc) -#define ENTRY do { } while (0) -#define EXIT do { } while (0) - -#endif /* !CDEBUG_ENTRY_EXIT */ /* * Some (nomina odiosa sunt) platforms define NULL as naked 0. This confuses @@ -342,22 +121,6 @@ do { \ #include -struct libcfs_ioctl_data; /* forward ref */ - -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 = */ CFS_LIST_HEAD_INIT(ident.item), \ - /* .handle_ioctl = */ func \ - } - -int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); -int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); - /* libcfs tcpip */ int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask); int libcfs_ipif_enumerate(char ***names); @@ -397,8 +160,7 @@ void lc_watchdog_delete(struct lc_watchdog *lcw); /* Dump a debug log */ void lc_watchdog_dumplog(pid_t pid, void *data); -/* __KERNEL__ */ -#endif +#endif /* __KERNEL__ */ /* need both kernel and user-land acceptor */ #define LNET_ACCEPTOR_MIN_RESERVED_PORT 512 @@ -431,149 +193,6 @@ struct cfs_psdev_ops { }; /* - * generic time manipulation functions. - */ - -static inline int cfs_time_after(cfs_time_t t1, cfs_time_t t2) -{ - return cfs_time_before(t2, t1); -} - -static inline int cfs_time_aftereq(cfs_time_t t1, cfs_time_t t2) -{ - return cfs_time_beforeq(t2, t1); -} - -/* - * return seconds since UNIX epoch - */ -static inline time_t cfs_unix_seconds(void) -{ - cfs_fs_time_t t; - - cfs_fs_time_current(&t); - return (time_t)cfs_fs_time_sec(&t); -} - -static inline cfs_time_t cfs_time_shift(int seconds) -{ - return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds)); -} - -static inline long cfs_timeval_sub(struct timeval *large, struct timeval *small, - struct timeval *result) -{ - long r = (long) ( - (large->tv_sec - small->tv_sec) * ONE_MILLION + - (large->tv_usec - small->tv_usec)); - if (result != NULL) { - result->tv_usec = r % ONE_MILLION; - result->tv_sec = r / ONE_MILLION; - } - return r; -} - -#define CFS_RATELIMIT(seconds) \ -({ \ - /* \ - * XXX nikita: non-portable initializer \ - */ \ - static time_t __next_message = 0; \ - int result; \ - \ - if (cfs_time_after(cfs_time_current(), __next_message)) \ - result = 1; \ - else { \ - __next_message = cfs_time_shift(seconds); \ - result = 0; \ - } \ - result; \ -}) - -struct libcfs_debug_msg_data { - cfs_debug_limit_state_t *msg_cdls; - int msg_subsys; - const char *msg_file; - const char *msg_fn; - int msg_line; -}; - -#define DEBUG_MSG_DATA_INIT(cdls, subsystem, file, func, ln ) { \ - .msg_cdls = (cdls), \ - .msg_subsys = (subsystem), \ - .msg_file = (file), \ - .msg_fn = (func), \ - .msg_line = (ln) \ - } - - -extern int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, - int subsys, int mask, - const char *file, const char *fn, const int line, - const char *format1, va_list args, - const char *format2, ...) - __attribute__ ((format (printf, 9, 10))); - -#define libcfs_debug_vmsg(cdls, subsys, mask, file, fn, line, format, args) \ - libcfs_debug_vmsg2(cdls, subsys, mask, file, fn,line,format,args,NULL,NULL) - -#define libcfs_debug_msg(cdls, subsys, mask, file, fn, line, format, a...) \ - libcfs_debug_vmsg2(cdls, subsys, mask, file, fn,line,NULL,NULL,format, ##a) - -#define cdebug_va(cdls, mask, file, func, line, fmt, args) do { \ - CHECK_STACK(); \ - \ - if (((mask) & D_CANTMASK) != 0 || \ - ((libcfs_debug & (mask)) != 0 && \ - (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \ - libcfs_debug_vmsg(cdls, DEBUG_SUBSYSTEM, (mask), \ - (file), (func), (line), fmt, args); \ -} while(0); - -#define cdebug(cdls, mask, file, func, line, fmt, a...) do { \ - CHECK_STACK(); \ - \ - if (((mask) & D_CANTMASK) != 0 || \ - ((libcfs_debug & (mask)) != 0 && \ - (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \ - libcfs_debug_msg(cdls, DEBUG_SUBSYSTEM, (mask), \ - (file), (func), (line), fmt, ## a); \ -} while(0); - -extern void libcfs_assertion_failed(const char *expr, const char *file, - const char *fn, const int line); - -static inline void cfs_slow_warning(cfs_time_t now, int seconds, char *msg) -{ - if (cfs_time_after(cfs_time_current(), - cfs_time_add(now, cfs_time_seconds(15)))) - CERROR("slow %s "CFS_TIME_T" sec\n", msg, - cfs_duration_sec(cfs_time_sub(cfs_time_current(),now))); -} - -/* - * helper function similar to do_gettimeofday() of Linux kernel - */ -static inline void cfs_fs_timeval(struct timeval *tv) -{ - cfs_fs_time_t time; - - cfs_fs_time_current(&time); - cfs_fs_time_usec(&time, tv); -} - -/* - * return valid time-out based on user supplied one. Currently we only check - * that time-out is not shorted than allowed. - */ -static inline cfs_duration_t cfs_timeout_cap(cfs_duration_t timeout) -{ - if (timeout < CFS_TICK) - timeout = CFS_TICK; - return timeout; -} - -/* * Universal memory allocator API */ enum cfs_alloc_flags { @@ -677,7 +296,11 @@ int cfs_oflags2univ(int flags); /* convert universal open flags to local open flags */ int cfs_univ2oflags(int flags); -#include "libcfs_private.h" +#include +#include +#include +#include +#include #define _LIBCFS_H diff --git a/libcfs/include/libcfs/libcfs_debug.h b/libcfs/include/libcfs/libcfs_debug.h new file mode 100644 index 0000000..f80f68d --- /dev/null +++ b/libcfs/include/libcfs/libcfs_debug.h @@ -0,0 +1,330 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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_debug.h + * + * Debug messages and assertions + * + */ + +#ifndef __LIBCFS_DEBUG_H__ +#define __LIBCFS_DEBUG_H__ + +/* + * Debugging + */ +extern unsigned int libcfs_subsystem_debug; +extern unsigned int libcfs_stack; +extern unsigned int libcfs_debug; +extern unsigned int libcfs_printk; +extern unsigned int libcfs_console_ratelimit; +extern cfs_duration_t libcfs_console_max_delay; +extern cfs_duration_t libcfs_console_min_delay; +extern unsigned int libcfs_console_backoff; +extern unsigned int libcfs_debug_binary; +extern char debug_file_path[1024]; + +int libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys); +int libcfs_debug_str2mask(int *mask, const char *str, int is_subsys); + +/* Has there been an LBUG? */ +extern unsigned int libcfs_catastrophe; +extern unsigned int libcfs_panic_on_lbug; + +/** + * Format for debug message headers + */ +struct ptldebug_header { + __u32 ph_len; + __u32 ph_flags; + __u32 ph_subsys; + __u32 ph_mask; + __u32 ph_cpu_id; + __u32 ph_sec; + __u64 ph_usec; + __u32 ph_stack; + __u32 ph_pid; + __u32 ph_extern_pid; + __u32 ph_line_num; +} __attribute__((packed)); + + +#define PH_FLAG_FIRST_RECORD 1 + +/* Debugging subsystems (32 bits, non-overlapping) */ +/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */ +#define S_UNDEFINED 0x00000001 +#define S_MDC 0x00000002 +#define S_MDS 0x00000004 +#define S_OSC 0x00000008 +#define S_OST 0x00000010 +#define S_CLASS 0x00000020 +#define S_LOG 0x00000040 +#define S_LLITE 0x00000080 +#define S_RPC 0x00000100 +#define S_MGMT 0x00000200 +#define S_LNET 0x00000400 +#define S_LND 0x00000800 /* ALL LNDs */ +#define S_PINGER 0x00001000 +#define S_FILTER 0x00002000 +/* unused */ +#define S_ECHO 0x00008000 +#define S_LDLM 0x00010000 +#define S_LOV 0x00020000 +/* unused */ +/* unused */ +/* unused */ +/* unused */ +/* unused */ +#define S_LMV 0x00800000 /* b_new_cmd */ +/* unused */ +#define S_SEC 0x02000000 /* upcall cache */ +#define S_GSS 0x04000000 /* b_new_cmd */ +/* unused */ +#define S_MGC 0x10000000 +#define S_MGS 0x20000000 +#define S_FID 0x40000000 /* b_new_cmd */ +#define S_FLD 0x80000000 /* b_new_cmd */ +/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */ + +/* Debugging masks (32 bits, non-overlapping) */ +/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */ +#define D_TRACE 0x00000001 /* ENTRY/EXIT markers */ +#define D_INODE 0x00000002 +#define D_SUPER 0x00000004 +#define D_EXT2 0x00000008 /* anything from ext2_debug */ +#define D_MALLOC 0x00000010 /* print malloc, free information */ +#define D_CACHE 0x00000020 /* cache-related items */ +#define D_INFO 0x00000040 /* general information */ +#define D_IOCTL 0x00000080 /* ioctl related information */ +#define D_NETERROR 0x00000100 /* network errors */ +#define D_NET 0x00000200 /* network communications */ +#define D_WARNING 0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */ +#define D_BUFFS 0x00000800 +#define D_OTHER 0x00001000 +#define D_DENTRY 0x00002000 +#define D_NETTRACE 0x00004000 +#define D_PAGE 0x00008000 /* bulk page handling */ +#define D_DLMTRACE 0x00010000 +#define D_ERROR 0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */ +#define D_EMERG 0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */ +#define D_HA 0x00080000 /* recovery and failover */ +#define D_RPCTRACE 0x00100000 /* for distributed debugging */ +#define D_VFSTRACE 0x00200000 +#define D_READA 0x00400000 /* read-ahead */ +#define D_MMAP 0x00800000 +#define D_CONFIG 0x01000000 +#define D_CONSOLE 0x02000000 +#define D_QUOTA 0x04000000 +#define D_SEC 0x08000000 +/* keep these in sync with lnet/{utils,libcfs}/debug.c */ + +#define D_CANTMASK (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE) + +#ifndef DEBUG_SUBSYSTEM +# define DEBUG_SUBSYSTEM S_UNDEFINED +#endif + +#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600)) /* jiffies */ +#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */ +#define CDEBUG_DEFAULT_BACKOFF 2 +typedef struct { + cfs_time_t cdls_next; + int cdls_count; + cfs_duration_t cdls_delay; +} cfs_debug_limit_state_t; + +#if defined(__KERNEL__) || (defined(__arch_lib__) && !defined(LUSTRE_UTILS)) + +#ifdef CDEBUG_ENABLED +#define __CDEBUG(cdls, mask, format, a...) \ +do { \ + CHECK_STACK(); \ + \ + if (((mask) & D_CANTMASK) != 0 || \ + ((libcfs_debug & (mask)) != 0 && \ + (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \ + libcfs_debug_msg(cdls, DEBUG_SUBSYSTEM, mask, \ + __FILE__, __FUNCTION__, __LINE__, \ + format, ## a); \ +} while (0) + +#define CDEBUG(mask, format, a...) __CDEBUG(NULL, mask, format, ## a) + +#define CDEBUG_LIMIT(mask, format, a...) \ +do { \ + static cfs_debug_limit_state_t cdls; \ + \ + __CDEBUG(&cdls, mask, format, ## a); \ +} while (0) + +#else /* !CDEBUG_ENABLED */ +#define CDEBUG(mask, format, a...) (void)(0) +#define CDEBUG_LIMIT(mask, format, a...) (void)(0) +#warning "CDEBUG IS DISABLED. THIS SHOULD NEVER BE DONE FOR PRODUCTION!" +#endif + +#else /* !__KERNEL__ && (!__arch_lib__ || LUSTRE_UTILS) */ + +#define CDEBUG(mask, format, a...) \ +do { \ + if (((mask) & D_CANTMASK) != 0) \ + fprintf(stderr, "(%s:%d:%s()) " format, \ + __FILE__, __LINE__, __FUNCTION__, ## a); \ +} while (0) + +#define CDEBUG_LIMIT CDEBUG + +#endif /* !__KERNEL__ ... */ + + +#define CWARN(format, a...) CDEBUG_LIMIT(D_WARNING, format, ## a) +#define CERROR(format, a...) CDEBUG_LIMIT(D_ERROR, format, ## a) +#define CEMERG(format, a...) CDEBUG_LIMIT(D_EMERG, format, ## a) + +#define LCONSOLE(mask, format, a...) CDEBUG(D_CONSOLE | (mask), format, ## a) +#define LCONSOLE_INFO(format, a...) CDEBUG_LIMIT(D_CONSOLE, format, ## a) +#define LCONSOLE_WARN(format, a...) CDEBUG_LIMIT(D_CONSOLE | D_WARNING, format, ## a) +#define LCONSOLE_ERROR_MSG(errnum, format, a...) CDEBUG_LIMIT(D_CONSOLE | D_ERROR, \ + "%x-%x: " format, errnum, LERRCHKSUM(errnum), ## a) +#define LCONSOLE_ERROR(format, a...) LCONSOLE_ERROR_MSG(0x00, format, ## a) + +#define LCONSOLE_EMERG(format, a...) CDEBUG(D_CONSOLE | D_EMERG, format, ## a) + +#ifdef CDEBUG_ENABLED + +#define GOTO(label, rc) \ +do { \ + long GOTO__ret = (long)(rc); \ + CDEBUG(D_TRACE,"Process leaving via %s (rc=%lu : %ld : %lx)\n", \ + #label, (unsigned long)GOTO__ret, (signed long)GOTO__ret,\ + (signed long)GOTO__ret); \ + goto label; \ +} while (0) +#else +#define GOTO(label, rc) do { ((void)(rc)); goto label; } while (0) +#endif + +#ifdef CDEBUG_ENTRY_EXIT + +/* + * if rc == NULL, we need to code as RETURN((void *)NULL), otherwise + * there will be a warning in osx. + */ +#define RETURN(rc) \ +do { \ + typeof(rc) RETURN__ret = (rc); \ + CDEBUG(D_TRACE, "Process leaving (rc=%lu : %ld : %lx)\n", \ + (long)RETURN__ret, (long)RETURN__ret, (long)RETURN__ret);\ + EXIT_NESTING; \ + return RETURN__ret; \ +} while (0) + +#define ENTRY \ +ENTRY_NESTING; \ +do { \ + CDEBUG(D_TRACE, "Process entered\n"); \ +} while (0) + +#define EXIT \ +do { \ + CDEBUG(D_TRACE, "Process leaving\n"); \ + EXIT_NESTING; \ +} while(0) +#else /* !CDEBUG_ENTRY_EXIT */ + +#define RETURN(rc) return (rc) +#define ENTRY do { } while (0) +#define EXIT do { } while (0) + +#endif /* !CDEBUG_ENTRY_EXIT */ + + +struct libcfs_debug_msg_data { + cfs_debug_limit_state_t *msg_cdls; + int msg_subsys; + const char *msg_file; + const char *msg_fn; + int msg_line; +}; + +#define DEBUG_MSG_DATA_INIT(cdls, subsystem, file, func, ln ) { \ + .msg_cdls = (cdls), \ + .msg_subsys = (subsystem), \ + .msg_file = (file), \ + .msg_fn = (func), \ + .msg_line = (ln) \ + } + + +extern int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, + int subsys, int mask, + const char *file, const char *fn, const int line, + const char *format1, va_list args, + const char *format2, ...) + __attribute__ ((format (printf, 9, 10))); + +#define libcfs_debug_vmsg(cdls, subsys, mask, file, fn, line, format, args) \ + libcfs_debug_vmsg2(cdls, subsys, mask, file, fn,line,format,args,NULL,NULL) + +#define libcfs_debug_msg(cdls, subsys, mask, file, fn, line, format, a...) \ + libcfs_debug_vmsg2(cdls, subsys, mask, file, fn,line,NULL,NULL,format, ##a) + +#define cdebug_va(cdls, mask, file, func, line, fmt, args) do { \ + CHECK_STACK(); \ + \ + if (((mask) & D_CANTMASK) != 0 || \ + ((libcfs_debug & (mask)) != 0 && \ + (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \ + libcfs_debug_vmsg(cdls, DEBUG_SUBSYSTEM, (mask), \ + (file), (func), (line), fmt, args); \ +} while(0); + +#define cdebug(cdls, mask, file, func, line, fmt, a...) do { \ + CHECK_STACK(); \ + \ + if (((mask) & D_CANTMASK) != 0 || \ + ((libcfs_debug & (mask)) != 0 && \ + (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \ + libcfs_debug_msg(cdls, DEBUG_SUBSYSTEM, (mask), \ + (file), (func), (line), fmt, ## a); \ +} while(0); + +extern void libcfs_assertion_failed(const char *expr, const char *file, + const char *fn, const int line); + + + +#endif /* __LIBCFS_DEBUG_H__ */ diff --git a/libcfs/include/libcfs/libcfs_hash.h b/libcfs/include/libcfs/libcfs_hash.h new file mode 100644 index 0000000..c016055 --- /dev/null +++ b/libcfs/include/libcfs/libcfs_hash.h @@ -0,0 +1,116 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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_hash.h + * + * Hashing routines + * + */ + +#ifndef __LIBCFS_HASH_H__ +#define __LIBCFS_HASH_H__ + +/* + * Ideally we would use HAVE_HASH_LONG for this, but on linux we configure + * the linux kernel and user space at the same time, so we need to differentiate + * between them explicitely. If this is not needed on other architectures, then + * we'll need to move the functions to archi specific headers. + */ + +#if (defined __linux__ && defined __KERNEL__) +#include +#else +/* Fast hashing routine for a long. + (C) 2002 William Lee Irwin III, IBM */ + +/* + * Knuth recommends primes in approximately golden ratio to the maximum + * integer representable by a machine word for multiplicative hashing. + * Chuck Lever verified the effectiveness of this technique: + * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf + * + * These primes are chosen to be bit-sparse, that is operations on + * them can use shifts and additions instead of multiplications for + * machines where multiplications are slow. + */ +#if BITS_PER_LONG == 32 +/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ +#define GOLDEN_RATIO_PRIME 0x9e370001UL +#elif BITS_PER_LONG == 64 +/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ +#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL +#else +#error Define GOLDEN_RATIO_PRIME for your wordsize. +#endif + +static inline unsigned long hash_long(unsigned long val, unsigned int bits) +{ + unsigned long hash = val; + +#if BITS_PER_LONG == 64 + /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ + unsigned long n = hash; + n <<= 18; + hash -= n; + n <<= 33; + hash -= n; + n <<= 3; + hash += n; + n <<= 3; + hash -= n; + n <<= 4; + hash += n; + n <<= 2; + hash += n; +#else + /* On some cpus multiply is faster, on others gcc will do shifts */ + hash *= GOLDEN_RATIO_PRIME; +#endif + + /* High bits are more random, so use them. */ + return hash >> (BITS_PER_LONG - bits); +} +#if 0 +static inline unsigned long hash_ptr(void *ptr, unsigned int bits) +{ + return hash_long((unsigned long)ptr, bits); +} +#endif + +/* !(__linux__ && __KERNEL__) */ +#endif + +/* !__LIBCFS__HASH_H__ */ +#endif diff --git a/libcfs/include/libcfs/libcfs_ioctl.h b/libcfs/include/libcfs/libcfs_ioctl.h new file mode 100644 index 0000000..93b14fa --- /dev/null +++ b/libcfs/include/libcfs/libcfs_ioctl.h @@ -0,0 +1,229 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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]; +}; + + +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) + +#ifdef __KERNEL__ + +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 = */ CFS_LIST_HEAD_INIT(ident.item), \ + /* .handle_ioctl = */ func \ + } + +#endif + +/* 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, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_LWT_CONTROL _IOWR('e', 33, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_LWT_SNAPSHOT _IOWR('e', 34, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_LWT_LOOKUP_STRING _IOWR('e', 35, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_PING_TEST _IOWR('e', 37, IOCTL_LIBCFS_TYPE) +/* lnet ioctls */ +#define IOC_LIBCFS_GET_NI _IOWR('e', 50, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_ADD_ROUTE _IOWR('e', 52, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_DEL_ROUTE _IOWR('e', 53, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_ROUTE _IOWR('e', 54, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_PING _IOWR('e', 61, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_LNETST _IOWR('e', 63, IOCTL_LIBCFS_TYPE) +/* lnd ioctls */ +#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_TXDESC _IOWR('e', 77, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_GMID _IOWR('e', 81, IOCTL_LIBCFS_TYPE) + +#define IOC_LIBCFS_MAX_NR 81 + +static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data) +{ + int len = sizeof(*data); + len += size_round(data->ioc_inllen1); + len += 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[size_round(data->ioc_inllen1) + + data->ioc_inllen2 - 1] != '\0') { + CERROR ("LIBCFS ioctl: inlbuf2 not 0 terminated\n"); + return 1; + } + return 0; +} + +#ifdef __KERNEL__ + +extern int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand); +extern int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand); +extern int libcfs_ioctl_getdata(char *buf, char *end, void *arg); +extern int libcfs_ioctl_popdata(void *arg, void *buf, int size); + +#endif + +#endif /* __LIBCFS_IOCTL_H__ */ diff --git a/libcfs/include/libcfs/libcfs_prim.h b/libcfs/include/libcfs/libcfs_prim.h new file mode 100644 index 0000000..c9b5c39 --- /dev/null +++ b/libcfs/include/libcfs/libcfs_prim.h @@ -0,0 +1,81 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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_prim.h + * + * General primitives. + * + */ + +#ifndef __LIBCFS_PRIM_H__ +#define __LIBCFS_PRIM_H__ + +/* + * Schedule + */ +void cfs_schedule_timeout(cfs_task_state_t state, int64_t timeout); +void cfs_schedule(void); +void cfs_pause(cfs_duration_t ticks); + +/* + * Wait Queues + */ +void cfs_waitq_init(cfs_waitq_t *waitq); +void cfs_waitlink_init(cfs_waitlink_t *link); +void cfs_waitq_add(cfs_waitq_t *waitq, cfs_waitlink_t *link); +void cfs_waitq_add_exclusive(cfs_waitq_t *waitq, + cfs_waitlink_t *link); +void cfs_waitq_del(cfs_waitq_t *waitq, cfs_waitlink_t *link); +int cfs_waitq_active(cfs_waitq_t *waitq); +void cfs_waitq_signal(cfs_waitq_t *waitq); +void cfs_waitq_signal_nr(cfs_waitq_t *waitq, int nr); +void cfs_waitq_broadcast(cfs_waitq_t *waitq); +void cfs_waitq_wait(cfs_waitlink_t *link, cfs_task_state_t state); +int64_t cfs_waitq_timedwait(cfs_waitlink_t *link, cfs_task_state_t state, + int64_t timeout); + +/* + * Timer + */ +typedef void (cfs_timer_func_t)(unsigned long); + +void cfs_init_timer(cfs_timer_t *t); +void cfs_timer_init(cfs_timer_t *t, cfs_timer_func_t *func, void *arg); +void cfs_timer_done(cfs_timer_t *t); +void cfs_timer_arm(cfs_timer_t *t, cfs_time_t deadline); +void cfs_timer_disarm(cfs_timer_t *t); +int cfs_timer_is_armed(cfs_timer_t *t); +cfs_time_t cfs_timer_deadline(cfs_timer_t *t); +#endif diff --git a/libcfs/include/libcfs/libcfs_private.h b/libcfs/include/libcfs/libcfs_private.h index 1caf5be..021ee61 100644 --- a/libcfs/include/libcfs/libcfs_private.h +++ b/libcfs/include/libcfs/libcfs_private.h @@ -32,27 +32,19 @@ /* * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. + * + * libcfs/include/libcfs/libcfs_private.h + * + * Various defines for libcfs. + * */ -#ifndef __LIBCFS_KP30_H__ -#define __LIBCFS_KP30_H__ - -/* Controlled via configure key */ -/* #define LIBCFS_DEBUG */ +#ifndef __LIBCFS_PRIVATE_H__ +#define __LIBCFS_PRIVATE_H__ -#include +/* XXX this layering violation is for nidstrings */ #include -#if defined(__linux__) -#include -#elif defined(__APPLE__) -#include -#elif defined(__WINNT__) -#include -#else -#error Unsupported operating system -#endif - #ifndef DEBUG_SUBSYSTEM # define DEBUG_SUBSYSTEM S_UNDEFINED #endif @@ -101,8 +93,8 @@ } \ }) -/* LASSERT_CHECKED */ -#else + +#else /* !LASSERT_CHECKED */ #define LASSERT(cond) \ ({ \ @@ -122,14 +114,14 @@ } \ }) -/* LASSERT_CHECKED */ -#endif -/* LIBCFS_DEBUG */ -#else +#endif /* !LASSERT_CHECKED */ + + +#else /* !LIBCFS_DEBUG */ #define LASSERT(e) ((void)(0)) #define LASSERTF(cond, fmt...) ((void)(0)) -#endif /* LIBCFS_DEBUG */ +#endif /* !LIBCFS_DEBUG */ #define KLASSERT(e) LASSERT(e) @@ -399,205 +391,9 @@ do { \ ptr += size_round(len + 1); \ } while (0) -/* - * USER LEVEL STUFF BELOW +/** + * Lustre Network Driver types. */ - -#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]; -}; - - -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) - -/* FIXME check conflict with lustre_lib.h */ -#define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long) - -static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data) -{ - int len = sizeof(*data); - len += size_round(data->ioc_inllen1); - len += 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[size_round(data->ioc_inllen1) + - data->ioc_inllen2 - 1] != '\0') { - CERROR ("LIBCFS ioctl: inlbuf2 not 0 terminated\n"); - return 1; - } - return 0; -} - -#ifndef __KERNEL__ -static inline int libcfs_ioctl_pack(struct libcfs_ioctl_data *data, char **pbuf, - int max) -{ - char *ptr; - struct libcfs_ioctl_data *overlay; - data->ioc_len = libcfs_ioctl_packlen(data); - data->ioc_version = LIBCFS_IOCTL_VERSION; - - if (*pbuf && libcfs_ioctl_packlen(data) > max) - return 1; - if (*pbuf == NULL) { - *pbuf = malloc(data->ioc_len); - } - if (!*pbuf) - return 1; - overlay = (struct libcfs_ioctl_data *)*pbuf; - memcpy(*pbuf, data, sizeof(*data)); - - ptr = overlay->ioc_bulk; - if (data->ioc_inlbuf1) - LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr); - if (data->ioc_inlbuf2) - LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr); - if (libcfs_ioctl_is_invalid(overlay)) - return 1; - - return 0; -} - -#else - -extern int libcfs_ioctl_getdata(char *buf, char *end, void *arg); -extern int libcfs_ioctl_popdata(void *arg, void *buf, int size); - -#endif - -/* 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, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LWT_CONTROL _IOWR('e', 33, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LWT_SNAPSHOT _IOWR('e', 34, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LWT_LOOKUP_STRING _IOWR('e', 35, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PING_TEST _IOWR('e', 37, IOCTL_LIBCFS_TYPE) -/* lnet ioctls */ -#define IOC_LIBCFS_GET_NI _IOWR('e', 50, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_ADD_ROUTE _IOWR('e', 52, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEL_ROUTE _IOWR('e', 53, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_ROUTE _IOWR('e', 54, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PING _IOWR('e', 61, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LNETST _IOWR('e', 63, IOCTL_LIBCFS_TYPE) -/* lnd ioctls */ -#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_TXDESC _IOWR('e', 77, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_GMID _IOWR('e', 81, IOCTL_LIBCFS_TYPE) - -#define IOC_LIBCFS_MAX_NR 81 - - enum { /* Only add to these values (i.e. don't ever change or redefine them): * network addresses depend on them... */ @@ -615,28 +411,4 @@ enum { MXLND = 12, }; -enum { - DEBUG_DAEMON_START = 1, - DEBUG_DAEMON_STOP = 2, - DEBUG_DAEMON_PAUSE = 3, - DEBUG_DAEMON_CONTINUE = 4, -}; - - -enum cfg_record_type { - PORTALS_CFG_TYPE = 1, - LUSTRE_CFG_TYPE = 123, -}; - -typedef int (*cfg_record_cb_t)(enum cfg_record_type, int len, void *data); - -/* lustre_id output helper macros */ -#define DLID4 "%lu/%lu/%lu/%lu" - -#define OLID4(id) \ - (unsigned long)(id)->li_fid.lf_id, \ - (unsigned long)(id)->li_fid.lf_group, \ - (unsigned long)(id)->li_stc.u.e3s.l3s_ino, \ - (unsigned long)(id)->li_stc.u.e3s.l3s_gen - #endif diff --git a/libcfs/include/libcfs/libcfs_time.h b/libcfs/include/libcfs/libcfs_time.h new file mode 100644 index 0000000..f165c67 --- /dev/null +++ b/libcfs/include/libcfs/libcfs_time.h @@ -0,0 +1,144 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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_time.h + * + * Time functions. + * + */ + +#ifndef __LIBCFS_TIME_H__ +#define __LIBCFS_TIME_H__ +/* + * generic time manipulation functions. + */ + +static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d) +{ + return t + d; +} + +static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2) +{ + return t1 - t2; +} + +static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2) +{ + return time_before(t1, t2); +} + +static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2) +{ + return time_before_eq(t1, t2); +} + +static inline int cfs_time_after(cfs_time_t t1, cfs_time_t t2) +{ + return cfs_time_before(t2, t1); +} + +static inline int cfs_time_aftereq(cfs_time_t t1, cfs_time_t t2) +{ + return cfs_time_beforeq(t2, t1); +} + + +static inline cfs_time_t cfs_time_shift(int seconds) +{ + return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds)); +} + +static inline long cfs_timeval_sub(struct timeval *large, struct timeval *small, + struct timeval *result) +{ + long r = (long) ( + (large->tv_sec - small->tv_sec) * ONE_MILLION + + (large->tv_usec - small->tv_usec)); + if (result != NULL) { + result->tv_usec = r % ONE_MILLION; + result->tv_sec = r / ONE_MILLION; + } + return r; +} + +static inline void cfs_slow_warning(cfs_time_t now, int seconds, char *msg) +{ + if (cfs_time_after(cfs_time_current(), + cfs_time_add(now, cfs_time_seconds(15)))) + CERROR("slow %s "CFS_TIME_T" sec\n", msg, + cfs_duration_sec(cfs_time_sub(cfs_time_current(),now))); +} + +#define CFS_RATELIMIT(seconds) \ +({ \ + /* \ + * XXX nikita: non-portable initializer \ + */ \ + static time_t __next_message = 0; \ + int result; \ + \ + if (cfs_time_after(cfs_time_current(), __next_message)) \ + result = 1; \ + else { \ + __next_message = cfs_time_shift(seconds); \ + result = 0; \ + } \ + result; \ +}) + +/* + * helper function similar to do_gettimeofday() of Linux kernel + */ +static inline void cfs_fs_timeval(struct timeval *tv) +{ + cfs_fs_time_t time; + + cfs_fs_time_current(&time); + cfs_fs_time_usec(&time, tv); +} + +/* + * return valid time-out based on user supplied one. Currently we only check + * that time-out is not shorted than allowed. + */ +static inline cfs_duration_t cfs_timeout_cap(cfs_duration_t timeout) +{ + if (timeout < CFS_TICK) + timeout = CFS_TICK; + return timeout; +} + +#endif diff --git a/libcfs/include/libcfs/types.h b/libcfs/include/libcfs/libcfsutil.h similarity index 70% rename from libcfs/include/libcfs/types.h rename to libcfs/include/libcfs/libcfsutil.h index 45018ee..5dad846 100644 --- a/libcfs/include/libcfs/types.h +++ b/libcfs/include/libcfs/libcfsutil.h @@ -32,22 +32,25 @@ /* * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. + * + * libcfs/include/libcfs/libcfsutil.h + * + * A library used for userspace utilities. + * */ -#ifndef _LIBCFS_TYPES_H -#define _LIBCFS_TYPES_H +#ifndef __LIBCFSUTIL_H__ +#define __LIBCFSUTIL_H__ -/* - * This file was inttroduced to resolve XT3 (Catamount) build issues. - * The orignal idea was to move here however at - * the time of this writing - * it's unclear what external dependencies are tied - * to that file (It's not just some source file #including it) - * there is some build/packaging infrastructure that includes it. - * Hopefully that will be resolved shortly, that file will - * be removed, its contents copied here and this comment can be deleted. - */ +#ifndef LUSTRE_UTILS +#define LUSTRE_UTILS 1 +#endif -#include +#include -#endif +#include +#include +#include + + +#endif /* __LIBCFSUTIL_H__ */ diff --git a/libcfs/include/libcfs/linux/kp30.h b/libcfs/include/libcfs/linux/kp30.h index b7c4715..2f9ef67 100644 --- a/libcfs/include/libcfs/linux/kp30.h +++ b/libcfs/include/libcfs/linux/kp30.h @@ -37,49 +37,45 @@ #ifndef __LIBCFS_LINUX_KP30_H__ #define __LIBCFS_LINUX_KP30_H__ -#ifndef __LIBCFS_KP30_H__ -#error Do not #include this file directly. #include instead -#endif -#ifdef __KERNEL__ #ifndef AUTOCONF_INCLUDED # include #endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# ifdef HAVE_MM_INLINE -# include -# endif -# if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -# include -# include -# endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_MM_INLINE +# include +#endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +# include +# include +#endif #include @@ -211,28 +207,6 @@ static inline void our_cond_resched(void) #define i_size_read(a) ((a)->i_size) #endif -#else /* !__KERNEL__ */ -# include -# include -#if defined(__CYGWIN__) -# include -#else -# include -#endif -# include -# include -# include -# include -# include /* for _IOWR */ -#ifndef _IOWR -#include "ioctl.h" -#endif - -# define CFS_MODULE_PARM(name, t, type, perm, desc) -#define PORTAL_SYMBOL_GET(x) inter_module_get(#x) -#define PORTAL_SYMBOL_PUT(x) inter_module_put(#x) - -#endif /* End of !__KERNEL__ */ /******************************************************************************/ /* Light-weight trace @@ -366,11 +340,7 @@ extern int lwt_snapshot (cycles_t *now, int *ncpu, int *total_size, /* this is a bit chunky */ -#if defined(__KERNEL__) - #define _LWORDSIZE BITS_PER_LONG -#else - #define _LWORDSIZE __WORDSIZE -#endif +#define _LWORDSIZE BITS_PER_LONG #if defined(HAVE_U64_LONG_LONG) # define LPU64 "%Lu" diff --git a/libcfs/include/libcfs/linux/libcfs.h b/libcfs/include/libcfs/linux/libcfs.h index ae960e8..44781cb 100644 --- a/libcfs/include/libcfs/linux/libcfs.h +++ b/libcfs/include/libcfs/linux/libcfs.h @@ -41,10 +41,12 @@ #error Do not #include this file directly. #include instead #endif +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + #ifdef HAVE_ASM_TYPES_H #include -#else -#include #endif #include @@ -54,91 +56,15 @@ #include #include #include +#include - -#ifdef __KERNEL__ -# include -# include -# include -#else -# include -# include -# define do_gettimeofday(tv) gettimeofday(tv, NULL); -typedef unsigned long long cycles_t; -#endif - -#ifndef __KERNEL__ -/* Userpace byte flipping */ -# include -# include -# define __swab16(x) bswap_16(x) -# define __swab32(x) bswap_32(x) -# define __swab64(x) bswap_64(x) -# define __swab16s(x) do {*(x) = bswap_16(*(x));} while (0) -# define __swab32s(x) do {*(x) = bswap_32(*(x));} while (0) -# define __swab64s(x) do {*(x) = bswap_64(*(x));} while (0) -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define le16_to_cpu(x) (x) -# define cpu_to_le16(x) (x) -# define le32_to_cpu(x) (x) -# define cpu_to_le32(x) (x) -# define le64_to_cpu(x) (x) -# define cpu_to_le64(x) (x) - -# define be16_to_cpu(x) bswap_16(x) -# define cpu_to_be16(x) bswap_16(x) -# define be32_to_cpu(x) bswap_32(x) -# define cpu_to_be32(x) bswap_32(x) -# define be64_to_cpu(x) bswap_64(x) -# define cpu_to_be64(x) bswap_64(x) - -# else -# if __BYTE_ORDER == __BIG_ENDIAN -# define le16_to_cpu(x) bswap_16(x) -# define cpu_to_le16(x) bswap_16(x) -# define le32_to_cpu(x) bswap_32(x) -# define cpu_to_le32(x) bswap_32(x) -# define le64_to_cpu(x) bswap_64(x) -# define cpu_to_le64(x) bswap_64(x) - -# define be16_to_cpu(x) (x) -# define cpu_to_be16(x) (x) -# define be32_to_cpu(x) (x) -# define cpu_to_be32(x) (x) -# define be64_to_cpu(x) (x) -# define cpu_to_be64(x) (x) - -# else -# error "Unknown byte order" -# endif /* __BIG_ENDIAN */ -# endif /* __LITTLE_ENDIAN */ -#endif /* ! __KERNEL__ */ - -struct ptldebug_header { - __u32 ph_len; - __u32 ph_flags; - __u32 ph_subsys; - __u32 ph_mask; - __u32 ph_cpu_id; - __u32 ph_sec; - __u64 ph_usec; - __u32 ph_stack; - __u32 ph_pid; - __u32 ph_extern_pid; - __u32 ph_line_num; -} __attribute__((packed)); - -#ifdef __KERNEL__ -# include /* THREAD_SIZE */ -#else -# ifndef THREAD_SIZE /* x86_64 has THREAD_SIZE in userspace */ -# define THREAD_SIZE 8192 -# endif -#endif +#include +#include +#include /* THREAD_SIZE */ #define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5) -#if defined(__KERNEL__) && !defined(__x86_64__) +#if !defined(__x86_64__) # ifdef __ia64__ # define CDEBUG_STACK() (THREAD_SIZE - \ ((unsigned long)__builtin_dwarf_cfa() & \ @@ -162,11 +88,10 @@ do { \ } \ } while (0) #define CHECK_STACK() __CHECK_STACK(__FILE__, __func__, __LINE__) -#else /* !__KERNEL__ */ -#define __CHECK_STACK(X, Y, Z) do { } while(0) +#else /* __x86_64__ */ #define CHECK_STACK() do { } while(0) #define CDEBUG_STACK() (0L) -#endif /* __KERNEL__ */ +#endif /* __x86_64__ */ /* initial pid */ #define LUSTRE_LNET_PID 12345 @@ -176,21 +101,16 @@ do { \ #define EXIT_NESTING do {;} while (0) #define __current_nesting_level() (0) -/* +/** * Platform specific declarations for cfs_curproc API (libcfs/curproc.h) * * Implementation is in linux-curproc.c */ #define CFS_CURPROC_COMM_MAX (sizeof ((struct task_struct *)0)->comm) -#if defined(__KERNEL__) #include typedef kernel_cap_t cfs_kernel_cap_t; -#else -typedef __u32 cfs_kernel_cap_t; -#endif -#if defined(__KERNEL__) /* * No stack-back-tracing in Linux for now. */ @@ -201,6 +121,4 @@ struct cfs_stack_trace { #define WITH_WATCHDOG #endif -#endif - #endif /* _LINUX_LIBCFS_H */ diff --git a/libcfs/include/libcfs/linux/linux-fs.h b/libcfs/include/libcfs/linux/linux-fs.h index b5201a2..1bccba0 100644 --- a/libcfs/include/libcfs/linux/linux-fs.h +++ b/libcfs/include/libcfs/linux/linux-fs.h @@ -45,26 +45,18 @@ #error Do not #include this file directly. #include instead #endif -#ifdef __KERNEL__ +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + #include #include #include -#else /* !__KERNEL__ */ -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* __KERNEL__ */ typedef struct file cfs_file_t; typedef struct dentry cfs_dentry_t; typedef struct dirent64 cfs_dirent_t; -#ifdef __KERNEL__ #define cfs_filp_size(f) (i_size_read((f)->f_dentry->d_inode)) #define cfs_filp_poff(f) (&(f)->f_pos) @@ -94,5 +86,3 @@ typedef struct file_lock cfs_flock_t; ssize_t cfs_user_write (cfs_file_t *filp, const char *buf, size_t count, loff_t *offset); #endif - -#endif diff --git a/libcfs/include/libcfs/linux/linux-lock.h b/libcfs/include/libcfs/linux/linux-lock.h index bd217ae..857a959 100644 --- a/libcfs/include/libcfs/linux/linux-lock.h +++ b/libcfs/include/libcfs/linux/linux-lock.h @@ -45,7 +45,10 @@ #error Do not #include this file directly. #include instead #endif -#ifdef __KERNEL__ +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + #include /* @@ -111,11 +114,4 @@ * - wait_for_completion(c) */ -/* __KERNEL__ */ -#else - -#include "../user-lock.h" - -/* __KERNEL__ */ -#endif #endif diff --git a/libcfs/include/libcfs/linux/linux-mem.h b/libcfs/include/libcfs/linux/linux-mem.h index eeb6d81..21a17d9 100644 --- a/libcfs/include/libcfs/linux/linux-mem.h +++ b/libcfs/include/libcfs/linux/linux-mem.h @@ -45,14 +45,17 @@ #error Do not #include this file directly. #include instead #endif -#ifdef __KERNEL__ -# include -# include -# include -# include -# ifdef HAVE_MM_INLINE -# include -# endif +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + +#include +#include +#include +#include +#ifdef HAVE_MM_INLINE +# include +#endif typedef struct page cfs_page_t; #define CFS_PAGE_SIZE PAGE_CACHE_SIZE @@ -133,13 +136,4 @@ extern void cfs_mem_cache_free ( cfs_mem_cache_t *, void *); #define CFS_MMSPACE_OPEN do { __oldfs = get_fs(); set_fs(get_ds());} while(0) #define CFS_MMSPACE_CLOSE set_fs(__oldfs) -#else /* !__KERNEL__ */ -#ifdef HAVE_ASM_PAGE_H -#include /* needed for PAGE_SIZE - rread */ -#endif - -#include -/* __KERNEL__ */ -#endif - #endif /* __LINUX_CFS_MEM_H__ */ diff --git a/libcfs/include/libcfs/linux/linux-prim.h b/libcfs/include/libcfs/linux/linux-prim.h index ea3097a..2ff5a97 100644 --- a/libcfs/include/libcfs/linux/linux-prim.h +++ b/libcfs/include/libcfs/linux/linux-prim.h @@ -45,7 +45,10 @@ #error Do not #include this file directly. #include instead #endif -#ifdef __KERNEL__ +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + #ifndef AUTOCONF_INCLUDED #include #endif @@ -118,27 +121,12 @@ typedef struct proc_dir_entry cfs_proc_dir_entry_t; */ #define CFS_TASK_INTERRUPTIBLE TASK_INTERRUPTIBLE #define CFS_TASK_UNINT TASK_UNINTERRUPTIBLE +#define CFS_TASK_RUNNING TASK_RUNNING typedef wait_queue_t cfs_waitlink_t; typedef wait_queue_head_t cfs_waitq_t; - typedef long cfs_task_state_t; -#define cfs_waitq_init(w) init_waitqueue_head(w) -#define cfs_waitlink_init(l) init_waitqueue_entry(l, current) -#define cfs_waitq_add(w, l) add_wait_queue(w, l) -#define cfs_waitq_add_exclusive(w, l) add_wait_queue_exclusive(w, l) -#define cfs_waitq_forward(l, w) do {} while(0) -#define cfs_waitq_del(w, l) remove_wait_queue(w, l) -#define cfs_waitq_active(w) waitqueue_active(w) -#define cfs_waitq_signal(w) wake_up(w) -#define cfs_waitq_signal_nr(w,n) wake_up_nr(w, n) -#define cfs_waitq_broadcast(w) wake_up_all(w) -#define cfs_waitq_wait(l, s) schedule() -#define cfs_waitq_timedwait(l, s, t) schedule_timeout(t) -#define cfs_schedule_timeout(s, t) schedule_timeout(t) -#define cfs_schedule() schedule() - /* Kernel thread */ typedef int (*cfs_thread_t)(void *); @@ -185,50 +173,8 @@ typedef sigset_t cfs_sigset_t; * Timer */ typedef struct timer_list cfs_timer_t; -typedef void (*timer_func_t)(unsigned long); - -#define cfs_init_timer(t) init_timer(t) - -static inline void cfs_timer_init(cfs_timer_t *t, void (*func)(unsigned long), void *arg) -{ - init_timer(t); - t->function = (timer_func_t)func; - t->data = (unsigned long)arg; -} - -static inline void cfs_timer_done(cfs_timer_t *t) -{ - return; -} - -static inline void cfs_timer_arm(cfs_timer_t *t, cfs_time_t deadline) -{ - mod_timer(t, deadline); -} - -static inline void cfs_timer_disarm(cfs_timer_t *t) -{ - del_timer(t); -} - -static inline int cfs_timer_is_armed(cfs_timer_t *t) -{ - return timer_pending(t); -} - -static inline cfs_time_t cfs_timer_deadline(cfs_timer_t *t) -{ - return t->expires; -} -/* deschedule for a bit... */ -static inline void cfs_pause(cfs_duration_t ticks) -{ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(ticks); -} - #ifndef wait_event_timeout /* Only for RHEL3 2.4.21 kernel */ #define __wait_event_timeout(wq, condition, timeout, ret) \ do { \ @@ -317,11 +263,4 @@ do { \ #define cfs_waitq_wait_event_interruptible_timeout wait_event_interruptible_timeout #endif -#else /* !__KERNEL__ */ - -typedef struct proc_dir_entry cfs_proc_dir_entry_t; -#include "../user-prim.h" - -#endif /* __KERNEL__ */ - #endif diff --git a/libcfs/include/libcfs/linux/linux-tcpip.h b/libcfs/include/libcfs/linux/linux-tcpip.h index ef36a45..45a5563 100644 --- a/libcfs/include/libcfs/linux/linux-tcpip.h +++ b/libcfs/include/libcfs/linux/linux-tcpip.h @@ -45,7 +45,10 @@ #error Do not #include this file directly. #include instead #endif -#ifdef __KERNEL__ +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + #include typedef struct socket cfs_socket_t; @@ -73,10 +76,4 @@ typedef struct socket cfs_socket_t; #define SOCK_ERROR(so) ((so)->sk->sk_err) #define SOCK_TEST_NOSPACE(so) test_bit(SOCK_NOSPACE, &(so)->flags) -#else /* !__KERNEL__ */ - -#include "../user-tcpip.h" - -#endif /* __KERNEL__ */ - #endif diff --git a/libcfs/include/libcfs/linux/linux-time.h b/libcfs/include/libcfs/linux/linux-time.h index f23e45a..c497aa5 100644 --- a/libcfs/include/libcfs/linux/linux-time.h +++ b/libcfs/include/libcfs/linux/linux-time.h @@ -47,6 +47,10 @@ #error Do not #include this file directly. #include instead #endif +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + /* Portable time API */ /* @@ -89,7 +93,10 @@ #define ONE_BILLION ((u_int64_t)1000000000) #define ONE_MILLION 1000000 -#ifdef __KERNEL__ +#ifndef __KERNEL__ +#error This include is only for kernel use. +#endif + #ifndef AUTOCONF_INCLUDED #include #endif @@ -182,26 +189,6 @@ static inline time_t cfs_time_current_sec(void) return CURRENT_SECONDS; } -static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d) -{ - return t + d; -} - -static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2) -{ - return t1 - t2; -} - -static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2) -{ - return time_before(t1, t2); -} - -static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2) -{ - return time_before_eq(t1, t2); -} - static inline void cfs_fs_time_current(cfs_fs_time_t *t) { *t = CURRENT_KERN_TIME; @@ -319,20 +306,7 @@ static inline int cfs_time_beforeq_64(__u64 t1, __u64 t2) #define CFS_TIME_T "%lu" #define CFS_DURATION_T "%ld" -#else /* !__KERNEL__ */ - -/* - * Liblustre. time(2) based implementation. - */ - -#define CFS_TIME_T "%lu" - -#include - -#endif /* __KERNEL__ */ - -/* __LIBCFS_LINUX_LINUX_TIME_H__ */ -#endif +#endif /* __LIBCFS_LINUX_LINUX_TIME_H__ */ /* * Local variables: * c-indentation-style: "K&R" diff --git a/libcfs/include/libcfs/posix/.cvsignore b/libcfs/include/libcfs/posix/.cvsignore new file mode 100644 index 0000000..3dda729 --- /dev/null +++ b/libcfs/include/libcfs/posix/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/libcfs/include/libcfs/posix/Makefile.am b/libcfs/include/libcfs/posix/Makefile.am new file mode 100644 index 0000000..feba1d5 --- /dev/null +++ b/libcfs/include/libcfs/posix/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST := libcfs.h posix-wordsize.h posix-types.h diff --git a/libcfs/include/libcfs/posix/libcfs.h b/libcfs/include/libcfs/posix/libcfs.h new file mode 100644 index 0000000..e74e717 --- /dev/null +++ b/libcfs/include/libcfs/posix/libcfs.h @@ -0,0 +1,245 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/posix/libcfs.h + * + * Defines for posix userspace. + * + * Author: Robert Read + */ + +#ifndef __LIBCFS_POSIX_LIBCFS_H__ +#define __LIBCFS_POSIX_LIBCFS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LIBPTHREAD +#include +#endif + +#if defined(HAVE_SYS_TYPES_H) +#include +#endif + +#ifdef HAVE_SYS_USER_H +# include +#endif + +#ifdef HAVE_SYS_VFS_H +# include +#endif + +#ifdef HAVE_STDINT_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +# define do_gettimeofday(tv) gettimeofday(tv, NULL); +typedef unsigned long long cycles_t; + +#define IS_ERR(a) ((unsigned long)(a) > (unsigned long)-1000L) +#define PTR_ERR(a) ((long)(a)) +#define ERR_PTR(a) ((void*)((long)(a))) + +/* this goes in posix-fs.h */ +#include + +#ifdef __linux__ +#include +#endif + +typedef struct file cfs_file_t; +typedef struct dentry cfs_dentry_t; +#ifdef __linux__ +typedef struct dirent64 cfs_dirent_t; +#endif + +#ifdef __linux__ +/* Userpace byte flipping */ +# include +# include +# define __swab16(x) bswap_16(x) +# define __swab32(x) bswap_32(x) +# define __swab64(x) bswap_64(x) +# define __swab16s(x) do {*(x) = bswap_16(*(x));} while (0) +# define __swab32s(x) do {*(x) = bswap_32(*(x));} while (0) +# define __swab64s(x) do {*(x) = bswap_64(*(x));} while (0) +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define le16_to_cpu(x) (x) +# define cpu_to_le16(x) (x) +# define le32_to_cpu(x) (x) +# define cpu_to_le32(x) (x) +# define le64_to_cpu(x) (x) +# define cpu_to_le64(x) (x) + +# define be16_to_cpu(x) bswap_16(x) +# define cpu_to_be16(x) bswap_16(x) +# define be32_to_cpu(x) bswap_32(x) +# define cpu_to_be32(x) bswap_32(x) +# define be64_to_cpu(x) bswap_64(x) +# define cpu_to_be64(x) bswap_64(x) +# else +# if __BYTE_ORDER == __BIG_ENDIAN +# define le16_to_cpu(x) bswap_16(x) +# define cpu_to_le16(x) bswap_16(x) +# define le32_to_cpu(x) bswap_32(x) +# define cpu_to_le32(x) bswap_32(x) +# define le64_to_cpu(x) bswap_64(x) +# define cpu_to_le64(x) bswap_64(x) + +# define be16_to_cpu(x) (x) +# define cpu_to_be16(x) (x) +# define be32_to_cpu(x) (x) +# define cpu_to_be32(x) (x) +# define be64_to_cpu(x) (x) +# define cpu_to_be64(x) (x) + +# else +# error "Unknown byte order" +# endif /* __BIG_ENDIAN */ +# endif /* __LITTLE_ENDIAN */ +#elif __APPLE__ +#define __cpu_to_le64(x) OSSwapHostToLittleInt64(x) +#define __cpu_to_le32(x) OSSwapHostToLittleInt32(x) +#define __cpu_to_le16(x) OSSwapHostToLittleInt16(x) + +#define __le16_to_cpu(x) OSSwapLittleToHostInt16(x) +#define __le32_to_cpu(x) OSSwapLittleToHostInt32(x) +#define __le64_to_cpu(x) OSSwapLittleToHostInt64(x) + +#define cpu_to_le64(x) __cpu_to_le64(x) +#define cpu_to_le32(x) __cpu_to_le32(x) +#define cpu_to_le16(x) __cpu_to_le16(x) + +#define le64_to_cpu(x) __le64_to_cpu(x) +#define le32_to_cpu(x) __le32_to_cpu(x) +#define le16_to_cpu(x) __le16_to_cpu(x) + +#define __swab16(x) OSSwapInt16(x) +#define __swab32(x) OSSwapInt32(x) +#define __swab64(x) OSSwapInt64(x) +#define __swab16s(x) do { *(x) = __swab16(*(x)); } while (0) +#define __swab32s(x) do { *(x) = __swab32(*(x)); } while (0) +#define __swab64s(x) do { *(x) = __swab64(*(x)); } while (0) +#endif + + +# ifndef THREAD_SIZE /* x86_64 linux has THREAD_SIZE in userspace */ +# define THREAD_SIZE 8192 +# endif + +#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5) + +#define CHECK_STACK() do { } while(0) +#define CDEBUG_STACK() (0L) + +/* initial pid */ +#define LUSTRE_LNET_PID 12345 + +#define ENTRY_NESTING_SUPPORT (1) +#define ENTRY_NESTING do {;} while (0) +#define EXIT_NESTING do {;} while (0) +#define __current_nesting_level() (0) + +/** + * Platform specific declarations for cfs_curproc API (libcfs/curproc.h) + * + * Implementation is in linux-curproc.c + */ +#define CFS_CURPROC_COMM_MAX (sizeof ((struct task_struct *)0)->comm) + +typedef __u32 cfs_kernel_cap_t; + +/** + * Module support (probably shouldn't be used in generic code?) + */ +struct module { + int count; +}; + +static inline void MODULE_AUTHOR(char *name) +{ + printf("%s\n", name); +} +#define MODULE_DESCRIPTION(name) MODULE_AUTHOR(name) +#define MODULE_LICENSE(name) MODULE_AUTHOR(name) + +#define THIS_MODULE NULL +#define __init +#define __exit + +static inline int request_module(char *name) +{ + return (-EINVAL); +} + +static inline void __module_get(struct module *module) +{ +} + +static inline int try_module_get(struct module *module) +{ + return 1; +} + +static inline void module_put(struct module *module) +{ +} + + +#endif diff --git a/libcfs/include/libcfs/posix/posix-types.h b/libcfs/include/libcfs/posix/posix-types.h new file mode 100644 index 0000000..1e27d23 --- /dev/null +++ b/libcfs/include/libcfs/posix/posix-types.h @@ -0,0 +1,64 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/posix/posix-types.h + * + * Define the linux types we use for posix userspace. + * + * Author: Robert Read + */ +#ifndef _LUSTRE_POSIX_TYPES_H +#define _LUSTRE_POSIX_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long long __s64; +typedef unsigned long long __u64; + +#endif diff --git a/libcfs/include/libcfs/posix/posix-wordsize.h b/libcfs/include/libcfs/posix/posix-wordsize.h new file mode 100644 index 0000000..408daa0 --- /dev/null +++ b/libcfs/include/libcfs/posix/posix-wordsize.h @@ -0,0 +1,149 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/posix/posix-wordsize.h + * + * Wordsize related defines for posix userspace. + * + * Author: Robert Read + */ + +#ifndef __LIBCFS_LINUX_KP30_H__ +#define __LIBCFS_LINUX_KP30_H__ + + + +#if defined(__CYGWIN__) +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifndef _IOWR +# include "ioctl.h" +#endif + +# define CFS_MODULE_PARM(name, t, type, perm, desc) +#define PORTAL_SYMBOL_GET(x) inter_module_get(#x) +#define PORTAL_SYMBOL_PUT(x) inter_module_put(#x) + + +#ifdef __CYGWIN__ +# ifndef BITS_PER_LONG +# if (~0UL) == 0xffffffffUL +# define BITS_PER_LONG 32 +# else +# define BITS_PER_LONG 64 +# endif +# endif +#else +# define BITS_PER_LONG __WORDSIZE +#endif + + +/******************************************************************************/ +/* Light-weight trace + * Support for temporary event tracing with minimal Heisenberg effect. */ +#define LWT_SUPPORT 0 + +#define LWT_MEMORY (16<<20) + +typedef struct { + long long lwte_when; + char *lwte_where; + void *lwte_task; + long lwte_p1; + long lwte_p2; + long lwte_p3; + long lwte_p4; +# if BITS_PER_LONG > 32 + long lwte_pad; +# endif +} lwt_event_t; + +#if LWT_SUPPORT +#define LWT_EVENT(p1,p2,p3,p4) /* no userland implementation yet */ +#endif /* LWT_SUPPORT */ + +/* ------------------------------------------------------------------ */ + +#define IOCTL_LIBCFS_TYPE long + + +#if BITS_PER_LONG > 32 +# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a) +#else +# define LI_POISON ((int)0x5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a) +#endif + +#if defined(HAVE_U64_LONG_LONG) +/* x86_64 defines __u64 as "long" in userspace, but "long long" in the kernel */ +# define LPU64 "%Lu" +# define LPD64 "%Ld" +# define LPX64 "%#Lx" +# define LPF64 "L" +#elif (BITS_PER_LONG == 32) +# define LPU64 "%Lu" +# define LPD64 "%Ld" +# define LPX64 "%#Lx" +# define LPF64 "L" +#elif (BITS_PER_LONG == 64) +# define LPU64 "%lu" +# define LPD64 "%ld" +# define LPX64 "%#lx" +# define LPF64 "l" +#endif + +#ifdef HAVE_SIZE_T_LONG +# define LPSZ "%lu" +#else +# define LPSZ "%u" +#endif + +#ifdef HAVE_SSIZE_T_LONG +# define LPSSZ "%ld" +#else +# define LPSSZ "%d" +#endif + +#ifndef LPU64 +# error "No word size defined" +#endif + +#endif diff --git a/libcfs/include/libcfs/user-lock.h b/libcfs/include/libcfs/user-lock.h index 4759e82..16409d0 100644 --- a/libcfs/include/libcfs/user-lock.h +++ b/libcfs/include/libcfs/user-lock.h @@ -56,10 +56,13 @@ */ #ifndef __KERNEL__ -#include -#include -#if 0 +/* + * The userspace implementations of linux/spinlock.h vary; we just + * include our own for all of them + */ +#define __LINUX_SPINLOCK_H + /* * Optional debugging (magic stamping and checking ownership) can be added. */ @@ -83,6 +86,7 @@ typedef struct spin_lock spinlock_t; #define SPIN_LOCK_UNLOCKED (spinlock_t) { } #define LASSERT_SPIN_LOCKED(lock) do {} while(0) +#define LASSERT_SEM_LOCKED(sem) do {} while(0) void spin_lock_init(spinlock_t *lock); void spin_lock(spinlock_t *lock); @@ -91,8 +95,8 @@ int spin_trylock(spinlock_t *lock); void spin_lock_bh_init(spinlock_t *lock); void spin_lock_bh(spinlock_t *lock); void spin_unlock_bh(spinlock_t *lock); -static inline int spin_is_locked(spinlock_t *l) {return 1;} +static inline int spin_is_locked(spinlock_t *l) {return 1;} static inline void spin_lock_irqsave(spinlock_t *l, unsigned long f){} static inline void spin_unlock_irqrestore(spinlock_t *l, unsigned long f){} @@ -119,11 +123,17 @@ void __up(struct semaphore *s); * - mutex_up(x) * - mutex_down(x) */ -#define mutex_up(s) __up(s) -#define mutex_down(s) __down(s) +#define DECLARE_MUTEX(name) \ + struct semaphore name = { 1 } + +#define mutex_up(s) __up(s) +#define up(s) mutex_up(s) +#define mutex_down(s) __down(s) +#define down(s) mutex_down(s) -#define init_mutex(x) sema_init(x, 1) -#define init_mutex_locked(x) sema_init(x, 0) +#define init_MUTEX(x) sema_init(x, 1) +#define init_MUTEX_LOCKED(x) sema_init(x, 0) +#define init_mutex(s) init_MUTEX(s) /* * Completion: @@ -132,13 +142,23 @@ void __up(struct semaphore *s); * - complete(c) * - wait_for_completion(c) */ -#if 0 -struct completion {}; +struct completion { + unsigned int done; + cfs_waitq_t wait; +}; void init_completion(struct completion *c); void complete(struct completion *c); void wait_for_completion(struct completion *c); -#endif + +#define COMPLETION_INITIALIZER(work) \ + { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } + +#define DECLARE_COMPLETION(work) \ + struct completion work = COMPLETION_INITIALIZER(work) + +#define INIT_COMPLETION(x) ((x).done = 0) + /* * rw_semaphore: @@ -149,7 +169,9 @@ void wait_for_completion(struct completion *c); * - down_write(x) * - up_write(x) */ -struct rw_semaphore {}; +struct rw_semaphore { + int foo; +}; void init_rwsem(struct rw_semaphore *s); void down_read(struct rw_semaphore *s); @@ -171,13 +193,14 @@ void up_write(struct rw_semaphore *s); * - write_unlock(x) */ typedef struct rw_semaphore rwlock_t; +#define RW_LOCK_UNLOCKED (rwlock_t) { } -#define rwlock_init(pl) init_rwsem(pl) +#define rwlock_init(pl) init_rwsem(pl) -#define read_lock(l) down_read(l) -#define read_unlock(l) up_read(l) -#define write_lock(l) down_write(l) -#define write_unlock(l) up_write(l) +#define read_lock(l) down_read(l) +#define read_unlock(l) up_read(l) +#define write_lock(l) down_write(l) +#define write_unlock(l) up_write(l) static inline void write_lock_irqsave(rwlock_t *l, unsigned long f) { write_lock(l); } @@ -196,17 +219,20 @@ read_unlock_irqrestore(rwlock_t *l, unsigned long f) { read_unlock(l); } typedef struct { volatile int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } + #define atomic_read(a) ((a)->counter) #define atomic_set(a,b) do {(a)->counter = b; } while (0) #define atomic_dec_and_test(a) ((--((a)->counter)) == 0) +#define atomic_dec_and_lock(a,b) ((--((a)->counter)) == 0) #define atomic_inc(a) (((a)->counter)++) #define atomic_dec(a) do { (a)->counter--; } while (0) #define atomic_add(b,a) do {(a)->counter += b;} while (0) -#define atomic_add_return(n,a) ((a)->counter = n) +#define atomic_add_return(n,a) ((a)->counter += n) #define atomic_inc_return(a) atomic_add_return(1,a) #define atomic_sub(b,a) do {(a)->counter -= b;} while (0) +#define atomic_sub_return(n,a) ((a)->counter -= n) +#define atomic_dec_return(a) atomic_sub_return(1,a) -#endif #ifdef HAVE_LIBPTHREAD #include diff --git a/libcfs/include/libcfs/user-mem.h b/libcfs/include/libcfs/user-mem.h new file mode 100644 index 0000000..3b0a606 --- /dev/null +++ b/libcfs/include/libcfs/user-mem.h @@ -0,0 +1,105 @@ +#ifndef __LIBCFS_USER_MEM_H__ +#define __LIBCFS_USER_MEM_H__ + +#ifndef __LIBCFS_LIBCFS_H__ +#error Do not #include this file directly. #include instead +#endif + +#ifdef __KERNEL__ +#error "This is only for user space." +#endif + + +/* XXX + * for this moment, liblusre will not rely OST for non-page-aligned write + */ +#define LIBLUSTRE_HANDLE_UNALIGNED_PAGE + +typedef struct page { + void *addr; + unsigned long index; + struct list_head list; + unsigned long private; + + /* internally used by liblustre file i/o */ + int _offset; + int _count; +#ifdef LIBLUSTRE_HANDLE_UNALIGNED_PAGE + int _managed; +#endif + struct list_head _node; +} cfs_page_t; + + +/* 4K */ +#define CFS_PAGE_SHIFT 12 +#define CFS_PAGE_SIZE (1UL << CFS_PAGE_SHIFT) +#define CFS_PAGE_MASK (~((__u64)CFS_PAGE_SIZE-1)) + +cfs_page_t *cfs_alloc_pages(int mask, unsigned long order); +void cfs_free_pages(cfs_page_t *pg, int what); +cfs_page_t *cfs_alloc_page(unsigned int flags); +void cfs_free_page(cfs_page_t *pg); +void *cfs_page_address(cfs_page_t *pg); +void *cfs_kmap(cfs_page_t *pg); +void cfs_kunmap(cfs_page_t *pg); + +#define __cfs_free_pages(pg, what) cfs_free_pages((pg), (what)) + +#define cfs_get_page(p) __I_should_not_be_called__(at_all) +#define cfs_page_count(p) __I_should_not_be_called__(at_all) +#define cfs_page_index(p) ((p)->index) + +/* + * Memory allocator + * Inline function, so utils can use them without linking of libcfs + */ +#define __ALLOC_ZERO (1 << 2) +static inline void *cfs_alloc(size_t nr_bytes, u_int32_t flags) +{ + void *result; + + result = malloc(nr_bytes); + if (result != NULL && (flags & __ALLOC_ZERO)) + memset(result, 0, nr_bytes); + return result; +} + +#define cfs_free(addr) free(addr) +#define cfs_alloc_large(nr_bytes) cfs_alloc(nr_bytes, 0) +#define cfs_free_large(addr) cfs_free(addr) + +#define CFS_ALLOC_ATOMIC_TRY (0) +/* + * SLAB allocator + */ +typedef struct { + int size; +} cfs_mem_cache_t; + +#define SLAB_HWCACHE_ALIGN 0 +#define SLAB_KERNEL 0 +#define SLAB_NOFS 0 + +cfs_mem_cache_t * +cfs_mem_cache_create(const char *, size_t, size_t, unsigned long); +int cfs_mem_cache_destroy(cfs_mem_cache_t *c); +void *cfs_mem_cache_alloc(cfs_mem_cache_t *c, int gfp); +void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr); + +/* + * Copy to/from user + */ +static inline int copy_from_user(void *a,void *b, int c) +{ + memcpy(a,b,c); + return 0; +} + +static inline int copy_to_user(void *a,void *b, int c) +{ + memcpy(a,b,c); + return 0; +} + +#endif diff --git a/libcfs/include/libcfs/user-prim.h b/libcfs/include/libcfs/user-prim.h index be03a9f..9ec6ff8 100644 --- a/libcfs/include/libcfs/user-prim.h +++ b/libcfs/include/libcfs/user-prim.h @@ -53,23 +53,23 @@ #ifndef __KERNEL__ -#include -#include -#include -#include -#include -#include -#include -#include -#include +typedef struct proc_dir_entry cfs_proc_dir_entry_t; -#ifdef HAVE_LIBPTHREAD -#include +/* + * Just present a single processor until will add thread support. + */ +#ifndef smp_processor_id +#define smp_processor_id() 0 +#endif +#ifndef num_online_cpus +#define num_online_cpus() 1 +#endif +#ifndef num_possible_cpus +#define num_possible_cpus() 1 #endif - /* - * Wait Queue. No-op implementation. + * Wait Queue. */ typedef struct cfs_waitlink { @@ -81,114 +81,22 @@ typedef struct cfs_waitq { struct list_head sleepers; } cfs_waitq_t; -void cfs_waitq_init(struct cfs_waitq *waitq); -void cfs_waitlink_init(struct cfs_waitlink *link); -void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link); -void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, - struct cfs_waitlink *link); -void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq); -void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link); -int cfs_waitq_active(struct cfs_waitq *waitq); -void cfs_waitq_signal(struct cfs_waitq *waitq); -void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr); -void cfs_waitq_broadcast(struct cfs_waitq *waitq); -void cfs_waitq_wait(struct cfs_waitlink *link, int state); -int64_t cfs_waitq_timedwait(struct cfs_waitlink *link, int state, int64_t timeout); -#define cfs_schedule_timeout(s, t) \ - do { \ - cfs_waitlink_t l; \ - cfs_waitq_timedwait(&l, s, t); \ - } while (0) - -#define CFS_TASK_INTERRUPTIBLE (0) -#define CFS_TASK_UNINT (0) - -/* 2.4 defines */ - -/* XXX - * for this moment, liblusre will not rely OST for non-page-aligned write - */ -#define LIBLUSTRE_HANDLE_UNALIGNED_PAGE - -struct page { - void *addr; - unsigned long index; - struct list_head list; - unsigned long private; - - /* internally used by liblustre file i/o */ - int _offset; - int _count; -#ifdef LIBLUSTRE_HANDLE_UNALIGNED_PAGE - int _managed; -#endif - struct list_head _node; -}; - -typedef struct page cfs_page_t; - -#ifndef PAGE_SIZE - -/* 4K */ -#define CFS_PAGE_SHIFT 12 -#define CFS_PAGE_SIZE (1UL << CFS_PAGE_SHIFT) -#define CFS_PAGE_MASK (~((__u64)CFS_PAGE_SIZE-1)) - -#else - -#define CFS_PAGE_SIZE PAGE_SIZE -#define CFS_PAGE_SHIFT PAGE_SHIFT -#define CFS_PAGE_MASK (~((__u64)CFS_PAGE_SIZE-1)) - -#endif - -cfs_page_t *cfs_alloc_page(unsigned int flags); -void cfs_free_page(cfs_page_t *pg); -void *cfs_page_address(cfs_page_t *pg); -void *cfs_kmap(cfs_page_t *pg); -void cfs_kunmap(cfs_page_t *pg); - -#define cfs_get_page(p) __I_should_not_be_called__(at_all) -#define cfs_page_count(p) __I_should_not_be_called__(at_all) -#define cfs_page_index(p) ((p)->index) +/* XXX: need to replace wake_up with cfs_waitq_signal() */ +#define wake_up(q) cfs_waitq_signal(q) /* - * Memory allocator - * Inline function, so utils can use them without linking of libcfs + * Task states */ -#define __ALLOC_ZERO (1 << 2) -static inline void *cfs_alloc(size_t nr_bytes, u_int32_t flags) -{ - void *result; +typedef long cfs_task_state_t; - result = malloc(nr_bytes); - if (result != NULL && (flags & __ALLOC_ZERO)) - memset(result, 0, nr_bytes); - return result; -} +#define CFS_TASK_INTERRUPTIBLE (0) +#define CFS_TASK_UNINT (1) +#define CFS_TASK_RUNNING (2) -#define cfs_free(addr) free(addr) -#define cfs_alloc_large(nr_bytes) cfs_alloc(nr_bytes, 0) -#define cfs_free_large(addr) cfs_free(addr) -#define CFS_ALLOC_ATOMIC_TRY (0) -/* - * SLAB allocator +/* + * Lproc */ -typedef struct { - int size; -} cfs_mem_cache_t; - -#define SLAB_HWCACHE_ALIGN 0 -#define SLAB_KERNEL 0 -#define SLAB_NOFS 0 - -cfs_mem_cache_t * -cfs_mem_cache_create(const char *, size_t, size_t, unsigned long); -int cfs_mem_cache_destroy(cfs_mem_cache_t *c); -void *cfs_mem_cache_alloc(cfs_mem_cache_t *c, int gfp); -void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr); - typedef int (cfs_read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -213,67 +121,9 @@ typedef struct { long expires; } cfs_timer_t; -#define cfs_init_timer(t) do {} while(0) -#define cfs_jiffies \ -({ \ - unsigned long _ret = 0; \ - struct timeval tv; \ - if (gettimeofday(&tv, NULL) == 0) \ - _ret = tv.tv_sec; \ - _ret; \ -}) - -static inline int cfs_timer_init(cfs_timer_t *l, void (* func)(unsigned long), void *arg) -{ - CFS_INIT_LIST_HEAD(&l->tl_list); - l->function = func; - l->data = (unsigned long)arg; - return 0; -} - -static inline int cfs_timer_is_armed(cfs_timer_t *l) -{ - if (cfs_time_before(cfs_jiffies, l->expires)) - return 1; - else - return 0; -} - -static inline void cfs_timer_arm(cfs_timer_t *l, int thetime) -{ - l->expires = thetime; -} - -static inline void cfs_timer_disarm(cfs_timer_t *l) -{ -} - -static inline long cfs_timer_deadline(cfs_timer_t *l) -{ - return l->expires; -} - -#if 0 -#define cfs_init_timer(t) do {} while(0) -void cfs_timer_init(struct cfs_timer *t, void (*func)(unsigned long), void *arg); -void cfs_timer_done(struct cfs_timer *t); -void cfs_timer_arm(struct cfs_timer *t, cfs_time_t deadline); -void cfs_timer_disarm(struct cfs_timer *t); -int cfs_timer_is_armed(struct cfs_timer *t); - -cfs_time_t cfs_timer_deadline(struct cfs_timer *t); -#endif #define in_interrupt() (0) -static inline void cfs_pause(cfs_duration_t d) -{ - struct timespec s; - - cfs_duration_nsec(d, &s); - nanosleep(&s, NULL); -} - typedef void cfs_psdev_t; static inline int cfs_psdev_register(cfs_psdev_t *foo) diff --git a/libcfs/include/libcfs/user-time.h b/libcfs/include/libcfs/user-time.h index f253325..5cbaecb 100644 --- a/libcfs/include/libcfs/user-time.h +++ b/libcfs/include/libcfs/user-time.h @@ -95,14 +95,16 @@ * Liblustre. time(2) based implementation. */ -#include -#include -#include - typedef time_t cfs_fs_time_t; typedef time_t cfs_time_t; typedef long cfs_duration_t; +/* looks like linux */ +#define time_after(a, b) ((long)(b) - (long)(a) < 0) +#define time_before(a, b) time_after(b,a) +#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) +#define time_before_eq(a,b) time_after_eq(b,a) + static inline cfs_time_t cfs_time_current(void) { return time(NULL); @@ -118,16 +120,6 @@ static inline time_t cfs_time_current_sec(void) return cfs_time_seconds(cfs_time_current()); } -static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2) -{ - return t1 < t2; -} - -static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2) -{ - return t1 <= t2; -} - static inline cfs_duration_t cfs_duration_build(int64_t nano) { return (cfs_duration_t) (nano / ONE_BILLION); @@ -184,24 +176,15 @@ static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2) #define CFS_TICK (1) -static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d) -{ - return t + d; -} - -static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2) -{ - return t1 - t2; -} - #define cfs_time_current_64 cfs_time_current #define cfs_time_add_64 cfs_time_add #define cfs_time_shift_64 cfs_time_shift #define cfs_time_before_64 cfs_time_before #define cfs_time_beforeq_64 cfs_time_beforeq +/* XXX needs to move to arch specific header or configured */ #ifndef CFS_TIME_T -#define CFS_TIME_T "%u" +#define CFS_TIME_T "%lu" #endif #define CFS_DURATION_T "%ld" diff --git a/libcfs/include/libcfs/util/.cvsignore b/libcfs/include/libcfs/util/.cvsignore new file mode 100644 index 0000000..3dda729 --- /dev/null +++ b/libcfs/include/libcfs/util/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/libcfs/include/libcfs/util/Makefile.am b/libcfs/include/libcfs/util/Makefile.am new file mode 100644 index 0000000..6d68892 --- /dev/null +++ b/libcfs/include/libcfs/util/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST := parser.h platform.h libcfsutil_ioctl.h diff --git a/libcfs/include/libcfs/util/libcfsutil_ioctl.h b/libcfs/include/libcfs/util/libcfsutil_ioctl.h new file mode 100644 index 0000000..d153963 --- /dev/null +++ b/libcfs/include/libcfs/util/libcfsutil_ioctl.h @@ -0,0 +1,54 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/util/libcfsutil_ioctl.h + * + * Utility functions for calling ioctls. + * + */ + +/* FIXME - rename these to libcfs_ */ + +int libcfs_ioctl_pack(struct libcfs_ioctl_data *data, char **pbuf, int max); +typedef int (ioc_handler_t)(int dev_id, unsigned int opc, void *buf); +void set_ioc_handler(ioc_handler_t *handler); +int register_ioc_dev(int dev_id, const char * dev_name, int major, int minor); +void unregister_ioc_dev(int dev_id); +int set_ioctl_dump(char * file); +int l_ioctl(int dev_id, unsigned int opc, void *buf); +int parse_dump(char * dump_file, ioc_handler_t ioc_func); +int jt_ioc_dump(int argc, char **argv); +extern char *dump_filename; +int dump(int dev_id, unsigned int opc, void *buf); diff --git a/libcfs/include/libcfs/util/parser.h b/libcfs/include/libcfs/util/parser.h new file mode 100644 index 0000000..725e763 --- /dev/null +++ b/libcfs/include/libcfs/util/parser.h @@ -0,0 +1,115 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/util/parser.h + * + * A command line parser. + * + */ + +#ifndef _PARSER_H_ +#define _PARSER_H_ + +#define HISTORY 100 /* Don't let history grow unbounded */ +#define MAXARGS 512 + +#define CMD_COMPLETE 0 +#define CMD_INCOMPLETE 1 +#define CMD_NONE 2 +#define CMD_AMBIG 3 +#define CMD_HELP 4 + +typedef struct parser_cmd { + char *pc_name; + int (* pc_func)(int, char **); + struct parser_cmd * pc_sub_cmd; + char *pc_help; +} command_t; + +typedef struct argcmd { + char *ac_name; + int (*ac_func)(int, char **); + char *ac_help; +} argcmd_t; + +typedef struct network { + char *type; + char *server; + int port; +} network_t; + +int Parser_quit(int argc, char **argv); +void Parser_init(char *, command_t *); /* Set prompt and load command list */ +int Parser_commands(void); /* Start the command parser */ +void Parser_qhelp(int, char **); /* Quick help routine */ +int Parser_help(int, char **); /* Detailed help routine */ +void Parser_ignore_errors(int ignore); /* Set the ignore errors flag */ +void Parser_printhelp(char *); /* Detailed help routine */ +void Parser_exit(int, char **); /* Shuts down command parser */ +int Parser_execarg(int argc, char **argv, command_t cmds[]); +int execute_line(char * line); + +/* Converts a string to an integer */ +int Parser_int(char *, int *); + +/* Prompts for a string, with default values and a maximum length */ +char *Parser_getstr(const char *prompt, const char *deft, char *res, + size_t len); + +/* Prompts for an integer, with minimum, maximum and default values and base */ +int Parser_getint(const char *prompt, long min, long max, long deft, + int base); + +/* Prompts for a yes/no, with default */ +int Parser_getbool(const char *prompt, int deft); + +/* Extracts an integer from a string, or prompts if it cannot get one */ +long Parser_intarg(const char *inp, const char *prompt, int deft, + int min, int max, int base); + +/* Extracts a word from the input, or propmts if it cannot get one */ +char *Parser_strarg(char *inp, const char *prompt, const char *deft, + char *answer, int len); + +/* Extracts an integer from a string with a base */ +int Parser_arg2int(const char *inp, long *result, int base); + +/* Convert human readable size string to and int; "1k" -> 1000 */ +int Parser_size(int *sizep, char *str); + +/* Convert a string boolean to an int; "enable" -> 1 */ +int Parser_bool(int *b, char *str); + +#endif diff --git a/libcfs/include/libcfs/util/platform.h b/libcfs/include/libcfs/util/platform.h new file mode 100644 index 0000000..794d71f --- /dev/null +++ b/libcfs/include/libcfs/util/platform.h @@ -0,0 +1,268 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/libcfsutil.h + * + * A portability layer for multi-threaded userspace applications. + * + */ + +#ifndef __LUSTRE_UTILS_PLATFORM_H +#define __LUSTRE_UTILS_PLATFORM_H + +#ifdef __linux__ + +#ifdef HAVE_LIBREADLINE +#define READLINE_LIBRARY +#include + +/* completion_matches() is #if 0-ed out in modern glibc */ + +#ifndef completion_matches +# define completion_matches rl_completion_matches +#endif +extern void using_history(void); +extern void stifle_history(int); +extern void add_history(char *); +#endif /* HAVE_LIBREADLINE */ + +#include +#include +#if HAVE_LIBPTHREAD +#include +#include +#include + +typedef pthread_mutex_t l_mutex_t; +typedef pthread_cond_t l_cond_t; +#define l_mutex_init(s) pthread_mutex_init(s, NULL) +#define l_mutex_lock(s) pthread_mutex_lock(s) +#define l_mutex_unlock(s) pthread_mutex_unlock(s) +#define l_cond_init(c) pthread_cond_init(c, NULL) +#define l_cond_broadcast(c) pthread_cond_broadcast(c) +#define l_cond_wait(c, s) pthread_cond_wait(c, s) +#endif + +#elif __APPLE__ + +#ifdef HAVE_LIBREADLINE +#define READLINE_LIBRARY +#include +typedef VFunction rl_vintfunc_t; +typedef VFunction rl_voidfunc_t; +#endif /* HAVE_LIBREADLINE */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * POSIX compliant inter-process synchronization aren't supported well + * in Darwin, pthread_mutex_t and pthread_cond_t can only work as + * inter-thread synchronization, they wouldn't work even being put in + * shared memory for multi-process. PTHREAD_PROCESS_SHARED is not + * supported by Darwin also (pthread_mutexattr_setpshared() with the + * PTHREAD_PROCESS_SHARED attribute will return EINVAL). + * + * The only inter-process sychronization mechanism can be used in Darwin + * is POSIX NAMED semaphores and file lock, here we use NAMED semaphore + * to implement mutex and condition. + * + * XXX Liang: + * They are just proto-type now, more tests are needed. + */ +#define L_LOCK_DEBUG (0) + +#define L_SEM_NAMESIZE 32 + +typedef struct { + sem_t *s_sem; +#if L_LOCK_DEBUG + char s_name[L_SEM_NAMESIZE]; +#endif +} l_sem_t; + +typedef l_sem_t l_mutex_t; + +typedef struct { + l_mutex_t c_guard; + int c_count; + l_sem_t c_waiter; +} l_cond_t; + +static inline int l_sem_init(l_sem_t *sem, int val) +{ + char *s_name; +#if L_LOCK_DEBUG + s_name = sem->s_name; +#else + char buf[L_SEM_NAMESIZE]; + s_name = buf; +#endif + /* get an unique name for named semaphore */ + snprintf(s_name, L_SEM_NAMESIZE, "%d-%p", (int)getpid(), sem); + sem->s_sem = sem_open(s_name, O_CREAT, 0600, val); + if ((int)sem->s_sem == SEM_FAILED) { + fprintf(stderr, "lock %s creating fail: %d, %d!\n", + s_name, (int)sem->s_sem, errno); + return -1; + } else { +#if L_LOCK_DEBUG + printf("open lock: %s\n", s_name); +#endif + } + return 0; +} + +static inline void l_sem_done(l_sem_t *sem) +{ +#if L_LOCK_DEBUG + printf("close lock: %s.\n", sem->s_name); +#endif + sem_close(sem->s_sem); +} + +static inline void l_sem_down(l_sem_t *sem) +{ +#if L_LOCK_DEBUG + printf("sem down :%s\n", sem->s_name); +#endif + sem_wait(sem->s_sem); +} + +static inline void l_sem_up(l_sem_t *sem) +{ +#if L_LOCK_DEBUG + printf("sem up :%s\n", sem->s_name); +#endif + sem_post(sem->s_sem); +} + +static inline void l_mutex_init(l_mutex_t *mutex) +{ + l_sem_init((l_sem_t *)mutex, 1); +} + +static inline void l_mutex_init_locked(l_mutex_t *mutex) +{ + l_sem_init((l_sem_t *)mutex, 0); +} + +static inline void l_mutex_done(l_mutex_t *mutex) +{ + l_sem_done((l_sem_t *)mutex); +} + +static inline void l_mutex_lock(l_mutex_t *mutex) +{ +#if L_LOCK_DEBUG + printf("lock mutex :%s\n", mutex->s_name); +#endif + sem_wait(mutex->s_sem); +} + +static inline void l_mutex_unlock(l_mutex_t *mutex) +{ +#if L_LOCK_DEBUG + printf("unlock mutex: %s\n", mutex->s_name); +#endif + sem_post(mutex->s_sem); +} + +static inline void l_cond_init(l_cond_t *cond) +{ + l_mutex_init(&cond->c_guard); + l_sem_init(&cond->c_waiter, 0); + cond->c_count = 0; +} + +static inline void l_cond_done(l_cond_t *cond) +{ + if (cond->c_count != 0) + fprintf(stderr, "your waiter list is not empty: %d!\n", cond->c_count); + l_mutex_done(&cond->c_guard); + l_sem_done(&cond->c_waiter); +} + +static inline void l_cond_wait(l_cond_t *cond, l_mutex_t *lock) +{ + l_mutex_lock(&cond->c_guard); + cond->c_count --; + l_mutex_unlock(&cond->c_guard); + l_mutex_unlock(lock); + l_sem_down(&cond->c_waiter); + l_mutex_lock(lock); +} + +static inline void l_cond_broadcast(l_cond_t *cond) +{ + l_mutex_lock(&cond->c_guard); + while (cond->c_count < 0) { + l_sem_up(&cond->c_waiter); + cond->c_count ++; + } + l_mutex_unlock(&cond->c_guard); +} + +#else /* other platform */ + +#ifdef HAVE_LIBREADLINE +#define READLINE_LIBRARY +#include +#endif /* HAVE_LIBREADLINE */ +#include +#include +#if HAVE_LIBPTHREAD +#include +#include +#include + +typedef pthread_mutex_t l_mutex_t; +typedef pthread_cond_t l_cond_t; +#define l_mutex_init(s) pthread_mutex_init(s, NULL) +#define l_mutex_lock(s) pthread_mutex_lock(s) +#define l_mutex_unlock(s) pthread_mutex_unlock(s) +#define l_cond_init(c) pthread_cond_init(c, NULL) +#define l_cond_broadcast(c) pthread_cond_broadcast(c) +#define l_cond_wait(c, s) pthread_cond_wait(c, s) +#endif /* HAVE_LIBPTHREAD */ + +#endif /* __linux__ */ + +#endif diff --git a/libcfs/include/libcfs/winnt/kp30.h b/libcfs/include/libcfs/winnt/kp30.h index 57d450c..8eb474e 100644 --- a/libcfs/include/libcfs/winnt/kp30.h +++ b/libcfs/include/libcfs/winnt/kp30.h @@ -37,10 +37,6 @@ #ifndef __LIBCFS_WINNT_KP30_H__ #define __LIBCFS_WINNT_KP30_H__ -#ifndef __LIBCFS_KP30_H__ -#error Do not #include this file directly. #include instead -#endif - #include #include diff --git a/libcfs/include/libcfs/winnt/libcfs.h b/libcfs/include/libcfs/winnt/libcfs.h index 7f894b8..c11426a 100644 --- a/libcfs/include/libcfs/winnt/libcfs.h +++ b/libcfs/include/libcfs/winnt/libcfs.h @@ -54,6 +54,7 @@ #include #include #include +#include struct ptldebug_header { __u32 ph_len; diff --git a/libcfs/include/libcfs/winnt/winnt-prim.h b/libcfs/include/libcfs/winnt/winnt-prim.h index 3add9b8..8e7d5c3 100644 --- a/libcfs/include/libcfs/winnt/winnt-prim.h +++ b/libcfs/include/libcfs/winnt/winnt-prim.h @@ -319,7 +319,7 @@ typedef int cfs_task_state_t; #define CFS_TASK_INTERRUPTIBLE 0x00000001 #define CFS_TASK_UNINT 0x00000002 - +#define CFS_TASK_RUNNING 0x00000003 #define CFS_WAITQ_MAGIC 'CWQM' @@ -374,7 +374,6 @@ void cfs_waitlink_init(struct cfs_waitlink *link); void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link); void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, struct cfs_waitlink *link); -void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq); void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link); int cfs_waitq_active(struct cfs_waitq *waitq); diff --git a/libcfs/libcfs/autoMakefile.am b/libcfs/libcfs/autoMakefile.am index ab72704..0c47352 100644 --- a/libcfs/libcfs/autoMakefile.am +++ b/libcfs/libcfs/autoMakefile.am @@ -34,7 +34,7 @@ # Lustre is a trademark of Sun Microsystems, Inc. # -SUBDIRS := linux +SUBDIRS := linux util posix if DARWIN SUBDIRS += darwin endif @@ -42,9 +42,14 @@ DIST_SUBDIRS := $(SUBDIRS) if LIBLUSTRE noinst_LIBRARIES= libcfs.a -libcfs_a_SOURCES= debug.c user-prim.c user-lock.c user-tcpip.c user-bitops.c +libcfs_a_SOURCES= posix/posix-debug.c user-prim.c user-lock.c user-tcpip.c user-bitops.c user-mem.c libcfs_a_CPPFLAGS = $(LLCPPFLAGS) libcfs_a_CFLAGS = $(LLCFLAGS) + +lib_LIBRARIES = libcfsutil.a +libcfsutil_a_SOURCES = nidstrings.c util/parser.c util/parser.h util/platform.h util/l_ioctl.c +libcfsutil_a_CPPFLAGS = $(LLCPPFLAGS) +libcfsutil_a_CFLAGS = $(LLCFLAGS) -DLUSTRE_UTILS=1 endif if MODULES @@ -61,7 +66,7 @@ nodist_libcfs_SOURCES := darwin/darwin-sync.c darwin/darwin-mem.c \ darwin/darwin-tcpip.c darwin/darwin-utils.c \ darwin/darwin-debug.c darwin/darwin-proc.c \ darwin/darwin-tracefile.c darwin/darwin-module.c \ - debug.c module.c tracefile.c nidstrings.c watchdog.c + posix/posix-debug.c module.c tracefile.c nidstrings.c watchdog.c libcfs_CFLAGS := $(EXTRA_KCFLAGS) libcfs_LDFLAGS := $(EXTRA_KLDFLAGS) @@ -81,4 +86,5 @@ EXTRA_DIST := Info.plist MOSTLYCLEANFILES := @MOSTLYCLEANFILES@ linux-*.c linux/*.o darwin/*.o libcfs DIST_SOURCES := $(libcfs-all-objs:%.o=%.c) tracefile.h user-prim.c \ - user-lock.c user-tcpip.c user-bitops.c + user-lock.c user-tcpip.c user-bitops.c\ + user-mem.c diff --git a/libcfs/libcfs/darwin/darwin-prim.c b/libcfs/libcfs/darwin/darwin-prim.c index b95cc76..a5dc735 100644 --- a/libcfs/libcfs/darwin/darwin-prim.c +++ b/libcfs/libcfs/darwin/darwin-prim.c @@ -475,12 +475,6 @@ void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, ksleep_add(&waitq->wq_ksleep_chan, &link->wl_ksleep_link); } -void cfs_waitq_forward(struct cfs_waitlink *link, - struct cfs_waitq *waitq) -{ - link->wl_ksleep_link.forward = &waitq->wq_ksleep_chan; -} - void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link) { diff --git a/libcfs/libcfs/darwin/darwin-utils.c b/libcfs/libcfs/darwin/darwin-utils.c index a6097b7..8cd3453 100644 --- a/libcfs/libcfs/darwin/darwin-utils.c +++ b/libcfs/libcfs/darwin/darwin-utils.c @@ -577,7 +577,7 @@ void cfs_stack_trace_fill(struct cfs_stack_trace *trace) int i; memset(trace, 0, sizeof *trace); - for (i = 0; i < sizeof_array(trace->frame); ++ i) { + for (i = 0; i < ARRAY_SIZE(trace->frame); ++ i) { void *addr; addr = get_frame(i); @@ -589,7 +589,7 @@ void cfs_stack_trace_fill(struct cfs_stack_trace *trace) void *cfs_stack_trace_frame(struct cfs_stack_trace *trace, int frame_no) { - if (0 <= frame_no && frame_no < sizeof_array(trace->frame)) + if (0 <= frame_no && frame_no < ARRAY_SIZE(trace->frame)) return trace->frame[frame_no]; else return NULL; diff --git a/libcfs/libcfs/debug.c b/libcfs/libcfs/debug.c index 3e5acd4..f1ccfc5 100644 --- a/libcfs/libcfs/debug.c +++ b/libcfs/libcfs/debug.c @@ -44,13 +44,11 @@ # define DEBUG_SUBSYSTEM S_LNET -#include #include #include "tracefile.h" static char debug_file_name[1024]; -#ifdef __KERNEL__ unsigned int libcfs_subsystem_debug = ~0; CFS_MODULE_PARM(libcfs_subsystem_debug, "i", int, 0644, "Lustre kernel debug subsystem mask"); @@ -531,328 +529,3 @@ void libcfs_debug_set_level(unsigned int debug_level) EXPORT_SYMBOL(libcfs_debug_dumplog); EXPORT_SYMBOL(libcfs_debug_set_level); - - -#else /* !__KERNEL__ */ - -#include - -#ifdef HAVE_CATAMOUNT_DATA_H -#include -#include - -static char source_nid[16]; -/* 0 indicates no messages to console, 1 is errors, > 1 is all debug messages */ -static int toconsole = 1; -unsigned int libcfs_console_ratelimit = 1; -cfs_duration_t libcfs_console_max_delay; -cfs_duration_t libcfs_console_min_delay; -unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF; -#else /* !HAVE_CATAMOUNT_DATA_H */ -#ifdef HAVE_NETDB_H -#include -#endif /* HAVE_NETDB_H */ -struct utsname *tmp_utsname; -static char source_nid[sizeof(tmp_utsname->nodename)]; -#endif /* HAVE_CATAMOUNT_DATA_H */ - -static int source_pid; -int smp_processor_id = 1; -char debug_file_path[1024]; -FILE *debug_file_fd; - -int portals_do_debug_dumplog(void *arg) -{ - printf("Look in %s\n", debug_file_name); - return 0; -} - - -void portals_debug_print(void) -{ - return; -} - - -void libcfs_debug_dumplog(void) -{ - printf("Look in %s\n", debug_file_name); - return; -} - -int libcfs_debug_init(unsigned long bufsize) -{ - char *debug_mask = NULL; - char *debug_subsys = NULL; - char *debug_filename; - -#ifdef HAVE_CATAMOUNT_DATA_H - char *debug_console = NULL; - char *debug_ratelimit = NULL; - char *debug_max_delay = NULL; - char *debug_min_delay = NULL; - char *debug_backoff = NULL; - - libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY; - libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY; - - snprintf(source_nid, sizeof(source_nid) - 1, "%u", _my_pnid); - source_pid = _my_pid; - - debug_console = getenv("LIBLUSTRE_DEBUG_CONSOLE"); - if (debug_console != NULL) { - toconsole = strtoul(debug_console, NULL, 0); - CDEBUG(D_INFO, "set liblustre toconsole to %u\n", toconsole); - } - debug_ratelimit = getenv("LIBLUSTRE_DEBUG_CONSOLE_RATELIMIT"); - if (debug_ratelimit != NULL) { - libcfs_console_ratelimit = strtoul(debug_ratelimit, NULL, 0); - CDEBUG(D_INFO, "set liblustre console ratelimit to %u\n", - libcfs_console_ratelimit); - } - debug_max_delay = getenv("LIBLUSTRE_DEBUG_CONSOLE_MAX_DELAY"); - if (debug_max_delay != NULL) - libcfs_console_max_delay = - cfs_time_seconds(strtoul(debug_max_delay, NULL, 0)); - debug_min_delay = getenv("LIBLUSTRE_DEBUG_CONSOLE_MIN_DELAY"); - if (debug_min_delay != NULL) - libcfs_console_min_delay = - cfs_time_seconds(strtoul(debug_min_delay, NULL, 0)); - if (debug_min_delay || debug_max_delay) { - if (!libcfs_console_max_delay || !libcfs_console_min_delay || - libcfs_console_max_delay < libcfs_console_min_delay) { - libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY; - libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY; - CDEBUG(D_INFO, "LIBLUSTRE_DEBUG_CONSOLE_MAX_DELAY " - "should be greater than " - "LIBLUSTRE_DEBUG_CONSOLE_MIN_DELAY " - "and both parameters should be non-null" - ": restore default values\n"); - } else { - CDEBUG(D_INFO, "set liblustre console max delay to %lus" - " and min delay to %lus\n", - (cfs_duration_t) - cfs_duration_sec(libcfs_console_max_delay), - (cfs_duration_t) - cfs_duration_sec(libcfs_console_min_delay)); - } - } - debug_backoff = getenv("LIBLUSTRE_DEBUG_CONSOLE_BACKOFF"); - if (debug_backoff != NULL) { - libcfs_console_backoff = strtoul(debug_backoff, NULL, 0); - if (libcfs_console_backoff <= 0) { - libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF; - CDEBUG(D_INFO, "LIBLUSTRE_DEBUG_CONSOLE_BACKOFF <= 0: " - "restore default value\n"); - } else { - CDEBUG(D_INFO, "set liblustre console backoff to %u\n", - libcfs_console_backoff); - } - } -#else - struct utsname myname; - - if (uname(&myname) == 0) - strcpy(source_nid, myname.nodename); - source_pid = getpid(); -#endif - /* debug masks */ - debug_mask = getenv("LIBLUSTRE_DEBUG_MASK"); - if (debug_mask) - libcfs_debug = (unsigned int) strtol(debug_mask, NULL, 0); - - debug_subsys = getenv("LIBLUSTRE_DEBUG_SUBSYS"); - if (debug_subsys) - libcfs_subsystem_debug = - (unsigned int) strtol(debug_subsys, NULL, 0); - - debug_filename = getenv("LIBLUSTRE_DEBUG_BASE"); - if (debug_filename) - strncpy(debug_file_path,debug_filename,sizeof(debug_file_path)); - - debug_filename = getenv("LIBLUSTRE_DEBUG_FILE"); - if (debug_filename) - strncpy(debug_file_name,debug_filename,sizeof(debug_file_name)); - - if (debug_file_name[0] == '\0' && debug_file_path[0] != '\0') - snprintf(debug_file_name, sizeof(debug_file_name) - 1, - "%s-%s-"CFS_TIME_T".log", debug_file_path, source_nid, time(0)); - - if (strcmp(debug_file_name, "stdout") == 0 || - strcmp(debug_file_name, "-") == 0) { - debug_file_fd = stdout; - } else if (strcmp(debug_file_name, "stderr") == 0) { - debug_file_fd = stderr; - } else if (debug_file_name[0] != '\0') { - debug_file_fd = fopen(debug_file_name, "w"); - if (debug_file_fd == NULL) - fprintf(stderr, "%s: unable to open '%s': %s\n", - source_nid, debug_file_name, strerror(errno)); - } - - if (debug_file_fd == NULL) - debug_file_fd = stdout; - - return 0; -} - -int libcfs_debug_cleanup(void) -{ - if (debug_file_fd != stdout && debug_file_fd != stderr) - fclose(debug_file_fd); - return 0; -} - -int libcfs_debug_clear_buffer(void) -{ - return 0; -} - -int libcfs_debug_mark_buffer(char *text) -{ - - fprintf(debug_file_fd, "*******************************************************************************\n"); - fprintf(debug_file_fd, "DEBUG MARKER: %s\n", text); - fprintf(debug_file_fd, "*******************************************************************************\n"); - - return 0; -} - -#ifdef HAVE_CATAMOUNT_DATA_H -#define CATAMOUNT_MAXLINE (256-4) -void catamount_printline(char *buf, size_t size) -{ - char *pos = buf; - int prsize = size; - - while (prsize > 0){ - lputs(pos); - pos += CATAMOUNT_MAXLINE; - prsize -= CATAMOUNT_MAXLINE; - } -} -#endif - -int -libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, - int subsys, int mask, - const char *file, const char *fn, const int line, - const char *format1, va_list args, - const char *format2, ...) -{ - struct timeval tv; - int nob; - int remain; - va_list ap; - char buf[CFS_PAGE_SIZE]; /* size 4096 used for compatimble - * with linux, where message can`t - * be exceed PAGE_SIZE */ - int console = 0; - char *prefix = "Lustre"; - -#ifdef HAVE_CATAMOUNT_DATA_H - /* toconsole == 0 - all messages to debug_file_fd - * toconsole == 1 - warnings to console, all to debug_file_fd - * toconsole > 1 - all debug to console */ - if (((mask & libcfs_printk) && toconsole == 1) || toconsole > 1) - console = 1; -#endif - - if ((!console) && (!debug_file_fd)) { - return 0; - } - - if (mask & (D_EMERG | D_ERROR)) - prefix = "LustreError"; - - nob = snprintf(buf, sizeof(buf), "%s: %u-%s:(%s:%d:%s()): ", prefix, - source_pid, source_nid, file, line, fn); - - remain = sizeof(buf) - nob; - if (format1) { - nob += vsnprintf(&buf[nob], remain, format1, args); - } - - remain = sizeof(buf) - nob; - if ((format2) && (remain > 0)) { - va_start(ap, format2); - nob += vsnprintf(&buf[nob], remain, format2, ap); - va_end(ap); - } - -#ifdef HAVE_CATAMOUNT_DATA_H - if (console) { - /* check rate limit for console */ - if (cdls != NULL) { - if (libcfs_console_ratelimit && - cdls->cdls_next != 0 && /* not first time ever */ - !cfs_time_after(cfs_time_current(), cdls->cdls_next)) { - - /* skipping a console message */ - cdls->cdls_count++; - goto out_file; - } - - if (cfs_time_after(cfs_time_current(), cdls->cdls_next + - libcfs_console_max_delay + - cfs_time_seconds(10))) { - /* last timeout was a long time ago */ - cdls->cdls_delay /= libcfs_console_backoff * 4; - } else { - cdls->cdls_delay *= libcfs_console_backoff; - - if (cdls->cdls_delay < - libcfs_console_min_delay) - cdls->cdls_delay = - libcfs_console_min_delay; - else if (cdls->cdls_delay > - libcfs_console_max_delay) - cdls->cdls_delay = - libcfs_console_max_delay; - } - - /* ensure cdls_next is never zero after it's been seen */ - cdls->cdls_next = (cfs_time_current() + cdls->cdls_delay) | 1; - } - - if (cdls != NULL && cdls->cdls_count != 0) { - char buf2[100]; - - nob = snprintf(buf2, sizeof(buf2), - "Skipped %d previous similar message%s\n", - cdls->cdls_count, (cdls->cdls_count > 1) ? "s" : ""); - - catamount_printline(buf2, nob); - cdls->cdls_count = 0; - goto out_file; - } - catamount_printline(buf, nob); - } -out_file: - /* return on toconsole > 1, as we don't want the user getting - * spammed by the debug data */ - if (toconsole > 1) - return 0; -#endif - if (debug_file_fd == NULL) - return 0; - - gettimeofday(&tv, NULL); - - fprintf(debug_file_fd, CFS_TIME_T".%06lu:%u:%s:(%s:%d:%s()): %s", - tv.tv_sec, tv.tv_usec, source_pid, source_nid, - file, line, fn, buf); - - return 0; -} - -void -libcfs_assertion_failed(const char *expr, const char *file, const char *func, - const int line) -{ - libcfs_debug_msg(NULL, 0, D_EMERG, file, func, line, - "ASSERTION(%s) failed\n", expr); - abort(); -} - -#endif /* __KERNEL__ */ diff --git a/libcfs/libcfs/linux/linux-prim.c b/libcfs/libcfs/linux/linux-prim.c index 6bee634..2405d82 100644 --- a/libcfs/libcfs/linux/linux-prim.c +++ b/libcfs/libcfs/linux/linux-prim.c @@ -40,12 +40,163 @@ #endif #include #include +#include + #include #if defined(CONFIG_KGDB) #include #endif +#define LINUX_WAITQ(w) ((wait_queue_t *) w) +#define LINUX_WAITQ_HEAD(w) ((wait_queue_head_t *) w) + +void +cfs_waitq_init(cfs_waitq_t *waitq) +{ + init_waitqueue_head(LINUX_WAITQ_HEAD(waitq)); +} +EXPORT_SYMBOL(cfs_waitq_init); + +void +cfs_waitlink_init(cfs_waitlink_t *link) +{ + init_waitqueue_entry(LINUX_WAITQ(link), current); +} +EXPORT_SYMBOL(cfs_waitlink_init); + +void +cfs_waitq_add(cfs_waitq_t *waitq, cfs_waitlink_t *link) +{ + add_wait_queue(LINUX_WAITQ_HEAD(waitq), LINUX_WAITQ(link)); +} +EXPORT_SYMBOL(cfs_waitq_add); + +void +cfs_waitq_add_exclusive(cfs_waitq_t *waitq, + cfs_waitlink_t *link) +{ + add_wait_queue_exclusive(LINUX_WAITQ_HEAD(waitq), LINUX_WAITQ(link)); +} +EXPORT_SYMBOL(cfs_waitq_add_exclusive); + +void +cfs_waitq_del(cfs_waitq_t *waitq, cfs_waitlink_t *link) +{ + remove_wait_queue(LINUX_WAITQ_HEAD(waitq), LINUX_WAITQ(link)); +} +EXPORT_SYMBOL(cfs_waitq_del); + +int +cfs_waitq_active(cfs_waitq_t *waitq) +{ + return waitqueue_active(LINUX_WAITQ_HEAD(waitq)); +} +EXPORT_SYMBOL(cfs_waitq_active); + +void +cfs_waitq_signal(cfs_waitq_t *waitq) +{ + wake_up(LINUX_WAITQ_HEAD(waitq)); +} +EXPORT_SYMBOL(cfs_waitq_signal); + +void +cfs_waitq_signal_nr(cfs_waitq_t *waitq, int nr) +{ + wake_up_nr(LINUX_WAITQ_HEAD(waitq), nr); +} +EXPORT_SYMBOL(cfs_waitq_signal_nr); + +void +cfs_waitq_broadcast(cfs_waitq_t *waitq) +{ + wake_up_all(LINUX_WAITQ_HEAD(waitq)); +} +EXPORT_SYMBOL(cfs_waitq_broadcast); + +void +cfs_waitq_wait(cfs_waitlink_t *link, cfs_task_state_t state) +{ + schedule(); +} +EXPORT_SYMBOL(cfs_waitq_wait); + +int64_t +cfs_waitq_timedwait(cfs_waitlink_t *link, cfs_task_state_t state, int64_t timeout) +{ + return schedule_timeout(timeout); +} +EXPORT_SYMBOL(cfs_waitq_timedwait); + +void +cfs_schedule_timeout(cfs_task_state_t state, int64_t timeout) +{ + set_current_state(state); + schedule_timeout(timeout); +} +EXPORT_SYMBOL(cfs_schedule_timeout); + +void +cfs_schedule(void) +{ + schedule(); +} +EXPORT_SYMBOL(cfs_schedule); + +/* deschedule for a bit... */ +void +cfs_pause(cfs_duration_t ticks) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(ticks); +} +EXPORT_SYMBOL(cfs_pause); + +void cfs_init_timer(cfs_timer_t *t) +{ + init_timer(t); +} +EXPORT_SYMBOL(cfs_init_timer); + +void cfs_timer_init(cfs_timer_t *t, cfs_timer_func_t *func, void *arg) +{ + init_timer(t); + t->function = func; + t->data = (unsigned long)arg; +} +EXPORT_SYMBOL(cfs_timer_init); + +void cfs_timer_done(cfs_timer_t *t) +{ + return; +} +EXPORT_SYMBOL(cfs_timer_done); + +void cfs_timer_arm(cfs_timer_t *t, cfs_time_t deadline) +{ + mod_timer(t, deadline); +} +EXPORT_SYMBOL(cfs_timer_arm); + +void cfs_timer_disarm(cfs_timer_t *t) +{ + del_timer(t); +} +EXPORT_SYMBOL(cfs_timer_disarm); + +int cfs_timer_is_armed(cfs_timer_t *t) +{ + return timer_pending(t); +} +EXPORT_SYMBOL(cfs_timer_is_armed); + +cfs_time_t cfs_timer_deadline(cfs_timer_t *t) +{ + return t->expires; +} +EXPORT_SYMBOL(cfs_timer_deadline); + void cfs_enter_debugger(void) { #if defined(CONFIG_KGDB) diff --git a/libcfs/libcfs/posix/.cvsignore b/libcfs/libcfs/posix/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/libcfs/libcfs/posix/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/libcfs/libcfs/posix/Makefile.am b/libcfs/libcfs/posix/Makefile.am new file mode 100644 index 0000000..ebabae3 --- /dev/null +++ b/libcfs/libcfs/posix/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST := posix-debug.c + diff --git a/libcfs/libcfs/posix/posix-debug.c b/libcfs/libcfs/posix/posix-debug.c new file mode 100644 index 0000000..f26a085 --- /dev/null +++ b/libcfs/libcfs/posix/posix-debug.c @@ -0,0 +1,364 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/libcfs/posix/posix_debug.c + * + * Userspace debugging. + * + */ + +# define DEBUG_SUBSYSTEM S_LNET + +#include + +static char debug_file_name[1024]; + +#ifdef HAVE_CATAMOUNT_DATA_H +#include +#include + +static char source_nid[16]; +/* 0 indicates no messages to console, 1 is errors, > 1 is all debug messages */ +static int toconsole = 1; +unsigned int libcfs_console_ratelimit = 1; +cfs_duration_t libcfs_console_max_delay; +cfs_duration_t libcfs_console_min_delay; +unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF; +#else /* !HAVE_CATAMOUNT_DATA_H */ +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +struct utsname *tmp_utsname; +static char source_nid[sizeof(tmp_utsname->nodename)]; +#endif /* HAVE_CATAMOUNT_DATA_H */ + +static int source_pid; +int smp_processor_id = 1; +char debug_file_path[1024]; +FILE *debug_file_fd; + +int portals_do_debug_dumplog(void *arg) +{ + printf("Look in %s\n", debug_file_name); + return 0; +} + + +void portals_debug_print(void) +{ + return; +} + + +void libcfs_debug_dumplog(void) +{ + printf("Look in %s\n", debug_file_name); + return; +} + +int libcfs_debug_init(unsigned long bufsize) +{ + char *debug_mask = NULL; + char *debug_subsys = NULL; + char *debug_filename; + +#ifdef HAVE_CATAMOUNT_DATA_H + char *debug_console = NULL; + char *debug_ratelimit = NULL; + char *debug_max_delay = NULL; + char *debug_min_delay = NULL; + char *debug_backoff = NULL; + + libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY; + libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY; + + snprintf(source_nid, sizeof(source_nid) - 1, "%u", _my_pnid); + source_pid = _my_pid; + + debug_console = getenv("LIBLUSTRE_DEBUG_CONSOLE"); + if (debug_console != NULL) { + toconsole = strtoul(debug_console, NULL, 0); + CDEBUG(D_INFO, "set liblustre toconsole to %u\n", toconsole); + } + debug_ratelimit = getenv("LIBLUSTRE_DEBUG_CONSOLE_RATELIMIT"); + if (debug_ratelimit != NULL) { + libcfs_console_ratelimit = strtoul(debug_ratelimit, NULL, 0); + CDEBUG(D_INFO, "set liblustre console ratelimit to %u\n", + libcfs_console_ratelimit); + } + debug_max_delay = getenv("LIBLUSTRE_DEBUG_CONSOLE_MAX_DELAY"); + if (debug_max_delay != NULL) + libcfs_console_max_delay = + cfs_time_seconds(strtoul(debug_max_delay, NULL, 0)); + debug_min_delay = getenv("LIBLUSTRE_DEBUG_CONSOLE_MIN_DELAY"); + if (debug_min_delay != NULL) + libcfs_console_min_delay = + cfs_time_seconds(strtoul(debug_min_delay, NULL, 0)); + if (debug_min_delay || debug_max_delay) { + if (!libcfs_console_max_delay || !libcfs_console_min_delay || + libcfs_console_max_delay < libcfs_console_min_delay) { + libcfs_console_max_delay = CDEBUG_DEFAULT_MAX_DELAY; + libcfs_console_min_delay = CDEBUG_DEFAULT_MIN_DELAY; + CDEBUG(D_INFO, "LIBLUSTRE_DEBUG_CONSOLE_MAX_DELAY " + "should be greater than " + "LIBLUSTRE_DEBUG_CONSOLE_MIN_DELAY " + "and both parameters should be non-null" + ": restore default values\n"); + } else { + CDEBUG(D_INFO, "set liblustre console max delay to %lus" + " and min delay to %lus\n", + (cfs_duration_t) + cfs_duration_sec(libcfs_console_max_delay), + (cfs_duration_t) + cfs_duration_sec(libcfs_console_min_delay)); + } + } + debug_backoff = getenv("LIBLUSTRE_DEBUG_CONSOLE_BACKOFF"); + if (debug_backoff != NULL) { + libcfs_console_backoff = strtoul(debug_backoff, NULL, 0); + if (libcfs_console_backoff <= 0) { + libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF; + CDEBUG(D_INFO, "LIBLUSTRE_DEBUG_CONSOLE_BACKOFF <= 0: " + "restore default value\n"); + } else { + CDEBUG(D_INFO, "set liblustre console backoff to %u\n", + libcfs_console_backoff); + } + } +#else + struct utsname myname; + + if (uname(&myname) == 0) + strcpy(source_nid, myname.nodename); + source_pid = getpid(); +#endif + /* debug masks */ + debug_mask = getenv("LIBLUSTRE_DEBUG_MASK"); + if (debug_mask) + libcfs_debug = (unsigned int) strtol(debug_mask, NULL, 0); + + debug_subsys = getenv("LIBLUSTRE_DEBUG_SUBSYS"); + if (debug_subsys) + libcfs_subsystem_debug = + (unsigned int) strtol(debug_subsys, NULL, 0); + + debug_filename = getenv("LIBLUSTRE_DEBUG_BASE"); + if (debug_filename) + strncpy(debug_file_path,debug_filename,sizeof(debug_file_path)); + + debug_filename = getenv("LIBLUSTRE_DEBUG_FILE"); + if (debug_filename) + strncpy(debug_file_name,debug_filename,sizeof(debug_file_name)); + + if (debug_file_name[0] == '\0' && debug_file_path[0] != '\0') + snprintf(debug_file_name, sizeof(debug_file_name) - 1, + "%s-%s-"CFS_TIME_T".log", debug_file_path, source_nid, time(0)); + + if (strcmp(debug_file_name, "stdout") == 0 || + strcmp(debug_file_name, "-") == 0) { + debug_file_fd = stdout; + } else if (strcmp(debug_file_name, "stderr") == 0) { + debug_file_fd = stderr; + } else if (debug_file_name[0] != '\0') { + debug_file_fd = fopen(debug_file_name, "w"); + if (debug_file_fd == NULL) + fprintf(stderr, "%s: unable to open '%s': %s\n", + source_nid, debug_file_name, strerror(errno)); + } + + if (debug_file_fd == NULL) + debug_file_fd = stdout; + + return 0; +} + +int libcfs_debug_cleanup(void) +{ + if (debug_file_fd != stdout && debug_file_fd != stderr) + fclose(debug_file_fd); + return 0; +} + +int libcfs_debug_clear_buffer(void) +{ + return 0; +} + +int libcfs_debug_mark_buffer(char *text) +{ + + fprintf(debug_file_fd, "*******************************************************************************\n"); + fprintf(debug_file_fd, "DEBUG MARKER: %s\n", text); + fprintf(debug_file_fd, "*******************************************************************************\n"); + + return 0; +} + +#ifdef HAVE_CATAMOUNT_DATA_H +#define CATAMOUNT_MAXLINE (256-4) +void catamount_printline(char *buf, size_t size) +{ + char *pos = buf; + int prsize = size; + + while (prsize > 0){ + lputs(pos); + pos += CATAMOUNT_MAXLINE; + prsize -= CATAMOUNT_MAXLINE; + } +} +#endif + +int +libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, + int subsys, int mask, + const char *file, const char *fn, const int line, + const char *format1, va_list args, + const char *format2, ...) +{ + struct timeval tv; + int nob; + int remain; + va_list ap; + char buf[CFS_PAGE_SIZE]; /* size 4096 used for compatimble + * with linux, where message can`t + * be exceed PAGE_SIZE */ + int console = 0; + char *prefix = "Lustre"; + +#ifdef HAVE_CATAMOUNT_DATA_H + /* toconsole == 0 - all messages to debug_file_fd + * toconsole == 1 - warnings to console, all to debug_file_fd + * toconsole > 1 - all debug to console */ + if (((mask & libcfs_printk) && toconsole == 1) || toconsole > 1) + console = 1; +#endif + + if ((!console) && (!debug_file_fd)) { + return 0; + } + + if (mask & (D_EMERG | D_ERROR)) + prefix = "LustreError"; + + nob = snprintf(buf, sizeof(buf), "%s: %u-%s:(%s:%d:%s()): ", prefix, + source_pid, source_nid, file, line, fn); + + remain = sizeof(buf) - nob; + if (format1) { + nob += vsnprintf(&buf[nob], remain, format1, args); + } + + remain = sizeof(buf) - nob; + if ((format2) && (remain > 0)) { + va_start(ap, format2); + nob += vsnprintf(&buf[nob], remain, format2, ap); + va_end(ap); + } + +#ifdef HAVE_CATAMOUNT_DATA_H + if (console) { + /* check rate limit for console */ + if (cdls != NULL) { + if (libcfs_console_ratelimit && + cdls->cdls_next != 0 && /* not first time ever */ + !cfs_time_after(cfs_time_current(), cdls->cdls_next)) { + + /* skipping a console message */ + cdls->cdls_count++; + goto out_file; + } + + if (cfs_time_after(cfs_time_current(), cdls->cdls_next + + libcfs_console_max_delay + + cfs_time_seconds(10))) { + /* last timeout was a long time ago */ + cdls->cdls_delay /= libcfs_console_backoff * 4; + } else { + cdls->cdls_delay *= libcfs_console_backoff; + + if (cdls->cdls_delay < + libcfs_console_min_delay) + cdls->cdls_delay = + libcfs_console_min_delay; + else if (cdls->cdls_delay > + libcfs_console_max_delay) + cdls->cdls_delay = + libcfs_console_max_delay; + } + + /* ensure cdls_next is never zero after it's been seen */ + cdls->cdls_next = (cfs_time_current() + cdls->cdls_delay) | 1; + } + + if (cdls != NULL && cdls->cdls_count != 0) { + char buf2[100]; + + nob = snprintf(buf2, sizeof(buf2), + "Skipped %d previous similar message%s\n", + cdls->cdls_count, (cdls->cdls_count > 1) ? "s" : ""); + + catamount_printline(buf2, nob); + cdls->cdls_count = 0; + goto out_file; + } + catamount_printline(buf, nob); + } +out_file: + /* return on toconsole > 1, as we don't want the user getting + * spammed by the debug data */ + if (toconsole > 1) + return 0; +#endif + if (debug_file_fd == NULL) + return 0; + + gettimeofday(&tv, NULL); + + fprintf(debug_file_fd, CFS_TIME_T".%06lu:%u:%s:(%s:%d:%s()): %s", + tv.tv_sec, tv.tv_usec, source_pid, source_nid, + file, line, fn, buf); + + return 0; +} + +void +libcfs_assertion_failed(const char *expr, const char *file, const char *func, + const int line) +{ + libcfs_debug_msg(NULL, 0, D_EMERG, file, func, line, + "ASSERTION(%s) failed\n", expr); + abort(); +} diff --git a/libcfs/libcfs/user-lock.c b/libcfs/libcfs/user-lock.c index a6d9973..f0f7fb7 100644 --- a/libcfs/libcfs/user-lock.c +++ b/libcfs/libcfs/user-lock.c @@ -50,14 +50,12 @@ #ifndef __KERNEL__ -#include #include /* * Optional debugging (magic stamping and checking ownership) can be added. */ -#if 0 /* * spin_lock * @@ -119,7 +117,6 @@ void spin_unlock_bh(spinlock_t *lock) * - __down(x) * - __up(x) */ -struct semaphore {}; void sema_init(struct semaphore *s, int val) { @@ -140,20 +137,6 @@ void __up(struct semaphore *s) (void)s; } -/* - * Mutex: - * - * - init_mutex(x) - * - init_mutex_locked(x) - * - mutex_up(x) - * - mutex_down(x) - */ - -#define mutex_up(s) __up(s) -#define mutex_down(s) __down(s) - -#define init_mutex(x) sema_init(x, 1) -#define init_mutex_locked(x) sema_init(x, 0) /* * Completion: @@ -162,24 +145,24 @@ void __up(struct semaphore *s) * - complete(c) * - wait_for_completion(c) */ -struct completion {}; void init_completion(struct completion *c) { LASSERT(c != NULL); - (void)c; + c->done = 0; + cfs_waitq_init(&c->wait); } void complete(struct completion *c) { LASSERT(c != NULL); - (void)c; + c->done = 1; + cfs_waitq_signal(&c->wait); } void wait_for_completion(struct completion *c) { LASSERT(c != NULL); - (void)c; } /* @@ -192,7 +175,6 @@ void wait_for_completion(struct completion *c) * - down_write(x) * - up_write(x) */ -struct rw_semaphore {}; void init_rwsem(struct rw_semaphore *s) { @@ -237,7 +219,6 @@ void up_write(struct rw_semaphore *s) LASSERT(s != NULL); (void)s; } -#endif #ifdef HAVE_LIBPTHREAD diff --git a/libcfs/libcfs/user-mem.c b/libcfs/libcfs/user-mem.c new file mode 100644 index 0000000..8043b61 --- /dev/null +++ b/libcfs/libcfs/user-mem.c @@ -0,0 +1,157 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * 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 [sun.com URL with a + * copy of GPLv2]. + * + * 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 2008 Sun Microsystems, Inc. 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/libcfs/user-mem.c + * + * Userspace memory management. + * + */ + +#ifdef __KERNEL__ +#error "This is not kernel code." +#endif + +#include + +#ifdef __linux__ +#include /* memalign declared here on linux */ +#endif + +/* + * Allocator + */ + +cfs_page_t *cfs_alloc_pages(int mask, unsigned long order) +{ + cfs_page_t *pg = malloc(sizeof(*pg)); + + if (!pg) + return NULL; +#if 0 //#ifdef MAP_ANONYMOUS + pg->addr = mmap(0, PAGE_SIZE << order, PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); +#elif defined (__DARWIN__) + pg->addr = valloc(CFS_PAGE_SIZE << order); +#else + pg->addr = memalign(CFS_PAGE_SIZE, CFS_PAGE_SIZE << order); +#endif + + if (!pg->addr) { + free(pg); + return NULL; + } + return pg; +} + +void cfs_free_pages(cfs_page_t *pg, int what) +{ +#if 0 //#ifdef MAP_ANONYMOUS + munmap(pg->addr, PAGE_SIZE); +#else + free(pg->addr); +#endif + free(pg); +} + +cfs_page_t *cfs_alloc_page(unsigned int flags) +{ + cfs_page_t *pg = malloc(sizeof(*pg)); + + if (!pg) + return NULL; + pg->addr = malloc(CFS_PAGE_SIZE); + + if (!pg->addr) { + free(pg); + return NULL; + } + return pg; +} + +void cfs_free_page(cfs_page_t *pg) +{ + free(pg->addr); + free(pg); +} + +void *cfs_page_address(cfs_page_t *pg) +{ + return pg->addr; +} + +void *cfs_kmap(cfs_page_t *pg) +{ + return pg->addr; +} + +void cfs_kunmap(cfs_page_t *pg) +{ +} + +/* + * SLAB allocator + */ + +cfs_mem_cache_t * +cfs_mem_cache_create(const char *name, size_t objsize, size_t off, unsigned long flags) +{ + cfs_mem_cache_t *c; + + c = malloc(sizeof(*c)); + if (!c) + return NULL; + c->size = objsize; + CDEBUG(D_MALLOC, "alloc slab cache %s at %p, objsize %d\n", + name, c, (int)objsize); + return c; +} + +int cfs_mem_cache_destroy(cfs_mem_cache_t *c) +{ + CDEBUG(D_MALLOC, "destroy slab cache %p, objsize %u\n", c, c->size); + free(c); + return 0; +} + +void *cfs_mem_cache_alloc(cfs_mem_cache_t *c, int gfp) +{ + return cfs_alloc(c->size, gfp); +} + +void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr) +{ + cfs_free(addr); +} + + diff --git a/libcfs/libcfs/user-prim.c b/libcfs/libcfs/user-prim.c index 2067c40..c6005a9 100644 --- a/libcfs/libcfs/user-prim.c +++ b/libcfs/libcfs/user-prim.c @@ -48,29 +48,8 @@ #include -#include -#ifndef __CYGWIN__ -#include -#ifdef HAVE_ASM_PAGE_H -#include -#endif -#ifdef HAVE_SYS_USER_H -#include -#endif -#else -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_VFS_H -#include -#endif - /* - * Sleep channel. No-op implementation. + * Wait queue. No-op implementation. */ void cfs_waitq_init(struct cfs_waitq *waitq) @@ -101,14 +80,6 @@ void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, struct cfs_waitlink *link) (void)link; } -void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq) -{ - LASSERT(waitq != NULL); - LASSERT(link != NULL); - (void)waitq; - (void)link; -} - void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link) { LASSERT(waitq != NULL); @@ -142,19 +113,85 @@ void cfs_waitq_broadcast(struct cfs_waitq *waitq) (void)waitq; } -void cfs_waitq_wait(struct cfs_waitlink *link, int state) +void cfs_waitq_wait(struct cfs_waitlink *link, cfs_task_state_t state) { LASSERT(link != NULL); (void)link; } -int64_t cfs_waitq_timedwait(struct cfs_waitlink *link, int state, int64_t timeout) +int64_t cfs_waitq_timedwait(struct cfs_waitlink *link, cfs_task_state_t state, + int64_t timeout) { LASSERT(link != NULL); (void)link; return 0; } +void cfs_schedule_timeout(cfs_task_state_t state, int64_t timeout) +{ + cfs_waitlink_t l; + /* sleep(timeout) here instead? */ + cfs_waitq_timedwait(&l, state, timeout); +} + +void +cfs_pause(cfs_duration_t d) +{ + struct timespec s; + + cfs_duration_nsec(d, &s); + nanosleep(&s, NULL); +} + +/* + * Timer + */ + +void cfs_init_timer(cfs_timer_t *t) +{ + CFS_INIT_LIST_HEAD(&t->tl_list); +} + +void cfs_timer_init(cfs_timer_t *l, cfs_timer_func_t *func, void *arg) +{ + CFS_INIT_LIST_HEAD(&l->tl_list); + l->function = func; + l->data = (unsigned long)arg; + return; +} + +#define cfs_jiffies \ +({ \ + unsigned long _ret = 0; \ + struct timeval tv; \ + if (gettimeofday(&tv, NULL) == 0) \ + _ret = tv.tv_sec; \ + _ret; \ +}) + +int cfs_timer_is_armed(cfs_timer_t *l) +{ + if (cfs_time_before(cfs_jiffies, l->expires)) + return 1; + else + return 0; +} + +void cfs_timer_arm(cfs_timer_t *l, cfs_time_t deadline) +{ + l->expires = deadline; +} + +void cfs_timer_disarm(cfs_timer_t *l) +{ +} + +long cfs_timer_deadline(cfs_timer_t *l) +{ + return l->expires; +} + + #ifdef HAVE_LIBPTHREAD /* @@ -218,79 +255,6 @@ int cfs_parse_int_tunable(int *value, char *name) return -EINVAL; } -/* - * Allocator - */ - -cfs_page_t *cfs_alloc_page(unsigned int flags) -{ - cfs_page_t *pg = malloc(sizeof(*pg)); - - if (!pg) - return NULL; - pg->addr = malloc(CFS_PAGE_SIZE); - - if (!pg->addr) { - free(pg); - return NULL; - } - return pg; -} - -void cfs_free_page(cfs_page_t *pg) -{ - free(pg->addr); - free(pg); -} - -void *cfs_page_address(cfs_page_t *pg) -{ - return pg->addr; -} - -void *cfs_kmap(cfs_page_t *pg) -{ - return pg->addr; -} - -void cfs_kunmap(cfs_page_t *pg) -{ -} - -/* - * SLAB allocator - */ - -cfs_mem_cache_t * -cfs_mem_cache_create(const char *name, size_t objsize, size_t off, unsigned long flags) -{ - cfs_mem_cache_t *c; - - c = malloc(sizeof(*c)); - if (!c) - return NULL; - c->size = objsize; - CDEBUG(D_MALLOC, "alloc slab cache %s at %p, objsize %d\n", - name, c, (int)objsize); - return c; -} - -int cfs_mem_cache_destroy(cfs_mem_cache_t *c) -{ - CDEBUG(D_MALLOC, "destroy slab cache %p, objsize %u\n", c, c->size); - free(c); - return 0; -} - -void *cfs_mem_cache_alloc(cfs_mem_cache_t *c, int gfp) -{ - return cfs_alloc(c->size, gfp); -} - -void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr) -{ - cfs_free(addr); -} void cfs_enter_debugger(void) { @@ -369,12 +333,12 @@ void cfs_clear_sigpending(void) void cfs_stack_trace_fill(struct cfs_stack_trace *trace) { - backtrace(trace->frame, sizeof_array(trace->frame)); + backtrace(trace->frame, ARRAY_SIZE(trace->frame)); } void *cfs_stack_trace_frame(struct cfs_stack_trace *trace, int frame_no) { - if (0 <= frame_no && frame_no < sizeof_array(trace->frame)) + if (0 <= frame_no && frame_no < ARRAY_SIZE(trace->frame)) return trace->frame[frame_no]; else return NULL; diff --git a/libcfs/libcfs/user-tcpip.c b/libcfs/libcfs/user-tcpip.c index ed0206b..945adb0 100644 --- a/libcfs/libcfs/user-tcpip.c +++ b/libcfs/libcfs/user-tcpip.c @@ -51,6 +51,7 @@ #include #include #include +#include #if defined(__sun__) || defined(__sun) #include #endif diff --git a/libcfs/libcfs/util/.cvsignore b/libcfs/libcfs/util/.cvsignore new file mode 100644 index 0000000..2bc4137 --- /dev/null +++ b/libcfs/libcfs/util/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +*.o.cmd diff --git a/libcfs/libcfs/util/Makefile.am b/libcfs/libcfs/util/Makefile.am new file mode 100644 index 0000000..7c00676 --- /dev/null +++ b/libcfs/libcfs/util/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST := parser.c l_ioctl.c + diff --git a/libcfs/libcfs/util/l_ioctl.c b/libcfs/libcfs/util/l_ioctl.c new file mode 100644 index 0000000..09cd171 --- /dev/null +++ b/libcfs/libcfs/util/l_ioctl.c @@ -0,0 +1,391 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (C) 2001, 2002 Cluster File Systems, Inc. + * + * This file is part of Portals, http://www.sf.net/projects/lustre/ + * + * Portals is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Portals 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Portals; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define __USE_FILE_OFFSET64 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include +#include + + +static ioc_handler_t do_ioctl; /* forward ref */ +static ioc_handler_t *current_ioc_handler = &do_ioctl; + +struct ioc_dev { + const char * dev_name; + int dev_fd; + int dev_major; + int dev_minor; +}; + +static struct ioc_dev ioc_dev_list[10]; + +struct dump_hdr { + int magic; + int dev_id; + unsigned int opc; +}; + +char *dump_filename; + +void +set_ioc_handler (ioc_handler_t *handler) +{ + if (handler == NULL) + current_ioc_handler = do_ioctl; + else + current_ioc_handler = handler; +} + +/* Catamount has no , so just define it here */ +#ifndef MKDEV +# define MKDEV(a,b) (((a) << 8) | (b)) +#endif + +static int +open_ioc_dev(int dev_id) +{ + const char * dev_name; + + if (dev_id < 0 || + dev_id >= sizeof(ioc_dev_list) / sizeof(ioc_dev_list[0])) + return -EINVAL; + + dev_name = ioc_dev_list[dev_id].dev_name; + if (dev_name == NULL) { + fprintf(stderr, "unknown device id: %d\n", dev_id); + return -EINVAL; + } + + if (ioc_dev_list[dev_id].dev_fd < 0) { + int fd = open(dev_name, O_RDWR); + + /* Make the /dev/ node if we need to */ + if (fd < 0 && errno == ENOENT) { + if (mknod(dev_name, + S_IFCHR|S_IWUSR|S_IRUSR, + MKDEV(ioc_dev_list[dev_id].dev_major, + ioc_dev_list[dev_id].dev_minor)) == 0) + fd = open(dev_name, O_RDWR); + else + fprintf(stderr, "mknod %s failed: %s\n", + dev_name, strerror(errno)); + } + + if (fd < 0) { + fprintf(stderr, "opening %s failed: %s\n" + "hint: the kernel modules may not be loaded\n", + dev_name, strerror(errno)); + return fd; + } + ioc_dev_list[dev_id].dev_fd = fd; + } + + return ioc_dev_list[dev_id].dev_fd; +} + + +static int +do_ioctl(int dev_id, unsigned int opc, void *buf) +{ + int fd, rc; + + fd = open_ioc_dev(dev_id); + if (fd < 0) + return fd; + + rc = ioctl(fd, opc, buf); + return rc; + +} + +static FILE * +get_dump_file() +{ + FILE *fp = NULL; + + if (!dump_filename) { + fprintf(stderr, "no dump filename\n"); + } else + fp = fopen(dump_filename, "a"); + return fp; +} + +/* + * The dump file should start with a description of which devices are + * used, but for now it will assumed whatever app reads the file will + * know what to do. */ +int +dump(int dev_id, unsigned int opc, void *buf) +{ + FILE *fp; + struct dump_hdr dump_hdr; + struct libcfs_ioctl_hdr * ioc_hdr = (struct libcfs_ioctl_hdr *) buf; + int rc; + + printf("dumping opc %x to %s\n", opc, dump_filename); + + + dump_hdr.magic = 0xdeadbeef; + dump_hdr.dev_id = dev_id; + dump_hdr.opc = opc; + + fp = get_dump_file(); + if (fp == NULL) { + fprintf(stderr, "%s: %s\n", dump_filename, + strerror(errno)); + return -EINVAL; + } + + rc = fwrite(&dump_hdr, sizeof(dump_hdr), 1, fp); + if (rc == 1) + rc = fwrite(buf, ioc_hdr->ioc_len, 1, fp); + fclose(fp); + if (rc != 1) { + fprintf(stderr, "%s: %s\n", dump_filename, + strerror(errno)); + return -EINVAL; + } + + return 0; +} + +/* register a device to send ioctls to. */ +int +register_ioc_dev(int dev_id, const char * dev_name, int major, int minor) +{ + + if (dev_id < 0 || + dev_id >= sizeof(ioc_dev_list) / sizeof(ioc_dev_list[0])) + return -EINVAL; + + unregister_ioc_dev(dev_id); + + ioc_dev_list[dev_id].dev_name = dev_name; + ioc_dev_list[dev_id].dev_fd = -1; + ioc_dev_list[dev_id].dev_major = major; + ioc_dev_list[dev_id].dev_minor = minor; + + return dev_id; +} + +void +unregister_ioc_dev(int dev_id) +{ + + if (dev_id < 0 || + dev_id >= sizeof(ioc_dev_list) / sizeof(ioc_dev_list[0])) + return; + if (ioc_dev_list[dev_id].dev_name != NULL && + ioc_dev_list[dev_id].dev_fd >= 0) + close(ioc_dev_list[dev_id].dev_fd); + + ioc_dev_list[dev_id].dev_name = NULL; + ioc_dev_list[dev_id].dev_fd = -1; +} + +/* If this file is set, then all ioctl buffers will be + appended to the file. */ +int +set_ioctl_dump(char * file) +{ + if (dump_filename) + free(dump_filename); + + dump_filename = strdup(file); + if (dump_filename == NULL) + abort(); + + set_ioc_handler(&dump); + return 0; +} + +int +l_ioctl(int dev_id, unsigned int opc, void *buf) +{ + return current_ioc_handler(dev_id, opc, buf); +} + +/* Read an ioctl dump file, and call the ioc_func for each ioctl buffer + * in the file. For example: + * + * parse_dump("lctl.dump", l_ioctl); + * + * Note: if using l_ioctl, then you also need to register_ioc_dev() for + * each device used in the dump. + */ +int +parse_dump(char * dump_file, ioc_handler_t ioc_func) +{ + int line =0; + struct stat st; + char *start, *buf, *end; +#ifndef __CYGWIN__ + int fd; +#else + HANDLE fd, hmap; + DWORD size; +#endif + +#ifndef __CYGWIN__ + fd = syscall(SYS_open, dump_file, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "couldn't open %s: %s\n", dump_file, + strerror(errno)); + exit(1); + } + + if (fstat(fd, &st)) { + perror("stat fails"); + exit(1); + } + + if (st.st_size < 1) { + fprintf(stderr, "KML is empty\n"); + exit(1); + } + + start = buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE , fd, 0); + end = start + st.st_size; + close(fd); + if (start == MAP_FAILED) { + fprintf(stderr, "can't create file mapping\n"); + exit(1); + } +#else + fd = CreateFile(dump_file, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + size = GetFileSize(fd, NULL); + if (size < 1) { + fprintf(stderr, "KML is empty\n"); + exit(1); + } + + hmap = CreateFileMapping(fd, NULL, PAGE_READONLY, 0,0, NULL); + start = buf = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0); + end = buf + size; + CloseHandle(fd); + if (start == NULL) { + fprintf(stderr, "can't create file mapping\n"); + exit(1); + } +#endif /* __CYGWIN__ */ + + while (buf < end) { + struct dump_hdr *dump_hdr = (struct dump_hdr *) buf; + struct libcfs_ioctl_hdr * data; + char tmp[8096]; + int rc; + + line++; + + data = (struct libcfs_ioctl_hdr *) (buf + sizeof(*dump_hdr)); + if (buf + data->ioc_len > end ) { + fprintf(stderr, "dump file overflow, %p + %d > %p\n", buf, + data->ioc_len, end); + return -1; + } +#if 0 + printf ("dump_hdr: %lx data: %lx\n", + (unsigned long)dump_hdr - (unsigned long)buf, (unsigned long)data - (unsigned long)buf); + + printf("%d: opcode %x len: %d ver: %x ", line, dump_hdr->opc, + data->ioc_len, data->ioc_version); +#endif + + memcpy(tmp, data, data->ioc_len); + + rc = ioc_func(dump_hdr->dev_id, dump_hdr->opc, tmp); + if (rc) { + printf("failed: %d\n", rc); + exit(1); + } + + buf += data->ioc_len + sizeof(*dump_hdr); + } + +#ifndef __CYGWIN__ + munmap(start, end - start); +#else + UnmapViewOfFile(start); + CloseHandle(hmap); +#endif + + return 0; +} + +int +jt_ioc_dump(int argc, char **argv) +{ + if (argc > 2) { + fprintf(stderr, "usage: %s [hostname]\n", argv[0]); + return 0; + } + printf("setting dumpfile to: %s\n", argv[1]); + + set_ioctl_dump(argv[1]); + return 0; +} + +int libcfs_ioctl_pack(struct libcfs_ioctl_data *data, char **pbuf, + int max) +{ + char *ptr; + struct libcfs_ioctl_data *overlay; + data->ioc_len = libcfs_ioctl_packlen(data); + data->ioc_version = LIBCFS_IOCTL_VERSION; + + if (*pbuf && libcfs_ioctl_packlen(data) > max) + return 1; + if (*pbuf == NULL) { + *pbuf = malloc(data->ioc_len); + } + if (!*pbuf) + return 1; + overlay = (struct libcfs_ioctl_data *)*pbuf; + memcpy(*pbuf, data, sizeof(*data)); + + ptr = overlay->ioc_bulk; + if (data->ioc_inlbuf1) + LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr); + if (data->ioc_inlbuf2) + LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr); + if (libcfs_ioctl_is_invalid(overlay)) + return 1; + + return 0; +} + diff --git a/libcfs/libcfs/util/parser.c b/libcfs/libcfs/util/parser.c new file mode 100644 index 0000000..ce2a99e --- /dev/null +++ b/libcfs/libcfs/util/parser.c @@ -0,0 +1,771 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (C) 2001 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.sf.net/projects/lustre/ + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static command_t * top_level; /* Top level of commands, initialized by + * InitParser */ +static char * parser_prompt = NULL;/* Parser prompt, set by InitParser */ +static int done; /* Set to 1 if user types exit or quit */ +static int ignore_errors; /* Normally, the parser will quit when + an error occurs in non-interacive + mode. Setting this to non-zero will + force it to keep buggering on. */ + + +/* static functions */ +static char *skipwhitespace(char *s); +static char *skiptowhitespace(char *s); +static command_t *find_cmd(char *name, command_t cmds[], char **next); +static int process(char *s, char **next, command_t *lookup, command_t **result, + char **prev); +static void print_commands(char *str, command_t *table); + +static char * skipwhitespace(char * s) +{ + char * t; + int len; + + len = (int)strlen(s); + for (t = s; t <= s + len && isspace(*t); t++); + return(t); +} + + +static char * skiptowhitespace(char * s) +{ + char * t; + + for (t = s; *t && !isspace(*t); t++); + return(t); +} + +static int line2args(char *line, char **argv, int maxargs) +{ + char *arg; + int i = 0; + + arg = strtok(line, " \t"); + if ( arg ) { + argv[i] = arg; + i++; + } else + return 0; + + while( (arg = strtok(NULL, " \t")) && (i <= maxargs)) { + argv[i] = arg; + i++; + } + return i; +} + +/* find a command -- return it if unique otherwise print alternatives */ +static command_t *Parser_findargcmd(char *name, command_t cmds[]) +{ + command_t *cmd; + + for (cmd = cmds; cmd->pc_name; cmd++) { + if (strcmp(name, cmd->pc_name) == 0) + return cmd; + } + return NULL; +} + +void Parser_ignore_errors(int ignore) +{ + ignore_errors = ignore; +} + +int Parser_execarg(int argc, char **argv, command_t cmds[]) +{ + command_t *cmd; + + cmd = Parser_findargcmd(argv[0], cmds); + if ( cmd ) { + int rc = (cmd->pc_func)(argc, argv); + if (rc == CMD_HELP) + fprintf(stderr, "%s\n", cmd->pc_help); + return rc; + } else { + printf("Try interactive use without arguments or use one of:\n"); + for (cmd = cmds; cmd->pc_name; cmd++) + printf("\"%s\"\n", cmd->pc_name); + printf("as argument.\n"); + } + return -1; +} + +/* returns the command_t * (NULL if not found) corresponding to a + _partial_ match with the first token in name. It sets *next to + point to the following token. Does not modify *name. */ +static command_t * find_cmd(char * name, command_t cmds[], char ** next) +{ + int i, len; + + if (!cmds || !name ) + return NULL; + + /* This sets name to point to the first non-white space character, + and next to the first whitespace after name, len to the length: do + this with strtok*/ + name = skipwhitespace(name); + *next = skiptowhitespace(name); + len = *next - name; + if (len == 0) + return NULL; + + for (i = 0; cmds[i].pc_name; i++) { + if (strncasecmp(name, cmds[i].pc_name, len) == 0) { + *next = skipwhitespace(*next); + return(&cmds[i]); + } + } + return NULL; +} + +/* Recursively process a command line string s and find the command + corresponding to it. This can be ambiguous, full, incomplete, + non-existent. */ +static int process(char *s, char ** next, command_t *lookup, + command_t **result, char **prev) +{ + *result = find_cmd(s, lookup, next); + *prev = s; + + /* non existent */ + if (!*result) + return CMD_NONE; + + /* found entry: is it ambigous, i.e. not exact command name and + more than one command in the list matches. Note that find_cmd + points to the first ambiguous entry */ + if (strncasecmp(s, (*result)->pc_name, strlen((*result)->pc_name))) { + char *another_next; + command_t *another_result = find_cmd(s, (*result) + 1, + &another_next); + int found_another = 0; + + while (another_result) { + if (strncasecmp(s, another_result->pc_name, + strlen(another_result->pc_name)) == 0){ + *result = another_result; + *next = another_next; + goto got_it; + } + another_result = find_cmd(s, another_result + 1, + &another_next); + found_another = 1; + } + if (found_another) + return CMD_AMBIG; + } + +got_it: + /* found a unique command: component or full? */ + if ( (*result)->pc_func ) { + return CMD_COMPLETE; + } else { + if ( *next == '\0' ) { + return CMD_INCOMPLETE; + } else { + return process(*next, next, (*result)->pc_sub_cmd, + result, prev); + } + } +} + +#ifdef HAVE_LIBREADLINE +static command_t * match_tbl; /* Command completion against this table */ +static char * command_generator(const char * text, int state) +{ + static int index, + len; + char *name; + + /* Do we have a match table? */ + if (!match_tbl) + return NULL; + + /* If this is the first time called on this word, state is 0 */ + if (!state) { + index = 0; + len = (int)strlen(text); + } + + /* Return next name in the command list that paritally matches test */ + while ( (name = (match_tbl + index)->pc_name) ) { + index++; + + if (strncasecmp(name, text, len) == 0) { + return(strdup(name)); + } + } + + /* No more matches */ + return NULL; +} + +/* probably called by readline */ +static char **command_completion(char * text, int start, int end) +{ + command_t * table; + char * pos; + + match_tbl = top_level; + + for (table = find_cmd(rl_line_buffer, match_tbl, &pos); + table; table = find_cmd(pos, match_tbl, &pos)) + { + + if (*(pos - 1) == ' ') match_tbl = table->pc_sub_cmd; + } + + return completion_matches(text, command_generator); +} +#endif + +/* take a string and execute the function or print help */ +int execute_line(char * line) +{ + command_t *cmd, *ambig; + char *prev; + char *next, *tmp; + char *argv[MAXARGS]; + int i; + int rc = 0; + + switch (process(line, &next, top_level, &cmd, &prev)) { + case CMD_AMBIG: + fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line); + while( (ambig = find_cmd(prev, cmd, &tmp)) ) { + fprintf(stderr, "%s ", ambig->pc_name); + cmd = ambig + 1; + } + fprintf(stderr, "\n"); + break; + case CMD_NONE: + fprintf(stderr, "No such command, type help\n"); + break; + case CMD_INCOMPLETE: + fprintf(stderr, + "'%s' incomplete command. Use '%s x' where x is one of:\n", + line, line); + fprintf(stderr, "\t"); + for (i = 0; cmd->pc_sub_cmd[i].pc_name; i++) { + fprintf(stderr, "%s ", cmd->pc_sub_cmd[i].pc_name); + } + fprintf(stderr, "\n"); + break; + case CMD_COMPLETE: + i = line2args(line, argv, MAXARGS); + rc = (cmd->pc_func)(i, argv); + + if (rc == CMD_HELP) + fprintf(stderr, "%s\n", cmd->pc_help); + + break; + } + + return rc; +} + +int +noop_fn () +{ + return (0); +} + +/* just in case you're ever in an airplane and discover you + forgot to install readline-dev. :) */ +int init_input() +{ + int interactive = isatty (fileno (stdin)); + +#ifdef HAVE_LIBREADLINE + using_history(); + stifle_history(HISTORY); + + if (!interactive) + { + rl_prep_term_function = (rl_vintfunc_t *)noop_fn; + rl_deprep_term_function = (rl_voidfunc_t *)noop_fn; + } + + rl_attempted_completion_function = (CPPFunction *)command_completion; + rl_completion_entry_function = (void *)command_generator; +#endif + return interactive; +} + +#ifndef HAVE_LIBREADLINE +#define add_history(s) +char * readline(char * prompt) +{ + int size = 2048; + char *line = malloc(size); + char *ptr = line; + int c; + int eof = 0; + + if (line == NULL) + return NULL; + if (prompt) + printf ("%s", prompt); + + while (1) { + if ((c = fgetc(stdin)) != EOF) { + if (c == '\n') + goto out; + *ptr++ = c; + + if (ptr - line >= size - 1) { + char *tmp; + + size *= 2; + tmp = malloc(size); + if (tmp == NULL) + goto outfree; + memcpy(tmp, line, ptr - line); + ptr = tmp + (ptr - line); + free(line); + line = tmp; + } + } else { + eof = 1; + if (ferror(stdin) || feof(stdin)) + goto outfree; + goto out; + } + } +out: + *ptr = 0; + if (eof && (strlen(line) == 0)) { + free(line); + line = NULL; + } + return line; +outfree: + free(line); + return NULL; +} +#endif + +/* this is the command execution machine */ +int Parser_commands(void) +{ + char *line, *s; + int rc = 0, save_error = 0; + int interactive; + + interactive = init_input(); + + while(!done) { + line = readline(interactive ? parser_prompt : NULL); + + if (!line) break; + + s = skipwhitespace(line); + + if (*s) { + add_history(s); + rc = execute_line(s); + } + /* stop on error if not-interactive */ + if (rc != 0 && !interactive) { + if (save_error == 0) + save_error = rc; + if (!ignore_errors) + done = 1; + } + + free(line); + } + if (save_error) + rc = save_error; + return rc; +} + + +/* sets the parser prompt */ +void Parser_init(char * prompt, command_t * cmds) +{ + done = 0; + top_level = cmds; + if (parser_prompt) free(parser_prompt); + parser_prompt = strdup(prompt); +} + +/* frees the parser prompt */ +void Parser_exit(int argc, char *argv[]) +{ + done = 1; + free(parser_prompt); + parser_prompt = NULL; +} + +/* convert a string to an integer */ +int Parser_int(char *s, int *val) +{ + int ret; + + if (*s != '0') + ret = sscanf(s, "%d", val); + else if (*(s+1) != 'x') + ret = sscanf(s, "%o", val); + else { + s++; + ret = sscanf(++s, "%x", val); + } + + return(ret); +} + + +void Parser_qhelp(int argc, char *argv[]) { + + printf("Available commands are:\n"); + + print_commands(NULL, top_level); + printf("For more help type: help command-name\n"); +} + +int Parser_help(int argc, char **argv) +{ + char line[1024]; + char *next, *prev, *tmp; + command_t *result, *ambig; + int i; + + if ( argc == 1 ) { + Parser_qhelp(argc, argv); + return 0; + } + + line[0]='\0'; + for ( i = 1 ; i < argc ; i++ ) { + strcat(line, argv[i]); + } + + switch ( process(line, &next, top_level, &result, &prev) ) { + case CMD_COMPLETE: + fprintf(stderr, "%s: %s\n",line, result->pc_help); + break; + case CMD_NONE: + fprintf(stderr, "%s: Unknown command.\n", line); + break; + case CMD_INCOMPLETE: + fprintf(stderr, + "'%s' incomplete command. Use '%s x' where x is one of:\n", + line, line); + fprintf(stderr, "\t"); + for (i = 0; result->pc_sub_cmd[i].pc_name; i++) { + fprintf(stderr, "%s ", result->pc_sub_cmd[i].pc_name); + } + fprintf(stderr, "\n"); + break; + case CMD_AMBIG: + fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line); + while( (ambig = find_cmd(prev, result, &tmp)) ) { + fprintf(stderr, "%s ", ambig->pc_name); + result = ambig + 1; + } + fprintf(stderr, "\n"); + break; + } + return 0; +} + + +void Parser_printhelp(char *cmd) +{ + char *argv[] = { "help", cmd }; + Parser_help(2, argv); +} + + +/************************************************************************* + * COMMANDS * + *************************************************************************/ +static void print_commands(char * str, command_t * table) { + command_t * cmds; + char buf[80]; + + for (cmds = table; cmds->pc_name; cmds++) { + if (cmds->pc_func) { + if (str) printf("\t%s %s\n", str, cmds->pc_name); + else printf("\t%s\n", cmds->pc_name); + } + if (cmds->pc_sub_cmd) { + if (str) { + sprintf(buf, "%s %s", str, cmds->pc_name); + print_commands(buf, cmds->pc_sub_cmd); + } else { + print_commands(cmds->pc_name, cmds->pc_sub_cmd); + } + } + } +} + +char *Parser_getstr(const char *prompt, const char *deft, char *res, + size_t len) +{ + char *line = NULL; + int size = strlen(prompt) + strlen(deft) + 8; + char *theprompt; + theprompt = malloc(size); + assert(theprompt); + + sprintf(theprompt, "%s [%s]: ", prompt, deft); + + line = readline(theprompt); + free(theprompt); + + if ( line == NULL || *line == '\0' ) { + strncpy(res, deft, len); + } else { + strncpy(res, line, len); + } + + if ( line ) { + free(line); + return res; + } else { + return NULL; + } +} + +/* get integer from prompt, loop forever to get it */ +int Parser_getint(const char *prompt, long min, long max, long deft, int base) +{ + int rc; + long result; + char *line; + int size = strlen(prompt) + 40; + char *theprompt = malloc(size); + assert(theprompt); + sprintf(theprompt,"%s [%ld, (0x%lx)]: ", prompt, deft, deft); + + fflush(stdout); + + do { + line = NULL; + line = readline(theprompt); + if ( !line ) { + fprintf(stdout, "Please enter an integer.\n"); + fflush(stdout); + continue; + } + if ( *line == '\0' ) { + free(line); + result = deft; + break; + } + rc = Parser_arg2int(line, &result, base); + free(line); + if ( rc != 0 ) { + fprintf(stdout, "Invalid string.\n"); + fflush(stdout); + } else if ( result > max || result < min ) { + fprintf(stdout, "Error: response must lie between %ld and %ld.\n", + min, max); + fflush(stdout); + } else { + break; + } + } while ( 1 ) ; + + if (theprompt) + free(theprompt); + return result; + +} + +/* get boolean (starting with YyNn; loop forever */ +int Parser_getbool(const char *prompt, int deft) +{ + int result = 0; + char *line; + int size = strlen(prompt) + 8; + char *theprompt = malloc(size); + assert(theprompt); + + fflush(stdout); + + if ( deft != 0 && deft != 1 ) { + fprintf(stderr, "Error: Parser_getbool given bad default %d\n", + deft); + assert ( 0 ); + } + sprintf(theprompt, "%s [%s]: ", prompt, (deft==0)? "N" : "Y"); + + do { + line = NULL; + line = readline(theprompt); + if ( line == NULL ) { + result = deft; + break; + } + if ( *line == '\0' ) { + result = deft; + break; + } + if ( *line == 'y' || *line == 'Y' ) { + result = 1; + break; + } + if ( *line == 'n' || *line == 'N' ) { + result = 0; + break; + } + if ( line ) + free(line); + fprintf(stdout, "Invalid string. Must start with yY or nN\n"); + fflush(stdout); + } while ( 1 ); + + if ( line ) + free(line); + if ( theprompt ) + free(theprompt); + return result; +} + +/* parse int out of a string or prompt for it */ +long Parser_intarg(const char *inp, const char *prompt, int deft, + int min, int max, int base) +{ + long result; + int rc; + + rc = Parser_arg2int(inp, &result, base); + + if ( rc == 0 ) { + return result; + } else { + return Parser_getint(prompt, deft, min, max, base); + } +} + +/* parse int out of a string or prompt for it */ +char *Parser_strarg(char *inp, const char *prompt, const char *deft, + char *answer, int len) +{ + if ( inp == NULL || *inp == '\0' ) { + return Parser_getstr(prompt, deft, answer, len); + } else + return inp; +} + +/* change a string into a number: return 0 on success. No invalid characters + allowed. The processing of base and validity follows strtol(3)*/ +int Parser_arg2int(const char *inp, long *result, int base) +{ + char *endptr; + + if ( (base !=0) && (base < 2 || base > 36) ) + return 1; + + *result = strtol(inp, &endptr, base); + + if ( *inp != '\0' && *endptr == '\0' ) + return 0; + else + return 1; +} + +/* Convert human readable size string to and int; "1k" -> 1000 */ +int Parser_size (int *sizep, char *str) { + int size; + char mod[32]; + + switch (sscanf (str, "%d%1[gGmMkK]", &size, mod)) { + default: + return (-1); + + case 1: + *sizep = size; + return (0); + + case 2: + switch (*mod) { + case 'g': + case 'G': + *sizep = size << 30; + return (0); + + case 'm': + case 'M': + *sizep = size << 20; + return (0); + + case 'k': + case 'K': + *sizep = size << 10; + return (0); + + default: + *sizep = size; + return (0); + } + } +} + +/* Convert a string boolean to an int; "enable" -> 1 */ +int Parser_bool (int *b, char *str) { + if (!strcasecmp (str, "no") || + !strcasecmp (str, "n") || + !strcasecmp (str, "off") || + !strcasecmp (str, "down") || + !strcasecmp (str, "disable")) + { + *b = 0; + return (0); + } + + if (!strcasecmp (str, "yes") || + !strcasecmp (str, "y") || + !strcasecmp (str, "on") || + !strcasecmp (str, "up") || + !strcasecmp (str, "enable")) + { + *b = 1; + return (0); + } + + return (-1); +} + +int Parser_quit(int argc, char **argv) +{ + argc = argc; + argv = argv; + done = 1; + return 0; +} diff --git a/libcfs/libcfs/winnt/winnt-sync.c b/libcfs/libcfs/winnt/winnt-sync.c index 87085e3..da0ac42 100644 --- a/libcfs/libcfs/winnt/winnt-sync.c +++ b/libcfs/libcfs/winnt/winnt-sync.c @@ -231,27 +231,6 @@ void cfs_waitq_add_exclusive( cfs_waitq_t *waitq, } /* - * cfs_waitq_forward - * To be determinated. - * - * Arguments: - * waitq: pointer to the cfs_waitq_t structure - * link: pointer to the cfs_waitlink_t structure - * - * Return Value: - * N/A - * - * Notes: - * N/A - */ - -void cfs_waitq_forward( cfs_waitlink_t *link, - cfs_waitq_t *waitq) -{ - cfs_waitq_add_internal(waitq, link, CFS_WAITQ_CHAN_FORWARD); -} - -/* * cfs_waitq_del * To remove the wait link node from the waitq * -- 1.8.3.1