Skip to content

Commit

Permalink
Add support for detecting docker container
Browse files Browse the repository at this point in the history
Add support in port library for detecting if we are running in
docker container or not.
This is required for cgroup related APIs in port library,
such as omrsysinfo_cgroup_get_memlimit, to work properly.
This is because when running in a docker container,
the cgroups listed in /proc/self/cgroup do not match the cgroups
of the process in the container. /proc/self/cgroup actually
shows the cgroups as seen from the host.

Eg if a process is running in a docker container,
its /proc/PID/cgroup on docker will show something like:

$ cat /proc/8364/cgroup
11:cpuset:/docker/<container id>
10:perf_event:/docker/<container id>
9:memory:/dockera/<container id>
...

but the actual cgroup of the process would be "/".

Once we figure out that we are running in docker container,
then cgroup APIs in port library would use "/" as cgroup name
for reading resource limits.

Note that as and when docker containers start supporting
cgroup namespace, then above mentioned mismatch would also be fixed.
Following issues and PRs are related to adding support for
cgroup namespace in docker container:
opencontainers/runc#1184
opencontainers/runtime-spec#62
opencontainers/runtime-spec#66

There is no direct mechanism to detect if we are running in
docker container.
Most reliable mechanism that I have come across is
by checking the cgroup for PID 1 (by reading /proc/1/cgroup file)
for all subsystems. If all cgroups are "/", then it indicates the
process is running on host system.
Else we conclude it to be running in a docker container.
Note that this mechanism will break when docker containers start
supporting cgroup namespace.

- Also added couple of APIs to return container type and name.

Signed-off-by: Ashutosh Mehra <[email protected]>
  • Loading branch information
Ashutosh Mehra committed Nov 23, 2017
1 parent d27a823 commit d152d87
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 27 deletions.
63 changes: 63 additions & 0 deletions fvtest/porttest/si.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2142,3 +2142,66 @@ TEST(PortSysinfoTest, sysinfo_cgroup_get_memlimit)
reportTestExit(OMRPORTLIB, testName);
return;
}

/**
* Test omrsysinfo_get_container_type.
*/
TEST(PortSysinfoTest, sysinfo_get_container_type)
{
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
const char *testName = "omrsysinfo_get_container_type";
int32_t rc = 0;
OMRContainerType containerType = OMR_CONTAINER_NONE;

reportTestEntry(OMRPORTLIB, testName);

rc = omrsysinfo_get_container_type(&containerType);

if (0 != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_container_type returned error code %d\n", rc);
}
#if defined(LINUX)
if ((OMR_CONTAINER_NONE != containerType) && (OMR_CONTAINER_DOCKER != containerType))
#else /* defined(LINUX) */
if (OMR_CONTAINER_NONE != containerType)
#endif /* defined(LINUX) */
{
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_container_type returned unexpected container type %d\n", containerType);
}

reportTestExit(OMRPORTLIB, testName);
return;
}

/**
* Test omrsysinfo_get_container_name.
*/
TEST(PortSysinfoTest, sysinfo_get_container_name)
{
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
const char *testName = "omrsysinfo_get_container_name";
OMRContainerType containerType = OMR_CONTAINER_NONE;
const char *expectedName = "none";
const char *name = NULL;

reportTestEntry(OMRPORTLIB, testName);

name = omrsysinfo_get_container_name(containerType);

if (strcmp(name, expectedName)) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_container_name returned \"%s\", expected \"%s\"", name, expectedName);
}

#if defined(LINUX)
containerType = OMR_CONTAINER_DOCKER;
expectedName = "docker";
name = omrsysinfo_get_container_name(containerType);

if (strcmp(name, expectedName)) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_get_container_name returned \"%s\", expected \"%s\"", name, expectedName);
}
#endif

reportTestExit(OMRPORTLIB, testName);
return;
}
13 changes: 13 additions & 0 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,13 @@ typedef struct OMROSKernelInfo {
#define OMR_CGROUP_SUBSYSTEM_MEMORY ((uint64_t)0x2)
#define OMR_CGROUP_SUBSYSTEM_ALL (OMR_CGROUP_SUBSYSTEM_CPU | OMR_CGROUP_SUBSYSTEM_MEMORY)

typedef enum OMRContainerType {
OMR_CONTAINER_NONE,
OMR_CONTAINER_DOCKER,
OMR_CONTAINER_NUM_CONTAINERS,
OMR_CONTAINER_EnsureWideEnum = 0x1000000 /* force 4-byte enum */
} OMRContainerType;

struct OMRPortLibrary;
typedef struct J9Heap J9Heap;

Expand Down Expand Up @@ -1463,6 +1470,10 @@ typedef struct OMRPortLibrary {
uint64_t ( *sysinfo_cgroup_are_subsystems_enabled)(struct OMRPortLibrary *portLibrary, uint64_t subsystemFlags);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_get_memlimit "omrsysinfo_cgroup_get_memlimit"*/
int32_t (*sysinfo_cgroup_get_memlimit)(struct OMRPortLibrary *portLibrary, uint64_t *limit);
/** see @ref omrsysinfo_get_container_type "omrsysinfo_get_container_type"*/
int32_t ( *sysinfo_get_container_type)(struct OMRPortLibrary *portLibrary, OMRContainerType *containerType);
/** see @ref omrsysinfo_get_container_name "omrsysinfo_get_container_name"*/
const char * ( *sysinfo_get_container_name)(struct OMRPortLibrary *portLibrary, OMRContainerType containerType);
/** see @ref omrport.c::omrport_init_library "omrport_init_library"*/
int32_t (*port_init_library)(struct OMRPortLibrary *portLibrary, uintptr_t size) ;
/** see @ref omrport.c::omrport_startup_library "omrport_startup_library"*/
Expand Down Expand Up @@ -1910,6 +1921,8 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary);
#define omrsysinfo_cgroup_enable_subsystems(param1) privateOmrPortLibrary->sysinfo_cgroup_enable_subsystems(privateOmrPortLibrary, param1)
#define omrsysinfo_cgroup_are_subsystems_enabled(param1) privateOmrPortLibrary->sysinfo_cgroup_are_subsystems_enabled(privateOmrPortLibrary, param1)
#define omrsysinfo_cgroup_get_memlimit(param1) privateOmrPortLibrary->sysinfo_cgroup_get_memlimit(privateOmrPortLibrary, param1)
#define omrsysinfo_get_container_type(param1) privateOmrPortLibrary->sysinfo_get_container_type(privateOmrPortLibrary, param1)
#define omrsysinfo_get_container_name(param1) privateOmrPortLibrary->sysinfo_get_container_name(privateOmrPortLibrary, param1)
#define omrintrospect_startup() privateOmrPortLibrary->introspect_startup(privateOmrPortLibrary)
#define omrintrospect_shutdown() privateOmrPortLibrary->introspect_shutdown(privateOmrPortLibrary)
#define omrintrospect_set_suspend_signal_offset(param1) privateOmrPortLibrary->introspect_set_suspend_signal_offset(privateOmrPortLibrary, param1)
Expand Down
1 change: 1 addition & 0 deletions include_core/omrporterror.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@
#define OMRPORT_ERROR_SYSINFO_CGROUP_SUBSYSTEM_UNAVAILABLE (OMRPORT_ERROR_SYSINFO_BASE-22)
#define OMRPORT_ERROR_SYSINFO_CGROUP_NAME_NOT_AVAILABLE (OMRPORT_ERROR_SYSINFO_BASE-23)
#define OMRPORT_ERROR_SYSINFO_CGROUP_MEMLIMIT_FILE_FOPEN_FAILED (OMRPORT_ERROR_SYSINFO_BASE-24)
#define OMRPORT_ERROR_SYSINFO_CONTAINER_UNSUPPORTED_PLATFORM (OMRPORT_ERROR_SYSINFO_BASE-25)

/**
* @name Port library initialization return codes
Expand Down
4 changes: 3 additions & 1 deletion port/common/omrport.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ static OMRPortLibrary MasterPortLibraryTable = {
omrsysinfo_cgroup_get_enabled_subsystems, /* sysinfo_cgroup_get_enabled_subsystems */
omrsysinfo_cgroup_enable_subsystems, /* sysinfo_cgroup_enable_subsystems */
omrsysinfo_cgroup_are_subsystems_enabled, /* sysinfo_cgroup_are_subsystems_enabled */
omrsysinfo_cgroup_get_memlimit, /* sysinfo_cgroup_get_memlimit */
omrsysinfo_cgroup_get_memlimit, /* sysinfo_cgroup_get_memlimit */
omrsysinfo_get_container_type, /* sysinfo_get_container_type */
omrsysinfo_get_container_name, /* sysinfo_get_container_name */
omrport_init_library, /* port_init_library */
omrport_startup_library, /* port_startup_library */
omrport_create_library, /* port_create_library */
Expand Down
32 changes: 32 additions & 0 deletions port/common/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -913,3 +913,35 @@ omrsysinfo_cgroup_get_memlimit(struct OMRPortLibrary *portLibrary, uint64_t *lim
{
return OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM;
}

/**
* Return container type
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[out] containerType pointer to OMRContainerType which on successful return contains the
* container type in which the process is running.
*
* @return 0 on success, otherwise negative error code
*/
int32_t
omrsysinfo_get_container_type(struct OMRPortLibrary *portLibrary, OMRContainerType *containerType)
{
Assert_PRT_true(NULL != containerType);
*containerType = OMR_CONTAINER_NONE;
return 0;
}

/**
* Return container name for the given container type
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[out] containerType type of the container
*
* @return container name for the given container type; return NULL on unsupported platforms
*/
const char *
omrsysinfo_get_container_name(struct OMRPortLibrary *portLibrary, OMRContainerType containerType)
{
Assert_PRT_true(OMR_CONTAINER_NONE == containerType);
return "none";
}
4 changes: 4 additions & 0 deletions port/omrportpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@ extern J9_CFUNC uint64_t
omrsysinfo_cgroup_are_subsystems_enabled(struct OMRPortLibrary *portLibrary, uint64_t subsystemFlags);
extern J9_CFUNC int32_t
omrsysinfo_cgroup_get_memlimit(struct OMRPortLibrary *portLibrary, uint64_t *limit);
extern J9_CFUNC int32_t
omrsysinfo_get_container_type(struct OMRPortLibrary *portLibrary, OMRContainerType *containerType);
extern J9_CFUNC const char *
omrsysinfo_get_container_name(struct OMRPortLibrary *portLibrary, OMRContainerType containerType);

/* J9SourceJ9Signal*/
extern J9_CFUNC int32_t
Expand Down
Loading

0 comments on commit d152d87

Please sign in to comment.