Thanks to visit codestin.com
Credit goes to github.com

Skip to content

app/console cache:clear problem #19851

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MicWit opened this issue Sep 5, 2016 · 15 comments
Closed

app/console cache:clear problem #19851

MicWit opened this issue Sep 5, 2016 · 15 comments

Comments

@MicWit
Copy link

MicWit commented Sep 5, 2016

I notice there have been quite a few issues with clearing the cashe with the "php bin/console cache:clear --env=prod" command. I have the same issue and I am running Virtual Box with a windows host and a Linux (RHEL) guest, with the web files stored on the host using a Virtual Box share under Guest Additions. When I run the command it will come up with the error that the rmdir command could not be run on dir xyz (this dir changes every time) as it is not empty.

I have mucked around with the rm command in RHEL on the shared folder (stored on the host) and found it is the '/var/cache/pro~' dir that is causing the issues (even though it normally says in the error it is a sub directory of it).

After a bit more mucking around, I found it is the ~ character causing the issues. I'm not sure if this will cause issues if the web server is also on windows (is someone able to check this), but it will be an issue if you are using a server on a UNIX based system and storing your files on a windows file system.

@sstok
Copy link
Contributor

sstok commented Sep 5, 2016

Please try this, https://technet.microsoft.com/en-us/library/cc959352.aspx

Older Windows versions (FAT16) used the ~ for long filenames, XP and Vista kept this compatibility in NTFS and it's known to cause problems.

See also: https://support.microsoft.com/en-us/kb/121007

@MicWit
Copy link
Author

MicWit commented Sep 5, 2016

So I tested that reg setting. For some reason it was set to 2 when I first opened it. I set it to 1 and rebooted, but when I went back in it was set to 0 (having had it not work when I tested clearing the cache). Changed it back to 1 and rebooted, this time it kept setting, so tested clearing the cache. It worked the first time and then failed each time after that. Checked the reg setting and it was still set to 1.

I believe you are correct with the ~ being because of the backward compatibility, but this doesn't seem to help. I have also tried using "rm -R /var/www/html/sdemo/var/cache/pro~/doctrine" (or whatever folder it had the issue with last) and it still comes up with the error "rm: cannot remove ‘/var/www/html/sdemo/var/cache/pro~/doctrine’: Directory not empty".

I have also tested it a bunch of times to work out when it does and doesn't work and have found a pattern.
Scenario 1:
Step 1 - Browse the site: fails cache clear
Step 2 - Delete the ~pro folder: succeeds cache clear

Scenario 2:
Step 1 - Delete all files in cache folder: fails cache clear
Step 2 - Delete ~pro folder: succeeds cache clear

After I get the pass, as long as I don't touch anything else, I can keep having successful cache clears.

It seems that when I browse the site or delete all files in the cache (or both) it fails. I have to fail it once so that it makes the ~pro folder, and then delete that folder manually and then run the command to clear the cache again.

It seems this registry setting does not make a difference, and I am wondering if the reason it works is the cache is detected as having been cleared already so it never needs to create the pro~ directory.

Have also tested the dev environment and it does the same thing.

@sstok
Copy link
Contributor

sstok commented Sep 6, 2016

Hmm, it could be related to the filemtime. Make sure both systems use the same time, but that should not cause the rm -R to fail 🤔 I never used Virtualbox with Symfony.

It could be that an antivirus is conflicting or because Windows doesn't support chmod but the Linux does expect this.

@MicWit
Copy link
Author

MicWit commented Sep 7, 2016

So after doing some more research, I have found that this is not an issue with ~ and may not be a Symfony issue. It seems to be an issue with the way Virtual Box handles long names in the shared directory using guest additions. I have tried to reproduce this on other files however, and do not get this problem (they can be deleted like normal). Will continue to try work out why this is happening.

@MicWit MicWit closed this as completed Sep 7, 2016
@MicWit MicWit reopened this Sep 7, 2016
@MicWit
Copy link
Author

MicWit commented Sep 7, 2016

So when logged with strace, we get a bunch of files reporting (all files reported success):

[pid  2601] lstat("/var/www/html/tut1/var/cache/pro~/twig/c9", {st_mode=S_IFDIR|0777, st_size=0, ...}) = 0
[pid  2601] stat("/var/www/html/tut1/var/cache/pro~/twig/c9", {st_mode=S_IFDIR|0777, st_size=0, ...}) = 0
[pid  2601] openat(AT_FDCWD, "/var/www/html/tut1/var/cache/pro~/twig/c9", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 7
[pid  2601] getdents(7, /* 3 entries */, 32768) = 136
[pid  2601] lseek(7, 0, SEEK_SET)       = 0
[pid  2601] getdents(7, /* 3 entries */, 32768) = 136
[pid  2601] getdents(7, /* 0 entries */, 32768) = 0
[pid  2601] lstat("/var/www/html/tut1/var/cache/pro~/twig/c9/c92c9d9e8ac656d6abb252ca1d812cfa7e1c9f2f3ad5dd79adf20da8ac81e87f.php", {st_mode=S_IFREG|0777, st_size=925, ...}) = 0
[pid  2601] stat("/var/www/html/tut1/var/cache/pro~/twig/c9/c92c9d9e8ac656d6abb252ca1d812cfa7e1c9f2f3ad5dd79adf20da8ac81e87f.php", {st_mode=S_IFREG|0777, st_size=925, ...}) = 0
[pid  2601] unlink("/var/www/html/tut1/var/cache/pro~/twig/c9/c92c9d9e8ac656d6abb252ca1d812cfa7e1c9f2f3ad5dd79adf20da8ac81e87f.php") = 0
[pid  2601] close(7)                    = 0
[pid  2601] rmdir("/var/www/html/tut1/var/cache/pro~/twig/c9") = 0

And then when it goes to delete the dir that is in pro~:

[pid  2601] rmdir("/var/www/html/tut1/var/cache/pro~/twig") = -1 ENOTEMPTY (Directory not empty)
...
[pid  2601] write(4, "  Failed to remove directory \"/v"..., 119  Failed to remove directory "
/var/www/html/tut1/var/cache/pro~/twig": rmdir(/var/www/html/tut1/var/cache/pro~/twig):  ) = 119
[pid  2601] write(4, "\n", 1
)           = 1
[pid  2601] write(4, "   Directory not empty.         "..., 119   Directory not empty.                                                                                                ) = 119
[pid  2601] write(4, "\n", 1
)           = 1

at the ... there were over 1000 line more (the log is 31,000 lines long).

So its like it is sending the unlink command through guest additions to the host and it is being reported as deleted. However, when it goes to do the final rmdir, its finding that the files are actually still there.

If I reboot the guest (or re-mount the share) before running this command, it seems to work fine as well.

@mvrhov
Copy link

mvrhov commented Sep 7, 2016

Well this means that the Virtual platform you are using is lying to you.
What do you expect symfony should do?

@MicWit
Copy link
Author

MicWit commented Sep 8, 2016

I forgot to mention that I opened up an issue on the Oracle bug tracker: https://www.virtualbox.org/ticket/15897

I can't reproduce this issue outside of Symfony however, so it appears that it may still be a Symfony/file system problem. If I can get this problem to replicate, it may end up just being a case of changing a permission somewhere or something.

@MicWit
Copy link
Author

MicWit commented Sep 9, 2016

OK, did some more testing. I set up a test dir (under /var/www/html) and put index.php in it with the following code:

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

$root="/var/www/html/test/";

rename($root."prod/", $root."pro~/");

remove($root."pro~/");

function remove($files)
{
    echo "in function<br>";
    if ($files instanceof \Traversable) {
        $files = iterator_to_array($files, false);
    } elseif (!is_array($files)) {
        $files = array($files);
    }
    $files = array_reverse($files);
    print_r($files);
    echo "<br>";
    foreach ($files as $file) {
        print_r($file);
        echo "<br>";
        if (is_link($file)) {
            echo "file found <br>";
            // See https://bugs.php.net/52176
            if (!@(unlink($file) || '\\' !== DIRECTORY_SEPARATOR || rmdir($file)) && file_exists($file)) {
                $error = error_get_last();
                echo $error;
                throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, $error['message']));
            }
        } elseif (is_dir($file)) {
            echo "found Dir<br>";
            remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));

            if (!@rmdir($file) && file_exists($file)) {
                $error = error_get_last();
                throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, $error['message']));
            }
        } elseif (!@unlink($file) && file_exists($file)) {
            echo "Did Other thing<br>";
            $error = error_get_last();
            echo $error."<br>";
            throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, $error['message']));
        }
    }
}

?>

I copied the prod dir from a current symfony /var/www/html/var/cache/ dir to /var/www/html/test/ and ran this index.php file, and it did the rename and remove of the files as expected. What else is Symfony doing to these files in the clear cache process that I may have missed?

@mvrhov
Copy link

mvrhov commented Sep 9, 2016

Symfony needs the booted kernel and DIC and all the stuff in prod dir, to run a command, so it boots from that, then in the process of cache clear it creates pro~ dir with the new DIC and new cache then it tries to delete the old dir and rename the new dir into the old one. The problem here is when things cross various emulation layers like in your case that the dirs or files might get locked in the process. That's why I said that the symfony is unable to do anything as this is very complicated procedure.

@podorozhny
Copy link

+1

@noahheck
Copy link
Contributor

One thing that is different between your tests is that when running the console commands, you will be executing those as whichever user you are logged in as, while running your test from the browser will execute the unlink and rmdir instructions as the webserver user (www-data / apache). I wonder if you are simply having file system permissions issues.

I've experienced issues with the VBox shared folders in the past as well. To mitigate them, I now always keep the application files on the guest and expose them to the host using samba. It's a little more work, but it's easier to keep your application files running correctly.

@MicWit
Copy link
Author

MicWit commented Dec 12, 2016

We are now using a different directory for all logs, cache and session data anyhow, so this is no longer an issue for us. I think the issue is coming back to the fact that the files are on a windows machine so the permissions look pretty screwed from the Linux end. We didn't save them on the virtual machine and samba as our unix team requested we didn't for security and support reasons.

To get around this issue, one of the following needs to happen:

  1. Save the cache, logs and session data on the virtual drive and then you should be able to keep the rest on the share.
  2. Save everything on the virtual drive and share via samba so that permissions are not played with like virtual box does.
  3. Convince Oracle to change the way they do permissions on a shared drive to allow the permission to be kept once set in the virtual drive.

For this bug, my suggestion would be to write up a section in the documentation something like "Issues you may encounter when running in a virtual environment". Put up this and any other issues that come up and step by step ways to solve them. Just remember, quite often someone who wants to experiment with Symfony will play around with it in a virtual box, so having a work around problems in a virtual environment is important.

@Tobion
Copy link
Contributor

Tobion commented Dec 12, 2016

Closing as there doesn't seem to be done in code. I'd welcome you to write a doc section about this as you suggested in https://github.com/symfony/symfony-docs

@Tobion Tobion closed this as completed Dec 12, 2016
@oussaka
Copy link

oussaka commented Apr 16, 2017

For me the solution was to install winNFSd plugin and sync_type: nfs activation:

  • no more clear cache error.
  • better performance.

@VolCh
Copy link
Contributor

VolCh commented Jun 6, 2017

In my case (PHP in linux docker container on linux) it seems like related with "rename() does NOT work for directories across filesystems or devices. Only files" explained at http://php.net/manual/en/function.rename.php#113943 and https://bugs.php.net/bug.php?id=54097.

Do we need patch with workaround to try copy() with following unlink() or exec/system("mv ...") on rename() fails?

fabpot added a commit that referenced this issue Jun 14, 2017
…P bug (VolCh)

This PR was squashed before being merged into the 2.7 branch (closes #23092).

Discussion
----------

[Filesystem] added workaround in Filesystem::rename for PHP bug

[Filesystem] added workaround in Filesystem::rename for https://bugs.php.net/bug.php?id=54097

Standard PHP rename() of dirs across devices/mounted filesystems  produces confusing copy error & throws IOException in Filesystem::rename. I got it during console cache:clear  in the Docker environment. This PR possible fixes #19851 and other environment related issues.

Workaround is on \rename() fails try to Filesystem::mirror & Filesystem::remove if $origin is directory

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Commits
-------

3ccbc47 [Filesystem] added workaround in Filesystem::rename for PHP bug
symfony-splitter pushed a commit to symfony/filesystem that referenced this issue Jun 14, 2017
…P bug (VolCh)

This PR was squashed before being merged into the 2.7 branch (closes #23092).

Discussion
----------

[Filesystem] added workaround in Filesystem::rename for PHP bug

[Filesystem] added workaround in Filesystem::rename for https://bugs.php.net/bug.php?id=54097

Standard PHP rename() of dirs across devices/mounted filesystems  produces confusing copy error & throws IOException in Filesystem::rename. I got it during console cache:clear  in the Docker environment. This PR possible fixes symfony/symfony#19851 and other environment related issues.

Workaround is on \rename() fails try to Filesystem::mirror & Filesystem::remove if $origin is directory

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Commits
-------

3ccbc479da [Filesystem] added workaround in Filesystem::rename for PHP bug
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants