예제 #1
0
    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)
예제 #3
0
        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