1 # Simple wrapper arround cgroups so we don't have to worry the type of
2 # virtualization the sliver runs on (lxc, qemu/kvm, etc.) managed by libvirt
4 # Xavi Leon <xleon@ac.upc.edu>
10 # Base dir for libvirt
11 BASE_DIR = '/sys/fs/cgroup'
12 SUB_SYSTEMS = ['blkio', 'freezer', 'devices', 'memory', 'cpu,cpuacct', 'cpuset']
15 # Global cgroup mapping.
18 class CgroupWatch(pyinotify.ProcessEvent):
20 def process_IN_CREATE(self, event):
21 path = os.path.join(event.path, event.name)
22 CGROUPS[event.name] = path
23 logger.verbose("Cgroup Notify: Created cgroup %s on %s" % \
24 (event.name, event.path))
26 def process_IN_DELETE(self, event):
28 del CGROUPS[event.name]
30 logger.verbose("Cgroup Notify: Cgroup %s does not exist, continuing..."%event.name)
31 logger.verbose("Cgroup Notify: Deleted cgroup %s on %s" % \
32 (event.name, event.path))
35 #logger.verbose("Cgroups: Recognizing already existing cgroups...")
36 #for virt in VIRT_TECHS:
37 # filenames = os.listdir(os.path.join(BASE_DIR, virt))
38 # for filename in filenames:
39 # path = os.path.join(BASE_DIR, virt, filename)
40 # if os.path.isdir(path):
41 # CGROUPS[filename] = path
43 #logger.verbose("Cgroups: Initializing watchers...")
44 #wm = pyinotify.WatchManager()
45 #notifier = pyinotify.ThreadedNotifier(wm, CgroupWatch())
46 #for virt in VIRT_TECHS:
47 # wdd = wm.add_watch(os.path.join(BASE_DIR, virt),
48 # pyinotify.IN_DELETE | pyinotify.IN_CREATE,
50 #notifier.daemon = True
53 def get_cgroup_paths(subsystem="cpuset"):
56 os.path.join(BASE_DIR, subsystem, 'libvirt', 'lxc'),
58 os.path.join(BASE_DIR, subsystem ),
60 os.path.join(BASE_DIR, subsystem, 'machine.slice'),
61 # as observed on f16 libvirt 1.2.1
62 os.path.join(BASE_DIR, subsystem, 'machine'),
64 # try several locations and return all the results
65 # get_cgroup_path will sort it out
67 # just return all the subdirs in the listed bases
70 for subsystem_base in subsystem_bases if os.path.isdir(subsystem_base)
71 # in each base search the immediate sons that are also dirs
72 for subdir in [ os.path.join(subsystem_base, f) for f in os.listdir(subsystem_base) ]
73 if os.path.isdir(subdir) ]
75 def get_cgroup_path(name, subsystem="cpuset"):
77 Returns the base path for the cgroup with a specific name or None.
79 result = reduce(lambda a, b: b if name in os.path.basename(b) else a,
80 get_cgroup_paths(subsystem), None)
83 name = name + ".libvirt-lxc"
84 result = reduce(lambda a, b: b if name in os.path.basename(b) else a,
85 get_cgroup_paths(subsystem), None)
93 """ Returns the list of cgroups active at this moment on the node """
94 return map(os.path.basename, get_cgroup_paths())
96 def write(name, key, value, subsystem="cpuset"):
97 """ Writes a value to the file key with the cgroup with name """
98 base_path = get_cgroup_path(name, subsystem)
99 with open(os.path.join(base_path, key), 'w') as f:
101 logger.verbose("cgroups.write: overwrote {}".format(base_path))
103 def append(name, key, value, subsystem="cpuset"):
104 """ Appends a value to the file key with the cgroup with name """
105 base_path = get_cgroup_path(name, subsystem)
106 with open(os.path.join(base_path, key), 'a') as f:
108 logger.verbose("cgroups.append: appended {}".format(base_path))
110 if __name__ == '__main__':
112 # goes with the system tests
115 subsystems = 'blkio cpu cpu,cpuacct cpuacct cpuset devices freezer memory net_cls perf_event systemd'.split()
117 for subsystem in subsystems:
118 print 'get_cgroup_path({}, {}) = {}'.\
119 format(name, subsystem, get_cgroup_path(name, subsystem))
121 # print 'get_cgroup_paths = {}'.format(get_cgroup_paths(subsystem))