3

I am trying to write a script for controling cpu usage of a VM n KVM using cpulimit. With cpulimit i can limit the cpu usage of a VM with pid say 2112 by :

./cpulimit -p 2112 -l 50.

I want to write a script which can open an interface

setcpu (vm_pid,limit)

Which can be called any number of times and I shud overwrite the existing limit. I can overwrite the existing limit by just adding the limit value as a runtime argument for the running cpulimit process. Like subprocess.Popen(..., stdin=subprocess.PIPE). I am a bit confused on how to grab the running process and provide runtime argument. For example (without scripting) :

# ./cpulimit -p 2112 -l 50

 Process 2112 detected 

Now It will set a cap on the process, Now I can simply enter

40

80

to overwrite the existing limit. I want to script this behavior . It will be great if you can provide a pointer or an idea on how to go about writing this script. Thanks a lot

  • Sethu

2 Answers 2

1

Edit: If you need to talk to an existing cpulimit, you should look at the accepted answer to How to write data to existing process's STDIN from external process?

Basically, do

(while [ 1 ]; do sleep 1; done) | ./cpulimit -p 2112 -l 50.

when you start cpulimit, because it's input needs to be a pipe.

Then, from Python write to /proc/{pid_of_cpulimit}/fd/0.


If you've spawned a process with

process = subprocess.Popen(['./cpulimit', '-p', '2112', '-l', '50'], stdin=subprocess.PIPE)

just do

process.communicate(input='40')
process.communicate(input='80')
Sign up to request clarification or add additional context in comments.

6 Comments

+1 for Popen, but communicate is no good - it closes stdin and waits for the process to terminate. You should write to process.stdin instead.
@orip I have read that to interact directly with stdin/stdout is prone to race condition. Isn't that true?
@brandizzi maybe you mean this issue which is only relevant for multithreaded code: bugs.python.org/issue2320, their final analysis shows the concurrency error happens even without stdin=PIPE. Interesting.
I've edited my answer; what I've posted should work if you start cpulimit with a pipe for it's stdin.
I have just one doubt ? Why are we writing to 2112 ? That will be the VM right ? If I have to write , it shud be to the terminal of the cpulimit process right ?
|
0

Open a subprocess like agf shows, don't forget to specify that stdin is piped:

import subprocess
p = subprocess.Popen("./cpulimit -p 2112 -l 50", stdin=subprocess.PIPE)

Then write to p.stdin:

p.stdin.write("40\n")
p.stdin.flush()

5 Comments

Thanks for the reply. For the first time it will work. But consider the script terminates after spawning the process and setting the initial limit. And after a second, if that api is called. I will not be able to proceed and write p.stdin.write("40\n"). That is the case I am worried about. Is it possible to spawn from a process ID? I will be able to retrieve the process id of the running cpulimit instance.
Why would the subprocess terminate? If climit waits for stdin to close, it should stay alive.
He means that the Python script isn't spawning the process; he needs to do it to an existing cpulimit.
@agf yeah , I want to do it to an existing process.
Look at my edited answer, I show you how, and link to a post with more details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.