Пример #1
0
 /**
  * Purges test devices/volumes prior to testing. Purge methods are determined 
  * by the type and capabilities of the target devices/volumes and the runtime 
  * arguments --nosecureerase, --notrim and --nozerofill. Returns TRUE on 
  * success, FALSE otherwise. Purge methods are tracked on a per device basis 
  * using the instance variable $purgeMethods
  * @return boolean
  */
 public final function purge()
 {
     $purgeCount = 0;
     $nopurge = isset($this->options['nopurge']) && $this->options['nopurge'];
     $nosecureerase = isset($this->options['nosecureerase']) && $this->options['nosecureerase'];
     $notrim = isset($this->options['notrim']) && $this->options['notrim'];
     $nozerofill = isset($this->options['nozerofill']) && $this->options['nozerofill'];
     if (!$nopurge) {
         foreach ($this->options['target'] as $target) {
             $purged = FALSE;
             $volume = BlockStorageTest::getVolume($target);
             $rotational = BlockStorageTest::isRotational($target);
             print_msg(sprintf('Attempting to purge %srotational target %s with --nosecureerase=%d; --notrim=%d; --nozerofill=%d', $rotational ? '' : 'non-', $target, $nosecureerase ? '1' : '0', $notrim ? '1' : '0', $nozerofill ? '1' : '0'), $this->verbose, __FILE__, __LINE__);
             // try ATA secure erase
             if ($this->deviceTargets && !$nosecureerase) {
                 print_msg(sprintf('Attempting ATA secure erase for target %s', $target), $this->verbose, __FILE__, __LINE__);
                 $cmd = sprintf('hdparm --user-master u --security-erase "%s" %s >/dev/null 2>&1; echo $?', $this->options['secureerase_pswd'], $target);
                 $ecode = trim(exec($cmd));
                 if ($ecode > 0) {
                     print_msg(sprintf('ATA secure erase not supported or failed for target %s', $target), $this->verbose, __FILE__, __LINE__);
                 } else {
                     print_msg(sprintf('ATA secure erase successful for target %s', $target), $this->verbose, __FILE__, __LINE__);
                     $this->purgeMethods[$target] = 'secureerase';
                     $purged = TRUE;
                 }
             } else {
                 print_msg(sprintf('ATA secure erase not be attempted for %s because %s', $target, $nosecureerase ? '--nosecureerase argument was specified (or implied due to lack of --secureerase_pswd argument)' : 'it is not a device'), $this->verbose, __FILE__, __LINE__);
             }
             // next try TRIM
             // if (!$purged && !$rotational && !$notrim) {
             if (!$purged && !$notrim) {
                 $cmd = sprintf(($this->deviceTargets ? 'blkdiscard' : 'fstrim') . '%s %s >/dev/null 2>&1; echo $?', $this->deviceTargets && isset($this->options['trim_offset_end']) && $this->options['trim_offset_end'] > 0 ? sprintf(' -o 0 -l %d', BlockStorageTest::getFreeSpace($target, TRUE) - $this->options['trim_offset_end']) : '', $this->deviceTargets ? $target : $volume);
                 print_msg(sprintf('Attempting TRIM for volume %s using command %s', $volume, $cmd), $this->verbose, __FILE__, __LINE__);
                 $ecode = trim(exec($cmd));
                 if ($ecode > 0) {
                     print_msg(sprintf('TRIM not supported or failed for target %s (exit code %d)', $target, $ecode), $this->verbose, __FILE__, __LINE__);
                 } else {
                     print_msg(sprintf('TRIM successful for target %s', $target), $this->verbose, __FILE__, __LINE__);
                     $this->purgeMethods[$target] = 'trim';
                     $purged = TRUE;
                 }
             } else {
                 if (!$purged) {
                     print_msg(sprintf('TRIM not attempted for target %s because %s', $target, $notrim ? '--notrim argument was specified' : 'device is rotational'), $this->verbose, __FILE__, __LINE__);
                 }
             }
             // finally try zero filling
             if (!$purged && !$nozerofill) {
                 $size = BlockStorageTest::getFreeSpace($target);
                 // adjust for active range and volume target free space buffer
                 if ($this->options['active_range'] < 100) {
                     $size *= $this->options['active_range'] * 0.01;
                 } else {
                     if ($this->volumeTargets) {
                         $size -= BlockStorageTest::BLOCK_STORAGE_TEST_FREE_SPACE_BUFFER;
                     }
                 }
                 $size = round($size);
                 if ($size < 1) {
                     print_msg(sprintf('Target %s does not have sufficient space (%d MB) to accomodate free space buffer (%d MB)', $target, $size + BlockStorageTest::BLOCK_STORAGE_TEST_FREE_SPACE_BUFFER, BlockStorageTest::BLOCK_STORAGE_TEST_FREE_SPACE_BUFFER), $this->verbose, __FILE__, __LINE__, TRUE);
                 } else {
                     print_msg(sprintf('Attempting to zero fill target %s with %d MB. This may take a while...', $target, $size), $this->verbose, __FILE__, __LINE__);
                     $cmd = sprintf('dd if=/dev/zero of=%s bs=1M count=%d >/dev/null 2>&1; echo $?', $file = $target . ($this->volumeTargets ? '/' . BlockStorageTest::BLOCK_STORAGE_TEST_FILE_NAME : ''), $size);
                     $ecode = trim(exec($cmd));
                     // delete zero file from volume type targets
                     if ($this->volumeTargets) {
                         print_msg(sprintf('Removing temporary zero fill file %s', $file), $this->verbose, __FILE__, __LINE__);
                         exec(sprintf('rm -f %s', $file));
                     }
                     if ($ecode > 0) {
                         print_msg(sprintf('Zero fill failed for target %s (exit code %d)', $target, $ecode), $this->verbose, __FILE__, __LINE__);
                     } else {
                         print_msg(sprintf('Zero fill successful for target %s', $target), $this->verbose, __FILE__, __LINE__);
                         $this->purgeMethods[$target] = 'zero';
                         $purged = TRUE;
                     }
                 }
             } else {
                 if (!$purged) {
                     print_msg(sprintf('Zero fill not attempted for target %s because %s', $target, $nozerofill ? '--nozerofill argument was specified' : 'it is not a device'), $this->verbose, __FILE__, __LINE__);
                 }
             }
             if ($purged) {
                 print_msg(sprintf('Target %s purged successfully using %s', $target, $this->purgeMethods[$target]), $this->verbose, __FILE__, __LINE__);
                 $purgeCount++;
             } else {
                 print_msg(sprintf('Target %s could not be purged', $target), $this->verbose, __FILE__, __LINE__);
             }
         }
     }
     return $purgeCount == count($this->options['target']);
 }