def chown(vendorid, productid): # remove the 0x from the vendor and product id devid = vendorid[2:] + ':' + productid[2:] command = ['lsusb', '-d', devid] retcode, out, err = hooking.execCmd(command, raw=True) if retcode != 0: sys.stderr.write('hostusb: cannot find usb device: %s\n' % devid) sys.exit(2) devpath = '/dev/bus/usb/' + out[4:7] + '/' + out[15:18] uid, gid = get_owner(devpath) if uid == -1: sys.stderr.write('hostusb after_vm_destroy: cannot find devpath: %s ' 'in file: %s\n' % (devpath, HOOK_HOSTUSB_PATH)) return # we don't use os.chown because we need sudo owner = str(uid) + ':' + str(gid) command = ['/bin/chown', owner, devpath] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('hostusb after_vm_destroy: error chown %s to %s, ' 'err = %s\n' % (devpath, owner, err)) sys.exit(2)
def removeMirrorNetwork(networkName): ''' this commands will remove our monitored network (bridge) from the queue: tc qdisc del dev networkName root tc qdisc del dev networkName ingress ''' command = ['/sbin/tc', 'qdisc', 'del', 'dev', networkName, 'root'] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) command = ['/sbin/tc', 'qdisc', 'del', 'dev', networkName, 'ingress'] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) # remove promisc mode flag from the bridge command = ['/sbin/ifconfig', networkName, '-promisc'] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err))
def chown(vendorid, productid): # remove the 0x from the vendor and product id devid = vendorid[2:] + ':' + productid[2:] command = ['lsusb', '-d', devid] retcode, out, err = hooking.execCmd(command, raw=True) if retcode != 0: sys.stderr.write('hostusb: cannot find usb device: %s\n' % devid) sys.exit(2) # find the device path: # /dev/bus/usb/xxx/xxx devpath = '/dev/bus/usb/' + out[4:7] + '/' + out[15:18] stat = os.stat(devpath) group = grp.getgrnam('qemu') gid = group.gr_gid user = pwd.getpwnam('qemu') uid = user.pw_uid # we don't use os.chown because we need sudo owner = str(uid) + ':' + str(gid) command = ['/bin/chown', owner, devpath] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('hostusb: error chown %s to %s, err = %s\n' % (devpath, owner, err)) sys.exit(2) log_dev_owner(devpath, stat.st_uid, stat.st_gid)
def _process_network(network, attrs): """Applies extra ipv4 addresses to the network if necessary""" options = attrs['custom'].get('ipv4_addrs') if options is not None: top_dev = _top_dev(network, attrs) for cmd in _generate_commands(options, top_dev): hooking.execCmd(cmd, sudo=True)
def checkImage(path, timeout): ''' Check qcow2 image using qemu-img QEMU utility ''' cmd = ['/usr/bin/qemu-img', 'check', '-f', 'qcow2', path] # Check the image using qemu-img. Enforce check termination # on timeout expiration p = hooking.execCmd(cmd, sudo=False, raw=True, sync=False) if not p.wait(timeout): p.kill() sys.stderr.write('checkimages: %s image check operation timed out.' % path) sys.stderr.write('Increate timeout or check image availability.') sys.exit(2) ((out, err), rc) = (p.communicate(), p.returncode) if rc == 0: sys.stderr.write('checkimages: %s image check returned: %s\n' % (path, out)) else: sys.stderr.write('checkimages: Error running %s command: %s\n' % (' '.join(cmd), err)) sys.exit(2)
def disconnectVnic(portId): tapName = ('tap' + portId)[:DEV_MAX_LENGTH] command = [EXT_BRCTL, 'delif', DUMMY_BRIDGE, tapName] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: hooking.exit_hook("Can't disconnect %s from %s, due to: %s" % (tapName, DUMMY_BRIDGE, err))
def _set_ethtool_opts(network, options): """Takes an iterable of the tokenized ethtool command line arguments and applies them to the network devices""" command = [ETHTOOL_BINARY.cmd] + options rc, _, err = hooking.execCmd(command) if rc != 0: raise EthtoolError('Failed to set ethtool opts (%s) for network %s. ' 'Err: %s' % (' '.join(options), network, err))
def removeDeviceNode(devpath): # we don't use os.unlink because we need sudo command = ['/bin/rm', '-f', devpath] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('directlun after_vm_destroy: error rm -f %s, ' 'err = %s\n' % (devpath, err)) sys.exit(2)
def ovs_bridge_exists(bridge): commands = [EXT_OVS_VSCTL, 'br-exists', bridge] rc, _, err = execCmd(commands) if rc == 0: return True elif rc == 2: return False else: raise Exception('\n'.join(err))
def create_image(path, size): """ Create image file """ command = ["/usr/bin/qemu-img", "create", "-f", "raw", path, size] retcode, out, err = hooking.execCmd(command, raw=True) if retcode != 0: sys.stderr.write("scratchpad: error running command %s, err = %s\n" % (" ".join(command), err)) sys.exit(2) os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP)
def create_image(path, size): ''' Create image file ''' command = ['/usr/bin/qemu-img', 'create', '-f', 'raw', path, size] retcode, out, err = hooking.execCmd(command, raw=True) if retcode != 0: sys.stderr.write('scratchpad: error running command %s, err = %s\n' % (' '.join(command), err)) sys.exit(2)
def _is_ovs_service_running(): try: rc, _, _ = hooking.execCmd([OVS_CTL, 'status']) except OSError as err: # Silently ignore the missing file and consider the service as down. if err.errno == errno.ENOENT: rc = errno.ENOENT else: raise return rc == 0
def _run_commands(commands): """ If there are any needed changes in OVS network listed in commands, apply them. Otherwise do nothing. """ if commands: commands = [EXT_OVS_VSCTL, '--', '--may-exist', 'add-br', BRIDGE_NAME] + commands log('Executing commands: %s' % ' '.join(commands)) rc, _, err = hooking.execCmd(commands) if rc != 0: raise Exception('Executing commands failed: %s' % '\n'.join(err))
def restoreDevicePermissions(devpath): owner = 'root:root' for f in os.listdir(devpath): if f.startswith('resource') or f in ('rom', 'reset'): dev = os.path.join(devpath, f) command = ['/bin/chown', owner, dev] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('sriov after_vm_destroy: error chown %s to ' '%s, err = %s\n' % (dev, owner, err)) sys.exit(2)
def _get_stp(iface): if iface != BRIDGE_NAME: return "off" rc, out, err = execCmd([EXT_OVS_VSCTL, "get", "Bridge", BRIDGE_NAME, "stp_enable"], sudo=True) if rc != 0: hooking.exit_hook("\n".join(err)) if out[0] == "true": return "on" else: return "off"
def _get_ovs_external_id(key): cmd_line = [ OVS_VSCTL, '--no-wait', '--verbose=db_ctl_base:syslog:off', 'get', 'Open_vSwitch', '.', 'external_ids:{}'.format(key) ] return hooking.execCmd(cmd_line, sudo=True, raw=False)
def chown(nic, devpath): '''Uses sudo and chown to change the sriov ownership.''' owner = ''.join([str(pwd.getpwnam('qemu').pw_uid), ':', str(grp.getgrnam('qemu').gr_gid)]) for f in os.listdir(devpath): if f.startswith('resource') or f in ('rom', 'reset'): command = ['/bin/chown', owner, os.path.join(devpath, f)] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('sriov: Error %s changing ownership of %s to' 'owner %s. Aborting.\n' % (err, nic, owner)) sys.exit(2)
def _execCmd(cmd, exit=True): print('> ' + ' '.join(cmd)) rc, out, err = execCmd(cmd) if rc == 0: for l in out: print(l) else: print('error %d' % rc) for l in err: print(err) if exit: raise RuntimeError()
def _get_stp(iface): if iface != BRIDGE_NAME: return 'off' rc, out, err = execCmd([EXT_OVS_VSCTL, 'get', 'Bridge', BRIDGE_NAME, 'stp_enable'], sudo=True) if rc != 0: hooking.exit_hook('\n'.join(err)) if out[0] == 'true': return 'on' else: return 'off'
def freeSysHugepages(pages): with open(NUMBER_OF_HUGETPAGES, 'r') as f: currPages = int(f.read()) if pages > 0: # command: sysctl vm.nr_hugepages=0 command = ['sysctl', 'vm.nr_hugepages=%d' % (currPages - pages)] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('hugepages: error in command: %s, err = %s\n' % (' '.join(command), err)) sys.exit(2)
def cloneDeviceNode(srcpath, devpath): '''Clone a device node into a temporary private location.''' # we don't use os.remove/mknod/chmod/chown because we need sudo command = ['/bin/rm', '-f', devpath] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('directlun: error rm -f %s, err = %s\n' % (devpath, err)) sys.exit(2) stat = os.stat(srcpath) major = os.major(stat.st_rdev) minor = os.minor(stat.st_rdev) command = ['/bin/mknod', devpath, 'b', str(major), str(minor)] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('directlun: error mknod %s, err = %s\n' % (devpath, err)) sys.exit(2) mode = '660' command = ['/bin/chmod', mode, devpath] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('directlun: error chmod %s to %s, err = %s\n' % (devpath, mode, err)) sys.exit(2) group = grp.getgrnam('qemu') gid = group.gr_gid user = pwd.getpwnam('qemu') uid = user.pw_uid owner = str(uid) + ':' + str(gid) command = ['/bin/chown', owner, devpath] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('directlun: error chown %s to %s, err = %s\n' % (devpath, owner, err)) sys.exit(2)
def createFloppy(filename, path, content): if os.path.exists(path): os.remove(path) # create floppy file system command = ['/sbin/mkfs.msdos', '-C', path, '1440'] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('floppyinject-before-dest-migration: error /sbin/mkfs.msdos fs: %s\n' % err) sys.exit(2) owner = '36:36' command = ['/bin/chown', owner, path] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('floppyinject-before-dest-migration: error /bin/chown: %s' % err) sys.exit(2) # create floppy file system command = ['/bin/chmod', '0770', path] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('floppyinject-before-dest-migration: error /bin/chmod: %s' % err) sys.exit(2) # mount the floppy file mntpoint = tempfile.mkdtemp() command = ['/bin/mount', '-o', 'loop,uid=36,gid=36' , path, mntpoint] sys.stderr.write('shahar: %s\n' % ' '.join(command)) retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('floppyinject-before-dest-migration: error /bin/mount: %s' % err) sys.exit(2) # write the file content contentpath = os.path.join(mntpoint, filename) f = open(contentpath, 'w') f.write(content) f.close() # unmounting command = ['/bin/umount', mntpoint] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('floppyinject-before-dest-migration: error /bin/umount: %s' % err) sys.exit(2) # remove tempdir command = ['/bin/rmdir', mntpoint] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('floppyinject-before-dest-migration: error /bin/rmdir: %s' % err) sys.exit(2)
def main(): """ Create lists of running networks and networks to be (un)configured as FCoE or removed. """ existing_fcoe_networks = _all_configured_fcoe_networks() changed_fcoe = {} changed_non_fcoe = {} removed_networks = {} custom_parameters = {} setup_nets_config = hooking.read_json() changed_all = setup_nets_config['request']['networks'] for net, net_attr in six.iteritems(changed_all): custom_parameters_string = net_attr.get('custom', {}).get('fcoe', '') custom_parameters[net] = _parse_custom(custom_parameters_string) if _has_fcoe(net_attr): changed_fcoe[net] = net_attr.get('nic') elif hooking.tobool(net_attr.get('remove')): removed_networks[net] = net_attr.get('nic') else: changed_non_fcoe[net] = net_attr.get('nic') _unconfigure_removed(existing_fcoe_networks, removed_networks) _unconfigure_non_fcoe(existing_fcoe_networks, changed_non_fcoe) _reconfigure_fcoe(existing_fcoe_networks, changed_fcoe, custom_parameters) # TODO If services are failed to start restore previous configuration # and notify user ret, _, err = hooking.execCmd(['/bin/systemctl', 'restart', 'lldpad']) if ret: hooking.log('Failed to restart lldpad service. err = %s' % (err)) ret, _, err = hooking.execCmd(['/bin/systemctl', 'restart', 'fcoe']) if ret: hooking.log('Failed to restart fcoe service. err = %s' % (err))
def freeSysHugepages(pages): with open(NUMBER_OF_HUGETPAGES, "r") as f: currPages = int(f.read()) if pages > 0: # command: sysctl vm.nr_hugepages=0 command = ["sysctl", "vm.nr_hugepages=%d" % (currPages - pages)] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write( "hugepages before_vm_migraton_destination: error " "in command: %s, err = %s\n" % (" ".join(command), err) ) sys.exit(2)
def freeSysHugepages(pages): f = file(NUMBER_OF_HUGETPAGES, 'r') currPages = int(f.read()) f.close() if pages > 0: # command: sysctl vm.nr_hugepages=0 command = ['sysctl', 'vm.nr_hugepages=%d' % (currPages - pages)] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('hugepages before_vm_migraton_destination: error ' 'in command: %s, err = %s\n' % (' '.join(command), err)) sys.exit(2)
def _get_active_slave(bonding): """ Get OVS bond's active slave if there is any. Match: slave iface_name: enabled active slave TODO: since openvswitch 2.3.1, active slave is also listed in header of command output. """ rc, out, err = execCmd([EXT_OVS_APPCTL, "bond/show", bonding], sudo=True) if rc != 0: hooking.exit_hook("\n".join(err)) active_slave_regex = re.compile("\nslave (.*):.*\n.*active slave\n") active_slaves = active_slave_regex.findall("\n".join(out)) active_slave = active_slaves[0] if len(active_slaves) > 0 else "" return active_slave
def createDirectory(dirpath): # we don't use os.mkdir/chown because we need sudo command = ['/bin/mkdir', '-p', dirpath] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('directlun: error mkdir %s, err = %s\n' % (dirpath, err)) sys.exit(2) mode = '755' command = ['/bin/chmod', mode, dirpath] if retcode != 0: sys.stderr.write('directlun: error chmod %s %s, err = %s\n' % (dirpath, mode, err)) sys.exit(2)
def addSysHugepages(pages): with open(NUMBER_OF_HUGETPAGES, 'r') as f: currPages = int(f.read()) totalPages = pages + currPages # command: sysctl vm.nr_hugepages=256 command = ['sysctl', 'vm.nr_hugepages=%d' % totalPages] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('hugepages: error in command: %s, err = %s\n' % (' '.join(command), err)) sys.exit(2) with open(NUMBER_OF_HUGETPAGES, 'r') as f: newCurrPages = int(f.read()) return (newCurrPages - currPages)
def addSysHugepages(pages): with open(NUMBER_OF_HUGETPAGES, "r") as f: currPages = int(f.read()) totalPages = pages + currPages # command: sysctl vm.nr_hugepages=256 command = ["sysctl", "vm.nr_hugepages=%d" % totalPages] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write( "hugepages before_vm_migraton_destination: error in " "command: %s, err = %s\n" % (" ".join(command), err) ) sys.exit(2) with open(NUMBER_OF_HUGETPAGES, "r") as f: newCurrPages = int(f.read()) return newCurrPages - currPages
def createFloppy(filename, path, content): # create floppy file system command = ['/sbin/mkfs.msdos', '-C', path, '1440'] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: log(format_error(command, err)) raise Exception(format_error(command, err)) owner = '36:36' command = ['/bin/chown', owner, path] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: raise Exception(format_error(command, err)) command = ['/bin/chmod', '0770', path] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: raise Exception(format_error(command, err)) try: # mount the floppy device in a tmpdir as a loopback mntpoint = tempfile.mkdtemp() command = ['/bin/mount', '-o', 'loop,uid=36,gid=36' , path, mntpoint] log('shahar: %s\n' % ' '.join(command)) retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: raise Exception(format_error(command, err)) # base64 decode the content content = base64.decodestring(content) # write the file content contentpath = os.path.join(mntpoint, filename) f = open(contentpath, 'w') f.write(content) f.close() finally: # unmount the loopback command = ['/bin/umount', mntpoint] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: # record the error, but don't die ... still need to rm tmpdir log("floppyinject error: %s (%s)" % (command.join(" "), err)) # remove tempdir command = ['/bin/rmdir', mntpoint] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: # record the error, but don't die log("floppyinject error: %s (%s)" % (command.join(" "), err))
def destroy_ovs_bridge(): commands = [EXT_OVS_VSCTL, '--if-exists', 'del-br', BRIDGE_NAME] rc, _, err = execCmd(commands) if rc != 0: raise Exception('\n'.join(err))
def captureNetwork(networkName, ifaceName, mode): ''' this commands mirror all networkName traffic to ifaceName: $ tc qdisc add dev networkName ingress $ tc filter add dev networkName parent ffff: protocol ip \ u32 match u8 0 0 action mirred egress mirror dev ifaceName $ tc qdisc replace dev networkName parent root prio get the id and set it as the parent id of the next command id=`tc qdisc show dev networkName | grep prio | awk '{print $3}'` # set the parent id tc filter add dev networkName parent $id protocol ip \ u32 match u8 0 0 action mirred egress mirror dev ifaceName NOTE: ===== in in-line mode we don't filter a network the network parameter here is a tap device for the security vm ''' command = ['/sbin/tc', 'qdisc', 'add', 'dev', networkName, 'ingress'] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) sys.exit(2) command = [ '/sbin/tc', 'filter', 'add', 'dev', networkName, 'parent', 'ffff:', 'protocol', 'ip', 'u32', 'match', 'u8', '0', '0', 'action', 'mirred', 'egress', mode, 'dev', ifaceName ] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) sys.exit(2) command = [ '/sbin/tc', 'qdisc', 'replace', 'dev', networkName, 'parent', 'root', 'prio' ] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) sys.exit(2) command = ['/sbin/tc', 'qdisc', 'show', 'dev', networkName] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) sys.exit(2) # TODO: change string slicing to regex devId = out[11:16] sys.stderr.write('promisc: filtering devId=%s\n' % devId) command = [ '/sbin/tc', 'filter', 'add', 'dev', networkName, 'parent', devId, 'protocol', 'ip', 'u32', 'match', 'u8', '0', '0', 'action', 'mirred', 'egress', mode, 'dev', ifaceName ] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) sys.exit(2) # add promisc mode to the bridge command = ['/sbin/ifconfig', networkName, 'promisc'] retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: sys.stderr.write('promisc: error executing command "%s" error: %s' % (command, err)) sys.exit(2)
def executeOrExit(command): retcode, out, err = hooking.execCmd(command, sudo=True, raw=True) if retcode != 0: raise RuntimeError("Failed to execute %s, due to: %s" % (command, err))
def deviceExists(dev): command = [EXT_IP, 'link', 'show', 'dev', dev] retcode, out, err = hooking.execCmd(command, raw=True) return retcode == 0
def _list_ports(bridge): rc, out, err = execCmd([EXT_OVS_VSCTL, 'list-ports', bridge], sudo=True) if rc != 0: hooking.exit_hook('\n'.join(err)) return out