[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MINI-OS PATCH 02/19] mini-os: kexec: add O_CLOEXEC support



Define O_CLOEXEC as a non-zero value and add a kexec callback to cycle
over all open files to close them in case O_CLOEXEC was specified when
opening the file.

This requires the addition of a cloexec boolean in struct file.

Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
 include/fcntl.h |  6 ++++++
 include/lib.h   |  1 +
 lib/sys.c       | 44 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/include/fcntl.h b/include/fcntl.h
index cc59b3ca..3205daed 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -3,6 +3,9 @@
 
 #ifdef HAVE_LIBC
 #include_next <fcntl.h>
+#ifndef O_CLOEXEC
+#define O_CLOEXEC      0x40000 /* Use newlib's value for WIN32 and CYGWIN. */
+#endif
 #else
 
 /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
@@ -25,6 +28,9 @@
 #define O_DIRECTORY    0200000 /* must be a directory */
 #define O_NOFOLLOW     0400000 /* don't follow links */
 #define O_NOATIME      01000000
+#ifndef O_CLOEXEC
+#define O_CLOEXEC      02000000
+#endif
 
 #define F_DUPFD                0       /* dup */
 #define F_GETFD                1       /* get close_on_exec */
diff --git a/include/lib.h b/include/lib.h
index de67bab0..ea146496 100644
--- a/include/lib.h
+++ b/include/lib.h
@@ -174,6 +174,7 @@ extern struct wait_queue_head event_queue;
 struct file {
     unsigned int type;
     bool read; /* maybe available for read */
+    bool cloexec;
     off_t offset;
     union {
         int fd; /* Any fd from an upper layer. */
diff --git a/lib/sys.c b/lib/sys.c
index 481067f7..7dc236e0 100644
--- a/lib/sys.c
+++ b/lib/sys.c
@@ -26,6 +26,7 @@
 #include <sched.h>
 #include <events.h>
 #include <wait.h>
+#include <kexec.h>
 #include <netfront.h>
 #include <blkfront.h>
 #include <fbfront.h>
@@ -221,6 +222,7 @@ int alloc_fd(unsigned int type)
        if (files[i].type == FTYPE_NONE) {
            files[i].type = type;
             files[i].offset = 0;
+            files[i].cloexec = false;
            pthread_mutex_unlock(&fd_lock);
            return i;
        }
@@ -231,6 +233,39 @@ int alloc_fd(unsigned int type)
 }
 EXPORT_SYMBOL(alloc_fd);
 
+#ifdef CONFIG_KEXEC
+static int kexec_close_files(bool undo)
+{
+    unsigned int i;
+    static int closed = 0;
+
+    if ( undo )
+    {
+        if ( closed )
+            printk("Can't undo closing files!\n");
+        closed = 0;
+
+        return 0;
+    }
+
+    pthread_mutex_lock(&fd_lock);
+
+    for ( i = 0; i < NOFILE; i++ )
+    {
+        if ( files[i].type != FTYPE_NONE && files[i].cloexec )
+        {
+            close(i);
+            closed++;
+        }
+    }
+
+    pthread_mutex_unlock(&fd_lock);
+
+    return 0;
+}
+kexec_call(kexec_close_files);
+#endif
+
 void close_all_files(void)
 {
     int i;
@@ -374,6 +409,7 @@ int open(const char *pathname, int flags, ...)
     struct mount_point *mnt;
     mode_t mode = 0;
     va_list ap;
+    int fd;
 
     if ( flags & O_CREAT )
     {
@@ -390,7 +426,13 @@ int open(const char *pathname, int flags, ...)
         mlen = strlen(mnt->path);
         if ( !strncmp(pathname, mnt->path, mlen) &&
              (pathname[mlen] == '/' || pathname[mlen] == 0) )
-            return mnt->open(mnt, pathname + mlen, flags, mode);
+        {
+            fd = mnt->open(mnt, pathname + mlen, flags, mode);
+            if ( fd >= 0 && (flags & O_CLOEXEC) )
+                files[fd].cloexec = true;
+
+            return fd;
+        }
     }
 
     errno = EIO;
-- 
2.43.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.