diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java index 798c7103784..869dbe156e8 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java @@ -597,6 +597,21 @@ public void removeChildQueue(CSQueue queue) throws SchedulerDynamicEditException { writeLock.lock(); try { + if (!(queue instanceof AbstractCSQueue) || + !((AbstractCSQueue) queue).isDynamicQueue()) { + throw new SchedulerDynamicEditException("Queue " + getQueuePath() + + " can not remove " + queue.getQueuePath() + + " because it is not a dynamic queue"); + } + + // We need to check if the parent of the child queue is exactly this + // ParentQueue object + if (queue.getParent() != this) { + throw new SchedulerDynamicEditException("Queue " + getQueuePath() + + " can not remove " + queue.getQueuePath() + + " because it has a different parent queue"); + } + // Now we can do remove and update this.childQueues.remove(queue); this.scheduler.getCapacitySchedulerQueueManager() diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerNewQueueAutoCreation.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerNewQueueAutoCreation.java index b96c1e48968..d68df5f9018 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerNewQueueAutoCreation.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestCapacitySchedulerNewQueueAutoCreation.java @@ -1137,6 +1137,51 @@ public void testRemoveDanglingAutoCreatedQueuesOnReinit() throws Exception { "when its dynamic parent is removed", bAutoLeaf); } + @Test + public void testParentQueueDynamicChildRemoval() throws Exception { + startScheduler(); + + createQueue("root.a.a-auto"); + createQueue("root.a.a-auto"); + AbstractCSQueue aAuto = (AbstractCSQueue) cs. + getQueue("root.a.a-auto"); + Assert.assertTrue(aAuto.isDynamicQueue()); + ParentQueue a = (ParentQueue) cs. + getQueue("root.a"); + createQueue("root.e.e1-auto"); + AbstractCSQueue eAuto = (AbstractCSQueue) cs. + getQueue("root.e.e1-auto"); + Assert.assertTrue(eAuto.isDynamicQueue()); + ParentQueue e = (ParentQueue) cs. + getQueue("root.e"); + + // Try to remove a static child queue + try { + a.removeChildQueue(cs.getQueue("root.a.a1")); + Assert.fail("root.a.a1 is a static queue and should not be removed at " + + "runtime"); + } catch (SchedulerDynamicEditException ignored) { + } + + // Try to remove a dynamic queue with a different parent + try { + a.removeChildQueue(eAuto); + Assert.fail("root.a should not be able to remove root.e.e1-auto"); + } catch (SchedulerDynamicEditException ignored) { + } + + a.removeChildQueue(aAuto); + e.removeChildQueue(eAuto); + + aAuto = (AbstractCSQueue) cs. + getQueue("root.a.a-auto"); + eAuto = (AbstractCSQueue) cs. + getQueue("root.e.e1-auto"); + + Assert.assertNull("root.a.a-auto should have been removed", aAuto); + Assert.assertNull("root.e.e1-auto should have been removed", eAuto); + } + protected LeafQueue createQueue(String queuePath) throws YarnException, IOException { return autoQueueHandler.createQueue(