HMCTxnUtils.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. /*
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one
  5. * or more contributor license agreements. See the NOTICE file
  6. * distributed with this work for additional information
  7. * regarding copyright ownership. The ASF licenses this file
  8. * to you under the Apache License, Version 2.0 (the
  9. * "License"); you may not use this file except in compliance
  10. * with the License. You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing,
  15. * software distributed under the License is distributed on an
  16. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  17. * KIND, either express or implied. See the License for the
  18. * specific language governing permissions and limitations
  19. * under the License.
  20. *
  21. */
  22. class HMCTxnUtils {
  23. private static $logger = NULL;
  24. public static function init() {
  25. if (self::$logger == NULL) {
  26. self::$logger = new HMCLogger("HMCTxnUtils");
  27. }
  28. }
  29. /**
  30. * Get current time in microsecs as int
  31. */
  32. public static function getCurrentTimeInMicroSecs() {
  33. $f = microtime(TRUE);
  34. return intval(round($f , 3)*1000);
  35. }
  36. public static function createNewTransaction($dbHandle, $clusterName,
  37. $statusInfo) {
  38. $statusStr = json_encode($statusInfo);
  39. $newTxn = $dbHandle->createNewTransaction($clusterName, $statusStr, "");
  40. if ($newTxn === FALSE || $newTxn["result"] != 0) {
  41. self::$logger->log_error("Failed to create new txn"
  42. . ", cluster=" . $clusterName
  43. . ", error=" . $newTxn["error"]);
  44. return FALSE;
  45. }
  46. $txnId = $newTxn["txnId"];
  47. self::$logger->log_debug("Created a new transaction"
  48. . ", cluster=" . $clusterName
  49. . ", txnId=" . $txnId);
  50. return $txnId;
  51. }
  52. /**
  53. * Execute command in a background process
  54. * @param resource $dbHandle HMCDBAccessor resource
  55. * @param string $clusterName
  56. * @param int $txnId
  57. * @param string $command
  58. * @param string $args args as a string
  59. * @param string $logFile file to log to - optional - default /dev/null
  60. * @return pid of running process on success
  61. * @return FALSE on failure
  62. */
  63. public static function execBackgroundProcess($dbHandle, $clusterName, $txnId,
  64. $command, $args, $logFile) {
  65. if (!isset($GLOBALS["BACKGROUND_EXECUTOR_PATH"])) {
  66. $GLOBALS["BACKGROUND_EXECUTOR_PATH"] = "/var/lib/HMC/BackgroundExecutor.php";
  67. }
  68. if (!isset($GLOBALS["PHP_EXEC_PATH"])) {
  69. $GLOBALS["PHP_EXEC_PATH"] = "/usr/bin/php";
  70. }
  71. $execCommand = $GLOBALS["PHP_EXEC_PATH"] . " " . $GLOBALS["BACKGROUND_EXECUTOR_PATH"]
  72. . " -t \"" . $txnId . "\""
  73. . " -c \"" . $command . "\"";
  74. if (isset($args) && $args != "") {
  75. $execCommand .= " -a \"" . $args . "\"";
  76. }
  77. $logDir = "/tmp";
  78. if (isset($GLOBALS["HMC_LOG_DIR"])) {
  79. $logDir = $GLOBALS["HMC_LOG_DIR"];
  80. }
  81. if (!isset($logFile) || $logFile == "") {
  82. $logFile = $logDir."/hmc.txn.".$txnId.".log";
  83. }
  84. $execCommand .= " -l \"" . $logFile . "\"";
  85. self::$logger->log_info("Trying to background a new process"
  86. . ", cluster=" . $clusterName
  87. . ", txnId=" . $txnId
  88. . ", command=" . $command
  89. . ", args=" . $args
  90. . ", logFile=" . $logFile
  91. . ", execCommand=" . $execCommand);
  92. $errCode = 0;
  93. $errMsg = "";
  94. $childPid = -1;
  95. $handle = popen($execCommand, "r");
  96. if ($handle === FALSE || !is_resource($handle)) {
  97. $errMsg = "Could not get valid handle from popen";
  98. self::$logger->log_error("Error executing background call"
  99. . ", command=" . $command
  100. . ", txnId=" . $txnId
  101. , ", error=" . $errMsg);
  102. return FALSE;
  103. }
  104. else {
  105. // get child pid
  106. $output = "";
  107. do {
  108. $data = fread($handle, 256);
  109. $output .= $data;
  110. self::$logger->log_info("Output from process"
  111. . ", command=" . $command
  112. . ", txnId=" . $txnId
  113. . ", output=" . $output);
  114. $match = array();
  115. $count = preg_match("/Background Child Process PID:(\d+)/",
  116. $output, $match);
  117. if ($count > 0) {
  118. $childPid = intval($match[1]);
  119. self::$logger->log_info("Found child pid"
  120. . ", command=" . $command
  121. . ", txnId=" . $txnId
  122. . ", output=" . $output
  123. . ", pid=" . $childPid);
  124. break;
  125. }
  126. if (strpos($output,"Done with parent") !== FALSE) {
  127. self::$logger->log_error("Background process ended without pid"
  128. . ", command=" . $command
  129. . ", txnId=" . $txnId);
  130. return FALSE;
  131. }
  132. } while(!feof($handle));
  133. }
  134. pclose($handle);
  135. if ($childPid > 0) {
  136. // update child pid into db
  137. $pidInfo = array();
  138. $pidInfo["mainParentPid"] = $childPid;
  139. $result = $dbHandle->updateTransactionPidInfo($clusterName, $txnId,
  140. json_encode($pidInfo));
  141. if ($result === FALSE || $result["result"] != 0) {
  142. self::$logger->log_error("Could not update pid info into DB"
  143. . ", command=" . $command
  144. . ", txnId=" . $txnId);
  145. return FALSE;
  146. }
  147. return $childPid;
  148. }
  149. self::$logger->log_error("Invalid pid found for background process"
  150. . ", command=" . $command
  151. . ", txnId=" . $txnId);
  152. return FALSE;
  153. }
  154. public static function checkTxnProcessStatus($pidInfo) {
  155. if (!isset($pidInfo["mainParentPid"])) {
  156. return FALSE;
  157. }
  158. $pid = intval($pidInfo["mainParentPid"]);
  159. $command = "ps -p $pid | grep $pid | grep -v grep | wc -l";
  160. $output = array();
  161. $errCode = 0;
  162. $lastLine = exec($command, $output, $errCode);
  163. if ($errCode != 0) {
  164. return FALSE;
  165. }
  166. $matchCount = intval($lastLine);
  167. return ($matchCount > 0);
  168. }
  169. }
  170. HMCTxnUtils::init();
  171. ?>