Updated: Comment #19
Problem/Motivation
In the current code (affects all versions of Drupal), if variable_init() is unsuccessful for any reason (for example: cache is corrupt, or the db_query() fails because the database server is having an hiccup) the process continues. This not acceptable, because the rest of the request rely on the variable system being properly initialized.
For example, if the request calls drupal_get_private_key(), a *new key* will be regenerated if the current one cannot be fetched by variable_get(). The variable_set() can succeed, resulting in a permanently changed private key.
We have seen that a few times already on drupal.org, especially in periods of database meltdown.
Proposed resolution
A patch needes to be made.
Remaining tasks
This task needs work. The previous patch does not apply.
User interface changes
None.
API changes
None.
Original report by Damien Tournoud
| Comment | File | Size | Author |
|---|---|---|---|
| #16 | variable_initalize.patch | 2.48 KB | alexpott |
| #13 | variable_initalize.patch | 4.02 KB | alexpott |
| #12 | variable_initalize.patch | 3.09 KB | chx |
Comments
Comment #2
jim0203 commentedSubscribe. variable_init() now variable_initialize() in Drupal 7.
Comment #3
chx commentedThis needs to put up a maintenance page with a nice message.
Comment #4
chx commentedwebchick asked for more hand holding here.Wrap the first if in a try-catch to make sure no exceptions are thrown when reading from the database or from cache. After that, check that the install_time variable is set -- given that's set by install.php it always will be set. If not then it's time to put up a maint page with a nice error message and leave.
Comment #5
sirkitree commentedNot sure what your definition of 'Novice' is, but by my definition, a novice would have no idea what to do here. So at risk of sounding like a complete novice myself, I ask that for a novice issue, please recommend at least a module to look at, if not an actual line number.
variable_init() looks like what?
D6: http://api.drupal.org/api/function/variable_init/6
D7: http://api.drupal.org/api/function/variable_initialize/7
Q: Where in the function is the problem?
A: The functions differ from D6 to D7 so there is an extra determination that must be made.
D6:
The error here is that it is assumed that the ...
D7:
The error here is...
Q: Where do I need to put a redirect to the maintenance page?
Q:How do I redirect to a maintenance page?
Q:How do I give the maintenance page a nice message?
Q:What are acceptable messages to give?
Sorry if this sounds just bothersome and inconsequential to you, but a novice would really have no idea and would most likely be asking these questions. I don't consider myself a novice, but I when it comes to D7 core, I must be since I am asking these questions. Though, a true 'novice' might not even know where to find these functions... not trying to be controversial, just encouraging you to keep it in perspective is all. And maybe tag with 'Intermediate' if a 'Novice' could not figure this out from the given information.
Comment #6
zserno commentedInteresting, so subscribing.
Comment #7
chx commentedI think sirkitree crossposted with me. The variable_initialize is in bootstrap.inc and short of writing the code myself I gave as much instructions I could, I think. There is no need to redirect -- you need to print a maint page. What message to give, well figure out one, that's a challenge yes but not insurmountable.
Comment #8
alexpottI'm not sure this is as simple as it first seems.
I tried changing the function to
This doesn't work as the function is called at this point in the bootstrap process the theme layer is not available. There does not appear to be a standard way of presenting an error page before the theme layer is loaded - is there?
Haha... that's why drupal_maintenance_theme() exists!!! Cross-posting strikes again...
Comment #9
chx commented@alexpott thanks for trying could you please read #4?
Comment #10
alexpott@chx
So I slotted this into the function...
just before the return... and I'm getting the white screen of death... which seems to be due to the theme_registry not loading correctly as this is returning nothing theme('maintenance_page', array('content' => t('Testing')))... with a few debug prints the theme function is returning nothing because theme_maintenance_page isn't set in $hooks:
I'm trying to investigate this further...
Comment #11
chx commentedThat will teach me what do I call novice... drupal_maintenance_theme does not behave as it should since the database is active.
Comment #12
chx commentedThis still needs a nice message and likely other polish but it will get you going.
Comment #13
alexpottUsed the same message as produced by _drupal_log_error() [in common.inc] as this message will be displayed any visitor to the site if the error occurs. The error will also generate a 503 http response with a retry time of 3 to indicate the site is temporarily unavailable.
The message is The website encountered an unexpected error. Please try again later.
Additionally, chx's original patch broke drupal installing as $variables is empty during an install so I've added a check on the global MAINTENANCE_MODE
Comment #14
damien tournoud commentedFrom #3, #4:
I believe this is dangerous and doesn't worth the effort. It is dangerous because invoking the maintenance page is somewhat heavy, and broken, as every one noted. It doesn't worth the effort because this will only happen in corner case. I would be *very* happy with just a guru meditation page.
Comment #15
moshe weitzman commentedComment #16
alexpottHere's a patch to generate a service unavailable based on the apache server 503 text and looking somewhat like Damien's guru mediation page.
There are a couple of things I don't like about this patch - it's not using the maintenance theme, it's putting html into bootstrap.inc, it's not translateable. However, because this is an edge case and will happen before Drupal is fully bootstrapped perhaps this is acceptable? It does have an advantage over using the maintenance theme because it is generating a 503 status rather a 500 which indicates the error is temporary.
Comment #17
Freso commentedApparently, I can't remove a tag without adding a comment. But I'm removing the "Novice" tag all the same.
Comment #18
ff1 commentedLast patch does not apply, so setting to 'needs work'.
Comment #19
PavanL commented