From 186fb02cf91a4d701f7d399be727484029720c54 Mon Sep 17 00:00:00 2001 From: Sagar Karandikar Date: Sat, 15 Oct 2022 20:44:22 -0700 Subject: [PATCH] don't do qcow2 setup if no sims require it --- deploy/runtools/firesim_topology_elements.py | 33 ++++++++++---------- deploy/runtools/run_farm.py | 4 +++ deploy/runtools/run_farm_deploy_managers.py | 27 +++++++++------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/deploy/runtools/firesim_topology_elements.py b/deploy/runtools/firesim_topology_elements.py index 4d900ffb..c45d3935 100644 --- a/deploy/runtools/firesim_topology_elements.py +++ b/deploy/runtools/firesim_topology_elements.py @@ -253,7 +253,7 @@ class FireSimServerNode(FireSimNode): def allocate_nbds(self) -> None: """ called by the allocate nbds pass to assign an nbd to a qcow2 image. """ - rootfses_list = [self.get_rootfs_name()] + rootfses_list = self.get_all_rootfs_names() for rootfsname in rootfses_list: if rootfsname is not None and rootfsname.endswith(".qcow2"): host_inst = self.get_host_instance() @@ -481,6 +481,15 @@ class FireSimServerNode(FireSimNode): # cases return self.get_job_name() + "-" + rootfs_path.split("/")[-1] + def get_all_rootfs_names(self) -> List[Optional[str]]: + """ Get all rootfs filenames as a list. """ + return [self.get_rootfs_name()] + + def qcow2_support_required(self) -> bool: + """ Return True iff any rootfses for this sim require QCOW2 support, as + determined by their filename ending (.qcow2). """ + return any(map(lambda x: x is not None and x.endswith(".qcow2"), self.get_all_rootfs_names())) + def get_bootbin_name(self) -> str: # prefix bootbin name with the job name to disambiguate in supernode # cases @@ -513,21 +522,6 @@ class FireSimSuperNodeServerNode(FireSimServerNode): sib.assign_host_instance(super_server_host) sib.copy_back_job_results_from_run(slotno, sudo) - def allocate_nbds(self) -> None: - """ called by the allocate nbds pass to assign an nbd to a qcow2 image. - """ - num_siblings = self.supernode_get_num_siblings_plus_one() - - rootfses_list = [self.get_rootfs_name()] + [self.supernode_get_sibling(x).get_rootfs_name() for x in range(1, num_siblings)] - - for rootfsname in rootfses_list: - if rootfsname is not None and rootfsname.endswith(".qcow2"): - host_inst = self.get_host_instance() - assert isinstance(host_inst.instance_deploy_manager, EC2InstanceDeployManager) - nbd_tracker = host_inst.instance_deploy_manager.nbd_tracker - assert nbd_tracker is not None - allocd_device = nbd_tracker.get_nbd_for_imagename(rootfsname) - def supernode_get_num_siblings_plus_one(self) -> int: """ This returns the number of siblings the supernodeservernode has, plus one (because in most places, we use siblings + 1, not just siblings) @@ -554,6 +548,11 @@ class FireSimSuperNodeServerNode(FireSimServerNode): return node assert False, "Should return supernode sibling" + def get_all_rootfs_names(self) -> List[Optional[str]]: + """ Get all rootfs filenames as a list. """ + num_siblings = self.supernode_get_num_siblings_plus_one() + return [self.get_rootfs_name()] + [self.supernode_get_sibling(x).get_rootfs_name() for x in range(1, num_siblings)] + def get_sim_start_command(self, slotno: int, sudo: bool) -> str: """ get the command to run a simulation. assumes it will be called in a directory where its required_files are already located.""" @@ -570,7 +569,7 @@ class FireSimSuperNodeServerNode(FireSimServerNode): assert self.plusarg_passthrough is not None all_macs = [self.get_mac_address()] + [self.supernode_get_sibling(x).get_mac_address() for x in range(1, num_siblings)] - all_rootfses = self.process_qcow2_rootfses([self.get_rootfs_name()] + [self.supernode_get_sibling(x).get_rootfs_name() for x in range(1, num_siblings)]) + all_rootfses = self.process_qcow2_rootfses(self.get_all_rootfs_names()) all_bootbins = [self.get_bootbin_name()] + [self.supernode_get_sibling(x).get_bootbin_name() for x in range(1, num_siblings)] all_linklatencies = [self.server_link_latency] for x in range(1, num_siblings): diff --git a/deploy/runtools/run_farm.py b/deploy/runtools/run_farm.py index e2ebae46..d7bf458b 100644 --- a/deploy/runtools/run_farm.py +++ b/deploy/runtools/run_farm.py @@ -107,6 +107,10 @@ class Inst(metaclass=abc.ABCMeta): self.sim_slots.append(firesimservernode) firesimservernode.assign_host_instance(self) + def qcow2_support_required(self) -> bool: + """ Return True iff any simulation on this Inst requires qcow2. """ + return any([x.qcow2_support_required() for x in self.sim_slots]) + class RunFarm(metaclass=abc.ABCMeta): """Abstract class to represent how to manage run farm hosts (similar to `BuildFarm`). In addition to having to implement how to spawn/terminate nodes, the child classes must diff --git a/deploy/runtools/run_farm_deploy_managers.py b/deploy/runtools/run_farm_deploy_managers.py index 0ad25878..8a39fc09 100644 --- a/deploy/runtools/run_farm_deploy_managers.py +++ b/deploy/runtools/run_farm_deploy_managers.py @@ -101,11 +101,11 @@ class InstanceDeployManager(metaclass=abc.ABCMeta): rootLogger.info("""[{}] """.format(env.host_string) + logstr) def sim_node_qcow(self) -> None: - """ If NBD is available, install qemu-img management tools and copy NBD - infra to remote node. This assumes that the kernel module was already - built and exists in the directory on this machine. - """ - if self.nbd_tracker is not None: + """ If NBD is available and qcow2 support is required, install qemu-img + management tools and copy NBD infra to remote node. This assumes that + the kernel module was already built and exists in the directory on this + machine. """ + if self.nbd_tracker is not None and self.parent_node.qcow2_support_required(): self.instance_logger("""Setting up remote node for qcow2 disk images.""") # get qemu-nbd ### XXX Centos Specific @@ -114,16 +114,18 @@ class InstanceDeployManager(metaclass=abc.ABCMeta): put('../build/nbd.ko', '/home/centos/nbd.ko', mirror_local_mode=True) def load_nbd_module(self) -> None: - """ If NBD is available, load the nbd module. always unload the module - first to ensure it is in a clean state. """ - if self.nbd_tracker is not None: + """ If NBD is available and qcow2 support is required, load the nbd + module. always unload the module first to ensure it is in a clean + state. """ + if self.nbd_tracker is not None and self.parent_node.qcow2_support_required(): self.instance_logger("Loading NBD Kernel Module.") self.unload_nbd_module() run("""sudo insmod /home/centos/nbd.ko nbds_max={}""".format(self.nbd_tracker.NBDS_MAX)) def unload_nbd_module(self) -> None: - """ If NBD is available, unload the nbd module. """ - if self.nbd_tracker is not None: + """ If NBD is available and qcow2 support is required, unload the nbd + module. """ + if self.nbd_tracker is not None and self.parent_node.qcow2_support_required(): self.instance_logger("Unloading NBD Kernel Module.") # disconnect all /dev/nbdX devices before rmmod @@ -132,8 +134,9 @@ class InstanceDeployManager(metaclass=abc.ABCMeta): run('sudo rmmod nbd') def disconnect_all_nbds_instance(self) -> None: - """ If NBD is available, disconnect all nbds on the instance. """ - if self.nbd_tracker is not None: + """ If NBD is available and qcow2 support is required, disconnect all + nbds on the instance. """ + if self.nbd_tracker is not None and self.parent_node.qcow2_support_required(): self.instance_logger("Disconnecting all NBDs.") # warn_only, so we can call this even if there are no nbds