$NetBSD: patch-am,v 1.1 2004/05/08 18:24:00 cl Exp $ --- xc/py/XenoUtil.py.orig 2004-04-18 04:29:13.000000000 +0200 +++ xc/py/XenoUtil.py @@ -25,26 +25,40 @@ except ImportError: # on failure, just catch the error, don't do anything pass +os_ifs = {'Linux' : 'eth0', 'NetBSD' : 'xennet0'} +default_if = os_ifs[os.uname()[0]] + +os_vfr_paths = {'Linux' : '/proc/xeno/vfr', 'NetBSD' : '/kern/xen/vfr'} +vfr_path = os_vfr_paths[os.uname()[0]] + +os_ipgw_cmds = {'Linux' : '/sbin/route -n', + 'NetBSD' : '/sbin/route -n get default'} +ipgw_cmd = os_ipgw_cmds[os.uname()[0]] + +os_ipgw_res = {'Linux' : '^\S+\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' + + '\s+\S+\s+\S*G.*%s.*', + 'NetBSD' : 'gateway:\s([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(?:%s)?'} +ipgw_re = os_ipgw_res[os.uname()[0]] ##### Networking-related functions -def get_current_ipaddr(dev='eth0'): +def get_current_ipaddr(dev=default_if): """Return a string containing the primary IP address for the given - network interface (default 'eth0'). - """ + network interface (default '%s'). + """ % default_if fd = os.popen( '/sbin/ifconfig ' + dev + ' 2>/dev/null' ) lines = fd.readlines() for line in lines: - m = re.search( '^\s+inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*', + m = re.search( '^\s+inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*', line ) if m: return m.group(1) return None -def get_current_ipmask(dev='eth0'): +def get_current_ipmask(dev=default_if): """Return a string containing the primary IP netmask for the given - network interface (default 'eth0'). - """ + network interface (default '%s'). + """ % default_if fd = os.popen( '/sbin/ifconfig ' + dev + ' 2>/dev/null' ) lines = fd.readlines() for line in lines: @@ -52,17 +66,22 @@ def get_current_ipmask(dev='eth0'): line ) if m: return m.group(1) + m = re.search( '^.+netmask (0x[0-9a-f]+)\s', + line ) + if m: + a = int(m.group(1), 16) + return '%d.%d.%d.%d' % ( ((a>>24)&0xff), ((a>>16)&0xff), + ((a>>8)&0xff), (a&0xff) ) return None -def get_current_ipgw(dev='eth0'): +def get_current_ipgw(dev=default_if): """Return a string containing the IP gateway for the given - network interface (default 'eth0'). - """ - fd = os.popen( '/sbin/route -n' ) + network interface (default '%s'). + """ % default_if + fd = os.popen( ipgw_cmd ) lines = fd.readlines() for line in lines: - m = re.search( '^\S+\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' + - '\s+\S+\s+\S*G.*' + dev + '.*', line ) + m = re.search( ipgw_re % dev, line ) if m: return m.group(1) return None @@ -72,7 +91,7 @@ def setup_vfr_rules_for_vif(dom,vif,addr is expressed as a textual dotted quad, and set up appropriate routing rules in Xen. No return value. """ - fd = os.open( '/proc/xeno/vfr', os.O_WRONLY ) + fd = os.open( vfr_path, os.O_WRONLY ) if ( re.search( '169\.254', addr) ): os.write( fd, 'ADD ACCEPT srcaddr=' + addr + ' srcaddrmask=255.255.255.255' + @@ -117,14 +136,42 @@ def check_subnet( ip, network, netmask ) ##### VBD-related Functions +# ls -l /dev/hd[a-z] /dev/sd[a-z] /dev/scd* | sed -e 's#/dev/##' -e 's#,##' +# | awk -v ORS=" " '{print "'\''" $10 "'\'':" $5 * 256 + $6 "," }'; +blkdev_name_to_number_dict = { + 'hda':768, 'hdb':832, 'hdc':5632, 'hdd':5696, 'hde':8448, + 'hdf':8512, 'hdg':8704, 'hdh':8768, 'hdi':14336, 'hdj':14400, + 'hdk':14592, 'hdl':14656, + 'sda':2048, 'sdb':2064, 'sdc':2080, 'sdd':2096, + 'sde':2112, 'sdf':2128, 'sdg':2144, 'sdh':2160, + 'scd0':2816, 'scd1':2817, 'scd10':2826, 'scd11':2827, + 'scd12':2828, 'scd13':2829, 'scd14':2830, 'scd15':2831, + 'scd16':2832, 'scd2':2818, 'scd3':2819, 'scd4':2820, + 'scd5':2821, 'scd6':2822, 'scd7':2823, 'scd8':2824, + 'scd9':2825 + } + def blkdev_name_to_number(name): """Take the given textual block-device name (e.g., '/dev/sda1', - 'hda') and return the device number used by the OS. """ + 'hda') and return the device number used by Xen. """ - if not re.match( '/dev/', name ): - name = '/dev/' + name - - return os.stat(name).st_rdev + m = re.search( '/dev/(.+)', name ) + if m: + name = m.group(1) + + try: + return blkdev_name_to_number_dict[name] + except KeyError: + pass + + m = re.search( '^(...)([0-9]+)', name ) + if not m: + return None + + try: + return blkdev_name_to_number_dict[m.group(1)] + int( m.group(2) ) + except KeyError: + return None # lookup_blkdev_partn_info( '/dev/sda3' ) def lookup_raw_partn(partition): @@ -137,6 +184,11 @@ def lookup_raw_partn(partition): type: 'Disk' or identifying name for partition type """ + os_lookup = { 'Linux' : lookup_raw_partn_linux, + 'NetBSD' : lookup_raw_partn_netbsd } + return os_lookup[os.uname()[0]](partition) + +def lookup_raw_partn_linux(partition): if not re.match( '/dev/', partition ): partition = '/dev/' + partition @@ -168,6 +220,37 @@ def lookup_raw_partn(partition): return None +def lookup_raw_partn_netbsd(partition): + m = re.search( '^(?:/dev/)?([a-z]+[0-9]+)([a-z]*)', partition ) + if not m: + return None + + drive = m.group(1) + partition = m.group(2) + + fd = os.popen( '/sbin/sysctl -n ' + + 'machdep.domain0.diskcookie.%s' % drive ) + try: + cookie = int(fd.readline()) + except ValueError: + cookie = -1 + fd.close() + + fd = os.popen( '/sbin/disklabel %s' % drive ) + lines = fd.readlines() + for line in lines: + # # size offset fstype [fsize bsize cpg/sgs] + # a: 80555328 9514512 4.2BSD 2048 16384 28624 + m = re.search( '^\s+%s:\s*([0-9]+)\s+([0-9]+)\s+' % partition, + line ) + if m: + return [ { 'device' : int(cookie), + 'start_sector' : long(m.group(2)), + 'nr_sectors' : long(m.group(1)), + 'type' : '0' } ] + + return None + def lookup_disk_uname( uname ): """Lookup a list of segments for either a physical or a virtual device. uname [string]: name of the device in the format \'vd:id\' for a virtual @@ -905,11 +988,12 @@ def vd_extents_validate(new_extents,new_ vbd_ext['writeable'] = vbd['writeable'] old_extents.append(vbd_ext) - ##### Now scan /proc/mounts for compile a list of extents corresponding to + ##### Now scan /bin/mount for compile a list of extents corresponding to ##### any devices mounted in DOM0. This list is added on to old_extents - regexp = re.compile("/dev/(\S*) \S* \S* (..).*") - fd = open('/proc/mounts', "r") + mount_cmd = { 'Linux' : '/bin/mount', 'NetBSD' : '/sbin/mount' } + regexp = re.compile("/dev/(\S*) on \S* type \S* \(([^\),]*)") + fd = os.popen(mount_cmd[os.uname()[0]]) while True: line = fd.readline() @@ -932,7 +1016,8 @@ def vd_extents_validate(new_extents,new_ # set a writeable flag as appropriate for ext in ext_list: - ext['writeable'] = m.group(2) == 'rw' + ext['writeable'] = (m.group(2) != 'ro' and + m.group(2) != 'read-only') # now we've got here, the contents of ext_list are in a # suitable format to be added onto the old_extents list, ready