When a node_load() on a node fails, node_access_rebuild will report a failure as it fails to load one node, and then gets itself lost. (describing this issue is far harder then just looking at the one line patch).
To test, I did the following. Created a large set of nodes, wrote a small node_access module that assigned a node to a random realm id. "DELETE FROM users where uid = 3". Then rebuilt the node_access. This will fail as node_load on anything user 3 created will fail (see INNER JOIN {users} in node_load()).
Now I understand that "DELETE FROM users where uid = 3" is of course awfully stupid. But, _node_access_rebuild_batch_operation() was built to try and handle that case.
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);
}
The handling just happened to have an obvious error in it that would only show up if loading a node would fail.
I will roll the same one line patch for D7 when im at home.
Again, this problem is much easier described by looking at the one line patch...
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | drupal_478946-12.patch | 1.12 KB | Scott Reynolds |
| access-D6.patch | 675 bytes | Scott Reynolds |
Comments
Comment #1
agentrickardOr maybe:
Smart patch in either format.
Comment #2
Scott Reynolds commentedthat is what is currently done. The problem is $loaded_node->nid is NULL. Which gets cast to 0 on the query, which screws everything up.
This patch says "there is a nid in the database, not sure though if it can be fully loaded so just use the nid from the $row"
Comment #3
agentrickardAh. I see. So the best may be:
Comment #4
Scott Reynolds commentedyep, thats the patch.
Comment #5
agentrickardNo, it's a subtle change from the existing patch (checking $loaded_node->nid instead of $loaded_node), which needs a reroll and a bit of testing so I can RTBC.
Comment #6
Scott Reynolds commentednode_load() returns FALSE. While I don't think checking
actually produces php warnings, which should be doubled checked.
Comment #7
agentrickardD'oh. Yes it does, buried in the call stack. OK, let's commit the original.
Comment #8
agentrickardWait, shouldn't we skip nodes that have no grants?
Comment #9
Scott Reynolds commentedhttp://api.drupal.org/api/function/node_access_acquire_grants/6 handles all that for us.
Comment #10
agentrickardThen I'll stop arguing! :-p
Comment #11
gábor hojtsyLet's get this rolled/committed for D7 first as said in the intro to ensure no regression. Then I'll commit to D6 :)
Comment #12
Scott Reynolds commentedDrupal 7 Version.
Comment #13
agentrickardTests pass, logic is the same.
Comment #14
dries commentedCommitted to CVS HEAD. Moving to D6.
Comment #15
Scott Reynolds commentedD6 patch is marked as RTBC #10. should be good to go.
Comment #16
gábor hojtsyCommitted to Drupal 6, thanks.
Comment #18
cyberjared4 commentedNever mind
Comment #19
agentrickardRestoring proper status.
Comment #20
raintonr commentedSorry, but this problems is not fixed.
Nodes are processed in batches of 20. If any node fails to load that's OK - it will be skipped. Unless it is the last node in the batch of 20.
In which case
$context['sandbox']['current_node']gets reset to zero and the job starts from the beginning again.In most cases it will again fail when reaching the same batch with bad node at the 20th position and thus the job will run forever.
Comment #21
agentrickard@raintonr
Do you have a reliable way to replicate that error?
Comment #22
Scott Reynolds commented@raintonr what drupal version?
The best way to actually replicate these types of errors is to change the uid column in the node table to a non-existing uid.
Comment #23
agentrickard@Scott Reynolds
Thanks. But we also have to set it to the 20th iteration, right? And should we move this fix to D7 first? I think we have to. (But I'm not moving it to 8.x).
Comment #24
raintonr commentedRe: #22. The bug I saw was in Drupal 6.16.
Comment #25
Scott Reynolds commentedAnd the patch was committed into 6.17.
http://drupal.org/node/816290