How to fix “touch(): Utime failed: Operation not p

2020-02-15 05:12发布

问题:

I want to caching some response with symfony\cache. But I've got some error with my cache and sometime with the symfony default cache.

Configuration :

Debian 9 on vagrant (with vagrant bindfs link to source code directory) with Apache2
php 7.2 / symfony 4.1
apcu enabled

For caching my response I use the FilesystemAdapter with dir {projectDir}/var/cache/{env}/api-cache and namespace app.cache

var/cache/

drwxrwxrwx 24 vagrant www-data 768 Apr 24 09:09 dev/
drwxrwxrwx 13 vagrant www-data 416 Apr 18 16:02 test/

var/cache/dev/

-rw-rw-rw-   1 vagrant www-data  165 Apr 24 09:09 annotations.map
-rw-rw-rw-   1 vagrant www-data  12K Apr 24 09:09 annotations.php
drwxrwxrwx   3 vagrant www-data   96 Apr 23 17:47 api-cache/
drwxrwxrwx 399 vagrant www-data  13K Apr 23 17:46 ContainerBrT4sD3/
-rw-rw-rw-   1 vagrant www-data    0 Apr 24 09:07 ContainerBrT4sD3.legacy
drwxrwxrwx 404 vagrant www-data  13K Apr 24 09:09 ContainerSaE63B9/
drwxrwxrwx   3 vagrant www-data   96 Apr 23 17:46 doctrine/
drwxrwxrwx   6 vagrant www-data  192 Apr 23 17:47 jms_serializer/
drwxrwxrwx   5 vagrant www-data  160 Apr 24 09:07 pools/
-rw-rw-rw-   1 vagrant www-data 220K Apr 24 09:09 srcDevDebugProjectContainerCompiler.log
-rw-rw-rw-   1 vagrant www-data 1.1K Apr 24 09:09 srcDevDebugProjectContainerDeprecations.log
-rw-rw-rw-   1 vagrant www-data  767 Apr 24 09:09 srcDevDebugProjectContainer.php
-rw-rw-rw-   1 vagrant www-data  58K Apr 24 09:09 srcDevDebugProjectContainer.php.meta
-rw-rw-rw-   1 vagrant www-data  49K Apr 23 17:46 srcDevDebugProjectContainerUrlGenerator.php
-rw-rw-rw-   1 vagrant www-data 5.4K Apr 23 17:46 srcDevDebugProjectContainerUrlGenerator.php.meta
-rw-rw-rw-   1 vagrant www-data  78K Apr 23 17:46 srcDevDebugProjectContainerUrlMatcher.php
-rw-rw-rw-   1 vagrant www-data 5.4K Apr 23 17:46 srcDevDebugProjectContainerUrlMatcher.php.meta
-rw-rw-rw-   1 vagrant www-data 519K Apr 24 09:09 srcDevDebugProjectContainer.xml
-rw-rw-rw-   1 vagrant www-data  58K Apr 24 09:09 srcDevDebugProjectContainer.xml.meta
drwxrwxrwx 108 vagrant www-data 3.4K Apr 23 17:46 translations/
drwxrwxrwx 142 vagrant www-data 4.5K Apr 24 09:09 twig/
-rw-rw-rw-   1 vagrant www-data   91 Apr 24 09:09 validation.php

Log for default symfony code :

 cache.WARNING: Failed to save key "%5B%5BC%5DApp%5CEntity%5CReport%5CReportItem%24hasBeenPushed%5D%5B1%5D" (integer) {"key":"%5B%5BC%5DApp%5CEntity%5CReport%5CReportItem%24hasBeenPushed%5D%5B1%5D","type":"integer","exception":"[object] (ErrorException(code: 0): touch(): Utime failed: Operation not permitted at /vagrant-bindfs/vendor/symfony/cache/Traits/FilesystemCommonTrait.php:90)"} []

Logs with my code :

php.DEBUG: User Warning: Failed to save key "my_tag" (string) {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\SilencedErrorContext: {\"severity\":512,\"file\":\"/vagrant-bindfs/vendor/symfony/cache/CacheItem.php\",\"line\":184,\"trace\":[{\"file\":\"/vagrant-bindfs/vendor/symfony/cache/Adapter/AbstractAdapter.php\",\"line\":242,\"function\":\"log\",\"class\":\"Symfony\\\\Component\\\\Cache\\\\CacheItem\",\"type\":\"::\"}],\"count\":1})"} []
app.ERROR: Cache not save : my_tag [] []

When I log some information about the exception in Symfony\Component\Cache\Adapter\AbstractAdapter->commit() I got this : ErrorException touch(): Utime failed: Operation not permitted

I already search a solution but nothing works. I think it's a problem of right on the cache directories and maybe a problem with vagrant and vagrant-binfs but I do not understand it.

What can I do/check to solve this ?

回答1:

I had the same problem.

All you need to do is change the type of the synced_folder to nfs, but that option only works with Mac hosts.

To be able to use it in Windows, you need to install vagrant-winnfsd

$ vagrant plugin install vagrant-winnfsd

Then change the type of the synchronisation in your Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.synced_folder "../project", "/var/www", type: "nfs"
end

The documentation says that it is also needed to change the type of the network to dhcp, but I didn't need to do that to solve my problem.

config.vm.network "private_network", type: "dhcp"

I hope this helped



回答2:

If you happened to use FAT/FAT32 or another file system with severely limited timestamp range, then that warning is to be expected.

Symfony's FilesystemCommonTrait::write() method calls touch() function with unix timestamp 0 to force expire cached content. Unix timestamp 0 represents 1970-01-01 date. In FAT file system the allowed timestamp range is 1980-01-01 to 2099-12-31, according Wikipedia. So the touch() function fails and a warning is issued.

The workaround is to modify the FilesystemCommonTrait::write() method, around line 80.

Find lines:

if (null !== $expiresAt) {
    touch($this->tmp, $expiresAt);
}

Insert before those lines:

if (0 === $expiresAt) {
    $expiresAt = time() - 1;
}

This should achieve virtually the same result by instantly expiring the cached content, but without using an invalid file system timestamp.

Alternatively, change the file system type.