How my custom module on linux 3.2.28 can make a call to print_cpu_info?
"print_cpu_info" is not exported symbol, so it can not be used by modules. However, you can use "kallsyms_lookup_name", which is exported, to get the address of "print_cpu_info" and execute the function call using a function pointer.
How can I convert XML into a Python object?
It's worth looking at lxml.objectify
.
xml = """<main>
<object1 attr="name">content</object1>
<object1 attr="foo">contenbar</object1>
<test>me</test>
</main>"""
from lxml import objectify
main = objectify.fromstring(xml)
main.object1[0] # content
main.object1[1] # contenbar
main.object1[0].get("attr") # name
main.test # me
Or the other way around to build xml structures:
item = objectify.Element("item")
item.title = "Best of python"
item.price = 17.98
item.price.set("currency", "EUR")
order = objectify.Element("order")
order.append(item)
order.item.quantity = 3
order.price = sum(item.price * item.quantity for item in order.item)
import lxml.etree
print(lxml.etree.tostring(order, pretty_print=True))
Output:
<order>
<item>
<title>Best of python</title>
<price currency="EUR">17.98</price>
<quantity>3</quantity>
</item>
<price>53.94</price>
</order>
Make a system call to get list of processes
Why would you implement a system call for this? You don't want to add a syscall to the existing Linux API. This is the primary Linux interface to userspace and nobody touches syscalls except top kernel developers who know what they do.
If you want to get a list of processes and their parameters and real-time statuses, use /proc
. Every directory that's an integer in there is an existing process ID and contains a bunch of useful dynamic files which ps
, top
and others use to print their output.
If you want to get a list of processes within the kernel (e.g. within a module), you should know that the processes are kept internally as a doubly linked list that starts with the init
process (symbol init_task
in the kernel). You should use macros defined in include/linux/sched.h
to get processes. Here's an example:
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/sched.h>
static int __init ex_init(void)
{
struct task_struct *task;
for_each_process(task)
pr_info("%s [%d]\n", task->comm, task->pid);
return 0;
}
static void __exit ex_fini(void)
{
}
module_init(ex_init);
module_exit(ex_fini);
This should be okay to gather information. However, don't change anything in there unless you really know what you're doing (which will require a bit more reading).
CPU usage of a kernel module
Sorry to disappoint, but there is no way to accomplish what you want -- not because Linux doesn't have the capability, but by definition:
A module can "plug-in" to the kernel of two general ways: Either by installing a callback (e.g. proc or sys file, device, etc), or starting a kernel thread. In your case, iptable_mangle plugs in by setting callbacks on iptables/netfilter. This means the module code is executed as part of the network stack (in ksoftirqd context, to be more accurate).
If this had been in a kernel thread context, Linux keeps statistics. But for callbacks, that is not the case. The thread which does end up executing the module code does a lot of other things, so just isolating your module code is impractical (unless, of course, you're in possession of the source, and then you can add timing statements very easily).
One partial solution would be to use the kernel ftrace mechanism - this allows for function call tracing in the kernel - it's unbelievably powerful, and can show you statistics as per particular functions. It's not exactly what you want, but it's as close as you'll get.
Calling times() in kernel space
If you want precisely measure times between some events in kernel (like context switching), you need some tracer, like SystemTap. From kernel module you may directly bind probes through various tracing and profiling subsystems like ftrace, perf or kprobes.
Here is an example which dumps message to kernel log when context is switched:
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/tracepoint.h>
#include <trace/events/sched.h>
...
void my_sched_switch_probe(void* ignore, struct task_struct* prev, struct task_struct* next) {
printk("my_sched_switch_probe: %s -> %s at %lu\n", prev->comm, next->comm,
(unsigned long) sched_clock());
}
int cswtracer_init(void) {
register_trace_sched_switch(my_sched_switch_probe, NULL);
return 0;
}
void cswtracer_fini(void) {
unregister_trace_sched_switch(my_sched_switch_probe, NULL);
}
module_init(cswtracer_init);
module_exit(cswtracer_fini);
NOTE: do not run it, it will slow your system dramatically.
So analyze name of processes in my_sched_switch_probe()
and calculate difference between time when process entered CPU (next->comm == "myprocessname"
) and when it leaves CPU (prev->comm == "myprocessname"
). That difference is the last time period process spent on CPU during.
Isolate Kernel Module to a Specific Core Using Cpuset
So I want the module to get executed in an isolated core.
and
actually isolate a specific core in our system and execute just one
specific process to that core
This is a working source code compiled and tested on a Debian box using kernel 3.16. I'll describe how to load and unload first and what the parameter passed means.
All sources can be found on github here...
https://github.com/harryjackson/doc/tree/master/linux/kernel/toy/toy
Build and load the module...
make
insmod toy param_cpu_id=2
To unload the module use
rmmod toy
I'm not using modprobe because it expects some configuration etc. The parameter we're passing to the toy
kernel module is the CPU we want to isolate. None of the device operations that get called will run unless they're executing on that CPU.
Once the module is loaded you can find it here
/dev/toy
Simple operations like
cat /dev/toy
create events that the kernel module catches and produces some output. You can see the output using dmesg
.
Source code...
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harry");
MODULE_DESCRIPTION("toy kernel module");
MODULE_VERSION("0.1");
#define DEVICE_NAME "toy"
#define CLASS_NAME "toy"
static int param_cpu_id;
module_param(param_cpu_id , int, (S_IRUSR | S_IRGRP | S_IROTH));
MODULE_PARM_DESC(param_cpu_id, "CPU ID that operations run on");
//static void bar(void *arg);
//static void foo(void *cpu);
static int toy_open( struct inode *inodep, struct file *fp);
static ssize_t toy_read( struct file *fp , char *buffer, size_t len, loff_t * offset);
static ssize_t toy_write( struct file *fp , const char *buffer, size_t len, loff_t *);
static int toy_release(struct inode *inodep, struct file *fp);
static struct file_operations toy_fops = {
.owner = THIS_MODULE,
.open = toy_open,
.read = toy_read,
.write = toy_write,
.release = toy_release,
};
static struct miscdevice toy_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "toy",
.fops = &toy_fops
};
//static int CPU_IDS[64] = {0};
static int toy_open(struct inode *inodep, struct file *filep) {
int this_cpu = get_cpu();
printk(KERN_INFO "open: called on CPU:%d\n", this_cpu);
if(this_cpu == param_cpu_id) {
printk(KERN_INFO "open: is on requested CPU: %d\n", smp_processor_id());
}
else {
printk(KERN_INFO "open: not on requested CPU:%d\n", smp_processor_id());
}
put_cpu();
return 0;
}
static ssize_t toy_read(struct file *filep, char *buffer, size_t len, loff_t *offset){
int this_cpu = get_cpu();
printk(KERN_INFO "read: called on CPU:%d\n", this_cpu);
if(this_cpu == param_cpu_id) {
printk(KERN_INFO "read: is on requested CPU: %d\n", smp_processor_id());
}
else {
printk(KERN_INFO "read: not on requested CPU:%d\n", smp_processor_id());
}
put_cpu();
return 0;
}
static ssize_t toy_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){
int this_cpu = get_cpu();
printk(KERN_INFO "write called on CPU:%d\n", this_cpu);
if(this_cpu == param_cpu_id) {
printk(KERN_INFO "write: is on requested CPU: %d\n", smp_processor_id());
}
else {
printk(KERN_INFO "write: not on requested CPU:%d\n", smp_processor_id());
}
put_cpu();
return 0;
}
static int toy_release(struct inode *inodep, struct file *filep){
int this_cpu = get_cpu();
printk(KERN_INFO "release called on CPU:%d\n", this_cpu);
if(this_cpu == param_cpu_id) {
printk(KERN_INFO "release: is on requested CPU: %d\n", smp_processor_id());
}
else {
printk(KERN_INFO "release: not on requested CPU:%d\n", smp_processor_id());
}
put_cpu();
return 0;
}
static int __init toy_init(void) {
int cpu_id;
if(param_cpu_id < 0 || param_cpu_id > 4) {
printk(KERN_INFO "toy: unable to load module without cpu parameter\n");
return -1;
}
printk(KERN_INFO "toy: loading to device driver, param_cpu_id: %d\n", param_cpu_id);
//preempt_disable(); // See notes below
cpu_id = get_cpu();
printk(KERN_INFO "toy init called and running on CPU: %d\n", cpu_id);
misc_register(&toy_device);
//preempt_enable(); // See notes below
put_cpu();
//smp_call_function_single(1,foo,(void *)(uintptr_t) 1,1);
return 0;
}
static void __exit toy_exit(void) {
misc_deregister(&toy_device);
printk(KERN_INFO "toy exit called\n");
}
module_init(toy_init);
module_exit(toy_exit);
The code above contains the two methods you asked for ie isolation of CPU and on init
run on an isolated core.
On init get_cpu
disables preemption ie anything that comes after it will not be preempted by the kernel and will run on one core. Note, this was done kernel using 3.16, your mileage may vary depending on your kernel version but I think these API's have been around a long time
This is the Makefile...
obj-m += toy.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Notes. get_cpu
is declared in linux/smp.h
as
#define get_cpu() ({ preempt_disable(); smp_processor_id(); })
#define put_cpu() preempt_enable()
so you don't actually need to call preempt_disable
before calling get_cpu
.
The get_cpu call is a wrapper around the following sequence of calls...
preempt_count_inc();
barrier();
and put_cpu is really doing this...
barrier();
if (unlikely(preempt_count_dec_and_test())) {
__preempt_schedule();
}
You can get as fancy as you like using the above. Almost all of this was taken from the following sources..
Google for... smp_call_function_single
Linux Kernel Development, book by Robert Love.
http://derekmolloy.ie/writing-a-linux-kernel-module-part-2-a-character-device/
https://github.com/vsinitsyn/reverse/blob/master/reverse.c
Related Topics
Run Linux Command in Background and Keep Runing After Closing Ssh
Gnuplot-Like Program for Timeline Data
Toolchain to Crosscompile Applications for Bbb
Difference Between "Cpu/Mem-Loads/Pp" and "Cpu/Mem-Loads/"
How to Handle Sigsegv Signal in Userspace Using Rust
Make for Compiling - All *.C Files in Folders & Subfolders in Project
Qemu Simple Backend Tracing Dosen'T Print Anything
Setting Color Brightness on Linux/Xorg
Aws Ec2: How to Remount Previous Ebs Volume Using Pivot_Root
How to Get Window Id for Xdotool Automatically
PHPmyadmin, Neginx Error.Log - Check Group Www-Data Has Read Access and Open_Basedir
Securing a Simple Linux Server That Holds a MySQL Database
Linux Bash Commands to Remove Duplicates from a CSV File
Run a .Net Mvc5 Application on Mono
Possible I/O Sync Issue with Ruby Script Under Nohup
How to Replace The Word "Hello" with "Goodbye" in Every File in This Directory, and Also Recursively