Created
November 7, 2013 01:09
-
-
Save pdrakeweb/7347198 to your computer and use it in GitHub Desktop.
Gluster v3.4.1 symlink bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Usage: | |
* | |
* Execute this script simultaneously on two separate gluster clients and you | |
* will see errors. Set the $gluster_path and $local_path variables below as | |
* needed for your environment. You may set $gluster_path to a different local | |
* path and then execute two copies of this on the same machine to prove that | |
* the problem does not occur with local filesystems. | |
*/ | |
// Set these values for your environment. | |
$gluster_path = '/mnt/gfs'; | |
$local_path = '/tmp'; | |
// Set up the target directory if it doesn't exist. | |
if (!is_dir("$gluster_path/test-target")) { mkdir("$gluster_path/test-target"); } | |
// Sync the system time, since we want to execute our actions as closely aligned | |
// as possible. | |
$sync_results = exec('ntpdate -u time-c.nist.gov'); | |
echo "Synced system time: $sync_results\n"; | |
// Run the symlink creation tests with and without clearing the stat cache | |
// before using is_link to ensure that this isn't a bug in PHP's stat cache. | |
test_symlinks(100, FALSE, $gluster_path, $local_path); | |
test_symlinks(100, TRUE, $gluster_path, $local_path); | |
/** | |
* Once each second, on the second, create a symlink on gluster to a directory | |
* on gluster. Then create a symlink on the local filesystem to the symlink we | |
* just created on gluster. We do this on the second in an attempt to collide | |
* with the other client. | |
* | |
* @param int $n | |
* The number of iterations to perform. | |
* @param bool $clearstatcache | |
* Whether we should clear the stat cache. | |
* @param string $gluster_path | |
* Path to a gluster mount or directory on a gluster mount. | |
* @param string $local_path | |
* Path to a local directory, such as tmp. | |
*/ | |
function test_symlinks($n = 100, $clearstatcache = TRUE, $gluster_path = '/mnt/gfs', $local_path = '/tmp') { | |
$old_testlink = NULL; | |
$i = 0; | |
$partial_failures = 0; | |
$total_failures = 0; | |
$gluster_failures = 0; | |
while($i < $n) { | |
// Set up our file paths. | |
$testsrc = $gluster_path . '/test-target'; | |
$testlink = $gluster_path . '/test' . time(); | |
$testlink2 = $local_path . '/test' . time(); | |
// Only run if the time has changed and we're at the start of a new second. | |
if ($testlink != $old_testlink) { | |
$old_testlink = $testlink; | |
$i++; | |
// If the symlink on gluster doesn't exist, attempt to create it. | |
if ($clearstatcache) { clearstatcache(); } | |
if (!is_link($testlink)) { | |
@symlink($testsrc, $testlink); | |
// If the symlink on gluster still doesn't exist, record a gluster | |
// failure. | |
if ($clearstatcache) { clearstatcache(); } | |
if (!is_link($testlink)) { | |
echo "Failed to create gluster link: $testlink.\n"; | |
$gluster_failures++; | |
continue; | |
} | |
} | |
// Create a local symlink to the gluster symlink. | |
@symlink($testlink, $testlink2); | |
// If the local symlink doesn't exist, we need to record a failure. | |
if ($clearstatcache) { clearstatcache(); } | |
if (!is_link($testlink2)) { | |
echo "Failed to create local link: $testlink2.\n"; | |
// Determine whether the failure is because the gluster symlink doesn't | |
// exist or if we just failed to create the local symlink to it. | |
if ($clearstatcache) { clearstatcache(); } | |
if (!is_link($testlink)) { | |
echo "Failed because target $testlink isn't actually a link."; | |
$partial_failures++; | |
} | |
else { | |
echo "But, target $testlink is actually a link.\n"; | |
$total_failures++; | |
} | |
} | |
} | |
} | |
// Output the results. | |
echo "\n\nClear Stat Cache: " . ($clearstatcache ? "TRUE" : "FALSE") . "\nAttempts: $i\nGluster Failures: $gluster_failures\nPartial Failures: $partial_failures\nTotal Failures: $total_failures\n\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment