def test_create_should_return_a_FileSystemCgroupsApi_on_non_systemd_platforms( self): with patch("azurelinuxagent.common.cgroupapi.CGroupsApi._is_systemd", return_value=False): api = CGroupsApi.create() self.assertTrue(type(api) == FileSystemCgroupsApi)
def __init__(self): """ Ensures the cgroups file system is mounted and selects the correct API to interact with it """ osutil = get_osutil() self._cgroups_supported = osutil.is_cgroups_supported() if self._cgroups_supported: self._enabled = True try: osutil.mount_cgroups() self._cgroups_api = CGroupsApi.create() status = "The cgroup filesystem is ready to use" except Exception as e: status = ustr(e) self._enabled = False else: self._enabled = False self._cgroups_api = None status = "Cgroups are not supported by the platform" logger.info("CGroups Status: {0}".format(status)) add_event(AGENT_NAME, version=CURRENT_VERSION, op=WALAEventOperation.InitializeCGroups, is_success=self._enabled, message=status, log_event=False)
def initialize(self): try: if self._initialized: return # # check whether cgroup monitoring is supported on the current distro # self._cgroups_supported = CGroupsApi.cgroups_supported() if not self._cgroups_supported: logger.info("Cgroup monitoring is not supported on {0}", get_distro()) return # # check systemd # self._cgroups_api = CGroupsApi.create() if not isinstance(self._cgroups_api, SystemdCgroupsApi): message = "systemd was not detected on {0}".format( get_distro()) logger.warn(message) add_event(op=WALAEventOperation.CGroupsInitialize, is_success=False, message=message, log_event=False) return def log_cgroup_info(format_string, *args): message = format_string.format(*args) logger.info(message) add_event(op=WALAEventOperation.CGroupsInfo, message=message) def log_cgroup_warn(format_string, *args): message = format_string.format(*args) logger.warn(message) add_event(op=WALAEventOperation.CGroupsInfo, message=message, is_success=False, log_event=False) log_cgroup_info("systemd version: {0}", self._cgroups_api.get_systemd_version()) # # Older versions of the daemon (2.2.31-2.2.40) wrote their PID to /sys/fs/cgroup/{cpu,memory}/WALinuxAgent/WALinuxAgent. When running # under systemd this could produce invalid resource usage data. Do not enable cgroups under this condition. # legacy_cgroups = self._cgroups_api.cleanup_legacy_cgroups() if legacy_cgroups > 0: log_cgroup_warn( "The daemon's PID was added to a legacy cgroup; will not monitor resource usage." ) return # # check v1 controllers # cpu_controller_root, memory_controller_root = self._cgroups_api.get_cgroup_mount_points( ) if cpu_controller_root is not None: logger.info("The CPU cgroup controller is mounted at {0}", cpu_controller_root) else: log_cgroup_warn("The CPU cgroup controller is not mounted") if memory_controller_root is not None: logger.info( "The memory cgroup controller is mounted at {0}", memory_controller_root) else: log_cgroup_warn( "The memory cgroup controller is not mounted") # # check v2 controllers # cgroup2_mountpoint, cgroup2_controllers = self._cgroups_api.get_cgroup2_controllers( ) if cgroup2_mountpoint is not None: log_cgroup_warn( "cgroups v2 mounted at {0}. Controllers: [{1}]", cgroup2_mountpoint, cgroup2_controllers) # # check the cgroups for the agent # agent_unit_name = self._cgroups_api.get_agent_unit_name() cpu_cgroup_relative_path, memory_cgroup_relative_path = self._cgroups_api.get_process_cgroup_relative_paths( "self") if cpu_cgroup_relative_path is None: log_cgroup_warn( "The agent's process is not within a CPU cgroup") else: cpu_accounting = self._cgroups_api.get_unit_property( agent_unit_name, "CPUAccounting") log_cgroup_info('CPUAccounting: {0}', cpu_accounting) if memory_cgroup_relative_path is None: log_cgroup_warn( "The agent's process is not within a memory cgroup") else: memory_accounting = self._cgroups_api.get_unit_property( agent_unit_name, "MemoryAccounting") log_cgroup_info('MemoryAccounting: {0}', memory_accounting) # # All good, enable cgroups and start monitoring the agent # self._cgroups_enabled = True if cpu_controller_root is None or cpu_cgroup_relative_path is None: logger.info("Will not track CPU for the agent's cgroup") else: self._agent_cpu_cgroup_path = os.path.join( cpu_controller_root, cpu_cgroup_relative_path) CGroupsTelemetry.track_cgroup( CpuCgroup(agent_unit_name, self._agent_cpu_cgroup_path)) if memory_controller_root is None or memory_cgroup_relative_path is None: logger.info("Will not track memory for the agent's cgroup") else: self._agent_memory_cgroup_path = os.path.join( memory_controller_root, memory_cgroup_relative_path) CGroupsTelemetry.track_cgroup( MemoryCgroup(agent_unit_name, self._agent_memory_cgroup_path)) log_cgroup_info("Agent cgroups: CPU: {0} -- MEMORY: {1}", self._agent_cpu_cgroup_path, self._agent_memory_cgroup_path) except Exception as e: message = "Error initializing cgroups: {0}".format(ustr(e)) logger.warn(message) add_event(op=WALAEventOperation.CGroupsInitialize, is_success=False, message=message, log_event=False) finally: self._initialized = True