WordPress.org

Make WordPress Core

Opened 16 months ago

Closed 14 months ago

Last modified 14 months ago

#38024 closed defect (bug) (fixed)

fs_unavailable while auto-updating several plugins in a row

Reported by: benjaminniess Owned by: dd32
Milestone: 4.7 Priority: normal
Severity: normal Version: 4.6
Component: Upgrade/Install Keywords: has-patch needs-testing
Focuses: Cc:

Description

It seems that when we have several plugins to auto-update, the process breaks after the first plugin update, sending back a WP_Error (fs_unavailable) with the message "Could not access filesystem"

I've run through the "upgrade" function wp-admin/includes/class-plugin-upgrader.php (Line 146) and saw that after the first updated plugin, the $current variable is empty in:

$current = get_site_transient( 'update_plugins' );

The "update_plugins" transient is empty because at the end of the upgrade process (wp-admin/includes/class-wp-upgrader Line 791), there's a hook:

do_action( 'upgrader_process_complete', $this, $options['hook_extra'] );

and attached to this hook we have the "wp_clean_plugins_cache" which delete the transient.
At the next plugin update iteration, the transient is empty and we get this WP_error

Attachments (3)

38024.diff (2.6 KB) - added by ronalfy 16 months ago.
Patch to add is_multi to automatic updater
38024.2.diff (9.9 KB) - added by dd32 14 months ago.
test.php (930 bytes) - added by dd32 14 months ago.

Download all attachments as: .zip

Change History (25)

#1 @agenciesFirst
16 months ago

agree with you, I uncommented the first" add filter" in "class-plugin-upgrader.php (comment out Line 172)", also in "class-theme-upgrader.php (comment out Line 273 ) as an quick workaround and viola, automatic updates now also working with the plugin: "Easy Updates Manager".
All the updatable items going succsessfully thru without WP_Error (fs_unavailable).

Thanks to benjaminniess

Last edited 16 months ago by agenciesFirst (previous) (diff)

#2 @ronalfy
16 months ago

Can confirm the same behavior is happening with automatic updates to themes.

#3 @ronalfy
16 months ago

I think I know where the problem lies, just not enough time to dig in completely atm.

The problem is easy to duplicate through the code.

It starts in wp-admin/includes/class-wp-automatic-upgrader.php.

On line 392, the foreach is run for the available plugins/themes to update. Source

On line 330 is the call for the upgrade method for the appropriate plugins or themes. Source.

Using plugins as an example, in wp-admin/includes/class-plugin-upgrader.php on line 172/174 (Source) is the call to clear the plugin cache and run the run method for the WP_Upgrader parent class. Note that is_multi is not being sent as an argument.

In wp-admin/includes/class-wp-upgrader.php, since is_multi is false, it runs the action upgrader_process_complete after the first iteration of a plugin or theme. Source, which I believe is clearing the plugin cache and causing the errors.

Last edited 16 months ago by ronalfy (previous) (diff)

This ticket was mentioned in Slack in #core by ronaldhuereca. View the logs.


16 months ago

#5 @ronalfy
16 months ago

The way to duplicate fs_unavailable is when $current is unavailable in L157, the method returns false.

In class-wp-automatic-updater.php L341 returns the file system error after false is returned.

@ronalfy
16 months ago

Patch to add is_multi to automatic updater

#6 @ronalfy
16 months ago

  • Keywords has-patch needs-testing added

Above patch adds the is_multi flag to automatic update items, resolving the fs_unavailable errors due to upgrader_process_complete clearing the plugin/theme transients before the upgrade cycle has finished.

This bug has been present since 4.6.0.

This ticket was mentioned in Slack in #core by ronaldhuereca. View the logs.


16 months ago

#8 @helen
16 months ago

  • Milestone changed from Awaiting Review to 4.6.2
  • Owner set to dd32
  • Status changed from new to reviewing
  • Version changed from 4.6.1 to 4.6

Assigning to @dd32 for review and putting it into the 4.6.2 milestone for now, so it doesn't get lost.

This ticket was mentioned in Slack in #forums by matthew. View the logs.


16 months ago

This ticket was mentioned in Slack in #forums by t-p. View the logs.


16 months ago

#11 @dd32
15 months ago

I haven't had a chance to review this yet, but my gut feeling is that setting is_multi in this form is the incorrect approach, I could be completely wrong though as it's been a long time since I've touched this code.

#12 @ronalfy
15 months ago

@dd32 it makes sense to me in a way that background updates should be treated like bulk updates.

#13 @ronalfy
15 months ago

@ocean90 have you had a chance to look at this? Maybe get this on the 4.7 or 4.7.1 milestone? Bug is super annoying :)

`
WordPress site: http://exampledomain.com/
The following plugins were successfully updated:

  • SUCCESS: CMB2
  • SUCCESS: Yoast SEO

UPDATE LOG
==========

CMB2


Updating plugin: CMB2
Downloading update from https://downloads.wordpress.org/plugin/cmb2.zip...
Unpacking the update...
Installing the latest version...
Removing the old version of the plugin...
Plugin updated successfully.

Yoast SEO


Updating plugin: Yoast SEO
The plugin is at the latest version.
Error: [fs_unavailable] Could not access filesystem.

`

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


15 months ago

This ticket was mentioned in Slack in #core by dd32. View the logs.


15 months ago

@dd32
14 months ago

@dd32
14 months ago

#16 @dd32
14 months ago

Traced this back to [37272] & [34751] which forcibly clears the update caches during the update, rather than respecting the parameters passed in.

We could pass the is_multi flag, but that doesn't actually fix anything, it simply avoids running the upgrader_process_complete action, which is what the problematic cache-clearing functions are hooked onto, it also happens to be the action that other things are hooked onto, so if we were to do that, we'd need to duplicate that action out into the automatic updater, not something I feel like doing right now.

38024.2.diff fixes this by rejigging the cache clearing to happen when it should, and also to respect the parameter which specifies to clear the cache or not. I'm posting here for others to test and review, I'll finish up reviewing it tomorrow and commit.
test.php is my CLI script for testing that the autoupdate is working; patch src, add some out-of-date plugins to it, and run that.. it does a grunt file copy, kicks off a background update and displays the email message on the command line.

I've tested and confirmed that translation installation appears to work as expected for the various update flows in WordPress, even the ones that are absolutely impossible to trigger now thanks to JS.

We could backport these to 4.4+ (which [37272] was in), but I'm okay with 4.7+ only. My reasoning is that the plugin background updates will be done the next time the cron is run (2~4 times daily) and it's not that often for multiple plugins to get updates within the same update check period. Those with background updates enabled for plugins are also more likely keeping up with major version updates, so they'll get the fixes anyway.

cc @ocean90

This ticket was mentioned in Slack in #core by dd32. View the logs.


14 months ago

#18 follow-up: @afragen
14 months ago

@dd32 I think this is the same issue I've run into when attempting multiple shiny updates on the plugins.php page. After having traced through the code I've found the exact same issue as originally described.

I was able to reset the update transient using the wp_get_update_data hook, but this is clearly not ideal. My point, yes, I finally got to it, is that I think the fix should be backported to 4.4+ because it doesn't only deal with automatic upgrades.

I'll try to test the code and see if it also fixes my issue.

#19 in reply to: ↑ 18 @afragen
14 months ago

Replying to afragen:

@dd32 I think this is the same issue I've run into when attempting multiple shiny updates on the plugins.php page. After having traced through the code I've found the exact same issue as originally described.

I was able to reset the update transient using the wp_get_update_data hook, but this is clearly not ideal. My point, yes, I finally got to it, is that I think the fix should be backported to 4.4+ because it doesn't only deal with automatic upgrades.

I'll try to test the code and see if it also fixes my issue.

After testing this patch doesn't seem to effect my issue. I was hopeful. Thought it might be related to #22377, but not.

#20 @dd32
14 months ago

  • Milestone changed from 4.6.2 to 4.7

Bumping to 4.7, based on my comments above in comment 16.

#21 @dd32
14 months ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 39211:

Updates: Allow background updates to update multiple plugins/themes in the same request.
Due to the clear_update_cache parameter not being respected, update caches were being cleared incorrectly which prevented multiple plugins to be updated at the same time in background updates - failing with a fs_unavailable error message.

Fixes #38024

#22 @aglyons
14 months ago

this sounds like what I am experiencing. I was prompted to add however that in my instance, the .maintenance file is getting created, locking the site down. Since the updates never complete, the site never gets unlocked unless done so manually via ftp.

kudos on all your great work.

Note: See TracTickets for help on using tickets.