ia64/xen-unstable

view tools/python/xen/xend/XendXSPolicyAdmin.py @ 19848:5839491bbf20

[IA64] replace MAX_VCPUS with d->max_vcpus where necessary.

don't use MAX_VCPUS, and use vcpu::max_vcpus.
The changeset of 2f9e1348aa98 introduced max_vcpus to allow more vcpus
per guest. This patch is ia64 counter part.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 11:26:05 2009 +0900 (2009-06-29)
parents a41d14c3bf19
children
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2006,2007 International Business Machines Corp.
16 # Author: Stefan Berger <stefanb@us.ibm.com>
17 #============================================================================
18 import os
19 import shutil
21 from xml.dom import minidom, Node
23 from xen.xend.XendLogging import log
24 from xen.xend import uuid
25 from xen.util import xsconstants, bootloader
26 import xen.util.xsm.acm.acm as security
27 from xen.util.xspolicy import XSPolicy
28 from xen.util.acmpolicy import ACMPolicy, initialize
29 from xen.xend.XendError import SecurityError
32 class XSPolicyAdmin:
33 """ The class that handles the managed policies in the system.
34 Handles adding and removing managed policies. All managed
35 policies are handled using a reference (UUID) which is
36 assigned to the policy by this class.
37 """
39 def __init__(self, maxpolicies):
40 """ Create a management class for managing the system's
41 policies.
43 @param maxpolicies: The max. number of policies allowed
44 on the system (currently '1')
45 """
46 self.maxpolicies = maxpolicies
47 self.policies = {}
48 self.xsobjs = {}
49 bootloader.init()
51 if security.on() == xsconstants.XS_POLICY_ACM:
52 self.__acm_init()
54 def __acm_init(self):
55 act_pol_name = self.get_hv_loaded_policy_name()
56 initialize()
58 ref = uuid.createString()
59 try:
60 self.xsobjs[ref] = ACMPolicy(name=act_pol_name, ref=ref)
61 self.policies[ref] = (act_pol_name, xsconstants.ACM_POLICY_ID)
62 self.xsobjs[ref].validate_enforced_policy_hash()
63 except Exception, e:
64 log.error("Could not find XML representation of policy '%s': "
65 "%s" % (act_pol_name,e))
66 rc, errors, acmpol_def = ACMPolicy.force_default_policy(ref)
67 if rc == xsconstants.XSERR_SUCCESS:
68 self.xsobjs[ref] = acmpol_def
69 self.policies[ref] = (acmpol_def.get_name(),
70 xsconstants.ACM_POLICY_ID)
71 log.info("Switched to DEFAULT policy.")
73 log.debug("XSPolicyAdmin: Known policies: %s" % self.policies)
76 def isXSEnabled(self):
77 """ Check whether 'security' is enabled on this system.
78 This currently only checks for ACM-enablement.
79 """
80 rc = 0
81 if security.on() == xsconstants.XS_POLICY_ACM:
82 rc |= xsconstants.XS_POLICY_ACM
83 return rc
85 def add_acmpolicy_to_system(self, xmltext, flags, overwrite):
86 """ Add an ACM policy's xml representation to the system. The
87 policy will automatically be compiled
88 flags:
89 XS_INST_BOOT : make policy the one to boot the system with
90 by default; if there's a policy already installed,
91 refuse to install this policy unless its one with
92 the same name
93 XS_INST_LOAD : load the policy immediately; if this does not work
94 refuse to install this policy
95 overwrite:
96 If any policy is installed and this is False, refuse to install
97 this policy
98 If flags is True, then any existing policy will be removed from
99 the system and the new one will be installed
100 """
101 from xen.xend import XendDomain
102 domains = XendDomain.instance()
103 try:
104 domains.domains_lock.acquire()
105 return self.__add_acmpolicy_to_system(xmltext, flags, overwrite)
106 finally:
107 domains.domains_lock.release()
109 def __add_acmpolicy_to_system(self, xmltext, flags, overwrite):
110 errors = ""
111 if security.on() != xsconstants.XS_POLICY_ACM:
112 raise SecurityError(-xsconstants.XSERR_POLICY_TYPE_UNSUPPORTED)
113 loadedpol = self.get_loaded_policy()
114 if loadedpol:
115 # This is meant as an update to a currently loaded policy
116 if flags & xsconstants.XS_INST_LOAD == 0:
117 raise SecurityError(-xsconstants.XSERR_POLICY_LOADED)
119 # Remember old flags, so they can be restored if update fails
120 old_flags = self.get_policy_flags(loadedpol)
122 # Remove policy from bootloader in case of new name of policy
123 self.rm_bootpolicy()
125 rc, errors = loadedpol.update(xmltext)
126 if rc == 0:
127 irc = self.activate_xspolicy(loadedpol, flags)
128 # policy is loaded; if setting the boot flag fails it's ok.
129 else:
130 old_flags = old_flags & xsconstants.XS_INST_BOOT
131 log.info("OLD FLAGS TO RESTORE: %s" % str(old_flags))
132 if old_flags != 0:
133 self.activate_xspolicy(loadedpol, xsconstants.XS_INST_BOOT)
135 return (loadedpol, rc, errors)
137 try:
138 dom = minidom.parseString(xmltext.encode("utf-8"))
139 except:
140 raise SecurityError(-xsconstants.XSERR_BAD_XML)
142 ref = uuid.createString()
144 acmpol = ACMPolicy(dom=dom, ref=ref)
146 #First some basic tests that do not modify anything:
148 if flags & xsconstants.XS_INST_BOOT and not overwrite:
149 filename = acmpol.get_filename(".bin","",dotted=True)
150 if bootloader.get_default_policy != None and \
151 not bootloader.loads_default_policy(filename):
152 raise SecurityError(-xsconstants.XSERR_BOOTPOLICY_INSTALLED)
154 if not overwrite and len(self.policies) >= self.maxpolicies:
155 raise SecurityError(-xsconstants.XSERR_BOOTPOLICY_INSTALLED)
157 if overwrite:
158 #This should only give one key since only one policy is
159 #allowed.
160 keys = self.policies.keys()
161 for k in keys:
162 self.rm_bootpolicy()
163 rc = self.rm_policy_from_system(k, force=overwrite)
164 if rc != xsconstants.XSERR_SUCCESS:
165 raise SecurityError(rc)
167 rc = acmpol.compile()
168 if rc != 0:
169 raise SecurityError(rc)
171 if flags & xsconstants.XS_INST_LOAD:
172 rc = acmpol.loadintohv()
173 if rc != 0:
174 raise SecurityError(rc)
176 if flags & xsconstants.XS_INST_BOOT:
177 rc = self.make_boot_policy(acmpol)
178 if rc != 0:
179 # If it cannot be installed due to unsupported
180 # bootloader, let it be ok.
181 pass
183 if dom:
184 new_entry = { ref : tuple([acmpol.get_name(),
185 xsconstants.ACM_POLICY_ID]) }
186 self.policies.update(new_entry)
187 self.xsobjs[ref] = acmpol
188 return (acmpol, xsconstants.XSERR_SUCCESS, errors)
191 def reset_acmpolicy(self):
192 """
193 Attempt to reset the system's policy by udating it with
194 the DEFAULT policy.
195 """
196 from xen.xend import XendDomain
197 domains = XendDomain.instance()
198 try:
199 domains.domains_lock.acquire()
200 xml = ACMPolicy.get_reset_policy_xml()
201 flags = xsconstants.XS_INST_BOOT | xsconstants.XS_INST_LOAD
202 return self.__add_acmpolicy_to_system(xml, flags, True)
203 finally:
204 domains.domains_lock.release()
207 def make_boot_policy(self, acmpol):
208 if acmpol.is_default_policy():
209 return xsconstants.XSERR_SUCCESS
210 rc = acmpol.copy_policy_file(".bin","/boot")
211 if rc != xsconstants.XSERR_SUCCESS:
212 return rc
214 try:
215 filename = acmpol.get_filename(".bin","",dotted=True)
216 if bootloader.set_default_boot_policy(filename) != True:
217 return xsconstants.XSERR_BOOTPOLICY_INSTALL_ERROR
218 except:
219 return xsconstants.XSERR_FILE_ERROR
220 return xsconstants.XSERR_SUCCESS
222 def activate_xspolicy(self, xspol, flags):
223 from xen.xend import XendDomain
224 domains = XendDomain.instance()
225 try:
226 domains.domains_lock.acquire()
227 return self.__activate_xspolicy(xspol, flags)
228 finally:
229 domains.domains_lock.release()
231 def __activate_xspolicy(self, xspol, flags):
232 rc = xsconstants.XSERR_SUCCESS
233 if flags & xsconstants.XS_INST_LOAD:
234 rc = xspol.loadintohv()
235 if rc == xsconstants.XSERR_SUCCESS and \
236 flags & xsconstants.XS_INST_BOOT:
237 rc = self.make_boot_policy(xspol)
238 if rc == xsconstants.XSERR_SUCCESS:
239 rc = flags
240 return rc
242 def rm_policy_from_system(self, ref, force=False):
243 if self.policies.has_key(ref):
244 acmpol = self.xsobjs[ref]
245 rc = acmpol.destroy()
246 if rc == xsconstants.XSERR_SUCCESS or force:
247 del self.policies[ref]
248 del self.xsobjs[ref]
249 rc = xsconstants.XSERR_SUCCESS
250 return rc
252 def rm_bootpolicy(self):
253 """ Remove any (ACM) boot policy from the grub configuration file
254 """
255 rc = 0
256 title = bootloader.get_default_title()
257 if title != None:
258 polnames = []
259 for (k, v) in self.xsobjs.items():
260 polnames.append(v.get_filename(".bin","",dotted=True))
261 bootloader.rm_policy_from_boottitle(title, polnames)
262 else:
263 rc = -xsconstants.XSERR_NO_DEFAULT_BOOT_TITLE
264 return rc
266 def get_policy_flags(self, acmpol):
267 """ Get the currently active flags of a policy, i.e., whether the
268 system is using this policy as its boot policy for the default
269 boot title.
270 """
271 flags = 0
273 filename = acmpol.get_filename(".bin","", dotted=True)
274 if bootloader.loads_default_policy(filename) or \
275 acmpol.is_default_policy():
276 flags |= xsconstants.XS_INST_BOOT
278 if acmpol.isloaded():
279 flags |= xsconstants.XS_INST_LOAD
280 return flags
282 def get_policies(self):
283 """ Get all managed policies. """
284 return self.xsobjs.values()
286 def get_policies_refs(self):
287 """ Get all managed policies' references. """
288 return self.xsobjs.keys()
290 def has_ref(self, ref):
291 """ Check whether there is a policy with the given reference """
292 return self.xsobjs.has_key(ref)
294 def policy_from_ref(self, ref):
295 """ Get the policy's object given its reference """
296 if ref in self.xsobjs.keys():
297 return self.xsobjs[ref]
298 return None
300 def ref_from_polname(self, polname):
301 """ Get the reference of the policy given its name """
302 ref = None
303 for (k, v) in self.xsobjs.items():
304 if v.get_name() == polname:
305 ref = k
306 break
307 return ref
309 def lock_policy(self, ref):
310 """ get exclusive access to a policy """
311 self.xsobjs[ref].grab_lock()
313 def unlock_policy(self, ref):
314 """ release exclusive access to a policy """
315 self.xsobjs[ref].unlock()
317 def get_loaded_policy(self):
318 for pol in self.xsobjs.values():
319 if pol.isloaded():
320 return pol
321 return None
323 def get_hv_loaded_policy_name(self):
324 return security.get_active_policy_name()
326 def get_policy_by_name(self, name):
327 for pol in self.xsobjs.values():
328 if pol.get_name() == name:
329 return pol
330 return None
332 def get_domain0_bootlabel(self):
333 """ Get the domain0 bootlabel from the default boot title """
334 title = ""
335 def_title = bootloader.get_default_title()
336 line = bootloader.get_kernel_val(def_title, "ssidref")
337 if line:
338 parms = line.split(":",1)
339 if len(parms) > 1:
340 title = parms[1]
341 return title
343 def set_domain0_bootlabel(self, xspol, label):
344 """ Set the domain-0 bootlabel under the given policy. If the
345 current policy is the default policy, it will remove it. """
346 rm_entry = (xspol.get_name() == "DEFAULT")
347 return xspol.set_vm_bootlabel(label, rm_entry)
349 def rm_domain0_bootlabel(self):
350 """ Remove the domain-0 bootlabel from the default boot title """
351 def_title = bootloader.get_default_title()
352 return bootloader.set_kernel_attval(def_title, "ssidref", None)
354 def ssidref_to_vmlabel(self, ssidref):
355 """ Given an ssidref, return the vmlabel under the current policy """
356 vmlabel = ""
357 pol = self.get_loaded_policy()
358 if pol:
359 vmlabel = pol.policy_get_domain_label_by_ssidref_formatted(ssidref)
360 return vmlabel
362 def get_stes_of_vmlabel(self, vmlabel_xapi):
363 """ Get the list of STEs given a VM label in XenAPI format """
364 stes = []
365 loadedpol = self.get_loaded_policy()
366 if loadedpol:
367 tmp = vmlabel_xapi.split(":")
368 if len(tmp) != 3:
369 return []
370 stes = loadedpol.policy_get_stes_of_vmlabel(tmp[2])
371 return stes
373 def get_enforced_binary(self, xstype):
374 res = None
375 if xstype == xsconstants.XS_POLICY_ACM:
376 res = ACMPolicy.get_enforced_binary()
377 return res
379 poladmin = None
381 def XSPolicyAdminInstance(maxpolicies=1):
382 global poladmin
383 if poladmin == None:
384 poladmin = XSPolicyAdmin(maxpolicies)
385 return poladmin