[ovs-dev] [PATCH] daemon: Avoid the link() syscall.

Ethan Jackson ethan at nicira.com
Sat Nov 17 01:26:52 UTC 2012


Here's an incremental.

---
 lib/daemon.c |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/lib/daemon.c b/lib/daemon.c
index da09eed..25f2db7 100644
--- a/lib/daemon.c
+++ b/lib/daemon.c
@@ -185,7 +185,7 @@ make_pidfile(void)
         tmpfile = xasprintf("%s.tmp", pidfile);
     }
 
-    file = fopen(tmpfile, "w+");
+    file = fopen(tmpfile, "a+");
     if (!file) {
         VLOG_FATAL("%s: create failed (%s)", tmpfile, strerror(errno));
     }
@@ -209,21 +209,29 @@ make_pidfile(void)
         VLOG_FATAL("%s: fstat failed (%s)", tmpfile, strerror(errno));
     }
 
+    if (ftruncate(fileno(file), 0) == -1) {
+        VLOG_FATAL("%s: truncate failed (%s)", tmpfile, strerror(errno));
+    }
+
     fprintf(file, "%ld\n", pid);
     if (fflush(file) == EOF) {
         VLOG_FATAL("%s: write failed (%s)", tmpfile, strerror(errno));
     }
 
-    /* Ensure that the pidfile will get deleted on exit. */
-    fatal_signal_add_file_to_unlink(pidfile);
+    error = rename(tmpfile, pidfile);
 
-    /* Note that since we locked 'tmpfile', we're the only process allowed to
-     * make this rename, and it's therefore atomic. */
-    if (rename(tmpfile, pidfile) < 0) {
+    /* Due to a race, 'tmpfile' may be owned by a different process, so we
+     * shouldn't delete it on exit. */
+    fatal_signal_remove_file_to_unlink(tmpfile);
+
+    if (error < 0) {
         VLOG_FATAL("failed to rename \"%s\" to \"%s\" (%s)",
                    tmpfile, pidfile, strerror(errno));
     }
 
+    /* Ensure that the pidfile will get deleted on exit. */
+    fatal_signal_add_file_to_unlink(pidfile);
+
     /* Clean up.
      *
      * We don't close 'file' because its file descriptor must remain open to
-- 
1.7.9.5




More information about the dev mailing list