From 200ad66cb7d89e9140c7d6d6987dc9190566927a Mon Sep 17 00:00:00 2001 From: Adnan Khan Date: Thu, 18 Jan 2018 17:53:05 -0800 Subject: [PATCH] wip --- agent/app/agent.go | 5 ++++- agent/config/config.go | 3 +++ agent/config/config_unix.go | 3 +++ agent/config/types.go | 2 ++ agent/engine/task_manager.go | 4 +++- agent/resources/interface.go | 3 +++ agent/resources/resources_linux.go | 12 +++++++++--- 7 files changed, 27 insertions(+), 5 deletions(-) diff --git a/agent/app/agent.go b/agent/app/agent.go index af5f5d8e856..50503ebc4b2 100644 --- a/agent/app/agent.go +++ b/agent/app/agent.go @@ -145,6 +145,9 @@ func newAgent( metadataManager = containermetadata.NewManager(dockerClient, cfg) } + resource := resources.New() + resource.ApplyConfigDependencies(cfg) + return &ecsAgent{ ctx: ctx, ec2MetadataClient: ec2MetadataClient, @@ -163,7 +166,7 @@ func newAgent( }), os: oswrapper.New(), metadataManager: metadataManager, - resource: resources.New(), + resource: resource, terminationHandler: sighandlers.StartDefaultTerminationHandler, }, nil } diff --git a/agent/config/config.go b/agent/config/config.go index 0f844a4c687..be997f93f25 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -280,6 +280,8 @@ func environmentConfig() (Config, error) { dockerStopTimeout := getDockerStopTimeout() + cgroupMemorySubsystemPath := os.Getenv("ECS_CGROUP_MEMORY_SUBSYSTEM_PATH") + taskCleanupWaitDuration := parseEnvVariableDuration("ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION") availableLoggingDriversEnv := os.Getenv("ECS_AVAILABLE_LOGGING_DRIVERS") @@ -388,6 +390,7 @@ func environmentConfig() (Config, error) { ContainerMetadataEnabled: containerMetadataEnabled, DataDirOnHost: dataDirOnHost, OverrideAWSLogsExecutionRole: overrideAWSLogsExecutionRoleEnabled, + CgroupMemorySubsystemPath: cgroupMemorySubsystemPath, }, err } diff --git a/agent/config/config_unix.go b/agent/config/config_unix.go index 27139f9870b..64c94eec133 100644 --- a/agent/config/config_unix.go +++ b/agent/config/config_unix.go @@ -27,6 +27,8 @@ const ( defaultCredentialsAuditLogFile = "/log/audit.log" // Default cgroup prefix for ECS tasks DefaultTaskCgroupPrefix = "/ecs" + + defaultCgroupMemorySubsystemPath = "/sys/fs/cgroup/memory/" ) // DefaultConfig returns the default configuration for Linux @@ -55,6 +57,7 @@ func DefaultConfig() Config { AWSVPCBlockInstanceMetdata: false, ContainerMetadataEnabled: false, TaskCPUMemLimit: DefaultEnabled, + CgroupMemorySubsystemPath: defaultCgroupMemorySubsystemPath, } } diff --git a/agent/config/types.go b/agent/config/types.go index c7a18f12a2f..c5f9d1f6f0d 100644 --- a/agent/config/types.go +++ b/agent/config/types.go @@ -194,4 +194,6 @@ type Config struct { // OverrideAWSLogsExecutionRole is config option used to enable awslogs // driver authentication over the task's execution role OverrideAWSLogsExecutionRole bool + + CgroupMemorySubsystemPath string } diff --git a/agent/engine/task_manager.go b/agent/engine/task_manager.go index fc66079a28b..faae6a44c2e 100644 --- a/agent/engine/task_manager.go +++ b/agent/engine/task_manager.go @@ -105,12 +105,14 @@ type managedTask struct { // This method must only be called when the engine.processTasks write lock is // already held. func (engine *DockerTaskEngine) newManagedTask(task *api.Task) *managedTask { + resource := resources.New() + resource.ApplyConfigDependencies(engine.cfg) t := &managedTask{ Task: task, acsMessages: make(chan acsTransition), dockerMessages: make(chan dockerContainerChange), engine: engine, - resource: resources.New(), + resource: resource, } engine.managedTasks[task.Arn] = t return t diff --git a/agent/resources/interface.go b/agent/resources/interface.go index 9a7423cc730..263e6ce0468 100644 --- a/agent/resources/interface.go +++ b/agent/resources/interface.go @@ -15,6 +15,7 @@ package resources import ( "github.com/aws/amazon-ecs-agent/agent/api" + "github.com/aws/amazon-ecs-agent/agent/config" ) // Resource interface to interact with platform level resource constructs @@ -26,4 +27,6 @@ type Resource interface { Setup(task *api.Task) error // Cleanup removes the resource Cleanup(task *api.Task) error + + ApplyConfigDependencies(cfg *config.Config) } diff --git a/agent/resources/resources_linux.go b/agent/resources/resources_linux.go index 32307bc4886..1b6bd4e5895 100644 --- a/agent/resources/resources_linux.go +++ b/agent/resources/resources_linux.go @@ -30,14 +30,14 @@ import ( ) const ( - memorySubsystem = "/sys/fs/cgroup/memory/" memoryUseHierarchy = "memory.use_hierarchy" ) // cgroupWrapper implements the Resource interface type cgroupWrapper struct { - control cgroup.Control - ioutil ioutilwrapper.IOUtil + control cgroup.Control + ioutil ioutilwrapper.IOUtil + memorySubsystemPath string } // New is used to return an object that implements the Resource interface @@ -67,6 +67,10 @@ func (c *cgroupWrapper) Cleanup(task *api.Task) error { return c.cleanupCgroup(task) } +func (c *cgroupWrapper) ApplyConfigDependencies(cfg *config.Config) { + c.memorySubsystemPath = cfg.CgroupMemorySubsystemPath +} + // cgroupInit is used to create the root '/ecs/ cgroup func (c *cgroupWrapper) cgroupInit() error { if c.control.Exists(config.DefaultTaskCgroupPrefix) { @@ -106,6 +110,8 @@ func (c *cgroupWrapper) setupCgroup(task *api.Task) error { } // echo 1 > memory.use_hierarchy + memorySubsystem := c.memorySubsystemPath + err = c.ioutil.WriteFile(filepath.Join(memorySubsystem, cgroupRoot, memoryUseHierarchy), []byte(strconv.Itoa(1)), os.FileMode(0)) if err != nil { return errors.Wrapf(err, "resource: setup cgroup: unable to set use hierarchy flag for task: %s", task.Arn)