# vim: tabstop=
4
shiftwidth=
4
softtabstop=
4
# Copyright (c)
2011
X.commerce, a business unit of eBay Inc.
# Copyright
2010
United States Government
as
represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version
2.0
(the
"License"
); you may
# not
use
this
file except
in
compliance
with
the License. You may obtain
# a copy of the License at
#
# http:
#
# Unless required by applicable law or agreed to
in
writing, software
# distributed under the License
is
distributed on an
"AS IS"
BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License
for
the specific language governing permissions and limitations
# under the License.
# Single virtual machine io limit , reader
70
/MB , writer
50
/MB
""
"
curl -d
'{"auth": {"tenantName": "admin", "passwordCredentials": {"username": "admin", "password": "admin"}}}'
-H
"Content-type: application/json"
http:
curl -v -d
'{"ioctlAction": {"instance_name":"instance-0000000c","limit_reader":"40MB","limit_writer":"60MB"}}'
-i http:
""
"
import
time,sys,os,libvirt,
trace
back,re,subprocess,json
from nova
import
log
as
logging
from nova
import
flags
from nova.periodic.blkio
import
config
from nova
import
utils
from nova.periodic.blkio
import
utils
as
blkio_utils
FLAGS = flags.FLAGS
LOG = logging.getLogger(__name__)
class
ActionIoctl(object):
def __init__(self,instance_name,limit_reader,limit_writer):
self.conn = libvirt.open(None)
self.limitReader =
int
(limit_reader[
0
:-
2
])
self.limitWriter =
int
(limit_writer[
0
:-
2
])
self.name = instance_name
self.path = FLAGS.instances_path
def diskDeviceNum(self,disk):
""
" Func info: Returns the number of hard disk,other is 8:0 "
""
if
disk ==
'/dev/sda1'
or disk ==
'/dev/hda1'
or disk[:-
1
] ==
'/dev/sda'
or disk[:-
1
] ==
'/dev/hda'
:
return
'8:0'
elif disk ==
'/dev/sdb1'
or disk ==
'/dev/hdb1'
or disk[:-
1
] ==
'/dev/sdb'
or disk[:-
1
] ==
'/dev/hdb'
:
return
'8:16'
elif disk ==
'/dev/sdc1'
or disk ==
'/dev/hdc1'
or disk[:-
1
] ==
'/dev/sdc'
or disk[:-
1
] ==
'/dev/hdc'
:
return
'8:32'
elif disk ==
'/dev/sdd1'
or disk ==
'/dev/hdd1'
or disk[:-
1
] ==
'/dev/sdd'
or disk[:-
1
] ==
'/dev/hdd'
:
return
'8:48'
else
:
return
'8:16'
def vmsPIDall(self):
""
" Getting all vm port, return to "
""
pid = list()
try
:
cmds =
""
"ps -ef |grep uuid|grep -v grep |awk '{print $2}'"
""
pid=os.popen(cmds).readlines()
return
pid
except Exception,e:
LOG.error(_(
'[-william-] Error %s'
%e))
return
def cgroupPath(self):
''
'
Func info : Return Cgroup path ,Because the system
is
not the same,
the Cgroup path
is
different also.
By
default
, have RedHat, Centos, Ubuntu linux ...
osType : The current system version , And
return
to ...
Cpath : Cgroup path
''
'
osType = open(
'/etc/issue'
).readlines()
for
i
in
osType:
if
re.match(
'Ubuntu'
,i):
Cpath =
'/sys/fs/cgroup/'
return
Cpath
elif re.match(
'CentOS'
,i):
Cpath =
'/cgroup/'
return
Cpath
elif re.match(
'Red Hat'
,i):
Cpath =
'/cgroup/'
return
Cpath
else
:
return
'/sys/fs/cgroup/'
def exeCmd(self,cmds):
''
' Perform system command '
''
LOG.info(_(
'exeCmd %s'
%cmds))
try
:
exec_process = subprocess.Popen(cmds,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
shell = True)
exec_process.wait()
rest = exec_process.stdout.read()
err = exec_process.stderr.read()
if
err ==
''
:
return
rest
else
:
LOG.error(_(
'[-william-] return values is null'
))
except Exception,e:
LOG.error(_(
'[-william-] Error %s'
) %e)
return
''
' Geting vmName name and pid '
''
def get_vm_pid(self,name):
pid = self.conn.listDomainsID()
try
:
pid = os.popen(
""
"ps -ef |grep %s |grep -v grep |awk '{print $2}'"
""
%name).readlines()
return
int
(pid[
0
])
except:
LOG.error(_(
'[-william-] Error %s'
\
%
trace
back.format_exc()))
return
def _vm_pids(self):
try
:
return
os.popen(
'pidof kvm'
).read().split()
except:
return
def work(self):
""
"
Func info : working func ................
Cpath :
is
_Cpath
function
return
values ...
path : The current virtual machine IMG file path
vm_count: All of the current node number of virtual machines
size : Limit size
mountInfo : mounting point
""
"
Cpath = self.cgroupPath()
vm_pid = self.get_vm_pid(self.name)
LOG.info(_(
'[- william -] %s , %s'
%(self.name,vm_pid)))
r_size = self.limitReader *
1000
*
1000
w_size = self.limitWriter *
1000
*
1000
device = blkio_utils.instance_path(self.path)
diskDeviceNum = self.diskDeviceNum(device)
vmTaskPath =
"%s/blkio/%s"
%(Cpath,self.name)
utils.execute(
"mkdir"
,
"-p"
,vmTaskPath,run_as_root=True)
utils.execute(
"tee"
,
"%s/blkio.throttle.read_bps_device"
%vmTaskPath,\
process_input =
"%s %s"
%(diskDeviceNum,r_size),\
run_as_root=True)
utils.execute(
"tee"
,
"%s/blkio.throttle.write_bps_device"
%vmTaskPath, \
process_input =
"%s %s"
%(diskDeviceNum,w_size) ,\
run_as_root=True)
LOG.info(_(
""
" [-william-] echo '%s, %s, %s , %s , %s ' write oK "
""
%(self.path , device, diskDeviceNum, w_size, r_size)))
utils.execute(
'tee'
,
'%s/tasks'
%vmTaskPath,\
process_input= str(vm_pid) ,\
run_as_root=True)
LOG.info(_(
'[- william-] append pid %s in task'
%vm_pid))
if
__name__ ==
"__main__"
:
sc = ActionIoctl(
'instance-0000000c'
,
'40MB'
,
'30MB'
)
sc.work()