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
sethu
  • 1,691
  • 4
  • 22
  • 34

2 Answers2

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')
Community
  • 1
  • 1
agf
  • 171,228
  • 44
  • 289
  • 238
  • +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 Aug 05 '11 at 00:54
  • @orip I have read that to interact directly with stdin/stdout is prone to race condition. Isn't that true? – brandizzi Aug 05 '11 at 01:02
  • @brandizzi maybe you mean this issue which is only relevant for multithreaded code: http://bugs.python.org/issue2320, their final analysis shows the concurrency error happens even without stdin=PIPE. Interesting. – orip Aug 05 '11 at 02:05
  • I've edited my answer; what I've posted should work if you start `cpulimit` with a pipe for it's `stdin`. – agf Aug 05 '11 at 02:27
  • 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 ? – sethu Aug 05 '11 at 15:33
  • Yes, absolutely. I didn't think about it. – agf Aug 05 '11 at 19:37
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()
orip
  • 73,323
  • 21
  • 116
  • 148
  • 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. – sethu Aug 05 '11 at 01:46
  • Why would the subprocess terminate? If climit waits for stdin to close, it should stay alive. – orip Aug 05 '11 at 02:00
  • He means that the Python script isn't spawning the process; he needs to do it to an existing `cpulimit`. – agf Aug 05 '11 at 02:18
  • @agf yeah , I want to do it to an existing process. – sethu Aug 05 '11 at 02:58
  • Look at my edited answer, I show you how, and link to a post with more details. – agf Aug 05 '11 at 03:00