Last active
August 29, 2015 14:05
-
-
Save pdrakeweb/ae046b4c70a42309be43 to your computer and use it in GitHub Desktop.
Gluster 3.4.1 directory permissions 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
#!/usr/bin/env php | |
<?php | |
/** | |
* Usage: | |
* | |
* Execute this script simultaneously on two separate gluster clients and you | |
* will see errors. Set the $gluster_path variables below as needed for your | |
* environment. You may set $gluster_path to a non-gluster 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. | |
$uid = 9999; | |
$username = 'testuser'; | |
$gid = 9999; | |
$groupname = 'testgroup'; | |
$gluster_path = '/mnt/gfs'; | |
$wait_for_gluster = 20; | |
// 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"; | |
// Set up users | |
exec("groupadd -g $gid $groupname"); | |
exec("useradd -u $uid -g $gid $username"); | |
// Run the directory creation test. | |
$success = test_dircreate(300, $uid, $gid, FALSE, "$gluster_path/test-target", $wait_for_gluster); | |
exit($success); | |
/** | |
* Once each 1/10 second, on 1/10 second, create a directory. | |
* | |
* @param int $n | |
* The number of iterations to perform. | |
* @param int $uid | |
* The number of iterations to perform. | |
* @param int $gid | |
* 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. | |
*/ | |
function test_dircreate($n, $uid, $gid, $clearstatcache, $test_root_path, $wait_for_gluster) { | |
$old_testpath = NULL; | |
$i = 0; | |
$final_count = 0; | |
$reported_count = 0; | |
while($i < $n) { | |
// Set up our file path. | |
$testpath = "$test_root_path/test" . round(microtime(TRUE), 1); | |
// Only run if the time has changed and we're at the start of a new 1/10 second. | |
if ($testpath != $old_testpath) { | |
$old_testpath = $testpath; | |
$i++; | |
// If the symlink on gluster doesn't exist, attempt to create it. | |
if ($clearstatcache) { clearstatcache(); } | |
if (!is_dir($testpath)) { | |
@mkdir($testpath, 0550); | |
chown($testpath, $uid); | |
chgrp($testpath, $gid); | |
if (fileowner($testpath) != $uid || filegroup($testpath) != $gid) { | |
echo "Failed to create properly permissioned dir: $testpath.\n"; | |
$reported_count++; | |
continue; | |
} | |
else { | |
echo "Create properly permissioned dir: $testpath.\n"; | |
} | |
} | |
} | |
} | |
// Wait for gluster to finish doing stuff, in case it is planning to be | |
// eventually consistent. | |
sleep($wait_for_gluster); | |
foreach(glob("$test_root_path/*") as $testpath) { | |
if (fileowner($testpath) != $uid || filegroup($testpath) != $gid) { | |
echo "Actually failed to create properly permissioned dir: $testpath.\n"; | |
$final_count++; | |
continue; | |
} | |
} | |
// Output the results. | |
echo "\n\nClear Stat Cache: " . ($clearstatcache ? "TRUE" : "FALSE") . "\nAttempts: $i\nReported Inconsistencies: $reported_count\nFinal Inconsistencies: $final_count\n\n"; | |
return ($final_count == 0) ? 0 : 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment