Merge branch 'rand-map'
authorJens Axboe <axboe@kernel.dk>
Thu, 29 Nov 2012 20:56:06 +0000 (21:56 +0100)
committerJens Axboe <axboe@kernel.dk>
Thu, 29 Nov 2012 20:56:06 +0000 (21:56 +0100)
HOWTO
engines/net.c
engines/windowsaio.c
helpers.c
helpers.h
libfio.c
os/os-linux.h
os/os-solaris.h
os/os.h
parse.c

diff --git a/HOWTO b/HOWTO
index 6391b82a9c79b31fe3e3b0f2fac2dd0b6caf57ae..32e5d668c89e42efec4704b2db8686afc32e17c2 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -61,7 +61,7 @@ bottom, it contains the following basic parameters:
 
        Num threads     How many threads or processes should we spread
                        this workload over.
-       
+
 The above are the basic parameters defined for a workload, in addition
 there's a multitude of parameters that modify other aspects of how this
 job behaves.
@@ -274,11 +274,14 @@ filename=str      Fio normally makes up a filename based on the job name,
                as the two working files, you would use
                filename=/dev/sda:/dev/sdb. On Windows, disk devices are accessed
                as \\.\PhysicalDrive0 for the first device, \\.\PhysicalDrive1
-               for the second etc.  If the wanted filename does need to 
-               include a colon, then escape that with a '\' character. 
-               For instance, if the filename is "/dev/dsk/foo@3,0:c", 
-               then you would use filename="/dev/dsk/foo@3,0\:c". 
-               '-' is a reserved name, meaning stdin or stdout. Which of the 
+               for the second etc.
+               Note: Windows and FreeBSD prevent write access to areas of the disk
+               containing in-use data (e.g. filesystems).
+               If the wanted filename does need to include a colon, then escape that
+               with a '\' character.
+               For instance, if the filename is "/dev/dsk/foo@3,0:c",
+               then you would use filename="/dev/dsk/foo@3,0\:c".
+               '-' is a reserved name, meaning stdin or stdout. Which of the
                two depends on the read/write direction set.
 
 opendir=str    Tell fio to recursively add any file it can find in this
@@ -1086,7 +1089,7 @@ verify_backlog_batch=int  Control how many blocks fio will verify
                less than verify_backlog then not all blocks will be verified,
                if verify_backlog_batch is larger than verify_backlog, some
                blocks will be verified more than once.
-               
+
 stonewall
 wait_for_previous Wait for preceeding jobs in the job file to exit, before
                starting this one. Can be used to insert serialization
@@ -1132,7 +1135,7 @@ read_iolog=str    Open an iolog with the specified file name and replay the
                for how to capture such logging data. For blktrace replay,
                the file needs to be turned into a blkparse binary data
                file first (blkparse <device> -o /dev/null -d file_for_fio.bin).
-               
+
 replay_no_stall=int When replaying I/O with read_iolog the default behavior
                is to attempt to respect the time stamps within the log and
                replay them with the appropriate delay between IOPS.  By
@@ -1295,12 +1298,12 @@ ignore_error=str Sometimes you want to ignore some errors during test
                 may be symbol ('ENOSPC', 'ENOMEM') or integer.
                 Example:
                        ignore_error=EAGAIN,ENOSPC:122
-                This option will ignore EAGAIN from READ, and ENOSPC and 
-                122(EDQUOT) from WRITE. 
+                This option will ignore EAGAIN from READ, and ENOSPC and
+                122(EDQUOT) from WRITE.
 
 error_dump=bool If set dump every error even if it is non fatal, true
                by default. If disabled only fatal error will be dumped
-                                
+
 cgroup=str     Add job to this control group. If it doesn't exist, it will
                be created. The system must have a mounted cgroup blkio
                mount point for this to work. If your system doesn't have it
@@ -1382,7 +1385,7 @@ that defines them is selected.
 [e4defrag] donorname=str
                File will be used as a block donor(swap extents between files)
 [e4defrag] inplace=int
-               Configure donor file blocks allocation strategy         
+               Configure donor file blocks allocation strategy
                0(default): Preallocate donor's file on init
                1         : allocate space immidietly inside defragment event,
                            and free right after event
@@ -1570,8 +1573,8 @@ Split up, the format is as follows:
                          Read merges, write merges,
                          Read ticks, write ticks,
                          Time spent in queue, disk utilization percentage
-       Additional Info (dependant on continue_on_error, default off): total # errors, first error code 
-       
+       Additional Info (dependant on continue_on_error, default off): total # errors, first error code
+
        Additional Info (dependant on description being set): Text description
 
 Completion latency percentiles can be a grouping of up to 20 sets, so
@@ -1587,7 +1590,7 @@ there will be a disk utilization section.
 
 8.0 Trace file format
 ---------------------
-There are two trace file format that you can encounter. The older (v1) format 
+There are two trace file format that you can encounter. The older (v1) format
 is unsupported since version 1.20-rc3 (March 2008). It will still be described
 below in case that you get an old trace and want to understand it.
 
@@ -1624,7 +1627,7 @@ filename action
 The filename is given as an absolute path. The action can be one of these:
 
 add          Add the given filename to the trace
-open         Open the file with the given filename. The filename has to have 
+open         Open the file with the given filename. The filename has to have
              been added with the add action before.
 close        Close the file with the given filename. The file has to have been
              opened before.
@@ -1635,7 +1638,7 @@ The file io action format:
 filename action offset length
 
 The filename is given as an absolute path, and has to have been added and opened
-before it can be used with this format. The offset and length are given in 
+before it can be used with this format. The offset and length are given in
 bytes. The action can be one of these:
 
 wait       Wait for 'offset' microseconds. Everything below 100 is discarded.
index c5337994fa41509acad7a4cf91003b0ac1422503..373821b2142bb8d3a7428179d4c4218ff05118e1 100644 (file)
@@ -360,6 +360,8 @@ static int fio_netio_recv(struct thread_data *td, struct io_u *io_u)
                }
                if (ret > 0)
                        break;
+               else if (!ret && (flags & MSG_WAITALL))
+                       break;
 
                ret = poll_wait(td, io_u->file->fd, POLLIN);
                if (ret <= 0)
@@ -473,24 +475,32 @@ static int fio_netio_accept(struct thread_data *td, struct fio_file *f)
        struct netio_data *nd = td->io_ops->data;
        struct netio_options *o = td->eo;
        fio_socklen_t socklen = sizeof(nd->addr);
+       int state;
 
        if (o->proto == FIO_TYPE_UDP) {
                f->fd = nd->listenfd;
                return 0;
        }
 
+       state = td->runstate;
+       td_set_runstate(td, TD_SETTING_UP);
+
        log_info("fio: waiting for connection\n");
 
        if (poll_wait(td, nd->listenfd, POLLIN) < 0)
-               return 1;
+               goto err;
 
        f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
        if (f->fd < 0) {
                td_verror(td, errno, "accept");
-               return 1;
+               goto err;
        }
 
+       td_set_runstate(td, state);
        return 0;
+err:
+       td_set_runstate(td, state);
+       return 1;
 }
 
 static int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
@@ -543,6 +553,15 @@ static int fio_netio_setup_connect_inet(struct thread_data *td,
 {
        struct netio_data *nd = td->io_ops->data;
 
+       if (!host) {
+               log_err("fio: connect with no host to connect to.\n");
+               if (td_read(td))
+                       log_err("fio: did you forget to set 'listen'?\n");
+
+               td_verror(td, EINVAL, "no hostname= set");
+               return 1;
+       }
+
        nd->addr.sin_family = AF_INET;
        nd->addr.sin_port = htons(port);
 
index ea899698b25e1474406e3c9a1fd7e3ddcc63c5a5..db7573049600b6686c74c241c719057544a0d099 100644 (file)
@@ -14,6 +14,8 @@
 
 typedef BOOL (WINAPI *CANCELIOEX)(HANDLE hFile, LPOVERLAPPED lpOverlapped);
 
+int geterrno_from_win_error (DWORD code, int deferrno);
+
 struct fio_overlapped {
        OVERLAPPED o;
        struct io_u *io_u;
@@ -48,6 +50,82 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter);
 static int fio_windowsaio_init(struct thread_data *td);
 static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f);
 static int fio_windowsaio_close_file(struct thread_data fio_unused *td, struct fio_file *f);
+static int win_to_poxix_error(DWORD winerr);
+
+static int win_to_poxix_error(DWORD winerr)
+{
+       switch (winerr)
+       {
+       case ERROR_FILE_NOT_FOUND:              return ENOENT;
+       case ERROR_PATH_NOT_FOUND:              return ENOENT;
+       case ERROR_ACCESS_DENIED:               return EACCES;
+       case ERROR_INVALID_HANDLE:              return EBADF;
+       case ERROR_NOT_ENOUGH_MEMORY:   return ENOMEM;
+       case ERROR_INVALID_DATA:                return EINVAL;
+       case ERROR_OUTOFMEMORY:                 return ENOMEM;
+       case ERROR_INVALID_DRIVE:               return ENODEV;
+       case ERROR_NOT_SAME_DEVICE:             return EXDEV;
+       case ERROR_WRITE_PROTECT:               return EROFS;
+       case ERROR_BAD_UNIT:                    return ENODEV;
+       case ERROR_SHARING_VIOLATION:   return EACCES;
+       case ERROR_LOCK_VIOLATION:              return EACCES;
+       case ERROR_SHARING_BUFFER_EXCEEDED:     return ENOLCK;
+       case ERROR_HANDLE_DISK_FULL:    return ENOSPC;
+       case ERROR_NOT_SUPPORTED:               return ENOSYS;
+       case ERROR_FILE_EXISTS:                 return EEXIST;
+       case ERROR_CANNOT_MAKE:                 return EPERM;
+       case ERROR_INVALID_PARAMETER:   return EINVAL;
+       case ERROR_NO_PROC_SLOTS:               return EAGAIN;
+       case ERROR_BROKEN_PIPE:                 return EPIPE;
+       case ERROR_OPEN_FAILED:                 return EIO;
+       case ERROR_NO_MORE_SEARCH_HANDLES:      return ENFILE;
+       case ERROR_CALL_NOT_IMPLEMENTED:        return ENOSYS;
+       case ERROR_INVALID_NAME:                return ENOENT;
+       case ERROR_WAIT_NO_CHILDREN:    return ECHILD;
+       case ERROR_CHILD_NOT_COMPLETE:  return EBUSY;
+       case ERROR_DIR_NOT_EMPTY:               return ENOTEMPTY;
+       case ERROR_SIGNAL_REFUSED:              return EIO;
+       case ERROR_BAD_PATHNAME:                return ENOENT;
+       case ERROR_SIGNAL_PENDING:              return EBUSY;
+       case ERROR_MAX_THRDS_REACHED:   return EAGAIN;
+       case ERROR_BUSY:                                return EBUSY;
+       case ERROR_ALREADY_EXISTS:              return EEXIST;
+       case ERROR_NO_SIGNAL_SENT:              return EIO;
+       case ERROR_FILENAME_EXCED_RANGE:        return EINVAL;
+       case ERROR_META_EXPANSION_TOO_LONG:     return EINVAL;
+       case ERROR_INVALID_SIGNAL_NUMBER:       return EINVAL;
+       case ERROR_THREAD_1_INACTIVE:   return EINVAL;
+       case ERROR_BAD_PIPE:                    return EINVAL;
+       case ERROR_PIPE_BUSY:                   return EBUSY;
+       case ERROR_NO_DATA:                             return EPIPE;
+       case ERROR_MORE_DATA:                   return EAGAIN;
+       case ERROR_DIRECTORY:                   return ENOTDIR;
+       case ERROR_PIPE_CONNECTED:              return EBUSY;
+       case ERROR_NO_TOKEN:                    return EINVAL;
+       case ERROR_PROCESS_ABORTED:             return EFAULT;
+       case ERROR_BAD_DEVICE:                  return ENODEV;
+       case ERROR_BAD_USERNAME:                return EINVAL;
+       case ERROR_OPEN_FILES:                  return EAGAIN;
+       case ERROR_ACTIVE_CONNECTIONS:  return EAGAIN;
+       case ERROR_DEVICE_IN_USE:               return EAGAIN;
+       case ERROR_INVALID_AT_INTERRUPT_TIME:   return EINTR;
+       case ERROR_IO_DEVICE:                   return EIO;
+       case ERROR_NOT_OWNER:                   return EPERM;
+       case ERROR_END_OF_MEDIA:                return ENOSPC;
+       case ERROR_EOM_OVERFLOW:                return ENOSPC;
+       case ERROR_BEGINNING_OF_MEDIA:  return ESPIPE;
+       case ERROR_SETMARK_DETECTED:    return ESPIPE;
+       case ERROR_NO_DATA_DETECTED:    return ENOSPC;
+       case ERROR_POSSIBLE_DEADLOCK:   return EDEADLOCK;
+       case ERROR_CRC:                                 return EIO;
+       case ERROR_NEGATIVE_SEEK:               return EINVAL;
+       case ERROR_DISK_FULL:                   return ENOSPC;
+       case ERROR_NOACCESS:                    return EFAULT;
+       case ERROR_FILE_INVALID:                return ENXIO;
+       }
+
+       return winerr;
+}
 
 int sync_file_range(int fd, off64_t offset, off64_t nbytes,
                           unsigned int flags)
@@ -350,7 +428,7 @@ static int fio_windowsaio_queue(struct thread_data *td, struct io_u *io_u)
        case DDIR_SYNC_FILE_RANGE:
                success = FlushFileBuffers(io_u->file->hFile);
                if (!success)
-                   io_u->error = GetLastError();
+                   io_u->error = win_to_poxix_error(GetLastError());
 
                return FIO_Q_COMPLETED;
                break;
@@ -368,7 +446,7 @@ static int fio_windowsaio_queue(struct thread_data *td, struct io_u *io_u)
        if (success || GetLastError() == ERROR_IO_PENDING)
                rc = FIO_Q_QUEUED;
        else {
-               io_u->error = GetLastError();
+               io_u->error = win_to_poxix_error(GetLastError());
                io_u->resid = io_u->xfer_buflen;
        }
 
@@ -390,7 +468,7 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter)
        wd = ctx->wd;
 
        do {
-               if (!GetQueuedCompletionStatus(ctx->iocp, &bytes, &ulKey, &ovl, 250))
+               if (!GetQueuedCompletionStatus(ctx->iocp, &bytes, &ulKey, &ovl, 250) && ovl == NULL)
                        continue;
 
                fov = CONTAINING_RECORD(ovl, struct fio_overlapped, o);
@@ -401,7 +479,7 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter)
                        io_u->error = 0;
                } else {
                        io_u->resid = io_u->xfer_buflen;
-                       io_u->error = ovl->Internal;
+                       io_u->error = win_to_poxix_error(GetLastError());
                }
 
                fov->io_complete = TRUE;
index 5be45ccf5f3954b3c87494132d7f0cdf94825814..1b4e1d0a2c9ccabe9c3e6483223f2abae54b5c7d 100644 (file)
--- a/helpers.c
+++ b/helpers.c
@@ -50,3 +50,10 @@ int _weak sync_file_range(int fd, off64_t offset, off64_t nbytes,
        return -1;
 }
 #endif
+
+#ifndef FIO_HAVE_FADVISE
+int _weak posix_fadvise(int fd, off_t offset, off_t len, int advice)
+{
+       return 0;
+}
+#endif
index ed2086d147cee112fd4681ef45b8d63681c3247a..191096bde600b07c1ed352b69cd4d72cf193a337 100644 (file)
--- a/helpers.h
+++ b/helpers.h
@@ -15,5 +15,6 @@ extern int _weak inet_aton(const char *cp, struct in_addr *inp);
 extern int _weak clock_gettime(clockid_t clk_id, struct timespec *ts);
 extern int _weak sync_file_range(int fd, off64_t offset, off64_t nbytes,
                                        unsigned int flags);
+extern int _weak posix_fadvise(int fd, off_t offset, off_t len, int advice);
 
 #endif /* FIO_HELPERS_H_ */
index 0cfd7f63fd72b2f2e3e4cd6f77eeb2857b4ddde1..ee5a0ead1707f66fc7418c2b0b964d72727912ee 100644 (file)
--- a/libfio.c
+++ b/libfio.c
@@ -162,6 +162,7 @@ void td_set_runstate(struct thread_data *td, int runstate)
 void fio_terminate_threads(int group_id)
 {
        struct thread_data *td;
+       pid_t pid = getpid();
        int i;
 
        dprint(FD_PROCESS, "terminate group_id=%d\n", group_id);
@@ -180,7 +181,7 @@ void fio_terminate_threads(int group_id)
                                continue;
                        else if (td->runstate < TD_RAMP)
                                kill(td->pid, SIGTERM);
-                       else {
+                       else if (pid != td->pid) {
                                struct ioengine_ops *ops = td->io_ops;
 
                                if (ops && (ops->flags & FIO_SIGTERM))
index 9b7ff29e50af7f07d656cf3e763e7fafe409a669..e9d7cf3e6f6e0cf4af791bab019fc9faf9586e21 100644 (file)
@@ -7,6 +7,7 @@
 #include <sys/uio.h>
 #include <sys/syscall.h>
 #include <sys/vfs.h>
+#include <sys/mman.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #define FIO_USE_GENERIC_INIT_RANDOM_STATE
 #define FIO_HAVE_E4_ENG
 
+#ifdef MAP_HUGETLB
+#define FIO_HAVE_MMAP_HUGE
+#endif
+
 /*
  * Can only enable this for newer glibcs, or the header and defines are
  * missing
index e7a544e1a0bc37c4766a2dc303da9701a1421efa..5efd7ac1e96481ec4ed0645c2c2bb88a66cbdf6d 100644 (file)
@@ -24,6 +24,7 @@
 #define FIO_USE_GENERIC_BDEV_SIZE
 #define FIO_USE_GENERIC_INIT_RANDOM_STATE
 #define FIO_HAVE_GETTID
+#define FIO_HAVE_FADVISE
 
 #define OS_MAP_ANON            MAP_ANON
 #define OS_RAND_MAX            2147483648UL
diff --git a/os/os.h b/os/os.h
index e150284ef6a84f10764abe08103e795ae2058ee6..2e4764e18f4ab6c021c3171827bd7323b52ef8bf 100644 (file)
--- a/os/os.h
+++ b/os/os.h
@@ -68,22 +68,11 @@ typedef struct aiocb os_aiocb_t;
 #define OS_MSG_DONTWAIT        MSG_DONTWAIT
 #endif
 
-#ifndef FIO_HAVE_FADVISE
-static inline int posix_fadvise(int fd, int off, int len, int advice)
-{
-       (void)fd;
-       (void)off;
-       (void)len;
-       (void)advice;
-       return 0;
-}
-
 #ifndef POSIX_FADV_DONTNEED
 #define POSIX_FADV_DONTNEED    (0)
 #define POSIX_FADV_SEQUENTIAL  (0)
 #define POSIX_FADV_RANDOM      (0)
 #endif
-#endif /* FIO_HAVE_FADVISE */
 
 #ifndef FIO_HAVE_CPU_AFFINITY
 #define fio_setaffinity(pid, mask)     (0)
@@ -115,6 +104,10 @@ typedef unsigned long os_cpu_mask_t;
 #endif
 #endif
 
+#ifndef FIO_HAVE_MMAP_HUGE
+#define MAP_HUGETLB                    0
+#endif
+
 #ifndef FIO_O_NOATIME
 #define FIO_O_NOATIME                  0
 #endif
diff --git a/parse.c b/parse.c
index 0bbb0b30dafd5c8b57ac842e28bdaeba789c6022..13783fa6d60c06f1df0fb82dcaf18ac2636750ae 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -361,7 +361,7 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
        long long ull, *ullp;
        long ul1, ul2;
        double uf;
-       char **cp;
+       char **cp = NULL;
        int ret = 0, is_time = 0;
        const struct value_pair *vp;
        struct value_pair posval[PARSE_MAX_VP];
@@ -536,8 +536,6 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                                cp = td_var(data, o->off1);
 
                        *cp = strdup(ptr);
-               } else {
-                       cp = NULL;
                }
 
                if (fn)