Problem/Motivation
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.
Steps to reproduce
Proposed resolution
Log an error message when the rebuild fails
Remaining tasks
Convert to MR
Review
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Comments
Comment #1
damienmckennaI 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:
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:
The part that seemed confusing to me was the following line:
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:
This 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.:
That allowed it to successfully complete the task.
Comment #3
liam mcdermott commentedsubscribing.
Comment #4
janusman commentedsubscribing
Comment #5
janusman commentedThis seems quite logical. If we are setting ['progress'] to be some property of an invalid (empty?) object, something is clearly amiss =)
In my case, it fixed a recurring problem in a site with 30k nodes which has both Workflow Access and OG Access modules enabled. (Before, after finishing the rebuild it still informed me that they should be rebuilt).
Just a change: patch contains some cruft:
I think the above should be removed. After that I think it's ready to go.
BTW I think this might also be a problem in D7? Here's a snippet from D7's _node_access_rebuild_batch_operation():
If so we should attract some attention to this =)
Comment #6
chx commentedI am very close to mark this as wont fix. How can the nid of a loaded node be 0 / NULL? You are fixing a symptom not the cause.
Comment #7
fizk commentedSame problem here. For example, in node_load():
SELECT * FROM node n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN node_revisions r ON r.vid = n.vid WHERE n.nid=817returns empty, but
SELECT * FROM node n INNER JOIN node_revisions r ON r.vid = n.vid WHERE n.nid=817returns one row. These rows were of type 'uprofile', so it seems the advanced_profile_kit module didn't delete the profile node when the user account was deleted.
Please add the patch for the next D6 release.
Comment #8
janusman commented@chx: re #6, is it possible that a node_delete could occur while a batch is processing, therefore causing node_load($nid) to not return a valid object? Are there any other possible cases? (My guess is YES, due to bad modules, database table corruption, cosmic rays, etc... of course, unlikely ... but possible.)
IMO if this patch makes Drupal more bulletproof... even if just by a tiny bit [EDIT: I missed saying "it's worth implementing" here] =)
And, OK, maybe it's not a "bug" as such. =)
Comment #9
salvisYou might try commenting out the
node_access_acquire_grants($loaded_node);line. That should allow the batch process to run much faster and still attempt to load each node. Does that run to completion?
WARNING:
Running the rebuild after commenting out that line only fakes rebuilding permissions —
if it 'succeeds,' then Drupal will stop asking to rebuild permissions, but you haven't actually done it!
This is intended only as an intermediate step in finding the cause of the problem, by checking whether you can at least load all nodes. It will probably result in all nodes becoming inaccessible to all but administrative users!
Comment #10
webchickI agree with chx that this is only making the problem. The real problem is that node_load() failed, and thus the node's access grants rebuild was not executed, so it gets flagged as a failure.
But that said, it's all but impossible to figure out what the root cause of the error was when such a thing occurs. I encountered the issue "somewhere" in my 60K nodes website, and only managed to track down the problem thanks to this issue providing a hint, and then tossing in some debug code (see #281326-51: The content access permissions need to be rebuilt.).
At the very least it seems like we ought to fire a dsm() and/or a watchdog when this condition happens:
Since the issue exists in D7 too, bumping to 7.x-dev so we can fix it there first.
Comment #11
webchickTurns out that technically, this is a duplicate of #315302: Node Access Rebuild never finishes (infinite loop) since that one is older. It's also been marked RTBC, pending tests. So I'm going to hijack this one and make it about error trapping instead. ;)
Comment #12
cyberswat commentedJust an FYI that this is similar to #225864: Don't assume that node_load returns a node ... I'm wondering if node_load itself should handle the watchdog entries to mitigate other possible occurrences. This won't stop the error messages but would at least give admins the ability to debug their problematic data.
Comment #13
janusman commentedThis patch logs to watchdog inside node_access_rebuild().
Comment #15
cyberswat commentedI think the root problem is bad data being passed to node_load and that issues like this one are a symptom of the cause. I don't believe Drupal should have to account for bad data that has been entered but I do believe that we should at least notify admins of the root problem. I'm of the opinion that the only place this can happen is in node_load() ... otherwise you would have to write a patch to fix every instance of a module that uses node_load and assumes the node is proper.
For the sake of argument here's a quick patch that modifies node_load()
Comment #16
cyberswat commentedHere's one that corrects the typo in my last patch
Comment #18
janusman commentedGah! Bad format in #13; sorry. retesting.
Comment #19
cyberswat commentedI re-rolled the patch I was working on it's original issue #225864: Don't assume that node_load returns a node
Comment #20
janusman commentedPossibly related: http://robshouse.net/blog-post/when-node-load-wont-load-and-anonymous-us...
Comment #21
tomhung commented#1: drupal-n471080.patch queued for re-testing.
Comment #22
brianV commented#18: 471080-12-watchdog_in_node_access_rebuild.patch queued for re-testing.
Comment #24
damienmckennaHello again, dear bug =)
Updating this to the node system and it needs to be rerolled for 8.0.
Comment #25
damienmckennaComment #34
catchComment #35
catchStill looks valid in node_access_rebuild(), adding a log message seems OK.
Comment #36
guilhermevp commentedNot sure if this is the expected message, but please review, also is it applicable for 9.3.x?
Comment #37
guilhermevp commentedSorry, patch 37 was sent by accident. Please dot not consider, patch #36 is the one to be reviewd.
Comment #38
guilhermevp commentedSending patch without whitespace.
Comment #41
rudrakumar188 commentedThe patch #38 is applied successfully on version 9.4.x . Added a screenshot of patch.
Comment #42
gaurav-mathur commentedComment #43
gaurav-mathur commentedComment #44
gaurav-mathur commentedApplied patch #38 successfully on drupal version 9.4.x
Thank you.
Comment #46
smustgrave commentedThis issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.
Did not review or test
Moving to NW for the issue summary update requested in #34
Comment #47
catchThis is a task now that #315302: Node Access Rebuild never finishes (infinite loop) is dealing with the actual bug.
Comment #49
quietone commentedComment #50
acbramley commentedThis issue was originally created because when the node wasn't loaded, the batch failed and the user was presented with "could not be rebuilt" and "need to be rebuilt" messages simultaneously.
Now that #315302: Node Access Rebuild never finishes (infinite loop) fixed the bug when a node couldn't be loaded, I'm not really sure what relevant information we could provide in this log message and why it would be the job of this batch process to call out a faulty node? A node has to exist in the database and then produce an error on load to even hit this issue (since $nids come from an entity query).
What information could we actually provide here that would help a user in any way? They'd still see a successful batch operation afaict.
Comment #51
smustgrave commented@acbramley where would that info popup though? Way I read this one was just adding a logger to the batch
Comment #52
acbramley commentedMy point in #50 is that there's not really any helpful info to add anyway. I'm not sure what you're referring to about an info popup.
Comment #54
quietone commentedI am removing the 'Novice' tag because what task someone new to Drupal contribution is not clearly defined. Converting to an MR would be but the subsystem maintainer is questioning the need for this change.