def _from_target(cls, target: Target, *, res_dir: ArtifactPath = None, seed=None, nr_operations=100, sleep_min_ms=10, sleep_max_ms=100, max_cpus_off=sys.maxsize) -> 'HotplugBase': """ :param seed: Seed of the RNG used to create the hotplug sequences :type seed: int :param nr_operations: Number of operations in the sequence :type nr_operations: int :param sleep_min_ms: Minimum sleep duration between hotplug operations :type sleep_min_ms: int :param sleep_max_ms: Maximum sleep duration between hotplug operations (0 would lead to no sleep) :type sleep_max_ms: int :param max_cpus_off: Maximum number of CPUs hotplugged out at any given moment :type max_cpus_off: int """ # Instantiate a generator so we can change the seed without any global # effect random_gen = random.Random() random_gen.seed(seed) target.hotplug.online_all() hotpluggable_cpus = target.hotplug.list_hotpluggable_cpus() sequence = list(cls.cpuhp_seq( nr_operations, hotpluggable_cpus, max_cpus_off, random_gen)) cls._check_cpuhp_seq_consistency(nr_operations, hotpluggable_cpus, max_cpus_off, sequence) script = cls._cpuhp_script( target, res_dir, sequence, sleep_min_ms, sleep_max_ms, random_gen) script.push() # We don't want a timeout but we do want to detect if/when the target # stops responding. So start a background shell and poll on it try: # Using DEVNULL is important to prevent the command from blocking # on its outputs with script.background(as_root=True, stdout=DEVNULL, stderr=DEVNULL) as bg: while bg.poll() is None: if not script.target.check_responsive(): break sleep(0.1) finally: target_alive = bool(script.target.check_responsive()) target.hotplug.online_all() live_cpus = target.list_online_cpus() if target_alive else [] return cls(target.plat_info, target_alive, hotpluggable_cpus, live_cpus)
def _from_target(cls, target: Target, *, res_dir: ArtifactPath = None, seed=None, nr_operations=100, sleep_min_ms=10, sleep_max_ms=100, max_cpus_off=sys.maxsize) -> 'HotplugBase': """ :param seed: Seed of the RNG used to create the hotplug sequences :type seed: int :param nr_operations: Number of operations in the sequence :type nr_operations: int :param sleep_min_ms: Minimum sleep duration between hotplug operations :type sleep_min_ms: int :param sleep_max_ms: Maximum sleep duration between hotplug operations (0 would lead to no sleep) :type sleep_max_ms: int :param max_cpus_off: Maximum number of CPUs hotplugged out at any given moment :type max_cpus_off: int """ # Instantiate a generator so we can change the seed without any global # effect random_gen = random.Random() random_gen.seed(seed) target.hotplug.online_all() hotpluggable_cpus = target.hotplug.list_hotpluggable_cpus() sequence = list( cls.cpuhp_seq(nr_operations, hotpluggable_cpus, max_cpus_off, random_gen)) cls._check_cpuhp_seq_consistency(nr_operations, hotpluggable_cpus, max_cpus_off, sequence) do_hotplug = cls._cpuhp_func(target, res_dir, sequence, sleep_min_ms, sleep_max_ms, random_gen) # We don't want a timeout but we do want to detect if/when the target # stops responding. So handle the hotplug remote func in a separate # thread and keep polling the target thread = Thread(target=do_hotplug, daemon=True) try: thread.start() while thread.is_alive(): # We might have a thread hanging off in that case, but there is # not much we can do since the remote func cannot really be # canceled. Since it was spawned with a timeout, it will # eventually die. if not target.check_responsive(): break sleep(0.1) finally: target_alive = bool(target.check_responsive()) target.hotplug.online_all() live_cpus = target.list_online_cpus() if target_alive else [] return cls(target.plat_info, target_alive, hotpluggable_cpus, live_cpus)
def _from_target(cls, target: Target, *, res_dir: ArtifactPath = None, seed=None, nr_operations=100, sleep_min_ms=10, sleep_max_ms=100, max_cpus_off=sys.maxsize) -> 'HotplugBase': """ :param seed: Seed of the RNG used to create the hotplug sequences :type seed: int :param nr_operations: Number of operations in the sequence :type nr_operations: int :param sleep_min_ms: Minimum sleep duration between hotplug operations :type sleep_min_ms: int :param sleep_max_ms: Maximum sleep duration between hotplug operations (0 would lead to no sleep) :type sleep_max_ms: int :param max_cpus_off: Maximum number of CPUs hotplugged out at any given moment :type max_cpus_off: int """ # Instantiate a generator so we can change the seed without any global # effect random_gen = random.Random() random_gen.seed(seed) target.hotplug.online_all() hotpluggable_cpus = target.hotplug.list_hotpluggable_cpus() sequence = list( cls.cpuhp_seq(nr_operations, hotpluggable_cpus, max_cpus_off, random_gen)) cls._check_cpuhp_seq_consistency(nr_operations, hotpluggable_cpus, max_cpus_off, sequence) script = cls._cpuhp_script(target, res_dir, sequence, sleep_min_ms, sleep_max_ms, random_gen) script.push() # We don't want a timeout but we do want to detect if/when the target # stops responding. So start a background shell and poll on it with script.background(as_root=True): try: script.wait() target_alive = True target.hotplug.online_all() except TargetNotRespondingError: target_alive = False live_cpus = target.list_online_cpus() if target_alive else [] return cls(target.plat_info, target_alive, hotpluggable_cpus, live_cpus)