1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# 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: //www.apache.org/licenses/LICENSE-2.0
#
#    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: //127.0.0.1:35357/v2.0/tokens | python -m json.tool
     curl -v -d  '{"ioctlAction": {"instance_name":"instance-0000000c","limit_reader":"40MB","limit_writer":"60MB"}}'  -i http: //127.0.0.1:8774/v2/ba5a6a86a8224a70ba0ffde747d8a724/servers/e6b9cae7-8732-405d-9aaf-575643b4bbef/action -X POST -H "X-Auth-Project-Id: ba5a6a86a8224a70ba0ffde747d8a724" -H "Accept: application/json" -H "X-Auth-Token: 6f0c37595f384fd4a18766825cf49013" -H "Content-Type: application/json"
"" "
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  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()

本文转自 swq499809608 51CTO博客,原文链接:http://blog.51cto.com/swq499809608/1412022