shm: have os remove shared memory if fio dies unexpectedly
authorSitsofe Wheeler <sitsofe@yahoo.com>
Tue, 24 Jan 2017 06:31:58 +0000 (06:31 +0000)
committerSitsofe Wheeler <sitsofe@yahoo.com>
Thu, 26 Jan 2017 11:06:30 +0000 (11:06 +0000)
When fio doesn't exit cleanly shared memory segments are left behind on
those platforms where shared memory is supported.

Due to how fio manages shared memory lifetime we can combat the above by
marking the shared memory segment as removed shortly after we attach to
it for the first time if the OS offers both the following (non-standard)
behaviours:

1. A shared memory segment marked for removal with IPC_RMID isn't
   destroyed until all processes have detached from it.
2. After 1. has occurred it is still possible to (re)attach to the
   marked-for-removal shared memory segment.

Linux has always done the above so enable the workaround there. OpenBSD
switched to having the above behaviours in 5.1 (see shmctl in
https://www.openbsd.org/plus51.html ) so add a comment about it in
os/os-openbsd.h . FreeBSD only has the above behaviours if
kern.ipc.shm_allow_removed (introduced in 5.2) is 1 and this only became
the default in FreeBSD 11
(https://svnweb.freebsd.org/base?view=revision&revision=289112 ) so add
a comment in os/os-freebsd.h . DragonFly also has the FreeBSD flag but
at the time of writing it defaults to 0 so add a comment to
os/os-dragonfly.h .

There's a nice (if dated) post discussing how IPC_RMID behaves on
various OSes in https://www.cygwin.com/ml/cygwin/2007-11/msg00078.html
("Re: cygwin stable and cvs snapshot - fork() bug").  While fio doesn't
support the Cygwin "OS", Cygwin itself has the
kern.ipc.shm_allow_removed option in a config file and defaults it to
no.

init.c
os/os-dragonfly.h
os/os-freebsd.h
os/os-linux.h
os/os-openbsd.h

diff --git a/init.c b/init.c
index c3cc3e54a38f514804a3b095c175f2a23e9b32ff..34ed20f19ad0f6257703f089e3acf0fa528ace67 100644 (file)
--- a/init.c
+++ b/init.c
@@ -356,6 +356,9 @@ static int setup_thread_area(void)
                perror("shmat");
                return 1;
        }
                perror("shmat");
                return 1;
        }
+#ifdef FIO_HAVE_SHM_ATTACH_REMOVED
+       shmctl(shm_id, IPC_RMID, NULL);
+#endif
 #endif
 
        memset(threads, 0, max_jobs * sizeof(struct thread_data));
 #endif
 
        memset(threads, 0, max_jobs * sizeof(struct thread_data));
index c799817765675542b01e8bf93ff946c9a9a4729b..5e94855cac5faef440a72492093944c0ffc0c3fa 100644 (file)
@@ -24,6 +24,8 @@
 #define FIO_HAVE_GETTID
 #define FIO_HAVE_CPU_AFFINITY
 #define FIO_HAVE_IOPRIO
 #define FIO_HAVE_GETTID
 #define FIO_HAVE_CPU_AFFINITY
 #define FIO_HAVE_IOPRIO
+/* Only have attach-to-open-removed when kern.ipc.shm_allow_removed is 1 */
+#undef  FIO_HAVE_SHM_ATTACH_REMOVED
 
 #define OS_MAP_ANON            MAP_ANON
 
 
 #define OS_MAP_ANON            MAP_ANON
 
index ac408c9df8ef509a94213ba8ca671c074f74885f..aa90954dc6497b54ef841cce82635847b5c354d9 100644 (file)
@@ -22,6 +22,9 @@
 #define FIO_HAVE_TRIM
 #define FIO_HAVE_GETTID
 #define FIO_HAVE_CPU_AFFINITY
 #define FIO_HAVE_TRIM
 #define FIO_HAVE_GETTID
 #define FIO_HAVE_CPU_AFFINITY
+/* Only have attach-to-open-removed when kern.ipc.shm_allow_removed is 1 */
+#undef  FIO_HAVE_SHM_ATTACH_REMOVED
+
 
 #define OS_MAP_ANON            MAP_ANON
 
 
 #define OS_MAP_ANON            MAP_ANON
 
index 06235abc0976e7107abc1da941138867afb32dd6..18298297756ed86d687fa9117b9fda2f3a6f6ab5 100644 (file)
@@ -41,6 +41,7 @@
 #define FIO_HAVE_GETTID
 #define FIO_USE_GENERIC_INIT_RANDOM_STATE
 #define FIO_HAVE_PWRITEV2
 #define FIO_HAVE_GETTID
 #define FIO_USE_GENERIC_INIT_RANDOM_STATE
 #define FIO_HAVE_PWRITEV2
+#define FIO_HAVE_SHM_ATTACH_REMOVED
 
 #ifdef MAP_HUGETLB
 #define FIO_HAVE_MMAP_HUGE
 
 #ifdef MAP_HUGETLB
 #define FIO_HAVE_MMAP_HUGE
index 3343cbdfbb18384ded0d4cfe0b145216cbf27590..47005721abba67b2f5bb12c760cf9ec144fa7b25 100644 (file)
@@ -25,6 +25,9 @@
 
 #undef FIO_HAVE_CPU_AFFINITY   /* XXX notyet */
 
 
 #undef FIO_HAVE_CPU_AFFINITY   /* XXX notyet */
 
+/* Only OpenBSD 5.1 and above have attach-to-open-removed semantics */
+#undef  FIO_HAVE_SHM_ATTACH_REMOVED
+
 #define OS_MAP_ANON            MAP_ANON
 
 #ifndef PTHREAD_STACK_MIN
 #define OS_MAP_ANON            MAP_ANON
 
 #ifndef PTHREAD_STACK_MIN