Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ContainerManagementProtocol.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ContainerManagementProtocol.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ContainerManagementProtocol.java (working copy) @@ -27,6 +27,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.records.Container; @@ -170,4 +171,7 @@ GetContainerStatusesResponse getContainerStatuses( GetContainerStatusesRequest request) throws YarnException, IOException; + + StopContainersResponse stopContainers1(StopContainerRequestList request) + throws YarnException, IOException; } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/StopContainerRequest.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/StopContainerRequest.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/StopContainerRequest.java (working copy) @@ -0,0 +1,67 @@ +/** +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.hadoop.yarn.api.protocolrecords; + +import org.apache.hadoop.classification.InterfaceAudience.Public; +import org.apache.hadoop.classification.InterfaceStability.Stable; +import org.apache.hadoop.yarn.api.ContainerManagementProtocol; +import org.apache.hadoop.yarn.api.records.ContainerId; +import org.apache.hadoop.yarn.util.Records; + +/** + *

The request sent by the ApplicationMaster to the + * NodeManager to stop containers.

+ * + * @see ContainerManagementProtocol#stopContainers(StopContainersRequest) + */ +@Public +@Stable +public abstract class StopContainerRequest { + + @Public + @Stable + public static StopContainerRequest newInstance(ContainerId containerId, + boolean dumpThreads) { + StopContainerRequest request = + Records.newRecord(StopContainerRequest.class); + request.setContainerId(containerId); + request.setDumpThreads(dumpThreads); + return request; + } + + /** + * Get the ContainerIds of the containers to be stopped. + * @return ContainerIds of containers to be stopped + */ + @Public + @Stable + public abstract ContainerId getContainerId(); + + /** + * Set the ContainerIds of the containers to be stopped. + * @param containerId ContainerIds of the containers to be stopped + */ + @Public + @Stable + public abstract void setContainerId(ContainerId containerId); + + public abstract boolean getDumpThreads(); + + public abstract void setDumpThreads(boolean dumpThreads); +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/StopContainerRequestList.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/StopContainerRequestList.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/StopContainerRequestList.java (working copy) @@ -0,0 +1,57 @@ +/** +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.hadoop.yarn.api.protocolrecords; + +import java.util.List; + +import org.apache.hadoop.classification.InterfaceAudience.Public; +import org.apache.hadoop.classification.InterfaceStability.Stable; +import org.apache.hadoop.yarn.api.ContainerManagementProtocol; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestListProto; +import org.apache.hadoop.yarn.util.Records; + +/** + *

The request sent by the ApplicationMaster to the + * NodeManager to stop containers.

+ * + * @see ContainerManagementProtocol#stopContainers(StopContainersRequest) + */ +@Public +@Stable +public abstract class StopContainerRequestList { + + @Public + @Stable + public static StopContainerRequestList newInstance( + List requestList) + { + StopContainerRequestList request = + Records.newRecord(StopContainerRequestList.class); + request.setRequests(requestList); + return request; + } + + @Public + @Stable + public abstract List getRequests(); + + @Public + @Stable + public abstract void setRequests(List requestList); +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/containermanagement_protocol.proto =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/containermanagement_protocol.proto (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/containermanagement_protocol.proto (working copy) @@ -34,4 +34,5 @@ rpc startContainers(StartContainersRequestProto) returns (StartContainersResponseProto); rpc stopContainers(StopContainersRequestProto) returns (StopContainersResponseProto); rpc getContainerStatuses(GetContainerStatusesRequestProto) returns (GetContainerStatusesResponseProto); + rpc stopContainers1(StopContainerRequestListProto) returns (StopContainersResponseProto); } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto (working copy) @@ -180,6 +180,7 @@ message StopContainerRequestProto { optional ContainerIdProto container_id = 1; + optional bool dump_threads = 2; } message StopContainerResponseProto { @@ -213,6 +214,10 @@ repeated ContainerIdProto container_id = 1; } +message StopContainerRequestListProto { + repeated StopContainerRequestProto container_requests = 1; +} + message StopContainersResponseProto { repeated ContainerIdProto succeeded_requests = 1; repeated ContainerExceptionMapProto failed_requests = 2; Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ContainerManagementProtocolPBClientImpl.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ContainerManagementProtocolPBClientImpl.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ContainerManagementProtocolPBClientImpl.java (working copy) @@ -35,11 +35,13 @@ import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.GetContainerStatusesRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.GetContainerStatusesResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StartContainersRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StartContainersResponsePBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StopContainerRequestListPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StopContainersRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StopContainersResponsePBImpl; import org.apache.hadoop.yarn.conf.YarnConfiguration; @@ -47,6 +49,7 @@ import org.apache.hadoop.yarn.ipc.RPCUtil; import org.apache.hadoop.yarn.proto.YarnServiceProtos.GetContainerStatusesRequestProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.StartContainersRequestProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestListProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainersRequestProto; import com.google.protobuf.ServiceException; @@ -128,4 +131,17 @@ return null; } } + + @Override + public StopContainersResponse stopContainers1(StopContainerRequestList requests) throws YarnException, IOException { + StopContainerRequestListProto requestProto = + ((StopContainerRequestListPBImpl)requests).getProto(); + try { + return new StopContainersResponsePBImpl(proxy.stopContainers1(null, + requestProto)); + } catch (ServiceException e) { + RPCUtil.unwrapAndThrowException(e); + return null; + } + } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ContainerManagementProtocolPBServiceImpl.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ContainerManagementProtocolPBServiceImpl.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ContainerManagementProtocolPBServiceImpl.java (working copy) @@ -30,9 +30,11 @@ import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.GetContainerStatusesResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StartContainersRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StartContainersResponsePBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StopContainerRequestListPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StopContainersRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.StopContainersResponsePBImpl; import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.proto.YarnServiceProtos; import org.apache.hadoop.yarn.proto.YarnServiceProtos.GetContainerStatusesRequestProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.GetContainerStatusesResponseProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.StartContainersRequestProto; @@ -94,4 +96,22 @@ throw new ServiceException(e); } } + + @Override + public StopContainersResponseProto stopContainers1( + RpcController arg0, + YarnServiceProtos.StopContainerRequestListProto proto) + throws ServiceException + { + StopContainerRequestListPBImpl request + = new StopContainerRequestListPBImpl(proto); + try { + StopContainersResponse response = real.stopContainers1(request); + return ((StopContainersResponsePBImpl)response).getProto(); + } catch (YarnException e) { + throw new ServiceException(e); + } catch (IOException e) { + throw new ServiceException(e); + } + } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/StopContainerRequestListPBImpl.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/StopContainerRequestListPBImpl.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/StopContainerRequestListPBImpl.java (working copy) @@ -0,0 +1,152 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.yarn.api.protocolrecords.impl.pb; + +import com.google.protobuf.TextFormat; +import org.apache.hadoop.classification.InterfaceAudience.Private; +import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequest; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestListProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestListProtoOrBuilder; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestProtoOrBuilder; +import java.util.ArrayList; +import java.util.List; + +@Private +@Unstable +public class StopContainerRequestListPBImpl extends StopContainerRequestList { + StopContainerRequestListProto proto = + StopContainerRequestListProto.getDefaultInstance(); + StopContainerRequestListProto.Builder builder; + boolean viaProto; + + private List requestList; + + public StopContainerRequestListPBImpl() { + builder = StopContainerRequestListProto.newBuilder(); + } + + public StopContainerRequestListPBImpl(StopContainerRequestListProto proto) { + super(); + this.proto = proto; + viaProto = true; + } + + public StopContainerRequestListProto getProto() { + mergeLocalToProto(); + proto = viaProto ? proto : builder.build(); + viaProto = true; + return proto; + } + + @Override + public int hashCode() { + return getProto().hashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == null) + return false; + if (other.getClass().isAssignableFrom(this.getClass())) { + return this.getProto().equals(this.getClass().cast(other).getProto()); + } + return false; + } + + @Override + public String toString() { + return TextFormat.shortDebugString(getProto()); + } + + private void mergeLocalToBuilder() { + if (requestList != null) { + addLocalRequestsToProto(); + } + } + + private void mergeLocalToProto() { + if (viaProto) + maybeInitBuilder(); + mergeLocalToBuilder(); + proto = builder.build(); + viaProto = true; + } + + private void maybeInitBuilder() { + if (viaProto || builder == null) { + builder = StopContainerRequestListProto.newBuilder(proto); + } + viaProto = false; + } + + private void addLocalRequestsToProto() { + maybeInitBuilder(); + builder.clearContainerRequests(); + if (this.requestList == null) { + return; + } + List protoList = + new ArrayList(); + for (StopContainerRequest requestProto : requestList) { + protoList.add(convertToProtoFormat(requestProto)); + } + builder.addAllContainerRequests(protoList); + } + + private void initLocalStopRequests() { + if (requestList != null) { + return; + } + StopContainerRequestListProtoOrBuilder p = viaProto ? proto : builder; + List requestProtos = + p.getContainerRequestsList(); + requestList = new ArrayList(); + for (StopContainerRequestProto r : requestProtos) { + requestList.add(convertFromProtoFormat(r)); + } + } + + @Override + public List getRequests() { + initLocalStopRequests(); + return requestList; + } + + @Override + public void setRequests(List requestList) { + maybeInitBuilder(); + if (requestList == null) { + builder.clearContainerRequests(); + } + this.requestList = requestList; + } + + private StopContainerRequestPBImpl convertFromProtoFormat( + StopContainerRequestProto p) + { + return new StopContainerRequestPBImpl(p); + } + + private StopContainerRequestProto convertToProtoFormat(StopContainerRequest t) { + return ((StopContainerRequestPBImpl) t).getProto(); + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/StopContainerRequestPBImpl.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/StopContainerRequestPBImpl.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/StopContainerRequestPBImpl.java (working copy) @@ -0,0 +1,128 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.yarn.api.protocolrecords.impl.pb; + + +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequest; +import org.apache.hadoop.yarn.api.records.ContainerId; +import org.apache.hadoop.yarn.api.records.impl.pb.ContainerIdPBImpl; +import org.apache.hadoop.yarn.proto.YarnProtos.ContainerIdProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.StopContainerRequestProtoOrBuilder; + + + +public class StopContainerRequestPBImpl extends StopContainerRequest { + StopContainerRequestProto proto = StopContainerRequestProto.getDefaultInstance(); + StopContainerRequestProto.Builder builder = null; + boolean viaProto = false; + + private ContainerId containerId = null; + private boolean dumpThreads; + + + public StopContainerRequestPBImpl() { + builder = StopContainerRequestProto.newBuilder(); + } + + public StopContainerRequestPBImpl(StopContainerRequestProto proto) { + this.proto = proto; + viaProto = true; + } + + public StopContainerRequestProto getProto() { + mergeLocalToProto(); + proto = viaProto ? proto : builder.build(); + viaProto = true; + return proto; + } + + private void mergeLocalToBuilder() { + if (this.containerId != null) { + builder.setContainerId(convertToProtoFormat(this.containerId)); + } + + if (this.dumpThreads) { + builder.setDumpThreads(this.dumpThreads); + } + } + + private void mergeLocalToProto() { + if (viaProto) + maybeInitBuilder(); + mergeLocalToBuilder(); + proto = builder.build(); + viaProto = true; + } + + private void maybeInitBuilder() { + if (viaProto || builder == null) { + builder = StopContainerRequestProto.newBuilder(proto); + } + viaProto = false; + } + + + @Override + public ContainerId getContainerId() { + StopContainerRequestProtoOrBuilder p = viaProto ? proto : builder; + if (this.containerId != null) { + return this.containerId; + } + if (!p.hasContainerId()) { + return null; + } + this.containerId = convertFromProtoFormat(p.getContainerId()); + return this.containerId; + } + + @Override + public void setContainerId(ContainerId containerId) { + maybeInitBuilder(); + if (containerId == null) + builder.clearContainerId(); + this.containerId = containerId; + } + + @Override + public void setDumpThreads(boolean dumpThreads) { + maybeInitBuilder(); + if (!dumpThreads) { + builder.clearDumpThreads(); + } + this.dumpThreads = dumpThreads; + } + + @Override + public boolean getDumpThreads() { + if (dumpThreads) { + return true; + } + StopContainerRequestProtoOrBuilder p = viaProto ? proto : builder; + return p.hasDumpThreads() ? p.getDumpThreads() : false; + } + + private ContainerIdPBImpl convertFromProtoFormat(ContainerIdProto p) { + return new ContainerIdPBImpl(p); + } + + private ContainerIdProto convertToProtoFormat(ContainerId t) { + return ((ContainerIdPBImpl)t).getProto(); + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/TestContainerLaunchRPC.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/TestContainerLaunchRPC.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/TestContainerLaunchRPC.java (working copy) @@ -38,6 +38,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; @@ -165,5 +166,15 @@ GetContainerStatusesResponse.newInstance(list, null); return null; } + + @Override + public StopContainersResponse stopContainers1( + StopContainerRequestList request) + throws YarnException, IOException + { + Exception e = new Exception("Dummy function", new Exception( + "Dummy function cause")); + throw new YarnException(e); + } } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/TestRPC.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/TestRPC.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/TestRPC.java (working copy) @@ -41,6 +41,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; @@ -187,6 +188,13 @@ } @Override + public StopContainersResponse stopContainers1(StopContainerRequestList request) throws YarnException, IOException { + Exception e = new Exception(EXCEPTION_MSG, + new Exception(EXCEPTION_CAUSE)); + throw new YarnException(e); + } + + @Override public StartContainersResponse startContainers( StartContainersRequest requests) throws YarnException { StartContainersResponse response = Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/ContainerManagerImpl.java (working copy) @@ -60,6 +60,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequest; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.records.ApplicationId; @@ -700,7 +702,31 @@ NMTokenIdentifier identifier = selectNMTokenIdentifier(remoteUgi); for (ContainerId id : requests.getContainerIds()) { try { - stopContainerInternal(identifier, id); + stopContainerInternal(identifier, id, false); + succeededRequests.add(id); + } catch (YarnException e) { + failedRequests.put(id, SerializedException.newInstance(e)); + } + } + return StopContainersResponse + .newInstance(succeededRequests, failedRequests); + } + + @Override + public StopContainersResponse stopContainers1( + StopContainerRequestList requestList) + throws YarnException, IOException { + + List succeededRequests = new ArrayList(); + Map failedRequests = + new HashMap(); + UserGroupInformation remoteUgi = getRemoteUgi(); + NMTokenIdentifier identifier = selectNMTokenIdentifier(remoteUgi); + for (StopContainerRequest r : requestList.getRequests()) { + final ContainerId id = r.getContainerId(); + final boolean dumpThreads = r.getDumpThreads(); + try { + stopContainerInternal(identifier, id, dumpThreads); succeededRequests.add(id); } catch (YarnException e) { failedRequests.put(id, SerializedException.newInstance(e)); @@ -712,7 +738,7 @@ @SuppressWarnings("unchecked") private void stopContainerInternal(NMTokenIdentifier nmTokenIdentifier, - ContainerId containerID) throws YarnException { + ContainerId containerID, boolean dumpThreads) throws YarnException { String containerIDStr = containerID.toString(); Container container = this.context.getContainers().get(containerID); LOG.info("Stopping container with container Id: " + containerIDStr); @@ -727,7 +753,8 @@ } else { dispatcher.getEventHandler().handle( new ContainerKillEvent(containerID, - "Container killed by the ApplicationMaster.")); + "Container killed by the ApplicationMaster.", + dumpThreads)); NMAuditLogger.logSuccess(container.getUser(), AuditConstants.STOP_CONTAINER, "ContainerManageImpl", containerID Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerImpl.java (working copy) @@ -127,6 +127,8 @@ private static final ContainerDiagnosticsUpdateTransition UPDATE_DIAGNOSTICS_TRANSITION = new ContainerDiagnosticsUpdateTransition(); + private static final KillTransition KILL_TRANSITION = new KillTransition(); + // State Machine for each container. private static StateMachineFactory @@ -191,7 +193,7 @@ ContainerEventType.UPDATE_DIAGNOSTICS_MSG, UPDATE_DIAGNOSTICS_TRANSITION) .addTransition(ContainerState.LOCALIZED, ContainerState.KILLING, - ContainerEventType.KILL_CONTAINER, new KillTransition()) + ContainerEventType.KILL_CONTAINER, KILL_TRANSITION) // From RUNNING State .addTransition(ContainerState.RUNNING, @@ -206,7 +208,7 @@ ContainerEventType.UPDATE_DIAGNOSTICS_MSG, UPDATE_DIAGNOSTICS_TRANSITION) .addTransition(ContainerState.RUNNING, ContainerState.KILLING, - ContainerEventType.KILL_CONTAINER, new KillTransition()) + ContainerEventType.KILL_CONTAINER, KILL_TRANSITION) .addTransition(ContainerState.RUNNING, ContainerState.EXITED_WITH_FAILURE, ContainerEventType.CONTAINER_KILLED_ON_REQUEST, new KilledExternallyTransition()) @@ -787,11 +789,12 @@ SingleArcTransition { @Override public void transition(ContainerImpl container, ContainerEvent event) { + ContainerKillEvent killEvent = (ContainerKillEvent) event; // Kill the process/process-grp container.dispatcher.getEventHandler().handle( new ContainersLauncherEvent(container, - ContainersLauncherEventType.CLEANUP_CONTAINER)); - ContainerKillEvent killEvent = (ContainerKillEvent) event; + ContainersLauncherEventType.CLEANUP_CONTAINER, + killEvent.getDumpThreads())); container.diagnostics.append(killEvent.getDiagnostic()).append("\n"); } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerKillEvent.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerKillEvent.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/ContainerKillEvent.java (working copy) @@ -23,13 +23,24 @@ public class ContainerKillEvent extends ContainerEvent { private final String diagnostic; + private final boolean dumpThreads; public ContainerKillEvent(ContainerId cID, String diagnostic) { + this(cID, diagnostic, false); + } + + public ContainerKillEvent(ContainerId cID, String diagnostic, + boolean dumpThreads) { super(cID, ContainerEventType.KILL_CONTAINER); this.diagnostic = diagnostic; + this.dumpThreads = dumpThreads; } public String getDiagnostic() { return this.diagnostic; } + + public boolean getDumpThreads() { + return dumpThreads; + } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java (working copy) @@ -45,6 +45,7 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.security.Credentials; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequest; import org.apache.hadoop.util.Shell; import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.yarn.api.ApplicationConstants; @@ -335,7 +336,7 @@ * @throws IOException */ @SuppressWarnings("unchecked") // dispatcher not typed - public void cleanupContainer() throws IOException { + public void cleanupContainer(boolean dumpThreads) throws IOException { ContainerId containerId = container.getContainerId(); String containerIdStr = ConverterUtils.toString(containerId); LOG.info("Cleaning up container " + containerIdStr); @@ -372,6 +373,15 @@ // kill process if (processId != null) { String user = container.getUser(); + boolean result; + if (dumpThreads) { + result = exec.signalContainer(user, processId, Signal.QUIT); + if (!result && LOG.isDebugEnabled()) { + LOG.debug("Failed to send " + Signal.QUIT + " to " + processId + + " to generate JVM thread dump"); + } + } + LOG.debug("Sending signal to pid " + processId + " as user " + user + " for container " + containerIdStr); @@ -380,7 +390,7 @@ ? Signal.TERM : Signal.KILL; - boolean result = exec.signalContainer(user, processId, signal); + result = exec.signalContainer(user, processId, signal); LOG.debug("Sent signal " + signal + " to pid " + processId + " as user " + user Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncher.java (working copy) @@ -135,7 +135,7 @@ // Cleanup a container whether it is running/killed/completed, so that // no sub-processes are alive. try { - launcher.cleanupContainer(); + launcher.cleanupContainer(event.getDumpThreads()); } catch (IOException e) { LOG.warn("Got exception while cleaning container " + containerId + ". Ignoring."); Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncherEvent.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncherEvent.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainersLauncherEvent.java (working copy) @@ -26,15 +26,27 @@ extends AbstractEvent{ private final Container container; + private final boolean dumpThreads; public ContainersLauncherEvent(Container container, ContainersLauncherEventType eventType) { + this(container, eventType, false); + } + + public ContainersLauncherEvent(Container container, + ContainersLauncherEventType eventType, + boolean dumpThreads) { super(eventType); this.container = container; + this.dumpThreads = dumpThreads; } public Container getContainer() { return container; } + public boolean getDumpThreads() { + return dumpThreads; + } + } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/SleepTask.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/SleepTask.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/SleepTask.java (working copy) @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher; + +public class SleepTask { + public static void main(String[] args) throws Throwable { + if (args.length != 1) { + System.exit(1); + } + final int sleepTime = Integer.valueOf(args[0]); + System.out.printf("Sleeping for %d milliseconds\n", sleepTime); + Thread.sleep(sleepTime); + System.out.println("Exiting after sleeping"); + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/TestContainerLaunch.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/TestContainerLaunch.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/TestContainerLaunch.java (working copy) @@ -52,6 +52,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetContainerStatusesRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequest; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationId; @@ -69,6 +71,7 @@ import org.apache.hadoop.yarn.event.Dispatcher; import org.apache.hadoop.yarn.event.Event; import org.apache.hadoop.yarn.event.EventHandler; +import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.security.ContainerTokenIdentifier; import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.ExitCode; import org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor; @@ -621,49 +624,7 @@ writer.println("while true; do\nsleep 1s;\ndone"); } writer.close(); - FileUtil.setExecutable(scriptFile, true); - - ContainerLaunchContext containerLaunchContext = - recordFactory.newRecordInstance(ContainerLaunchContext.class); - - // upload the script file so that the container can run it - URL resource_alpha = - ConverterUtils.getYarnUrlFromPath(localFS - .makeQualified(new Path(scriptFile.getAbsolutePath()))); - LocalResource rsrc_alpha = - recordFactory.newRecordInstance(LocalResource.class); - rsrc_alpha.setResource(resource_alpha); - rsrc_alpha.setSize(-1); - rsrc_alpha.setVisibility(LocalResourceVisibility.APPLICATION); - rsrc_alpha.setType(LocalResourceType.FILE); - rsrc_alpha.setTimestamp(scriptFile.lastModified()); - String destinationFile = "dest_file.sh"; - Map localResources = - new HashMap(); - localResources.put(destinationFile, rsrc_alpha); - containerLaunchContext.setLocalResources(localResources); - - // set up the rest of the container - List commands = Arrays.asList(Shell.getRunScriptCommand(scriptFile)); - containerLaunchContext.setCommands(commands); - Token containerToken = createContainerToken(cId); - - StartContainerRequest scRequest = - StartContainerRequest.newInstance(containerLaunchContext, - containerToken); - List list = new ArrayList(); - list.add(scRequest); - StartContainersRequest allRequests = - StartContainersRequest.newInstance(list); - containerManager.startContainers(allRequests); - - int timeoutSecs = 0; - while (!processStartFile.exists() && timeoutSecs++ < 20) { - Thread.sleep(1000); - LOG.info("Waiting for process start-file to be created"); - } - Assert.assertTrue("ProcessStartFile doesn't exist!", - processStartFile.exists()); + startKillTestContainer(cId, processStartFile, scriptFile); // Now test the stop functionality. List containerIds = new ArrayList(); @@ -714,6 +675,52 @@ } } + private void startKillTestContainer(ContainerId cId, File processStartFile, File scriptFile) throws YarnException, IOException, InterruptedException { + FileUtil.setExecutable(scriptFile, true); + + ContainerLaunchContext containerLaunchContext = + recordFactory.newRecordInstance(ContainerLaunchContext.class); + + // upload the script file so that the container can run it + URL resource_alpha = + ConverterUtils.getYarnUrlFromPath(localFS + .makeQualified(new Path(scriptFile.getAbsolutePath()))); + LocalResource rsrc_alpha = + recordFactory.newRecordInstance(LocalResource.class); + rsrc_alpha.setResource(resource_alpha); + rsrc_alpha.setSize(-1); + rsrc_alpha.setVisibility(LocalResourceVisibility.APPLICATION); + rsrc_alpha.setType(LocalResourceType.FILE); + rsrc_alpha.setTimestamp(scriptFile.lastModified()); + String destinationFile = "dest_file.sh"; + Map localResources = + new HashMap(); + localResources.put(destinationFile, rsrc_alpha); + containerLaunchContext.setLocalResources(localResources); + + // set up the rest of the container + List commands = Arrays.asList(Shell.getRunScriptCommand(scriptFile)); + containerLaunchContext.setCommands(commands); + Token containerToken = createContainerToken(cId); + + StartContainerRequest scRequest = + StartContainerRequest.newInstance(containerLaunchContext, + containerToken); + List list = new ArrayList(); + list.add(scRequest); + StartContainersRequest allRequests = + StartContainersRequest.newInstance(list); + containerManager.startContainers(allRequests); + + int timeoutSecs = 0; + while (!processStartFile.exists() && timeoutSecs++ < 20) { + Thread.sleep(1000); + LOG.info("Waiting for process start-file to be created"); + } + Assert.assertTrue("ProcessStartFile doesn't exist!", + processStartFile.exists()); + } + @Test public void testDelayedKill() throws Exception { internalKillTest(true); @@ -763,4 +770,72 @@ return containerToken; } + + @Test + public void testThreadDumpKill() throws Exception { + containerManager.start(); + + File processStartFile = new File(tmpDir, "pid.txt").getAbsoluteFile(); + + // setup a script that can handle sigterm gracefully + File scriptFile = new File(tmpDir, "testscript.sh"); + PrintWriter writer = new PrintWriter( + new FileOutputStream(scriptFile)); + writer.println("#!/bin/bash\n\n"); + writer.println("exec $JAVA_HOME/bin/java -classpath " + + System.getProperty("java.class.path") + " " + + SleepTask.class.getName() + " 600000 >> " + processStartFile); + writer.close(); + FileUtil.setExecutable(scriptFile, true); + + // ////// Construct the Container-id + ApplicationId appId = ApplicationId.newInstance(1, 1); + ApplicationAttemptId appAttemptId = ApplicationAttemptId. + newInstance(appId, 1); + ContainerId cId = ContainerId.newInstance(appAttemptId, 0); + + startKillTestContainer(cId, processStartFile, scriptFile); + + // Now test the stop functionality. + List containerIds = new ArrayList(); + containerIds.add(cId); + + StopContainerRequest stopRequest = StopContainerRequest.newInstance( + cId, true /* dump threads */) ; + containerManager.stopContainers1(StopContainerRequestList.newInstance( + Collections.singletonList(stopRequest))); + + BaseContainerManagerTest.waitForContainerState(containerManager, cId, + ContainerState.COMPLETE); + + // if delayed container stop sends a sigterm followed by a sigkill + // otherwise sigkill is sent immediately + GetContainerStatusesRequest gcsRequest = + GetContainerStatusesRequest.newInstance(containerIds); + + ContainerStatus containerStatus = + containerManager.getContainerStatuses(gcsRequest) + .getContainerStatuses().get(0); + Assert.assertEquals(ExitCode.TERMINATED.getExitCode(), + containerStatus.getExitStatus()); + Assert.assertFalse("Process is still alive!", + DefaultContainerExecutor.containerIsAlive(cId.toString())); + + BufferedReader reader = + new BufferedReader(new FileReader(processStartFile)); + + boolean found = false; + while (true) { + String line = reader.readLine(); + if (line == null) { + break; + } + if (line.contains("Full thread dump")) { + found = true; + break; + } + } + Assert.assertTrue("Did not find \"Full thread dump\"", found); + reader.close(); + } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/NodeManager.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/NodeManager.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/NodeManager.java (working copy) @@ -36,6 +36,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequest; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.records.ApplicationId; @@ -223,54 +225,58 @@ synchronized public StopContainersResponse stopContainers(StopContainersRequest request) throws YarnException { for (ContainerId containerID : request.getContainerIds()) { - String applicationId = - String.valueOf(containerID.getApplicationAttemptId() - .getApplicationId().getId()); - // Mark the container as COMPLETE - List applicationContainers = containers.get(containerID.getApplicationAttemptId() - .getApplicationId()); - for (Container c : applicationContainers) { - if (c.getId().compareTo(containerID) == 0) { - ContainerStatus containerStatus = containerStatusMap.get(c); - containerStatus.setState(ContainerState.COMPLETE); - containerStatusMap.put(c, containerStatus); - } - } + internalStopContainer(containerID); + } + return StopContainersResponse.newInstance(null,null); + } - // Send a heartbeat - try { - heartbeat(); - } catch (IOException ioe) { - throw RPCUtil.getRemoteException(ioe); + private void internalStopContainer(ContainerId containerID) throws YarnException { + String applicationId = + String.valueOf(containerID.getApplicationAttemptId() + .getApplicationId().getId()); + // Mark the container as COMPLETE + List applicationContainers = containers.get(containerID.getApplicationAttemptId() + .getApplicationId()); + for (Container c : applicationContainers) { + if (c.getId().compareTo(containerID) == 0) { + ContainerStatus containerStatus = containerStatusMap.get(c); + containerStatus.setState(ContainerState.COMPLETE); + containerStatusMap.put(c, containerStatus); } + } - // Remove container and update status - int ctr = 0; - Container container = null; - for (Iterator i = applicationContainers.iterator(); i - .hasNext();) { - container = i.next(); - if (container.getId().compareTo(containerID) == 0) { - i.remove(); - ++ctr; - } - } + // Send a heartbeat + try { + heartbeat(); + } catch (IOException ioe) { + throw RPCUtil.getRemoteException(ioe); + } - if (ctr != 1) { - throw new IllegalStateException("Container " + containerID - + " stopped " + ctr + " times!"); + // Remove container and update status + int ctr = 0; + Container container = null; + for (Iterator i = applicationContainers.iterator(); i + .hasNext();) { + container = i.next(); + if (container.getId().compareTo(containerID) == 0) { + i.remove(); + ++ctr; } + } - Resources.addTo(available, container.getResource()); - Resources.subtractFrom(used, container.getResource()); + if (ctr != 1) { + throw new IllegalStateException("Container " + containerID + + " stopped " + ctr + " times!"); + } - if (LOG.isDebugEnabled()) { - LOG.debug("stopContainer:" + " node=" + containerManagerAddress - + " application=" + applicationId + " container=" + containerID - + " available=" + available + " used=" + used); - } + Resources.addTo(available, container.getResource()); + Resources.subtractFrom(used, container.getResource()); + + if (LOG.isDebugEnabled()) { + LOG.debug("stopContainer:" + " node=" + containerManagerAddress + + " application=" + applicationId + " container=" + containerID + + " available=" + available + " used=" + used); } - return StopContainersResponse.newInstance(null,null); } @Override @@ -295,6 +301,17 @@ return GetContainerStatusesResponse.newInstance(statuses, null); } + @Override + public synchronized StopContainersResponse stopContainers1( + StopContainerRequestList request) + throws YarnException, IOException + { + for (StopContainerRequest r : request.getRequests()) { + internalStopContainer(r.getContainerId()); + } + return StopContainersResponse.newInstance(null,null); + } + public static org.apache.hadoop.yarn.server.api.records.NodeStatus createNodeStatus(NodeId nodeId, List containers) { RecordFactory recordFactory = RecordFactoryProvider.getRecordFactory(null); Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMAuthorization.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMAuthorization.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMAuthorization.java (working copy) @@ -45,6 +45,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.records.ApplicationAccessType; @@ -121,6 +122,13 @@ return GetContainerStatusesResponse.newInstance(null, null); } + @Override + public StopContainersResponse stopContainers1( + StopContainerRequestList request) + throws YarnException, IOException { + return StopContainersResponse.newInstance(null, null); + } + public Credentials getContainerCredentials() throws IOException { Credentials credentials = new Credentials(); DataInputByteBuffer buf = new DataInputByteBuffer(); Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestApplicationMasterLauncher.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestApplicationMasterLauncher.java (revision 1543313) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestApplicationMasterLauncher.java (working copy) @@ -34,6 +34,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.StartContainerRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StartContainersResponse; +import org.apache.hadoop.yarn.api.protocolrecords.StopContainerRequestList; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersRequest; import org.apache.hadoop.yarn.api.protocolrecords.StopContainersResponse; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; @@ -118,6 +119,15 @@ GetContainerStatusesRequest request) throws YarnException { return null; } + + @Override + public StopContainersResponse stopContainers1( + StopContainerRequestList request) + throws YarnException, IOException { + LOG.info("Container cleaned up by MyContainerManager"); + cleanedup = true; + return null; + } } @Test