From bf2e821a55d8aa3de1cda7288a0e22883110fdc6 Mon Sep 17 00:00:00 2001 From: Cigy Cyriac Date: Tue, 10 Aug 2010 19:51:11 -0400 Subject: [PATCH] Add support for AIX Signed-off-by: Jens Axboe --- Makefile.aix | 73 ++++++++++++++++++++++ README | 23 ++++++- fio.h | 2 +- init.c | 3 +- lib/getopt.h | 26 ++++++++ lib/getopt_long.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++ options.c | 1 - os/os-aix.h | 46 ++++++++++++++ os/os.h | 2 + 9 files changed, 324 insertions(+), 4 deletions(-) create mode 100644 Makefile.aix create mode 100644 lib/getopt.h create mode 100644 lib/getopt_long.c create mode 100644 os/os-aix.h diff --git a/Makefile.aix b/Makefile.aix new file mode 100644 index 00000000..29d6e099 --- /dev/null +++ b/Makefile.aix @@ -0,0 +1,73 @@ +CC = gcc +DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG +OPTFLAGS= -O2 -g $(EXTFLAGS) +CFLAGS = -Wwrite-strings -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(DEBUGFLAGS) -fno-omit-frame-pointer -D_LARGE_FILES -D__ppc__ +PROGS = fio +SCRIPTS = fio_generate_plots +OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ + eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \ + rbtree.o fifo.o smalloc.o filehash.o helpers.o \ + profile.o debug.o getopt_long.o + +OBJS += lib/rand.o +OBJS += lib/getopt_long.o + +OBJS += crc/crc7.o +OBJS += crc/crc16.o +OBJS += crc/crc32.o +OBJS += crc/crc32c.o +OBJS += crc/crc32c-intel.o +OBJS += crc/crc64.o +OBJS += crc/sha1.o +OBJS += crc/sha256.o +OBJS += crc/sha512.o +OBJS += crc/md5.o + +OBJS += engines/cpu.o +OBJS += engines/mmap.o +OBJS += engines/posixaio.o +OBJS += engines/sync.o +OBJS += engines/null.o +OBJS += engines/net.o + +OBJS += profiles/tiobench.o + +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + QUIET_CC = @echo ' ' CC $@; + QUIET_DEP = @echo ' ' DEP $@; +endif +endif + +INSTALL = installbsd -c +prefix = /usr/local +bindir = $(prefix)/bin +mandir = $(prefix)/man + +%.o: %.c + $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $< +fio: $(OBJS) + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(EXTLIBS) -lpthread -lm -ldl -lrt + +depend: + $(QUIET_DEP)$(CC) -MM $(ALL_CFLAGS) *.c engines/*.c crc/*.c 1> .depend + +$(PROGS): depend + +all: depend $(PROGS) $(SCRIPTS) + +clean: + -rm -f .depend cscope.out $(OBJS) $(PROGS) core.* core + +cscope: + @cscope -b + +install: $(PROGS) $(SCRIPTS) + mkdir -p -m 755 $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1 + $(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir) + $(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1 + $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1 + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/README b/README index f2438bad..41154552 100644 --- a/README +++ b/README @@ -65,6 +65,10 @@ specify the FreeBSD Makefile with -f and use gmake (not make), eg: $ gmake -f Makefile.Freebsd && gmake -f Makefile.FreeBSD install +Same goes for AIX: + +$ gmake -f Makefile.aix && gmake -f Makefile.aix install + Likewise with OpenSolaris, use the Makefile.solaris to compile there. The OpenSolaris make should work fine. This might change in the future if I opt for an autoconf type setup. @@ -270,7 +274,7 @@ The job file parameters are: Platforms --------- -Fio works on (at least) Linux, Solaris, and FreeBSD. Some features and/or +Fio works on (at least) Linux, Solaris, AIX and FreeBSD. Some features and/or options may only be available on some of the platforms, typically because those features only apply to that platform (like the solarisaio engine, or the splice engine on Linux). @@ -291,6 +295,23 @@ your mileage may vary. Sending me patches for other platforms is greatly appreciated. There's a lot of value in having the same test/benchmark tool available on all platforms. +Note that POSIX aio is not enabled by default on AIX. If you get messages like: + + Symbol resolution failed for /usr/lib/libc.a(posix_aio.o) because: + Symbol _posix_kaio_rdwr (number 2) is not exported from dependent module /unix. + +you need to enable POSIX aio. Run the following commands as root: + + # lsdev -C -l posix_aio0 + posix_aio0 Defined Posix Asynchronous I/O + # cfgmgr -l posix_aio0 + # lsdev -C -l posix_aio0 + posix_aio0 Available Posix Asynchronous I/O + +POSIX aio should work now. To make the change permanent: + + # chdev -l posix_aio0 -P -a autoconfig='available' + posix_aio0 changed Author diff --git a/fio.h b/fio.h index de76e659..57881072 100644 --- a/fio.h +++ b/fio.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -32,6 +31,7 @@ #include "options.h" #include "profile.h" #include "time.h" +#include "lib/getopt.h" #ifdef FIO_HAVE_GUASI #include diff --git a/init.c b/init.c index 09b9152a..c3fe88f6 100644 --- a/init.c +++ b/init.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -21,6 +20,8 @@ #include "verify.h" #include "profile.h" +#include "lib/getopt.h" + static char fio_version_string[] = "fio 1.42"; #define FIO_RANDSEED (0xb1899bedUL) diff --git a/lib/getopt.h b/lib/getopt.h new file mode 100644 index 00000000..56fe3bf4 --- /dev/null +++ b/lib/getopt.h @@ -0,0 +1,26 @@ +#ifndef _AIX + +#include + +#else /* _AIX */ + +#ifndef _GETOPT_H +#define _GETOPT_H + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +enum { + no_argument = 0, + required_argument = 1, + optional_argument = 2, +}; + +int getopt_long_only(int, char *const *, const char *, const struct option *, int *); + +#endif /* _GETOPT_H */ +#endif /* _AIX */ diff --git a/lib/getopt_long.c b/lib/getopt_long.c new file mode 100644 index 00000000..3d80627f --- /dev/null +++ b/lib/getopt_long.c @@ -0,0 +1,152 @@ +/* + * getopt.c + * + * getopt_long(), or at least a common subset thereof: + * + * - Option reordering is not supported + * - -W foo is not supported + * - First optstring character "-" not supported. + */ + +#include +#include +#include +#include + +char *optarg; +int optind, opterr, optopt; +static struct getopt_private_state { + const char *optptr; + const char *last_optstring; + char *const *last_argv; +} pvt; + +static inline const char *option_matches(const char *arg_str, + const char *opt_name) +{ + while (*arg_str != '\0' && *arg_str != '=') { + if (*arg_str++ != *opt_name++) + return NULL; + } + + if (*opt_name) + return NULL; + + return arg_str; +} + +int getopt_long_only(int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longindex) +{ + const char *carg; + const char *osptr; + int opt; + + /* getopt() relies on a number of different global state + variables, which can make this really confusing if there is + more than one use of getopt() in the same program. This + attempts to detect that situation by detecting if the + "optstring" or "argv" argument have changed since last time + we were called; if so, reinitialize the query state. */ + + if (optstring != pvt.last_optstring || argv != pvt.last_argv || + optind < 1 || optind > argc) { + /* optind doesn't match the current query */ + pvt.last_optstring = optstring; + pvt.last_argv = argv; + optind = 1; + pvt.optptr = NULL; + } + + carg = argv[optind]; + + /* First, eliminate all non-option cases */ + + if (!carg || carg[0] != '-' || !carg[1]) + return -1; + + if (carg[1] == '-') { + const struct option *lo; + const char *opt_end = NULL; + + optind++; + + /* Either it's a long option, or it's -- */ + if (!carg[2]) { + /* It's -- */ + return -1; + } + + for (lo = longopts; lo->name; lo++) { + if ((opt_end = option_matches(carg+2, lo->name))) + break; + } + if (!opt_end) + return '?'; + + if (longindex) + *longindex = lo-longopts; + + if (*opt_end == '=') { + if (lo->has_arg) + optarg = (char *)opt_end+1; + else + return '?'; + } else if (lo->has_arg == 1) { + if (!(optarg = argv[optind])) + return '?'; + optind++; + } + + if (lo->flag) { + *lo->flag = lo->val; + return 0; + } else { + return lo->val; + } + } + + if ((uintptr_t) (pvt.optptr - carg) > (uintptr_t) strlen(carg)) { + /* Someone frobbed optind, change to new opt. */ + pvt.optptr = carg + 1; + } + + opt = *pvt.optptr++; + + if (opt != ':' && (osptr = strchr(optstring, opt))) { + if (osptr[1] == ':') { + if (*pvt.optptr) { + /* Argument-taking option with attached + argument */ + optarg = (char *)pvt.optptr; + optind++; + } else { + /* Argument-taking option with non-attached + argument */ + if (argv[optind + 1]) { + optarg = (char *)argv[optind+1]; + optind += 2; + } else { + /* Missing argument */ + optind++; + return (optstring[0] == ':') + ? ':' : '?'; + } + } + return opt; + } else { + /* Non-argument-taking option */ + /* pvt.optptr will remember the exact position to + resume at */ + if (!*pvt.optptr) + optind++; + return opt; + } + } else { + /* Unknown option */ + optopt = opt; + if (!*pvt.optptr) + optind++; + return '?'; + } +} diff --git a/options.c b/options.c index 6dd74ed4..7a9d5d39 100644 --- a/options.c +++ b/options.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include diff --git a/os/os-aix.h b/os/os-aix.h new file mode 100644 index 00000000..1cc35e86 --- /dev/null +++ b/os/os-aix.h @@ -0,0 +1,46 @@ +#ifndef FIO_OS_AIX_H +#define FIO_OS_AIX_H + +#include +#include +#include +#include + +#define FIO_HAVE_POSIXAIO +#define FIO_HAVE_FALLOCATE +#define FIO_HAVE_ODIRECT +#define FIO_USE_GENERIC_RAND + +#define FIO_HAVE_PSHARED_MUTEX + +#define OS_MAP_ANON MAP_ANON + +static inline int blockdev_invalidate_cache(int fd) +{ + return EINVAL; +} + +static inline int blockdev_size(int fd, unsigned long long *bytes) +{ + struct devinfo info; + + if (!ioctl(fd, IOCINFO, &info)) { + *bytes = (unsigned long long)info.un.scdk.numblks * + info.un.scdk.blksize; + return 0; + } + + return errno; +} + +static inline unsigned long long os_phys_mem(void) +{ + long mem = sysconf(_SC_AIX_REALMEM); + + if (mem == -1) + return 0; + + return (unsigned long long) mem * 1024; +} + +#endif diff --git a/os/os.h b/os/os.h index 218766ab..e2bb0ba9 100644 --- a/os/os.h +++ b/os/os.h @@ -14,6 +14,8 @@ #include "os-solaris.h" #elif defined(__APPLE__) #include "os-mac.h" +#elif defined(_AIX) +#include "os-aix.h" #else #error "unsupported os" #endif -- 2.25.1