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

net_cls cgroup mounting #301

Open
MaciekLeks opened this issue Jul 21, 2023 · 1 comment
Open

net_cls cgroup mounting #301

MaciekLeks opened this issue Jul 21, 2023 · 1 comment

Comments

@MaciekLeks
Copy link

MaciekLeks commented Jul 21, 2023

Hello,

this code is not working

package main

import (
	"github.com/containerd/cgroups/v3/cgroup1"
	"github.com/opencontainers/runtime-spec/specs-go"
)

func uint32Ptr(v uint32) *uint32 {
	return &v
}

func main() {
	netClsController := cgroup1.NewNetCls("/sys/fs/cgroup")
	err := netClsController.Create("foobar", &specs.LinuxResources{
		Network: &specs.LinuxNetwork{
			ClassID: uint32Ptr(0x00100010), //10:10
		},
	})

	if err != nil {
		panic(err)
	}
}

but I think is equivalent of this:

mkdir /sys/fs/cgroup/net_cls
#mount -t cgroup -onet_cls net_cls /sys/fs/cgroup/net_cls
mkdir /sys/fs/cgroup/net_cls/foobar
echo 0x100010 > /sys/fs/cgroup/net_cls/foobar/net_cls.classid

except mounting part. We need mounting to get net_cls cgroup and to put classid into net_cls.classid.

I could not figure out if the package supports mounting, but if so, then how to force it to do that? If not, then I think it's an issue because Create creates and writes to net_cls.classid file so there is no place to put own mounting code between NewNetCls and Create.

To make Create work, the code should look something like this:

func (n *netclsController) Create(path string, resources *specs.LinuxResources) error {
	if err := os.MkdirAll(path, defaultDirPerm); err != nil {
		return err
	}

	if err := syscall.Mount("cgroup", n.root, "cgroup", 0, NetCls); err != nil {
		if !errors.Is(err, syscall.EBUSY) { //could be already mounted and it's ok
			// some other error
			return err
		}
	}

	if resources.Network != nil && resources.Network.ClassID != nil && *resources.Network.ClassID > 0 {
		return os.WriteFile(
			filepath.Join(n.Path(path), "net_cls.classid"),
			[]byte(strconv.FormatUint(uint64(*resources.Network.ClassID), 10)),
			defaultFilePerm,
		)
	}

	return nil
}

version: github.com/containerd/cgroups/v3 v3.0.2

@MaciekLeks
Copy link
Author

MaciekLeks commented Jul 23, 2023

Ok, I think I've made a mistake. The project has nothing to do with subsystem management. It's up to me to create a net_cls mounting point first and then create a subgroup`.

	if err := os.MkdirAll("/sys/fs/cgroup/net_cls", 0o755); err != nil {
		panic(err)
	}

	err := syscall.Mount("net_cls", "/sys/fs/cgroup/net_cls", "cgroup", 0, "net_cls")
	if err != nil {
		if !errors.Is(err, syscall.EBUSY) {
			panic(err)
		}
	}

	subsystems, err := cgroup1.Default()
	if err != nil {
		fmt.Println("Default error:", err)
                panic(err)

	}

	for i := range subsystems {
		fmt.Println("Subsystem:", subsystems[i].Name())
	}
	
	control, err := cgroup1.New(cgroup1.StaticPath("foobar4"),
		&specs.LinuxResources{
			Network: &specs.LinuxNetwork{
				ClassID: uint32Ptr(0x00100010), //10:10
			},
		},
		cgroup1.WithHiearchy(func() ([]cgroup1.Subsystem, error) {
			return []cgroup1.Subsystem{cgroup1.NewNetCls("/sys/fs/cgroup")}, nil
		}) /* [1] */)

	if err := control.AddTask(cgroup1.Process{
		Pid: os.Getpid(),
	}); err != nil {
		panic(err)
	}

Having look at [1] and New internals I see that this option has no meaning while you do nothing with opts except checking it's validity inside New function. So, why does New use options? And the second thing. If you try to create sub group in all subsystems it means that my foobar4 will be spread in subsystems where I do not want it to.

Still, I do not catch how to make this simple thing correctly with your code:

mkdir /sys/fs/cgroup/net_cls
mount -t cgroup -onet_cls net_cls /sys/fs/cgroup/net_cls
mkdir /sys/fs/cgroup/net_cls/foobar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant