ia64/xen-unstable

view tools/python/xen/util/pci.py @ 10720:8922c1fbe684

[XM][ACM] Add xm subcommands to work with security resource labels.

This patch adds new xm subcommands to support working with resource
labels. The new subcommands are 'xm resources', 'xm rmlabel', 'xm
getlabel' and 'xm dry-run'. In addition, the 'xm addlabel' subcommand
now uses an updated syntax to support labeling both domains and
resources. See the xm man page for details on each subcommand.

Beyond the new subcommands, this patch allows users to immediately see
when security checks will fail by pushing some basic security checking
into the beginning of 'xm create' and 'xm block-attach'. ACM security
attributes for block devices are added to XenStore in order to support
the final security enforcement, which will be performed in the kernel
and included in a separate patch.

Signed-off-by: Bryan D. Payne <bdpayne@us.ibm.com>
Signed-off-by: Reiner Sailer <sailer@us.ibm.com>
author kfraser@localhost.localdomain
date Mon Jul 10 17:18:07 2006 +0100 (2006-07-10)
parents 7c720ccec00a
children 8cd577110904
line source
1 #!/usr/bin/env python
2 #
3 # PCI Device Information Class
4 # - Helps obtain information about which I/O resources a PCI device needs
5 #
6 # Author: Ryan Wilson <hap9@epoch.ncsc.mil>
8 import sys
9 import os, os.path
11 PROC_MNT_PATH = '/proc/mounts'
12 PROC_PCI_PATH = '/proc/bus/pci/devices'
13 PROC_PCI_NUM_RESOURCES = 7
15 SYSFS_PCI_DEVS_PATH = '/bus/pci/devices'
16 SYSFS_PCI_DEV_RESOURCE_PATH = '/resource'
17 SYSFS_PCI_DEV_IRQ_PATH = '/irq'
18 SYSFS_PCI_DEV_DRIVER_DIR_PATH = '/driver'
20 PCI_BAR_IO = 0x01
21 PCI_BAR_IO_MASK = ~0x03
22 PCI_BAR_MEM_MASK = ~0x0f
24 # Definitions from Linux: include/linux/pci.h
25 def PCI_DEVFN(slot, func):
26 return ((((slot) & 0x1f) << 3) | ((func) & 0x07))
28 def find_sysfs_mnt():
29 mounts_file = open(PROC_MNT_PATH,'r')
31 for line in mounts_file:
32 sline = line.split()
33 if len(sline)<3:
34 continue
36 if sline[2]=='sysfs':
37 return sline[1]
39 return None
41 class PciDeviceNotFoundError(Exception):
42 def __init__(self,domain,bus,slot,func):
43 self.domain = domain
44 self.bus = bus
45 self.slot = slot
46 self.func = func
47 self.name = "%04x:%02x:%02x.%01x"%(domain, bus, slot, func)
49 def __str__(self):
50 return ('PCI Device %s Not Found' % (self.name))
52 class PciDeviceParseError(Exception):
53 def __init__(self,msg):
54 self.message = msg
55 def __str__(self):
56 return 'Error Parsing PCI Device Info: '+self.message
58 class PciDevice:
59 def __init__(self, domain, bus, slot, func):
60 self.domain = domain
61 self.bus = bus
62 self.slot = slot
63 self.func = func
64 self.name = "%04x:%02x:%02x.%01x"%(domain, bus, slot, func)
65 self.irq = 0
66 self.iomem = []
67 self.ioports = []
68 self.driver = None
70 if not self.get_info_from_sysfs():
71 self.get_info_from_proc()
73 def get_info_from_sysfs(self):
74 try:
75 sysfs_mnt = find_sysfs_mnt()
76 except IOError, (errno, strerr):
77 raise PciDeviceParseError(('Failed to locate sysfs mount: %s (%d)' %
78 (PROC_PCI_PATH, strerr, errno)))
80 if sysfs_mnt == None:
81 return False
83 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
84 self.name+SYSFS_PCI_DEV_RESOURCE_PATH
85 try:
86 resource_file = open(path,'r')
88 for i in range(7):
89 line = resource_file.readline()
90 sline = line.split()
91 if len(sline)<3:
92 continue
94 start = int(sline[0],16)
95 end = int(sline[1],16)
96 flags = int(sline[2],16)
97 size = end-start+1
99 if start!=0:
100 if flags&PCI_BAR_IO:
101 self.ioports.append( (start,size) )
102 else:
103 self.iomem.append( (start,size) )
105 except IOError, (errno, strerr):
106 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
107 (path, strerr, errno)))
109 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
110 self.name+SYSFS_PCI_DEV_IRQ_PATH
111 try:
112 self.irq = int(open(path,'r').readline())
113 except IOError, (errno, strerr):
114 raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
115 (path, strerr, errno)))
117 path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
118 self.name+SYSFS_PCI_DEV_DRIVER_DIR_PATH
119 try:
120 self.driver = os.path.basename(os.readlink(path))
121 except IOError, (errno, strerr):
122 raise PciDeviceParseError(('Failed to read %s: %s (%d)' %
123 (path, strerr, errno)))
125 return True
127 def get_info_from_proc(self):
128 bus_devfn = '%02x%02x' % (self.bus,PCI_DEVFN(self.slot,self.func))
130 # /proc/bus/pci/devices doesn't expose domains
131 if self.domain!=0:
132 raise PciDeviceParseError("Can't yet detect resource usage by "+
133 "devices in other domains through proc!")
135 try:
136 proc_pci_file = open(PROC_PCI_PATH,'r')
137 except IOError, (errno, strerr):
138 raise PciDeviceParseError(('Failed to open %s: %s (%d)' %
139 (PROC_PCI_PATH, strerr, errno)))
141 for line in proc_pci_file:
142 sline = line.split()
143 if len(sline)<(PROC_PCI_NUM_RESOURCES*2+3):
144 continue
146 if sline[0]==bus_devfn:
147 self.dissect_proc_pci_line(sline)
148 break
149 else:
150 raise PciDeviceNotFoundError(self.domain, self.bus,
151 self.slot, self.func)
153 def dissect_proc_pci_line(self, sline):
154 self.irq = int(sline[2],16)
155 start_idx = 3
156 for i in range(PROC_PCI_NUM_RESOURCES):
157 flags = int(sline[start_idx+i],16)
158 size = int(sline[start_idx+i+PROC_PCI_NUM_RESOURCES],16)
159 if flags&PCI_BAR_IO:
160 start = flags&PCI_BAR_IO_MASK
161 if start!=0:
162 self.ioports.append( (start,size) )
163 else:
164 start = flags&PCI_BAR_MEM_MASK
165 if start!=0:
166 self.iomem.append( (start,size) )
168 # detect driver module name
169 driver_idx = PROC_PCI_NUM_RESOURCES*2+3
170 if len(sline)>driver_idx:
171 self.driver = sline[driver_idx]
173 def __str__(self):
174 str = "PCI Device %s\n" % (self.name)
175 for (start,size) in self.ioports:
176 str = str + "IO Port 0x%02x [size=%d]\n"%(start,size)
177 for (start,size) in self.iomem:
178 str = str + "IO Mem 0x%02x [size=%d]\n"%(start,size)
179 str = str + "IRQ %d"%(self.irq)
180 return str
182 def main():
183 if len(sys.argv)<5:
184 print "Usage: %s <domain> <bus> <slot> <func>\n"
185 sys.exit(2)
187 dev = PciDevice(int(sys.argv[1],16), int(sys.argv[2],16),
188 int(sys.argv[3],16), int(sys.argv[4],16))
189 print str(dev)
191 if __name__=='__main__':
192 main()