Add support for compiling for ESX
With contributions from Ryan Haynes <rhaynes@fusionio.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
diff --git a/README b/README
index f8aaef2..2be0bfd 100644
--- a/README
+++ b/README
@@ -101,6 +101,9 @@
$ make CROSS_COMPILE=/path/to/toolchain/prefix
Configure will attempt to determine the target platform automatically.
+It's possible to build fio for ESX as well, use the --esx switch to
+configure.
+
Windows
-------
diff --git a/backend.c b/backend.c
index 23fa345..ee75566 100644
--- a/backend.c
+++ b/backend.c
@@ -1575,7 +1575,7 @@
struct thread_data *td;
void *data, *ret;
-#ifndef __hpux
+#if !defined(__hpux) && !defined(CONFIG_NO_SHM)
data = shmat(shmid, NULL, 0);
if (data == (void *) -1) {
int __err = errno;
diff --git a/configure b/configure
index be63eb1..aa15c5b 100755
--- a/configure
+++ b/configure
@@ -141,6 +141,10 @@
case "$opt" in
--cpu=*) cpu="$optarg"
;;
+ # esx is cross compiled and cannot be detect through simple uname calls
+ --esx)
+ esx="yes"
+ ;;
--cc=*) CC="$optarg"
;;
--extra-cflags=*) CFLAGS="$CFLAGS $optarg"
@@ -167,6 +171,7 @@
echo "--cc= Specify compiler to use"
echo "--extra-cflags= Specify extra CFLAGS to pass to compiler"
echo "--build-32bit-win Enable 32-bit build on Windows"
+ echo "--esx Configure build options for esx"
echo "--enable-gfio Enable building of gtk gfio"
echo "--disable-numa Disable libnuma even if found"
exit $exit_val
@@ -1323,6 +1328,10 @@
if test "$gfio" = "yes" ; then
echo "CONFIG_GFIO=y" >> $config_host_mak
fi
+if test "$esx" = "yes" ; then
+ output_sym "CONFIG_ESX"
+ output_sym "CONFIG_NO_SHM"
+fi
if test "$sched_idle" = "yes" ; then
output_sym "CONFIG_SCHED_IDLE"
fi
diff --git a/filesetup.c b/filesetup.c
index 2049fd6..1facccd 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -390,6 +390,10 @@
{
int ret = 0;
+#ifdef CONFIG_ESX
+ return 0;
+#endif
+
if (len == -1ULL)
len = f->io_size;
if (off == -1ULL)
diff --git a/init.c b/init.c
index 74a02e0..d44eb5b 100644
--- a/init.c
+++ b/init.c
@@ -238,15 +238,19 @@
void free_threads_shm(void)
{
- struct shmid_ds sbuf;
-
if (threads) {
void *tp = threads;
+#ifndef CONFIG_NO_SHM
+ struct shmid_ds sbuf;
threads = NULL;
shmdt(tp);
shmctl(shm_id, IPC_RMID, &sbuf);
shm_id = -1;
+#else
+ threads = NULL;
+ free(tp);
+#endif
}
}
@@ -287,6 +291,7 @@
size += file_hash_size;
size += sizeof(unsigned int);
+#ifndef CONFIG_NO_SHM
shm_id = shmget(0, size, IPC_CREAT | 0600);
if (shm_id != -1)
break;
@@ -294,10 +299,16 @@
perror("shmget");
break;
}
+#else
+ threads = malloc(size);
+ if (threads)
+ break;
+#endif
max_jobs >>= 1;
} while (max_jobs);
+#ifndef CONFIG_NO_SHM
if (shm_id == -1)
return 1;
@@ -306,6 +317,7 @@
perror("shmat");
return 1;
}
+#endif
memset(threads, 0, max_jobs * sizeof(struct thread_data));
hash = (void *) threads + max_jobs * sizeof(struct thread_data);
@@ -1947,6 +1959,7 @@
break;
case 'S':
did_arg = 1;
+#ifndef CONFIG_NO_SHM
if (nr_clients) {
log_err("fio: can't be both client and server\n");
do_exit++;
@@ -1957,6 +1970,11 @@
fio_server_set_arg(optarg);
is_backend = 1;
backend = 1;
+#else
+ log_err("fio: client/server requires SHM support\n");
+ do_exit++;
+ exit_val = 1;
+#endif
break;
case 'D':
if (pid_file)
diff --git a/options.c b/options.c
index d5bf00c..74347f3 100644
--- a/options.c
+++ b/options.c
@@ -2226,6 +2226,7 @@
.oval = MEM_MALLOC,
.help = "Use malloc(3) for IO buffers",
},
+#ifndef CONFIG_NO_SHM
{ .ival = "shm",
.oval = MEM_SHM,
.help = "Use shared memory segments for IO buffers",
@@ -2236,6 +2237,7 @@
.help = "Like shm, but use huge pages",
},
#endif
+#endif
{ .ival = "mmap",
.oval = MEM_MMAP,
.help = "Use mmap(2) (file or anon) for IO buffers",
@@ -3048,6 +3050,10 @@
.type = FIO_OPT_STR_SET,
.off1 = td_var_offset(use_thread),
.help = "Use threads instead of processes",
+#ifdef CONFIG_NO_SHM
+ .def = "1",
+ .no_warn_def = 1,
+#endif
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_PROCESS,
},
diff --git a/parse.c b/parse.c
index 188f728..e6d9406 100644
--- a/parse.c
+++ b/parse.c
@@ -1167,7 +1167,7 @@
o->minfp = DBL_MIN;
o->maxfp = DBL_MAX;
}
- if (o->type == FIO_OPT_STR_SET && o->def) {
+ if (o->type == FIO_OPT_STR_SET && o->def && !o->no_warn_def) {
log_err("Option %s: string set option with"
" default will always be true\n", o->name);
}
diff --git a/parse.h b/parse.h
index c797b92..2a1e06a 100644
--- a/parse.h
+++ b/parse.h
@@ -73,6 +73,7 @@
unsigned int group; /* who to group with */
void *gui_data;
int is_seconds; /* time value with seconds base */
+ int no_warn_def;
};
typedef int (str_cb_fn)(void *, char *);
diff --git a/smalloc.c b/smalloc.c
index c8f1642..d0f732b 100644
--- a/smalloc.c
+++ b/smalloc.c
@@ -180,6 +180,7 @@
static int add_pool(struct pool *pool, unsigned int alloc_size)
{
int bitmap_blocks;
+ int mmap_flags;
void *ptr;
#ifdef SMALLOC_REDZONE
@@ -198,8 +199,14 @@
pool->nr_blocks = bitmap_blocks;
pool->free_blocks = bitmap_blocks * SMALLOC_BPB;
- ptr = mmap(NULL, alloc_size, PROT_READ|PROT_WRITE,
- MAP_SHARED | OS_MAP_ANON, -1, 0);
+ mmap_flags = OS_MAP_ANON;
+#ifdef CONFIG_ESX
+ mmap_flags |= MAP_PRIVATE;
+#else
+ mmap_flags |= MAP_SHARED;
+#endif
+ ptr = mmap(NULL, alloc_size, PROT_READ|PROT_WRITE, mmap_flags, -1, 0);
+
if (ptr == MAP_FAILED)
goto out_fail;