*CeJddlZddlZddlZddlZddlZddlmZddlmZddl m Z ddl Z ddl Z Gdde Zd ejefd Zd ejed ejefd Zd ZdZdZdZdZddZddZy)N) defaultdict)utils)ConfigurationErrorceZdZdZdefdZedefdZedefdZdedefdZ edefd Z ede fd Z ede fd Z ede fd Zedefd ZedefdZdededefdZdefdZdefdZy) PCIDevicez.Helper class for interaction with a PCI devicepci_addrc||_y)znInitialise a new PCI device handler :param pci_addr: PCI address of device :type: str Nr )selfr s +/usr/share/netplan/netplan_cli/cli/sriov.py__init__zPCIDevice.__init__(s ! returncy)zusysfs path (can be overridden for testing) :return: full path to /sys filesystem :rtype: str z/sysr s rsysz PCIDevice.sys/s rcltjj|jd|jS)zq/sys path for PCI device :return: full path to PCI device in /sys filesystem :rtype: str zbus/pci/devices)ospathjoinrr rs rrzPCIDevice.path7s$ ww||DHH&7GGrsubpathcVtjj|j|S)z/sys subpath helper for PCI device :param subpath: subpath to construct path for :type: str :return: self.path + subpath :rtype: str )rrr)r rs rrzPCIDevice.subpath?sww||DIIw//rcd}tjj|jdrAtjj tj |jd}|S)zjKernel driver for PCI device :return: kernel driver in use for device :rtype: str driver)rrexistsrbasenamereadlink)r rs rrzPCIDevice.driverHsM  77>>$,,x0 1WW%%bkk$,,x2H&IJF rc^tjj|jdS)zDetermine if device is bound to a kernel driver :return: whether device is bound to a kernel driver :rtype: bool rrrrrrs rboundzPCIDevice.boundS ww~~dll8455rc^tjj|jdS)zwDetermine if device is a SR-IOV Physical Function :return: whether device is a PF :rtype: bool sriov_numvfsr#rs ris_pfzPCIDevice.is_pf[s ww~~dll>:;;rc^tjj|jdS)zvDetermine if device is a SR-IOV Virtual Function :return: whether device is a VF :rtype: bool physfnr#rs ris_vfzPCIDevice.is_vfcr%rc g}d} |jtjjtj|j dj ||dz }f#t$rY|SwxYw)zList Virtual Function addresses associated with a Physical Function :return: List of PCI addresses of Virtual Functions :rtype: list[str] rzvirtfn{}r)appendrrr r!rformatFileNotFoundError)r vf_addrsis rr0zPCIDevice.vf_addrsks}   GG$$ DLL1B1B11E$FG FA%  sAA,, A98A9cR|jDcgc] }t|c}Scc}w)zList Virtual Function associated with a Physical Function :return: List of PCI devices of Virtual Functions :rtype: list[PCIDevice] )r0r )r addrs rvfsz PCIDevice.vfss -1MM:D $:::s$obj_namepropvaluec ntjdd|ddj|j||gy)zSet devlink options for the PCI device :param obj_name: devlink object to set options on :type: str :param prop: property to set :type: str :param value: value to set for property :type: str /sbin/devlinkdevsetzpci/{}N) subprocess check_callr.r )r r5r6r7s r devlink_setzPCIDevice.devlink_sets9  .  rc8d|j} tjddddd|gtj}t j |}|jdij|ijd dS#tj$rYywxYw) zQuery eswitch mode via devlink for the PCI device :return: the eswitch mode or '__undetermined' if it can't be retrieved :rtype: str zpci/r9z-jr:eswitchshow)stderr__undeterminedmode)r r< check_outputDEVNULLCalledProcessErrorjsonloadsget)r pcioutput json_outputs rdevlink_eswitch_modezPCIDevice.devlink_eswitch_modes T]]O$ $,,# ")) Fjj( ub)--c26::6CSTT,, $# $s+BBBc|jS)zbString represenation of object :return: PCI address of string :rtype: str r rs r__str__zPCIDevice.__str__s }}rN)__name__ __module__ __qualname____doc__strrpropertyrrrrboolr$r(r+listr0r4r>rNrPrrrr r %s38!!SHcHH0s0s06t66||vrt d|z|||<Vn ||vr|||<|j|dS)N) iface_name iface_driver iface_macz3matched more than one interface for a PF device: %s) _has_matchset_name_match_interfacerget_interface_driver_nameget_interface_macaddressrrJ) interfacesnp_statepf_linkpfspf_devrk interfaces r_get_target_interfacerusc'"   HH 2 (G !+ -I!22'0).)H)H)S&+&D&DY&O3Q!#~01fip1pqq#,CL -*$&G 777D !!rc tjjd|d} t|5}d}|j D]E}|j }|j ds%|jddd}|ccdddS dddy#1swYyxYw#t$r}td|d t|d}~wwxYw) z5 Read PCI slot name for given interface name /sys/class/netz device/ueventNzPCI_SLOT_NAME==rrz!failed parsing PCI slot name for : ) rrrr\ readlinesstrip startswithsplitIOError RuntimeErrorrU)netdev uevent_pathr` pci_slot_namelinees r_get_pci_slot_namers'',,/IK Y +  )! M  )zz|??#34$(JJsA$6q$9M((  ) ) ) ) ) ) YPSTUPVWXXYsF B7B&B> BB BBBB C(CCc|jjD]\}}|jjdr6t |||jjdj |rd||< |j }|dk(rjt ||||} | s{||| <y#tj$r}tt|d}~wwxYw)z Go through the list of netplan ethernet devices and identify which are PFs and VFs, matching the former with actual networking interfaces. Count how many VFs each PF will need. sriovNr) ethernetsitemslinksrJruid _vf_countnetplanNetplanExceptionrrU) rorp vf_countsr4rrnidnetdefcountrpfs rget_vf_count_and_functionsr s ))//1 " V <<  G $)>z8U[UaUaUeUefmUnUqUqsv)wCH -$$E A:  ":xc B !IbM " '' -$SV, , -s3 BC 1CC c |dkDrtd|d|dtjjd|d}tjj|d}tjj|d} t |5}t |j j}d d d |kDrtd|d |d|d t |d5}|jt|d d d y#1swYTxYw#t$r}td |d t|d }~wt$rtd |zwxYw#1swYyxYw#t$r}d}|jdk(rtjd|z t |d5}|jdd d d n #1swYnxYwt |d5}|jt|d d d n #1swYnxYwd}n#t$r } | }Yd } ~ nd } ~ wwxYw|rtd|d|d t|Yd }~yd }~wwxYw)zB Allocate the required number of VFs for the selected PF. z cannot allocate more VFs for PF z than the SR-IOV maximum: z > 256rwdevicer'sriov_totalvfsNz"failed parsing sriov_totalvfs for ryz#invalid sriov_totalvfs value for %sz than supported: z > z (sriov_totalvfs)wTzLdevice or resource busy while setting sriov_numvfs for %s, trying workaround0Fzfailed setting sriov_numvfs to z for )rrrrr\intreadr{r~rrU ValueErrorr]errnologgingwarning) rvf_countdevdir numvfs_path totalvfs_pathr`vf_maxrbaile_inners rset_numvfs_for_pfr s%#~ VXZb ce eWW\\*B 9F'',,v~6KGGLL)9:MG -  +A)*F +& ]_aikq rt th +s # #q GGCM " #( A + + VSQRVTUU G@2EFFG #( % h 77b= OOjmoo p +s+!qGGCL!!!+s++qGGCM*+++    QY[]_bcd_efg g  %hs: D (D-D  EE 7ED D E D//E  EEE H?")H: G>F3* G>3F< 8G> G/& G>/G8 4G>;H:> HH H:H"H::H?c Ntjjd|d} ttjj|d5}|j j dd}dddttjj|d5}|j j dd}ddddjg}d }||vryy#1swYwxYw#1swY0xYw#t $r}td|dt|d}~wwxYw) z Perform any hardware-specific quirks for the given SR-IOV device to make sure all the VF-count changes are applied. rwrvendorrNz,could not determine vendor and device ID of ry:r) rrrr\rr{r~rrU)rrr` device_id vendor_idr combined_id quirk_devicess r perform_hardware_specific_quirksrOs WW\\*B 9F` "'',,vx0 1 -Q(,I - "'',,vx0 1 -Q(,I - ((Iy12KMm# $ - - - - `SUWZ[\W]^__`sG)C< "C$.1C<"C0C<$C-)C<0C95C<< D$DD$c d}tjj|d|d}tjjtj|}tjj|d|d}tj |D]e} d| vstjj|| } tjjtj| } | |k(s`| dd}n|st d|d| tjdd d d |d |d t|g tjtjy#tj$rt d|zwxYw)z@ Apply the hardware VLAN filtering for the selected VF. Nz sys/class/netrvirtfnz%could not determine the VF index for z while configuring vlan iplinkr;r:r_vlan)stdoutrBzJfailed setting SR-IOV VLAN filter for vlan %s (ip link set command failed)) rrrr r!listdirrr<r=rUrFrG) rr_ vlan_namevlan_idprefixvf_index vf_devdir vf_dev_id pf_devdirr`dev_pathdev_ids rapply_vlan_filter_for_vfrlsPH V_b(CI  Y!78I V_b(CI ZZ " q=ww||Iq1HWW%%bkk(&;s| j@jCd}| jD}|jC|jF} | s't'jHd|d |jFd ~|jC|j@jCd jF}| |vrtd | d |jFd|dtK|| |||jM| y#|s!t9|j.|j4wwxYw)z Go through all interfaces, identify which ones are SR-IOV VFs, create them and perform all other necessary setup. )rgz3matched more than one interface for a VF device: %s) switchdevlegacyzFound VFs of {}: {}r@rDrzSR-IOV vlan defined for z but link z% is either not a VF or has no matchesrz interface z for netplan device z (z$) already has an SR-IOV vlan definedN)'parse netifacesrorprrrrrr-rrjrlr_embedded_switch_moderr rNr(rdebugr.r0r4_delay_virtual_functions_rebindrerr>rar;vlans_has_sriov_vlan_filterrrJ_vlan_idrrradd)config_managerrootdirrorprr4rrvf_count_changedrrr_rrt netdef_idiface eswitch_moder pcidevcurrent_eswitch_mode_systemrebind_delayedfiltered_vlans_setrrrs rapply_sriov_configrs1 %%'J&&H C I C CHic3 %OO- (LB$R2  # #B '  ( # 1B ,R 0 1 ))+ "    ( ( **i*@SySW01fik1kll'CG  ( ZB" IIKD 5)$33 2 2)%0Hx(F*0*E*E*G '::<<MM"7">">vv"WXzz)/)O)OD&vzz6==A"..y&,O#1 (V]] C#D& ,,.' f  ( (<<##F+DooG!Beikokrkrsu 0334B''(dfhlhohoquvxx %RT7 ;  " "2 &9' $2 (V]] C$2s <3L//%M)/)rHrrr<typing collectionsrrr configmanagerrrrobjectr Iterablerarerurrrrrrrrrrs&   #. YYx&//),FOOI.6??9;U"BY"".,^ :$fNq'r