[darwinbuild-changes] [672] trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue Dec 22 13:47:57 PST 2009
Revision: 672
http://trac.macosforge.org/projects/darwinbuild/changeset/672
Author: wsiegrist at apple.com
Date: 2009-12-22 13:47:55 -0800 (Tue, 22 Dec 2009)
Log Message:
-----------
Merge PR-7482850
Modified Paths:
--------------
trunk/CHANGES
trunk/darwinup/Depot.cpp
trunk/darwinup/Depot.h
trunk/testing/darwinup/run-tests.sh
Added Paths:
-----------
trunk/testing/darwinup/root5.tar.gz
trunk/testing/darwinup/root6.tar.gz
trunk/testing/darwinup/root7.tar.gz
Property Changed:
----------------
trunk/
Property changes on: trunk
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/PR-4841388:399-419
/branches/PR-6358021:442-443
/branches/PR-6392966:423-427
/branches/PR-6398060:433-434
/branches/PR-6493844:460-461
/branches/PR-6497694:466-468,471
/branches/PR-6634286:632-650
/branches/PR-6688645:479-490
/branches/PR-6722857:495-499
/branches/PR-6729491:655-664
/branches/PR-7250612:635-650
/branches/PR-7431723:660-664
/branches/PR-7461534:650-664
/trunk:432-434
+ /branches/PR-4841388:399-419
/branches/PR-6358021:442-443
/branches/PR-6392966:423-427
/branches/PR-6398060:433-434
/branches/PR-6493844:460-461
/branches/PR-6497694:466-468,471
/branches/PR-6634286:632-650
/branches/PR-6688645:479-490
/branches/PR-6722857:495-499
/branches/PR-6729491:655-664
/branches/PR-7250612:635-650
/branches/PR-7431723:660-664
/branches/PR-7461534:650-664
/branches/PR-7482850:670-671
/trunk:432-434
Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES 2009-12-21 19:04:39 UTC (rev 671)
+++ trunk/CHANGES 2009-12-22 21:47:55 UTC (rev 672)
@@ -1,6 +1,11 @@
Darwin Build Scripts Change History
-----------------------------------
+Release 13.1 [22-Dec-2009]
+ - darwinup: fix bug where rollback archives for user modifications
+ did not contain parent directories and thus certain
+ install/modify/uninstall patterns would result in data loss.
+
Release 13 [16-Dec-2009]
- darwinup: convert use of fork()/exec() to posix_spawn()
- darwinup: add Serial to archive list, allow use of serial, name,
Modified: trunk/darwinup/Depot.cpp
===================================================================
--- trunk/darwinup/Depot.cpp 2009-12-21 19:04:39 UTC (rev 671)
+++ trunk/darwinup/Depot.cpp 2009-12-22 21:47:55 UTC (rev 672)
@@ -316,7 +316,6 @@
extern uint32_t verbosity;
int res = 0;
*count = this->count_archives();
- //fprintf(stderr, "DEBUG: get_all_archives got count = %d \n", (int)*count);
Archive** list = (Archive**)malloc(*count * sizeof(Archive*));
static sqlite3_stmt* stmt = NULL;
if (stmt == NULL && m_db) {
@@ -332,9 +331,7 @@
while (res != SQLITE_DONE) {
res = sqlite3_step(stmt);
if (res == SQLITE_ROW) {
- //fprintf(stderr, "DEBUG: making %d-th archive \n", (int)i);
list[i++] = this->archive(stmt);
- //fprintf(stderr, "DEBUG: archive = %p \n", list[i-1]);
}
}
sqlite3_reset(stmt);
@@ -369,9 +366,7 @@
int res = 0;
size_t count = 0;
Archive** list = this->get_all_archives(&count);
- //fprintf(stderr, "DEBUG: iterate got: %p %d \n", *list, (int)count);
for (size_t i = 0; i < count; i++) {
- //fprintf(stderr, "DEBUG: iterating on i = %d list[i] = %p \n", (int)i, list[i]);
if (list[i]) {
res = func(list[i], context);
delete list[i];
@@ -558,6 +553,30 @@
IF_DEBUG("[analyze] insert rollback\n");
res = this->insert(rollback, actual);
assert(res == 0);
+ // need to save parent directories as well
+ char *ppath;
+ char *pathbuf;
+ pathbuf = strdup(actual->path());
+ ppath = dirname(pathbuf);
+ free(pathbuf);
+ // while we have a valid path that is below the prefix
+ while (ppath
+ && strncmp(ppath, this->prefix(), strlen(this->prefix())) == 0
+ && strncmp(ppath, this->prefix(), strlen(ppath)) > 0) {
+ File* parent = FileFactory(ppath);
+ // if parent dir does not exist, we are
+ // generating a rollback of base system
+ // which does not have matching directories,
+ // so we can just move on.
+ if (!parent) {
+ IF_DEBUG("[analyze] parent path not found, skipping parents\n");
+ break;
+ }
+ IF_DEBUG("[analyze] adding parent to rollback: %s \n", parent->path());
+ res = this->insert(rollback, parent);
+ assert(res == 0);
+ ppath = dirname(ppath);
+ }
}
fprintf(stderr, "%c %s\n", state, file->path());
@@ -1227,7 +1246,7 @@
int Depot::insert(Archive* archive, File* file) {
int res = 0;
-
+ int do_update = 0;
// check for the destination prefix in file's path, remove if found
char *path, *relpath;
size_t prefixlen = strlen(this->prefix());
@@ -1237,15 +1256,21 @@
relpath += prefixlen - 1;
}
- static sqlite3_stmt* stmt = NULL;
- if (stmt == NULL && m_db) {
- const char* query = "INSERT INTO files (archive, info, mode, uid, gid, digest, path) VALUES (?, ?, ?, ?, ?, ?, ?)";
+ const char* query = NULL;
+ if (this->has_file(archive, file)) {
+ do_update = 1;
+ IF_DEBUG("archive(%llu) already has %s, updating instead \n", archive->serial(), relpath);
+ query = "UPDATE files SET info=?, mode=?, uid=?, gid=?, digest=? WHERE archive=? and path=?";
+ } else {
+ query = "INSERT INTO files (info, mode, uid, gid, digest, archive, path) VALUES (?, ?, ?, ?, ?, ?, ?)";
+ }
+ sqlite3_stmt* stmt = NULL;
+ if (m_db) {
res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
}
if (stmt && res == 0) {
int i = 1;
- if (res == 0) res = sqlite3_bind_int64(stmt, i++, archive->serial());
if (res == 0) res = sqlite3_bind_int(stmt, i++, file->info());
if (res == 0) res = sqlite3_bind_int(stmt, i++, file->mode());
if (res == 0) res = sqlite3_bind_int(stmt, i++, file->uid());
@@ -1253,10 +1278,14 @@
Digest* dig = file->digest();
if (res == 0 && dig) res = sqlite3_bind_blob(stmt, i++, dig->data(), dig->size(), SQLITE_STATIC);
else if (res == 0) res = sqlite3_bind_blob(stmt, i++, NULL, 0, SQLITE_STATIC);
+ if (res == 0) res = sqlite3_bind_int64(stmt, i++, archive->serial());
if (res == 0) res = sqlite3_bind_text(stmt, i++, relpath, -1, SQLITE_STATIC);
if (res == 0) res = sqlite3_step(stmt);
if (res == SQLITE_DONE) {
- file->m_serial = (uint64_t)sqlite3_last_insert_rowid(m_db);
+ // if we did an insert, update the file serial
+ if (!do_update) {
+ file->m_serial = (uint64_t)sqlite3_last_insert_rowid(m_db);
+ }
res = 0;
} else {
fprintf(stderr, "%s:%d: Could not add file to database: %s (%d)\n", __FILE__, __LINE__, sqlite3_errmsg(m_db), res);
@@ -1267,6 +1296,42 @@
return res;
}
+int Depot::has_file(Archive* archive, File* file) {
+ int res = 0;
+ size_t count = 0;
+ // check for the destination prefix in file's path, remove if found
+ char *path, *relpath;
+ size_t prefixlen = strlen(this->prefix());
+ asprintf(&path, "%s", file->path());
+ relpath = path;
+ if (strncmp(file->path(), this->prefix(), prefixlen) == 0) {
+ relpath += prefixlen - 1;
+ }
+
+ static sqlite3_stmt* stmt = NULL;
+ if (stmt == NULL && m_db) {
+ const char* query = "SELECT count(*) FROM files WHERE archive=? and path=?";
+ res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
+ if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
+ }
+ if (stmt && res == 0) {
+ int i = 1;
+ if (res == 0) res = sqlite3_bind_int64(stmt, i++, archive->serial());
+ if (res == 0) res = sqlite3_bind_text(stmt, i++, relpath, -1, SQLITE_STATIC);
+ if (res == 0) res = sqlite3_step(stmt);
+ if (res == SQLITE_ROW) {
+ count = sqlite3_column_int64(stmt, 0);
+ IF_DEBUG("has_file(%llu, %s) got count = %u \n", archive->serial(), relpath, (unsigned int)count);
+ } else {
+ res = -1;
+ fprintf(stderr, "%s:%d: Could not query for file in archive: %s (%d)\n", __FILE__, __LINE__, sqlite3_errmsg(m_db), res);
+ }
+ sqlite3_reset(stmt);
+ }
+ free(path);
+ return count > 0;
+}
+
int Depot::remove(Archive* archive) {
int res = 0;
uint64_t serial = archive->serial();
@@ -1317,10 +1382,7 @@
count = 1;
}
- //fprintf(stderr, "DEBUG: count = %d \n", (int)count);
-
for (size_t i = 0; i < count; i++) {
- //fprintf(stderr, "DEBUG: i = %d \n", (int)i);
if (!list[i]) {
fprintf(stderr, "Archive not found: %s\n", arg);
return -1;
@@ -1330,7 +1392,6 @@
uuid_unparse_upper(list[i]->uuid(), uuid);
fprintf(stderr, "Found archive: %s\n", uuid);
}
- //fprintf(stderr, "DEBUG: dispatching %p %s \n", list[i], command);
res = this->dispatch_command(list[i], command);
delete list[i];
}
Modified: trunk/darwinup/Depot.h
===================================================================
--- trunk/darwinup/Depot.h 2009-12-21 19:04:39 UTC (rev 671)
+++ trunk/darwinup/Depot.h 2009-12-22 21:47:55 UTC (rev 672)
@@ -123,6 +123,8 @@
// If the File already has a serial number, it cannot be inserted.
int insert(Archive* archive, File* file);
+ int has_file(Archive* archive, File* file);
+
// Removes an Archive from the database.
int remove(Archive* archive);
Copied: trunk/testing/darwinup/root5.tar.gz (from rev 671, branches/PR-7482850/testing/darwinup/root5.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/root6.tar.gz (from rev 671, branches/PR-7482850/testing/darwinup/root6.tar.gz)
===================================================================
(Binary files differ)
Copied: trunk/testing/darwinup/root7.tar.gz (from rev 671, branches/PR-7482850/testing/darwinup/root7.tar.gz)
===================================================================
(Binary files differ)
Modified: trunk/testing/darwinup/run-tests.sh
===================================================================
--- trunk/testing/darwinup/run-tests.sh 2009-12-21 19:04:39 UTC (rev 671)
+++ trunk/testing/darwinup/run-tests.sh 2009-12-22 21:47:55 UTC (rev 672)
@@ -1,4 +1,6 @@
#!/bin/bash
+set -e
+set -x
#
# Run tests on darwinup
@@ -9,6 +11,8 @@
DEST=$PREFIX/dest
DESTTAR=dest.tar.gz
+DIFF="diff -x .DarwinDepot -qru"
+
ROOTS="root root2 root3"
echo "INFO: Cleaning up testing area ..."
@@ -22,8 +26,12 @@
do
tar zxvf $R.tar.gz -C $PREFIX
done;
-tar zxvf root4.tar.gz -C $PREFIX
+for R in root4 root5 root6 root7;
+do
+ tar zxvf $R.tar.gz -C $PREFIX
+done;
+
mkdir -p $ORIG
cp -R $DEST/* $ORIG/
@@ -32,13 +40,11 @@
do
echo "INFO: Installing $R ...";
darwinup -vv -p $DEST install $PREFIX/$R
- if [ $? -gt 0 ]; then exit 1; fi
UUID=$(darwinup -p $DEST list | head -3 | tail -1 | awk '{print $1}')
echo "INFO: Uninstalling $R ...";
darwinup -vv -p $DEST uninstall $UUID
- if [ $? -gt 0 ]; then exit 1; fi
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
- diff -qru $ORIG $DEST 2>&1 | grep -v \\.DarwinDepot
+ $DIFF $ORIG $DEST 2>&1
done
echo "TEST: Trying all roots at once, uninstall in reverse ...";
@@ -46,74 +52,79 @@
do
echo "INFO: Installing $R ...";
darwinup -vv -p $DEST install $PREFIX/$R
- if [ $? -gt 0 ]; then exit 1; fi
done
for R in $ROOTS;
do
UUID=$(darwinup -p $DEST list | head -3 | tail -1 | awk '{print $1}')
echo "INFO: Uninstalling $UUID ...";
darwinup -vv -p $DEST uninstall $UUID
- if [ $? -gt 0 ]; then exit 1; fi
done
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
-diff -qru $ORIG $DEST 2>&1 | grep -v \\.DarwinDepot
+$DIFF $ORIG $DEST 2>&1
echo "TEST: Trying all roots at once, uninstall in install order ..."
for R in $ROOTS;
do
echo "INFO: Installing $R ...";
darwinup -vv -p $DEST install $PREFIX/$R
- if [ $? -gt 0 ]; then exit 1; fi
done
for R in $ROOTS;
do
UUID=$(darwinup -p $DEST list | grep $R$ | awk '{print $1}')
echo "INFO: Uninstalling $UUID ...";
darwinup -vv -p $DEST uninstall $UUID
- if [ $? -gt 0 ]; then exit 1; fi
done
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
-diff -qru $ORIG $DEST 2>&1 | grep -v \\.DarwinDepot
+$DIFF $ORIG $DEST 2>&1
echo "TEST: Trying all roots at once, uninstall root2, root3, root ..."
for R in $ROOTS;
do
echo "INFO: Installing $R ...";
darwinup -vv -p $DEST install $PREFIX/$R
- if [ $? -gt 0 ]; then exit 1; fi
done
for R in root2 root3 root;
do
UUID=$(darwinup -p $DEST list | grep $R$ | awk '{print $1}')
echo "INFO: Uninstalling $UUID ...";
darwinup -vv -p $DEST uninstall $UUID
- if [ $? -gt 0 ]; then exit 1; fi
done
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
-diff -qru $ORIG $DEST 2>&1 | grep -v \\.DarwinDepot
+$DIFF $ORIG $DEST 2>&1
echo "TEST: Trying roots in reverse, uninstall in install order ..."
for R in root3 root2 root;
do
echo "INFO: Installing $R ...";
darwinup -vv -p $DEST install $PREFIX/$R
- if [ $? -gt 0 ]; then exit 1; fi
done
for R in root3 root2 root;
do
UUID=$(darwinup -p $DEST list | grep $R$ | awk '{print $1}')
echo "INFO: Uninstalling $UUID ...";
darwinup -vv -p $DEST uninstall $UUID
- if [ $? -gt 0 ]; then exit 1; fi
done
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
-diff -qru $ORIG $DEST 2>&1 | grep -v \\.DarwinDepot
+$DIFF $ORIG $DEST 2>&1
+echo "TEST: Try uninstalling with user data in rollback"
+echo "INFO: Installing root5 ...";
+darwinup -vv -p $DEST install $PREFIX/root5
+darwinup -vv -p $DEST install $PREFIX/root6
+echo "modification" >> $DEST/d/file
+darwinup -vv -p $DEST install $PREFIX/root7
+darwinup -vv -p $DEST uninstall root6
+darwinup -vv -p $DEST uninstall root5
+darwinup -vv -p $DEST uninstall root7
+
+
+set +e
+
echo "TEST: Trying a root that will fail due to object change ..."
darwinup -vv -p $DEST install $PREFIX/root4
if [ $? -ne 1 ]; then exit 1; fi
echo "DIFF: diffing original test files to dest (should be no diffs) ..."
-diff -qru $ORIG $DEST 2>&1 | grep -v \\.DarwinDepot
+$DIFF $ORIG $DEST 2>&1
echo "INFO: Done testing!"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20091222/0ff84ddd/attachment-0001.html>
More information about the darwinbuild-changes
mailing list