4040import java .util .concurrent .ScheduledFuture ;
4141import java .util .concurrent .TimeUnit ;
4242import java .util .concurrent .TimeoutException ;
43+ import java .util .concurrent .atomic .AtomicReference ;
4344import java .util .stream .Collectors ;
4445
4546import org .apache .cloudstack .utils .security .KeyStoreUtils ;
47+ import org .apache .commons .collections .CollectionUtils ;
4648import org .apache .commons .io .IOUtils ;
4749import org .apache .logging .log4j .LogManager ;
4850import org .apache .logging .log4j .Logger ;
@@ -708,13 +710,31 @@ public static int executeCommandForExitValue(String... command) {
708710 return executeCommandForExitValue (0 , command );
709711 }
710712
713+ private static void cleanupProcesses (AtomicReference <List <Process >> processesRef ) {
714+ List <Process > processes = processesRef .get ();
715+ if (CollectionUtils .isNotEmpty (processes )) {
716+ for (Process process : processes ) {
717+ if (process == null ) {
718+ continue ;
719+ }
720+ LOGGER .trace (String .format ("Cleaning up process [%s] from piped commands." , process .pid ()));
721+ IOUtils .closeQuietly (process .getErrorStream ());
722+ IOUtils .closeQuietly (process .getOutputStream ());
723+ IOUtils .closeQuietly (process .getInputStream ());
724+ process .destroyForcibly ();
725+ }
726+ }
727+ }
728+
711729 public static Pair <Integer , String > executePipedCommands (List <String []> commands , long timeout ) {
712730 if (timeout <= 0 ) {
713731 timeout = DEFAULT_TIMEOUT ;
714732 }
733+ final AtomicReference <List <Process >> processesRef = new AtomicReference <>();
715734 Callable <Pair <Integer , String >> commandRunner = () -> {
716735 List <ProcessBuilder > builders = commands .stream ().map (ProcessBuilder ::new ).collect (Collectors .toList ());
717736 List <Process > processes = ProcessBuilder .startPipeline (builders );
737+ processesRef .set (processes );
718738 Process last = processes .get (processes .size ()-1 );
719739 try (BufferedReader reader = new BufferedReader (new InputStreamReader (last .getInputStream ()))) {
720740 String line ;
@@ -741,6 +761,8 @@ public static Pair<Integer, String> executePipedCommands(List<String[]> commands
741761 result .second (ERR_TIMEOUT );
742762 } catch (InterruptedException | ExecutionException e ) {
743763 LOGGER .error ("Error executing piped commands" , e );
764+ } finally {
765+ cleanupProcesses (processesRef );
744766 }
745767 return result ;
746768 }
0 commit comments