Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.307
diff -u -p -r1.307 update.php
--- update.php	9 Oct 2009 07:48:06 -0000	1.307
+++ update.php	23 Oct 2009 18:23:22 -0000
@@ -334,6 +334,16 @@ if (empty($op) && update_access_allowed(
   install_goto('update.php?op=info');
 }
 
+// update_fix_d7_requirements() needs to run before bootstrapping beyond path.
+// So bootstrap to DRUPAL_BOOTSTRAP_LANGUAGE then include unicode.inc.
+
+drupal_bootstrap(DRUPAL_BOOTSTRAP_LANGUAGE);
+include_once DRUPAL_ROOT . '/includes/unicode.inc';
+
+update_fix_d7_requirements();
+
+// Now proceed with a full bootstrap.
+
 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
 drupal_maintenance_theme();
 
@@ -348,7 +358,6 @@ if (update_access_allowed()) {
   include_once DRUPAL_ROOT . '/includes/batch.inc';
   drupal_load_updates();
 
-  update_fix_d7_requirements();
   update_fix_compatibility();
 
   $op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
@@ -386,6 +395,10 @@ else {
   $output = update_access_denied_page();
 }
 if (isset($output) && $output) {
+  // Commit the session data, force the session to stay open for 15 minutes.
+  drupal_session_start();
+  drupal_session_keep(300);
+
   // We defer the display of messages until all updates are done.
   $progress_page = ($batch = batch_get()) && isset($batch['running']);
   print theme('update_page', array('content' => $output, 'show_messages' => !$progress_page));
Index: includes/session.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/session.inc,v
retrieving revision 1.72
diff -u -p -r1.72 session.inc
--- includes/session.inc	28 Sep 2009 22:22:54 -0000	1.72
+++ includes/session.inc	23 Oct 2009 18:23:22 -0000
@@ -235,6 +235,11 @@ function drupal_session_commit() {
     return;
   }
 
+  // Expire the keep if possible.
+  if (isset($_SESSION['drupal_keep']) && ($_SESSION['drupal_keep'] > REQUEST_TIME)) {
+    unset($_SESSION['drupal_keep']);
+  }
+
   if (empty($user->uid) && empty($_SESSION)) {
     // There is no session data to store, destroy the session if it was
     // previously started.
@@ -265,6 +270,25 @@ function drupal_session_started($set = N
 }
 
 /**
+ * Keep the current user's session open for a given length of time.
+ *
+ * @param $duration The length the session needs to remain open, in seconds.
+ */
+function drupal_session_keep($duration) {
+  $new_timestamp = REQUEST_TIME + $duration;
+  if (!isset($_SESSION['drupal_keep']) || ($new_timestamp > $_SESSION['drupal_keep'])) {
+    $_SESSION['drupal_keep'] = $new_timestamp;
+  }
+}
+
+/**
+ * Stop keeping the current user's session open.
+ */
+function drupal_session_keep_reset() {
+  unset($_SESSION['drupal_keep']);
+}
+
+/**
  * Called when an anonymous user becomes authenticated or vice-versa.
  *
  * @ingroup php_wrappers
Index: includes/update.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/update.inc,v
retrieving revision 1.13
diff -u -p -r1.13 update.inc
--- includes/update.inc	13 Oct 2009 05:26:57 -0000	1.13
+++ includes/update.inc	23 Oct 2009 18:23:22 -0000
@@ -126,7 +126,15 @@ function update_fix_d7_requirements() {
     // Add the cache_path table.
     $schema['cache_path'] = drupal_get_schema_unprocessed('system', 'cache');
     $schema['cache_path']['description'] = 'Cache table used for path alias lookups.';
-    db_create_table('cache_path', $schema['cache_path']);
+
+    // system_update_7042() renames columns, but these are needed to bootstrap.
+    // add empty columns for now.
+    db_add_field('url_alias', 'source', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
+    db_add_field('url_alias', 'alias', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
+
+    // Add the role_permisson table
+    $schema['role_permission'] = drupal_get_schema_unprocessed('user', 'role_permission');
+    db_create_table('role_permission', $schema['role_permission']);
 
     // Add column for locale context.
     if (db_table_exists('locales_source')) {
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.410
diff -u -p -r1.410 system.install
--- modules/system/system.install	20 Oct 2009 19:06:09 -0000	1.410
+++ modules/system/system.install	23 Oct 2009 18:23:24 -0000
@@ -2011,8 +2011,9 @@ function system_update_7007() {
       'permission' => array('permission'),
     ),
   );
-
-  db_create_table('role_permission', $schema['role_permission']);
+  if (!db_table_exists('role_permission')) {
+    db_create_table('role_permission', $schema['role_permission']);
+  }
 
   // Copy the permissions from the old {permission} table to the new {role_permission} table.
   $messages = array();
@@ -2832,6 +2833,16 @@ function system_update_7041() {
  * Rename dst and src to source and alias.
  */
 function system_update_7042() {
+  // update_fix_d7_requirements() adds 'fake' source and alias columns to
+  // allow bootstrap to run without fatal errors. Remove those columns now
+  // so that we can rename properly.
+  db_drop_field('url_alias', 'source');
+  db_drop_field('url_alias', 'alias');
+
+  // Add the cache_path table.
+  $schema['cache_path'] = drupal_get_schema_unprocessed('system', 'cache');
+  $schema['cache_path']['description'] = 'Cache table used for path alias lookups.';
+  db_create_table('cache_path', $schema['cache_path']);
   // Drop indexes.
   db_drop_index('url_alias', 'src_language_pid');
   db_drop_unique_key('url_alias', 'dst_language_pid');
