[pacman-dev] [PATCH 1/2] libalpm: sync changes to disk when appropriate

Dan McGee dan at archlinux.org
Sun Mar 15 11:50:55 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 disk whenever we close it.

Another important thing to ensure is that we commit our database additions
and removals as well by syncing the DB directory itself.

Signed-off-by: Dan McGee <dan at archlinux.org>
---

Just a slight refactor- moving the sync code to it's own function so
we can call it on both an add and remove operation.

-Dan

 lib/libalpm/be_files.c |   30 +++++++++++++++++++++++-------
 lib/libalpm/handle.c   |    6 +++++-
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 0765b8d..3da58a3 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"
@@ -343,6 +345,21 @@ static char *get_pkgpath(pmdb_t *db, pmpkg_t *info)
 	return(pkgpath);
 }
 
+static int sync_db(pmdb_t *db)
+{
+	int fd;
+	/* by syncing the parent directory, we can be sure any database
+	 * changes (adding or removing a package) are committed to disk. */
+	fd = open(db->path, 0);
+	if(fd != -1) {
+		fsync(fd);
+		close(fd);
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
 int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 {
 	FILE *fp = NULL;
@@ -776,8 +793,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 +819,6 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 			}
 			fprintf(fp, "\n");
 		}
-		fclose(fp);
-		fp = NULL;
 	}
 
 	/* DEPENDS */
@@ -848,8 +861,6 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
 			}
 			fprintf(fp, "\n");
 		}
-		fclose(fp);
-		fp = NULL;
 	}
 
 	/* INSTALL */
@@ -860,7 +871,11 @@ cleanup:
 	free(pkgpath);
 
 	if(fp) {
+		fflush(fp);
+		fdatasync(fileno(fp));
 		fclose(fp);
+		fp = NULL;
+		sync_db(db);
 	}
 
 	return(retval);
@@ -868,7 +883,7 @@ cleanup:
 
 int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
 {
-	int ret = 0;
+	int ret;
 	char *pkgpath = NULL;
 
 	ALPM_LOG_FUNC;
@@ -881,6 +896,7 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
 
 	ret = _alpm_rmrf(pkgpath);
 	free(pkgpath);
+	sync_db(db);
 	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