In my logs the following error is showing up directly after each cron.php run.


require_once(sites/all/modules/pathauto/pathauto.inc) [function.require-once]: failed to open stream: No such file or directory in /home/cherrybomb/dodsonandross.com/html/sites/all/modules/pathauto/pathauto.module on line 85.

<?php
/**
 * Include all Pathauto include files.
 */
function _pathauto_include() {
  $pathauto_path = drupal_get_path('module', 'pathauto');
  require_once("$pathauto_path/pathauto.inc");                   /** LINE 85 **/
  require_once("$pathauto_path/pathauto_node.inc");
  require_once("$pathauto_path/pathauto_taxonomy.inc");
  require_once("$pathauto_path/pathauto_user.inc");
}
?>

I checked the server and the file does exist. Any clue why this might be happening?

CommentFileSizeAuthor
#9 pathauto_include_optimization.patch1.5 KBjwilson3
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jwilson3’s picture

Is this http://drupal.org/node/331357, rearing its nasty head?

jazzdrive3’s picture

I'm getting this error as well. Just started happening in the past week or so.

It's preventing my site from being indexed by search at cron. Which is very critical!

Any news on this?

jazzdrive3’s picture

Priority: Normal » Critical

I'm going to make this critical, because shutting down search is pretty serious, especially with my site.

As a test, I changed line 85 to an include_once so it went on, but then the require_once for pathauto_node.inc failed. So it seems all the pathauto stuff is failing during a cron run.

greggles’s picture

Status: Active » Closed (duplicate)

@jazzdrive3 - please test out the solution in #331357: Requires are unanchored because this seems like a duplicate.

greggles’s picture

Status: Closed (duplicate) » Active

jrguitar did some awesome investigation in http://drupal.org/node/331357#comment-1186315

The real question to me is: why is pathauto getting called during cron?

That is not generally recommended nor supported. If we can make Pathauto work in that scenario then that's fine, but I don't plan to put a lot of work into it at this point.

jwilson3’s picture

Title: require_once failure during cron with akismet module » require_once failure during cron
Priority: Normal » Critical
Status: Needs review » Active

UPDATED: the solution in this entry is not ideal; please skip down to #9 and try that patch...

This problem was tracked down to a limitation of php's register_shutdown_function(). And in particular, the combination of the way Akismet module has decided to code their cron processing as a shutdown function. To answer the question above, Akismet is making the pathauto module get called during cron! -- i didnt investigate exactly what point, but its definitely part of the akismet_cron_shutdown() function in the akismet_cron.inc file. That function is registered as a shutdown function during a normal akismet_cron() run. (See final thoughts below for more on this)

Note the following comments from the register_shutdown_function page on php.net:

If you want to do something with files in function, that registered in register_shutdown_function(), use ABSOLUTE paths to files instead of relative. Because when script processing is complete current working directory chages to ServerRoot (see httpd.conf)

This means that require_once "path/to/script" (or similar constructs) with relative paths will not work in shutdown functions.

Research

Taking ideas from Drupal's conf_init() I tried to gain access to the Drupal install dir, based on the script path but it doesnt work, and i tried using both PHP_SELF and SCRIPT_NAME, with no success:

$_SERVER['PHP_SELF'] is set to "/cron.php"
$_SERVER['SCRIPT_NAME'] is set to "/"
dirname($_SERVER['PHP_SELF']) gives me '/'

Solution

Hardcoding the path to Drupal root seems really too hackish, and since database activity seems to work alright during a shutdown function, I've implemented a db-cached global variable. Setting 'path_to_drupal' during normal pathauto module execution and then using variable_get() inside the _pathauto_include() function. It currently solved the errors and allowed Akismet to finish its processing. Unfortunately the problem lies deeper than just Akismet modules dependence on the register_shutdown_function.

At the top of pathauto.module I added:

if (getcwd() != "/") variable_set('path_to_drupal',getcwd());

then inside the _pathauto_incude() function i added:

if (getcwd() == "/") chdir(variable_get('path_to_drupal','/'));

I'm not going to submit a patchfile (unless someone specifically wants it) since this seems to be a bit of an edge case that requires akismet module and pathauto module. It could potentially and unwittingly happen with any combination of modules... and so maybe this will help someone else if they run into the same problem.

Final Thoughts
The ServerRoot issue with register_shutdown_function() is somewhat moot, its not going to change anytime soon. But it feels like the cause of the error I'm encountering could be addressed in some way by Drupal core. Akismet seems to want to run their cron tasks last, and AFAIK there's no way to ensure a specific module's hook gets run last.

greggles’s picture

Title: require_once failure during cron » require_once failure during cron with akismet module
Priority: Critical » Normal

Very interesting...given the fact that this only impacts Pathauto when Akismet is installed and given that Akismet is only somewhat popular I'm downgrading the priority.

I believe the problem comes because Akismet deletes content during cron which calls node_invoke_nodeapi($node, 'delete'); which calls pathauto_nodeapi with an op of delete.

We could make Pathauto's hook_nodeapi a little smarter so that it only does the includes for presave, insert, and update operations which should make this problem go away and provide a very tiny performance boost for delete operations.

Thoughts? Care to try that out?

jwilson3’s picture

"given that Akismet is only somewhat popular"

on D6 I would agree, guess people are going for mollom now.... but akismet still beats mollom for D5.

I'll test out your suggestion.

jwilson3’s picture

Status: Active » Needs review
FileSize
1.5 KB

Your suggestion also works. Since this actually is an optimization, albeit tiny, I went ahead and rolled a patch for it.

I optimized the logic for when to execute _pathauto_include() in the following 3 functions for consistency because they all use the same switch logic and, in all 3 cases, the case 'delete' doesn't require any includes.

  • pathauto_nodeapi()
  • pathauto_taxonomy()
  • pathauto_user()
greggles’s picture

In a visual review this looks fine to me. We should probably do this for all three branches.

TCRobbert’s picture

I ran into a similar problem, but a few things are different.
First of all im on Dru 6
Second im not running Akismet.

Yet it seemed to be the exact same error and after trying a few things it appeared that it would work with the solution mentioned above -> http://drupal.org/node/337615#comment-1186480

Just wanted to let you know this problem does seem to be occurring on more instances. As the website im working for is currently in development and already runs more than 60 modules, im going to spare you the list ;)

greggles’s picture

@TCRobbert - could you test the patch provided in #10?

TCRobbert’s picture

@greggles
I tested the patch provided in #9 this does also seem to work. At least I do no longer have the error. I have not tested if functionality remains the same, but I assume it does (I havent run in any other errors so far).

bago’s picture

I have the issue also in trackback. Trackback uses register_shutdown_function and inside that function calls a drupal_render that in turn calls pathout that throw this error.

The fix in #6 works, but probably it is better to use a GLOBALS variable instead of a variable_set that require a db update.

greggles’s picture

@bago - please test the patch in #9. The idea in #6 is not ideal.

bago’s picture

Title: require_once failure during cron » require_once failure during cron with akismet module
Priority: Critical » Normal
Status: Active » Needs review

@greggles: in the specific trackback case #9 works, but #9 does not fix the case where some update is done to a node/taxonomy/user in a shutdown function. Not sure if this case is important and valid at all. We kept the #6 with GLOBALS instead of the variable_set/get, ATM.

kenorb’s picture

Maybe you should change:

$pathauto_path = drupal_get_path('module', 'pathauto');

to:

$pathauto_path = './'. drupal_get_path('module', 'pathauto');
kenorb’s picture

apaderno’s picture

Title: require_once failure during cron with akismet module » require_once failure

That is the exactly the reason the code fails to load the include file. The bug is not caused in any way from the presence of askimet.module.

To add the ./ in front of file names passed to require_once is also made from code used by Drupal; just to make an example, this is the code used for module_load_include():

function module_load_include($type, $module, $name = NULL) {
  if (empty($name)) {
    $name = $module;
  }

  $file = './'. drupal_get_path('module', $module) ."/$name.$type";

  if (is_file($file)) {
    require_once $file;
  }
  else {
    return FALSE;
  }
}

This code present in Drupal 6 core code, but that doesn't matter. It's clear that it uses $file = './'. drupal_get_path('module', $module) ."/$name.$type".

apaderno’s picture

Status: Needs review » Needs work

The patch attached to the ninth comment needs to be re-written as it doesn't correct the _pathauto_include() function, which is the only responsible of the issue reported here.

greggles’s picture

@kiam - we have an issue for that problem, it is #331357: Requires are unanchored and has a patch. jrquitar21 tried out the patch in that issue and it didn't solve the problem. I think these are two separate issues.

apaderno’s picture

From the description given from who opened the report I would think the problem is that.

In my logs the following error is showing up directly after each cron.php run.

require_once(sites/all/modules/pathauto/pathauto.inc) [function.require-once]: failed to open stream: No such file or directory in /home/cherrybomb/dodsonandross.com/html/sites/all/modules/pathauto/pathauto.module on line 85.

jwilson3’s picture

@kiam: although the error message is a result of execution of said function, the /reason/ it was happening is because that func was getting executed inside of a shutdown_function() routine. The solution was to simply not call that function during shutdown, which is what the patch in #9 does. Please read message #7 because the patch is based off the explanation and suggestion there.

jwilson3’s picture

@greggles: if you have ability we might change the title of this thread to "require_once failure on cron run" or something like that since it elaborates the special case here...

greggles’s picture

Title: require_once failure » require_once failure on cron with modules that have a register_shutdown_function

Thanks for the feedback, jrguitar21. Makes sense to me.

kenorb’s picture

kenorb’s picture

Status: Needs work » Reviewed & tested by the community

Tested #9 and it's working fine.

Freso’s picture

Version: 5.x-2.3 » 7.x-1.x-dev
Status: Reviewed & tested by the community » Fixed

Committed to 6.x-2.x, 6.x-1.x, and 5.x-2.x. :)

gpk’s picture

For info, re. #6 and #7 (unless I'm off-track..), the reason Drupal 7 defines and uses the constant DRUPAL_ROOT http://api.drupal.org/api/constant/DRUPAL_ROOT/7 is precisely to get round the problem of the cwd changing when inside a shutdown function. #259623: Broken autoloader: convert includes/requires to use absolute paths

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

greggles’s picture

This seems to have caused a regression in #428332: Call to undefined function pathauto_get_placeholders(). Fixing now...

Alexander Ufimtsev’s picture

Just moved a D5 website from RHEL5 to Ubuntu LTS 8.04 and started having this problem. Fix at #17 alone did not help, it was a combination of #17 and #9 that solved the problem for me. Basically, I ended up using the latest 5.x-dev version of pathauto. Thanks, guys!

gpk’s picture

Yes, although the fix above was committed on March 21 this year, the latest releases (6.x-1.1, 5.x-1.3) date from June 26 last year...