8287007: [cgroups] Consistently use stringStream throughout parsing code

Reviewed-by: iklam
This commit is contained in:
Severin Gehwolf 2022-06-13 15:14:51 +00:00
parent 17695962ac
commit e0baf012b1
5 changed files with 243 additions and 34 deletions

View File

@ -37,40 +37,26 @@
* on the contents of the mountinfo and cgroup files.
*/
void CgroupV1Controller::set_subsystem_path(char *cgroup_path) {
char buf[MAXPATHLEN+1];
stringStream ss;
if (_root != NULL && cgroup_path != NULL) {
if (strcmp(_root, "/") == 0) {
int buflen;
strncpy(buf, _mount_point, MAXPATHLEN);
buf[MAXPATHLEN-1] = '\0';
ss.print_raw(_mount_point);
if (strcmp(cgroup_path,"/") != 0) {
buflen = strlen(buf);
if ((buflen + strlen(cgroup_path)) > (MAXPATHLEN-1)) {
return;
}
strncat(buf, cgroup_path, MAXPATHLEN-buflen);
buf[MAXPATHLEN-1] = '\0';
ss.print_raw(cgroup_path);
}
_path = os::strdup(buf);
_path = os::strdup(ss.base());
} else {
if (strcmp(_root, cgroup_path) == 0) {
strncpy(buf, _mount_point, MAXPATHLEN);
buf[MAXPATHLEN-1] = '\0';
_path = os::strdup(buf);
ss.print_raw(_mount_point);
_path = os::strdup(ss.base());
} else {
char *p = strstr(cgroup_path, _root);
if (p != NULL && p == _root) {
if (strlen(cgroup_path) > strlen(_root)) {
int buflen;
strncpy(buf, _mount_point, MAXPATHLEN);
buf[MAXPATHLEN-1] = '\0';
buflen = strlen(buf);
if ((buflen + strlen(cgroup_path) - strlen(_root)) > (MAXPATHLEN-1)) {
return;
}
strncat(buf, cgroup_path + strlen(_root), MAXPATHLEN-buflen);
buf[MAXPATHLEN-1] = '\0';
_path = os::strdup(buf);
ss.print_raw(_mount_point);
const char* cg_path_sub = cgroup_path + strlen(_root);
ss.print_raw(cg_path_sub);
_path = os::strdup(ss.base());
}
}
}

View File

@ -213,17 +213,12 @@ char* CgroupV2Subsystem::mem_limit_val() {
}
char* CgroupV2Controller::construct_path(char* mount_path, char *cgroup_path) {
char buf[MAXPATHLEN+1];
int buflen;
strncpy(buf, mount_path, MAXPATHLEN);
buf[MAXPATHLEN] = '\0';
buflen = strlen(buf);
if ((buflen + strlen(cgroup_path)) > MAXPATHLEN) {
return NULL;
stringStream ss;
ss.print_raw(mount_path);
if (strcmp(cgroup_path, "/") != 0) {
ss.print_raw(cgroup_path);
}
strncat(buf, cgroup_path, MAXPATHLEN-buflen);
buf[MAXPATHLEN] = '\0';
return os::strdup(buf);
return os::strdup(ss.base());
}
char* CgroupV2Subsystem::pids_max_val() {

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2022, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "precompiled.hpp"
#ifdef LINUX
#include "cgroupV1Subsystem_linux.hpp"
#include "cgroupV2Subsystem_linux.hpp"
#include "unittest.hpp"
typedef struct {
const char* mount_path;
const char* root_path;
const char* cgroup_path;
const char* expected_path;
} TestCase;
TEST(os_linux_cgroup, set_cgroupv1_subsystem_path) {
TestCase host = {
"/sys/fs/cgroup/memory", // mount_path
"/", // root_path
"/user.slice/user-1000.slice/user@1000.service", // cgroup_path
"/sys/fs/cgroup/memory/user.slice/user-1000.slice/user@1000.service" // expected_path
};
TestCase container_engine = {
"/sys/fs/cgroup/mem", // mount_path
"/user.slice/user-1000.slice/user@1000.service", // root_path
"/user.slice/user-1000.slice/user@1000.service", // cgroup_path
"/sys/fs/cgroup/mem" // expected_path
};
int length = 2;
TestCase* testCases[] = { &host,
&container_engine };
for (int i = 0; i < length; i++) {
CgroupV1Controller* ctrl = new CgroupV1Controller( (char*)testCases[i]->root_path,
(char*)testCases[i]->mount_path);
ctrl->set_subsystem_path((char*)testCases[i]->cgroup_path);
ASSERT_STREQ(testCases[i]->expected_path, ctrl->subsystem_path());
}
}
TEST(os_linux_cgroup, set_cgroupv2_subsystem_path) {
TestCase at_mount_root = {
"/sys/fs/cgroup", // mount_path
NULL, // root_path, ignored
"/", // cgroup_path
"/sys/fs/cgroup" // expected_path
};
TestCase sub_path = {
"/sys/fs/cgroup", // mount_path
NULL, // root_path, ignored
"/foobar", // cgroup_path
"/sys/fs/cgroup/foobar" // expected_path
};
int length = 2;
TestCase* testCases[] = { &at_mount_root,
&sub_path };
for (int i = 0; i < length; i++) {
CgroupV2Controller* ctrl = new CgroupV2Controller( (char*)testCases[i]->mount_path,
(char*)testCases[i]->cgroup_path);
ASSERT_STREQ(testCases[i]->expected_path, ctrl->subsystem_path());
}
}
#endif

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2022, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import jdk.internal.platform.cgroupv1.CgroupV1SubsystemController;
/*
* @test
* @key cgroups
* @requires os.family == "linux"
* @modules java.base/jdk.internal.platform.cgroupv1
* @library /test/lib
* @run junit/othervm CgroupV1SubsystemControllerTest
*/
public class CgroupV1SubsystemControllerTest {
/*
* Common case: Containers
*/
@Test
public void testCgPathEqualsRoot() {
String root = "/machine.slice/libpod-7145e2e7dbeab5aa96bd79beed79eda286a2d299a0ee386e704cad9f53a70979.scope";
String mountPoint = "/somemount";
CgroupV1SubsystemController ctrl = new CgroupV1SubsystemController(root, mountPoint);
ctrl.setPath("/machine.slice/libpod-7145e2e7dbeab5aa96bd79beed79eda286a2d299a0ee386e704cad9f53a70979.scope");
assertEquals(mountPoint, ctrl.path());
}
/*
* Common case: Host
*/
@Test
public void testCgPathNonEmptyRoot() {
String root = "/";
String mountPoint = "/sys/fs/cgroup/memory";
CgroupV1SubsystemController ctrl = new CgroupV1SubsystemController(root, mountPoint);
String cgroupPath = "/subpath";
ctrl.setPath(cgroupPath);
String expectedPath = mountPoint + cgroupPath;
assertEquals(expectedPath, ctrl.path());
}
@Test
public void testCgPathSubstring() {
String root = "/foo/bar/baz";
String mountPoint = "/sys/fs/cgroup/memory";
CgroupV1SubsystemController ctrl = new CgroupV1SubsystemController(root, mountPoint);
String cgroupPath = "/foo/bar/baz/some";
ctrl.setPath(cgroupPath);
String expectedPath = mountPoint + "/some";
assertEquals(expectedPath, ctrl.path());
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import jdk.internal.platform.cgroupv2.CgroupV2SubsystemController;
/*
* @test
* @key cgroups
* @requires os.family == "linux"
* @modules java.base/jdk.internal.platform.cgroupv2
* @library /test/lib
* @run junit/othervm CgroupV2SubsystemControllerTest
*/
public class CgroupV2SubsystemControllerTest {
/*
* Common case: No nested cgroup path (i.e. at the unified root)
*/
@Test
public void testCgPathAtRoot() {
String mountPoint = "/sys/fs/cgroup";
String cgroupPath = "/";
CgroupV2SubsystemController ctrl = new CgroupV2SubsystemController(mountPoint, cgroupPath);
assertEquals(mountPoint, ctrl.path());
}
/*
* Cgroup path at a sub-path
*/
@Test
public void testCgPathNonEmptyRoot() {
String mountPoint = "/sys/fs/cgroup";
String cgroupPath = "/foobar";
CgroupV2SubsystemController ctrl = new CgroupV2SubsystemController(mountPoint, cgroupPath);
String expectedPath = mountPoint + cgroupPath;
assertEquals(expectedPath, ctrl.path());
}
}