[pacman-dev] [PATCH] libalpm: sync changes to disc when appropriate

Dan McGee dan at archlinux.org
Fri Mar 13 22:20:22 EDT 2009


We don't make calls to fsync() or fdatasync() when we are attempting to do
something transactionally, such as writing out one of our DB entries. Add a
call to fdatasync() when we write DB entries, and also ensure we sync our
log changes to disc whenever we close it.

Another important thing to ensure is that we commit removals of DB entries.
The method isn't necessarily pretty, but it works in _alpm_db_remove().

Signed-off-by: Dan McGee <dan at archlinux.org>
---
 lib/libalpm/be_files.c |   22 +++++++++++++++-------
 lib/libalpm/handle.c   |    6 +++++-
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 0765b8d..4faa61e 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -27,11 +27,13 @@
 #include <string.h>
 #include <stdint.h> /* uintmax_t, intmax_t */
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <dirent.h>
 #include <ctype.h>
 #include <time.h>
 #include <limits.h> /* PATH_MAX */
 #include <locale.h> /* setlocale */
+#include <fcntl.h>  /* open, close */
 
 /* libalpm */
 #include "db.h"
@@ -776,8 +778,6 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 								"%s\n\n", info->md5sum);
 			}
 		}
-		fclose(fp);
-		fp = NULL;
 	}
 
 	/* FILES */
@@ -804,8 +804,6 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 			}
 			fprintf(fp, "\n");
 		}
-		fclose(fp);
-		fp = NULL;
 	}
 
 	/* DEPENDS */
@@ -848,8 +846,6 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 			}
 			fprintf(fp, "\n");
 		}
-		fclose(fp);
-		fp = NULL;
 	}
 
 	/* INSTALL */
@@ -860,7 +856,10 @@ cleanup:
 	free(pkgpath);
 
 	if(fp) {
+		fflush(fp);
+		fdatasync(fileno(fp));
 		fclose(fp);
+		fp = NULL;
 	}
 
 	return(retval);
@@ -868,7 +867,7 @@ cleanup:
 
 int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
 {
-	int ret = 0;
+	int fd, ret;
 	char *pkgpath = NULL;
 
 	ALPM_LOG_FUNC;
@@ -881,6 +880,15 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
 
 	ret = _alpm_rmrf(pkgpath);
 	free(pkgpath);
+	/* by syncing the parent directory, we can be sure the removal is
+	 * committed to disk. */
+	fd = open(db->path, 0);
+	if(fd != -1) {
+		fsync(fd);
+		close(fd);
+	} else {
+		ret = -1;
+	}
 	if(ret != 0) {
 		ret = -1;
 	}
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 813f439..488459e 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -63,8 +63,10 @@ void _alpm_handle_free(pmhandle_t *handle)
 
 	/* close logfile */
 	if(handle->logstream) {
+		fflush(handle->logstream);
+		fdatasync(fileno(handle->logstream));
 		fclose(handle->logstream);
-		handle->logstream= NULL;
+		handle->logstream = NULL;
 	}
 	if(handle->usesyslog) {
 		handle->usesyslog = 0;
@@ -419,6 +421,8 @@ int SYMEXPORT alpm_option_set_logfile(const char *logfile)
 		FREE(oldlogfile);
 	}
 	if(handle->logstream) {
+		fflush(handle->logstream);
+		fdatasync(fileno(handle->logstream));
 		fclose(handle->logstream);
 		handle->logstream = NULL;
 	}
-- 
1.6.2



More information about the pacman-dev mailing list