Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide APIs for enabling cgroup subsystems #1424

Merged
merged 2 commits into from
Nov 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 11 additions & 27 deletions fvtest/porttest/si.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2109,51 +2109,35 @@ TEST(PortSysinfoTest, sysinfo_cgroup_get_memlimit)
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
const char *testName = "omrsysinfo_cgroup_get_memlimit";
uint64_t cgroupMemLimit = 0;
int32_t cgroupLimitEnabled = 0;
int32_t rc = 0;
uint64_t enabledSubsystems = 0;

reportTestEntry(OMRPORTLIB, testName);

/* Call omrsysinfo_cgroup_get_memlimit without enabling cgroup limits */
rc = omrsysinfo_cgroup_get_memlimit(&cgroupMemLimit);

#if defined(LINUX)
if (OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, expected %d\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED);
}
#else
#if !defined(LINUX)
if (OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, exptected %d on platform that does not support cgroups\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM);
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, expected %d on platform that does not support cgroups\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM);
}
#endif

/* Call omrsysinfo_cgroup_get_memlimit after enabling cgroup limits */
cgroupLimitEnabled = omrsysinfo_cgroup_enable_limits();

rc = omrsysinfo_cgroup_get_memlimit(&cgroupMemLimit);

#if defined(LINUX)
if (0 == cgroupLimitEnabled) {
if (OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED == rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d when cgroup limits was enabled successfully\n", rc);
/* Compare sysinfo_get_physical_memory and sysinfo_cgroup_get_memlimit after enabling memory subsystem */
enabledSubsystems = omrsysinfo_cgroup_enable_subsystems(OMR_CGROUP_SUBSYSTEM_MEMORY);
if (OMR_ARE_ALL_BITS_SET(enabledSubsystems, OMR_CGROUP_SUBSYSTEM_MEMORY)) {
rc = omrsysinfo_cgroup_get_memlimit(&cgroupMemLimit);
if (0 != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit failed with error code %d\n", rc);
} else if (0 == rc) {
uint64_t physicalMemLimit = 0;

physicalMemLimit = omrsysinfo_get_physical_memory();
if (cgroupMemLimit != physicalMemLimit) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "Expected omrsysinfo_cgroup_get_memlimit and omrsysinfo_get_physical_memory to return same value, but omrsysinfo_cgroup_get_memlimit returned %ld and omrsysinfo_get_physical_memory returned %ld\n");
outputErrorMessage(PORTTEST_ERROR_ARGS, "Expected omrsysinfo_cgroup_get_memlimit and omrsysinfo_get_physical_memory to return same value, but omrsysinfo_cgroup_get_memlimit returned %ld and omrsysinfo_get_physical_memory returned %ld\n", cgroupMemLimit, physicalMemLimit);
}
}
} else {
if (OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, expected %d\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED);
}
}
#else
if (OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM != rc) {
outputErrorMessage(PORTTEST_ERROR_ARGS, "omrsysinfo_cgroup_get_memlimit returned %d, exptected %d on platform that does not support cgroups\n", rc, OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM);
}
#endif

reportTestExit(OMRPORTLIB, testName);
return;
}
32 changes: 23 additions & 9 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,11 @@ typedef struct OMROSKernelInfo {
uint32_t minorRevision;
} OMROSKernelInfo;

/* bitwise flags indicating cgroup subsystems supported by portlibrary */
#define OMR_CGROUP_SUBSYSTEM_CPU ((uint64_t)0x1)
#define OMR_CGROUP_SUBSYSTEM_MEMORY ((uint64_t)0x2)
#define OMR_CGROUP_SUBSYSTEM_ALL (OMR_CGROUP_SUBSYSTEM_CPU | OMR_CGROUP_SUBSYSTEM_MEMORY)

struct OMRPortLibrary;
typedef struct J9Heap J9Heap;

Expand Down Expand Up @@ -1438,12 +1443,18 @@ typedef struct OMRPortLibrary {
BOOLEAN ( *sysinfo_os_has_feature)(struct OMRPortLibrary *portLibrary, struct OMROSDesc *desc, uint32_t feature) ;
/** see @ref omrsysinfo.c::omrsysinfo_os_kernel_info "omrsysinfo_os_kernel_info"*/
BOOLEAN ( *sysinfo_os_kernel_info)(struct OMRPortLibrary *portLibrary, struct OMROSKernelInfo *kernelInfo) ;
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_is_limits_supported "omrsysinfo_cgroup_is_limits_supported"*/
int32_t ( *sysinfo_cgroup_is_limits_supported)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_is_limits_enabled "omrsysinfo_cgroup_is_limits_enabled"*/
BOOLEAN ( *sysinfo_cgroup_is_limits_enabled)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_enable_limits "omrsysinfo_cgroup_enable_limits"*/
int32_t ( *sysinfo_cgroup_enable_limits)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_is_system_available "omrsysinfo_cgroup_is_system_available"*/
BOOLEAN ( *sysinfo_cgroup_is_system_available)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_get_available_subsystems "omrsysinfo_cgroup_get_available_subsystems"*/
uint64_t ( *sysinfo_cgroup_get_available_subsystems)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_are_subsystems_available "omrsysinfo_cgroup_are_subsystems_available"*/
uint64_t ( *sysinfo_cgroup_are_subsystems_available)(struct OMRPortLibrary *portLibrary, uint64_t subsystemFlags);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_get_enabled_subsystems "omrsysinfo_cgroup_get_enabled_subsystems"*/
uint64_t ( *sysinfo_cgroup_get_enabled_subsystems)(struct OMRPortLibrary *portLibrary);
/** see @ref omrsysinfo_cgroup_enable_subsystems "omrsysinfo_cgroup_enable_subsystems"*/
uint64_t ( *sysinfo_cgroup_enable_subsystems)(struct OMRPortLibrary *portLibrary, uint64_t requestedSubsystems);
/** see @ref omrsysinfo_cgroup_are_subsystems_enabled "omrsysinfo_cgroup_are_subsystems_enabled"*/
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 omrport.c::omrport_init_library "omrport_init_library"*/
Expand Down Expand Up @@ -1886,9 +1897,12 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary);
#define omrsysinfo_get_os_description(param1) privateOmrPortLibrary->sysinfo_get_os_description(privateOmrPortLibrary, (param1))
#define omrsysinfo_os_has_feature(param1,param2) privateOmrPortLibrary->sysinfo_os_has_feature(privateOmrPortLibrary, (param1), (param2))
#define omrsysinfo_os_kernel_info(param1) privateOmrPortLibrary->sysinfo_os_kernel_info(privateOmrPortLibrary, (param1))
#define omrsysinfo_cgroup_is_limits_supported() privateOmrPortLibrary->sysinfo_cgroup_is_limits_supported(privateOmrPortLibrary)
#define omrsysinfo_cgroup_is_limits_enabled() privateOmrPortLibrary->sysinfo_cgroup_is_limits_enabled(privateOmrPortLibrary)
#define omrsysinfo_cgroup_enable_limits() privateOmrPortLibrary->sysinfo_cgroup_enable_limits(privateOmrPortLibrary)
#define omrsysinfo_cgroup_is_system_available() privateOmrPortLibrary->sysinfo_cgroup_is_system_available(privateOmrPortLibrary)
#define omrsysinfo_cgroup_get_available_subsystems() privateOmrPortLibrary->sysinfo_cgroup_get_available_subsystems(privateOmrPortLibrary)
#define omrsysinfo_cgroup_are_subsystems_available(param1) privateOmrPortLibrary->sysinfo_cgroup_are_subsystems_available(privateOmrPortLibrary, param1)
#define omrsysinfo_cgroup_get_enabled_subsystems() privateOmrPortLibrary->sysinfo_cgroup_get_enabled_subsystems(privateOmrPortLibrary)
#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 omrintrospect_startup() privateOmrPortLibrary->introspect_startup(privateOmrPortLibrary)
#define omrintrospect_shutdown() privateOmrPortLibrary->introspect_shutdown(privateOmrPortLibrary)
Expand Down
11 changes: 5 additions & 6 deletions include_core/omrporterror.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,11 @@
#define OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM (OMRPORT_ERROR_SYSINFO_BASE-17)
#define OMRPORT_ERROR_SYSINFO_PROCESS_CGROUP_FILE_FOPEN_FAILED (OMRPORT_ERROR_SYSINFO_BASE-18)
#define OMRPORT_ERROR_SYSINFO_PROCESS_CGROUP_FILE_READ_FAILED (OMRPORT_ERROR_SYSINFO_BASE-19)
#define OMRPORT_ERROR_SYSINFO_PROCESS_CGROUP_FILE_DUPLICATE_SUBSYSTEM_ENTRIES (OMRPORT_ERROR_SYSINFO_BASE-20)
#define OMRPORT_ERROR_SYSINFO_SYS_FS_CGROUP_STATFS_FAILED (OMRPORT_ERROR_SYSINFO_BASE-21)
#define OMRPORT_ERROR_SYSINFO_SYS_FS_CGROUP_TMPFS_NOT_MOUNTED (OMRPORT_ERROR_SYSINFO_BASE-22)
#define OMRPORT_ERROR_SYSINFO_CGROUP_LIMITS_DISABLED (OMRPORT_ERROR_SYSINFO_BASE-23)
#define OMRPORT_ERROR_SYSINFO_CGROUP_NAME_NOT_AVAILABLE (OMRPORT_ERROR_SYSINFO_BASE-24)
#define OMRPORT_ERROR_SYSINFO_CGROUP_MEMLIMIT_FILE_FOPEN_FAILED (OMRPORT_ERROR_SYSINFO_BASE-25)
#define OMRPORT_ERROR_SYSINFO_SYS_FS_CGROUP_STATFS_FAILED (OMRPORT_ERROR_SYSINFO_BASE-20)
#define OMRPORT_ERROR_SYSINFO_SYS_FS_CGROUP_TMPFS_NOT_MOUNTED (OMRPORT_ERROR_SYSINFO_BASE-21)
#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)

/**
* @name Port library initialization return codes
Expand Down
9 changes: 6 additions & 3 deletions port/common/omrport.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,12 @@ static OMRPortLibrary MasterPortLibraryTable = {
omrsysinfo_get_os_description, /* sysinfo_get_os_description */
omrsysinfo_os_has_feature, /* sysinfo_os_has_feature */
omrsysinfo_os_kernel_info, /* sysinfo_os_kernel_info */
omrsysinfo_cgroup_is_limits_supported, /* sysinfo_cgroup_is_limits_supported */
omrsysinfo_cgroup_is_limits_enabled, /* sysinfo_cgroup_is_limits_enabled */
omrsysinfo_cgroup_enable_limits, /* sysinfo_cgroup_enable_limits */
omrsysinfo_cgroup_is_system_available, /* sysinfo_cgroup_is_system_available */
omrsysinfo_cgroup_get_available_subsystems, /* sysinfo_cgroup_get_available_subsystems */
omrsysinfo_cgroup_are_subsystems_available, /* sysinfo_cgroup_are_subsystems_available */
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 */
omrport_init_library, /* port_init_library */
omrport_startup_library, /* port_startup_library */
Expand Down
76 changes: 61 additions & 15 deletions port/common/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,42 +808,88 @@ omrsysinfo_os_kernel_info(struct OMRPortLibrary *portLibrary, struct OMROSKernel
}

/**
* Checks if the port library can use cgroup limits
* Checks if the platform supports cgroup system and the port library can use it
*
* @param[in] portLibrary pointer to OMRPortLibrary
*
* @return 0 if the port library can use cgroup limits, otherwise negative error code
* @return TRUE if the the cgroup system is available, otherwise FALSE
*/
int32_t
omrsysinfo_cgroup_is_limits_supported(struct OMRPortLibrary *portLibrary)
BOOLEAN
omrsysinfo_cgroup_is_system_available(struct OMRPortLibrary *portLibrary)
{
return OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM;
return FALSE;
}

/**
* Returns TRUE if port library is using cgroup limits, FALSE otherwise
* Returns cgroup subsystems available for port library to use
*
* @param[in] portLibrary pointer to OMRPortLibrary
*
* @return TRUE if port library has been enabled to use cgroup limits, FALSE otherwise
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the
* subsystems that are available
*/
BOOLEAN
omrsysinfo_cgroup_is_limits_enabled(struct OMRPortLibrary *portLibrary)
uint64_t
omrsysinfo_cgroup_get_available_subsystems(struct OMRPortLibrary *portLibrary)
{
return 0;
}

/**
* Checks if the specified cgroup subsystems are available for port library to use.
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[in] subsystemFlags bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_*
*
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the
* subsystems that are available
*/
uint64_t
omrsysinfo_cgroup_are_subsystems_available(struct OMRPortLibrary *portLibrary, uint64_t subsystemFlags)
{
return FALSE;
}

/**
* Enable port library to use cgroup limits
* Returns cgroup subsystems enabled for port library to use
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[in] portLibrary pointer to OMRPortLibrary
*
* @return 0 if the port library can use cgroup limits, otherwise negative error code
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the
* subsystems that are enbaled
*/
int32_t
omrsysinfo_cgroup_enable_limits(struct OMRPortLibrary *portLibrary)
uint64_t
omrsysinfo_cgroup_get_enabled_subsystems(struct OMRPortLibrary *portLibrary)
{
return OMRPORT_ERROR_SYSINFO_CGROUP_UNSUPPORTED_PLATFORM;
return 0;
}

/**
* Enable port library to use specified cgroup subsystems
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[in] subsystems bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_*
* indicating the subsystems to be enabled
*
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the subsystems that are enabled
*/
uint64_t
omrsysinfo_cgroup_enable_subsystems(struct OMRPortLibrary *portLibrary, uint64_t requestedSubsystems)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are errors handled / communicated to the caller by this function?

What if the user tries to enable a subsystem that isn't enabled in the system?

Copy link
Contributor Author

@ashu-mehra ashu-mehra Aug 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error can occur during omrsysinfo_cgroup_is_system_available in which case no subsystem is enabled, but the error is not communicated back to the user.
I am expecting the APIs would be used in following manner:

if (0 == omrsysinfo_cgroup_is_system_available()) {
    availableSubsystems = omrsysinfo_cgroup_get_available_subsystems();
    if (requiredSubsystem & availableSubsystems) {
        omrsysinfo_cgroup_enable_subsystems(requiredSubsystems);
    }
}

What if the user tries to enable a subsystem that isn't enabled in the system?

No error is returned. If the APIs are used as above, this situation shouldn't happen.
And the API actually returns the subsystems that are enabled. So the user can check which subsystems got enabled on this call.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So a user that wanted to validate that the subsystems were actually enabled would need to do the following:

if (0 == omrsysinfo_cgroup_is_system_available()) {
    availableSubsystems = omrsysinfo_cgroup_get_available_subsystems();
    if (requiredSubsystem & availableSubsystems) {
        uint64_t enabledSubsystems = omrsysinfo_cgroup_enable_subsystems(requiredSubsystems);
        if ((enabledSubsystems & requiredSybsystems) != enabledSubsystems) {
            /* do error handling */
        }
    }
}

Isn't exactly user friendly but is something I can live with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually there is no need to call omrsysinfo_cgroup_get_available_subsystems() here:

if (0 == omrsysinfo_cgroup_is_system_available()) {
    uint64_t enabledSubsystems = omrsysinfo_cgroup_enable_subsystems(requiredSubsystems);
    if ((enabledSubsystems & requiredSybsystems) != enabledSubsystems) {
            /* do error handling */
    }
}

return 0;
}

/**
* Check which subsystems are enabled in port library
*
* @param[in] portLibrary pointer to OMRPortLibrary
* @param[in] subsystemsFlags bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_*
*
* @return bitwise-OR of flags of type OMR_CGROUP_SUBSYSTEMS_* indicating the subsystems that are enabled
*/
uint64_t
omrsysinfo_cgroup_are_subsystems_enabled(struct OMRPortLibrary *portLibrary, uint64_t subsystemsFlags)
{
return 0;
}

/**
Expand Down
16 changes: 11 additions & 5 deletions port/omrportpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,12 +511,18 @@ extern J9_CFUNC BOOLEAN
omrsysinfo_os_has_feature(struct OMRPortLibrary *portLibrary, struct OMROSDesc *desc, uint32_t feature);
extern J9_CFUNC BOOLEAN
omrsysinfo_os_kernel_info(struct OMRPortLibrary *portLibrary, struct OMROSKernelInfo *kernelInfo);
extern J9_CFUNC int32_t
omrsysinfo_cgroup_is_limits_supported(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC BOOLEAN
omrsysinfo_cgroup_is_limits_enabled(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC int32_t
omrsysinfo_cgroup_enable_limits(struct OMRPortLibrary *portLibrary);
omrsysinfo_cgroup_is_system_available(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC uint64_t
omrsysinfo_cgroup_get_available_subsystems(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC uint64_t
omrsysinfo_cgroup_are_subsystems_available(struct OMRPortLibrary *portLibrary, uint64_t subsystemFlags);
extern J9_CFUNC uint64_t
omrsysinfo_cgroup_get_enabled_subsystems(struct OMRPortLibrary *portLibrary);
extern J9_CFUNC uint64_t
omrsysinfo_cgroup_enable_subsystems(struct OMRPortLibrary *portLibrary, uint64_t requestedSubsystems);
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);

Expand Down
Loading