3939import java .util .concurrent .ScheduledFuture ;
4040import java .util .concurrent .TimeUnit ;
4141import java .util .concurrent .TimeoutException ;
42+ import java .util .concurrent .atomic .AtomicReference ;
4243import java .util .stream .Collectors ;
4344
4445import org .apache .cloudstack .utils .security .KeyStoreUtils ;
46+ import org .apache .commons .collections .CollectionUtils ;
4547import org .apache .commons .io .IOUtils ;
4648import org .apache .logging .log4j .LogManager ;
4749import org .apache .logging .log4j .Logger ;
@@ -729,13 +731,31 @@ public static int executeCommandForExitValue(String... command) {
729731 return executeCommandForExitValue (0 , command );
730732 }
731733
734+ private static void cleanupProcesses (AtomicReference <List <Process >> processesRef ) {
735+ List <Process > processes = processesRef .get ();
736+ if (CollectionUtils .isNotEmpty (processes )) {
737+ for (Process process : processes ) {
738+ if (process == null ) {
739+ continue ;
740+ }
741+ LOGGER .trace (String .format ("Cleaning up process [%s] from piped commands." , process .pid ()));
742+ IOUtils .closeQuietly (process .getErrorStream ());
743+ IOUtils .closeQuietly (process .getOutputStream ());
744+ IOUtils .closeQuietly (process .getInputStream ());
745+ process .destroyForcibly ();
746+ }
747+ }
748+ }
749+
732750 public static Pair <Integer , String > executePipedCommands (List <String []> commands , long timeout ) {
733751 if (timeout <= 0 ) {
734752 timeout = DEFAULT_TIMEOUT ;
735753 }
754+ final AtomicReference <List <Process >> processesRef = new AtomicReference <>();
736755 Callable <Pair <Integer , String >> commandRunner = () -> {
737756 List <ProcessBuilder > builders = commands .stream ().map (ProcessBuilder ::new ).collect (Collectors .toList ());
738757 List <Process > processes = ProcessBuilder .startPipeline (builders );
758+ processesRef .set (processes );
739759 Process last = processes .get (processes .size ()-1 );
740760 try (BufferedReader reader = new BufferedReader (new InputStreamReader (last .getInputStream ()))) {
741761 String line ;
@@ -762,6 +782,8 @@ public static Pair<Integer, String> executePipedCommands(List<String[]> commands
762782 result .second (ERR_TIMEOUT );
763783 } catch (InterruptedException | ExecutionException e ) {
764784 LOGGER .error ("Error executing piped commands" , e );
785+ } finally {
786+ cleanupProcesses (processesRef );
765787 }
766788 return result ;
767789 }
0 commit comments