Преглед на файлове

YARN-10727. ParentQueue does not validate the queue on removal. Contributed by Andras Gyori

Szilard Nemeth преди 3 години
родител
ревизия
8d0297c213

+ 15 - 0
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

@@ -581,6 +581,21 @@ public class ParentQueue extends AbstractCSQueue {
       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()

+ 45 - 0
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

@@ -1162,6 +1162,51 @@ public class TestCapacitySchedulerNewQueueAutoCreation
         "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(