Rebuild Permissions process not completing correctly
LynnS - May 23, 2009 - 18:55
| Project: | Drupal |
| Version: | 6.14 |
| Component: | base system |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Description
On trying to use any kind of node permissions module (the main case: forum_access), when I went to rebuild node permissions from the accepted ~/admin/content/node-settings/rebuild the status bar would complete to 100% and I would get the following error message:
The content access permissions could not be rebuilt.
The content access permissions need to be rebuilt.That was on two of three sites in a multisite installation. The third would get to 97% and stall.
The only solution, after much consultation with Marco at Advomatic, was to put this in a node and click "Preview":
<?php
set_time_limit(0);
db_query("DELETE FROM {node_access}");
node_access_rebuild();
?>That makes the error go away. Marco suspects an issue with the batch function.

#1
I ran into this using og_access.module on a site migrated from D5 that has ~90,000 nodes. For completeness sake, here are the steps I've performed so far:
Each time I perform the Rebuild Permissions step it fails with the above error. I did a dump of the corresponding {batch} table record when it got to the 'finished' callback and it said the following:
Array(
[sets] => Array
(
[0] => Array
(
[sandbox] => Array
(
[progress] => 96600
[current_node] => 4605
[max] => 96553
)
[results] => Array
(
)
[success] =>
[title] => Rebuilding content access permissions
[operations] => Array
(
[0] => Array
(
[0] => _node_access_rebuild_batch_operation
[1] => Array
(
)
)
)
[finished] => _node_access_rebuild_batch_finished
[init_message] => Initializing.
[progress_message] => Remaining @remaining of @total.
[error_message] => An error has occurred.
[total] => 1
)
)
// and more with the form details..
Tracing through the code I found that _node_access_rebuild_batch_operation() was doing all of the work of managing the batch process, which contains the following:
<?php$result = db_query_range("SELECT nid FROM {node} WHERE nid > %d ORDER BY nid ASC", $context['sandbox']['current_node'], 0, $limit);
while ($row = db_fetch_array($result)) {
$loaded_node = node_load($row['nid'], NULL, TRUE);
// To preserve database integrity, only aquire grants if the node
// loads successfully.
if (!empty($loaded_node)) {
node_access_acquire_grants($loaded_node);
}
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $loaded_node->nid;
}
?>
The part that seemed confusing to me was the following line:
<?php$context['sandbox']['current_node'] = $loaded_node->nid;
?>
I figured that there could be circumstances when the $loaded_node would fail on the last node load of a particular loop thus storing an empty value in $current_node for the next loop. On the next loop the database abstraction layer takes this NULL value and the query above, performs a type casting on the NULL to make it an integer, resulting in the following query:
SELECT nid FROM {node} WHERE nid > 0 ORDER BY nid ASCThis could then cause the whole batch process to start over.
In my case it always ran to completion and returned the error above.
What I did to fix it was changed the current_node assignment to just use the nid value from the row itself, i.e.:
<?php$context['sandbox']['current_node'] = $row['nid'];
?>
That allowed it to successfully complete the task.