a ”ˆ«h [ã@snddlZddlmZddlZddlZddlZddlmZddl Z ddl m Z m Z ej  ¡ZGdd„deƒZdS)éN)Úcommands)ÚPopenÚPIPEc@s6eZdZdZdd„Zdd„Zdd„Zedd „ƒZe d d „ƒZ e d d „ƒZ e dd„ƒZ dd„Z dd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Zd.d/„Zd0d1„Zd2d3„Zej fd4d5„Z!d6d7„Z"d8d9„Z#d:d;„Z$ej fdd?„Z&d@dA„Z'ej fdBdC„Z(dDdE„Z)dFdG„Z*dHdI„Z+dJdK„Z,dLdM„Z-dNdO„Z.dPdQ„Z/d€dSdT„Z0ddUdV„Z1d‚dWdX„Z2dƒdYdZ„Z3d[d\„Z4d]d^„Z5d_d`„Z6dadb„Z7dcdd„Z8d„dfdg„Z9d…dhdi„Z:djdk„Z;dldm„Zd‡drds„Z?dtdu„Z@dvdw„ZAdxdy„ZBdˆdzd{„ZCd‰d|d}„ZDd~d„ZEdRS)ŠÚPlugina Base class for all plugins. Plugins change various system settings in order to get desired performance or power saving. Plugins use Monitor objects to get information from the running system. Intentionally a lot of logic is included in the plugin to increase plugin flexibility. c Csn| |jj¡|_||_||_||_||_||_t   ¡|_ |  ¡||_ ||_d|_d|_| ¡|_tƒ|_dS)zPlugin constructor.FN)ÚcreateÚ __class__Ú__name__Ú_storageZ_monitors_repositoryZ_hardware_inventoryÚ_device_matcherÚ_device_matcher_udevÚ_instance_factoryÚ collectionsÚ OrderedDictÚ _instancesÚ_init_commandsÚ _global_cfgÚ _variablesÚ_has_dynamic_optionsÚ_devices_initedÚ#_get_config_options_used_by_dynamicÚ_options_used_by_dynamicrÚ_cmd) ÚselfZmonitors_repositoryZstorage_factoryZhardware_inventoryZdevice_matcherZdevice_matcher_udevZinstance_factoryZ global_cfgZ variables©rú6/usr/lib/python3.9/site-packages/tuned/plugins/base.pyÚ__init__s  zPlugin.__init__cCs | ¡dS©N)Údestroy_instances©rrrrÚcleanup,szPlugin.cleanupcCs|js| ¡d|_dS)NT)rÚ _init_devicesrrrrÚ init_devices/szPlugin.init_devicescCs|jj d¡d dd¡dS)NÚ.éÿÿÿÿÚ_é)rÚ __module__ÚsplitrrrrÚname4sz Plugin.namecCsiS)z-Default configuration options for the plugin.rrrrrÚ_get_config_options<szPlugin._get_config_optionscCsiS)z*Explanation of each config option functionr)ÚclsrrrÚget_config_options_hintsAszPlugin.get_config_options_hintscCsgS)znList of config options used by dynamic tuning. Their previous values will be automatically saved and restored.rrrrrrFsz*Plugin._get_config_options_used_by_dynamiccCsL| ¡ ¡}|D]6}||vs"|jr0||||<qt d||jjf¡q|S)z3Merge provided options with plugin default options.z$Unknown option '%s' for plugin '%s'.)r)ÚcopyrÚlogÚwarningrr)rÚoptionsZ effectiveÚkeyrrrÚ_get_effective_optionsKs  zPlugin._get_effective_optionscCs,t|ƒtur|St|ƒ ¡}|dkp*|dkS)NÚtrueÚ1)ÚtypeÚboolÚstrÚlower)rÚvaluerrrÚ _option_boolVs  zPlugin._option_boolc Csf||jvrtd|ƒ‚| |¡}|j ||||||||¡} | |j|<t t|j ¡dd„d¡|_| S)z8Create new instance of the plugin and seize the devices.z.Plugin instance with name '%s' already exists.cSs |djS)Nr%)Úpriority)ÚxrrrÚióz(Plugin.create_instance..©r0) rÚ Exceptionr1r rr rÚsortedÚitems) rr(r:Údevices_expressionÚdevices_udev_regexÚ script_preÚ script_postr/Zeffective_optionsÚinstancerrrÚcreate_instance`s   ÿ zPlugin.create_instancecCsV|j|krtd||fƒ‚|j|jvr2td|ƒ‚|j|j}| |¡|j|j=dS)zDestroy existing instance.z9Plugin instance '%s' does not belong to this plugin '%s'.z+Plugin instance '%s' was already destroyed.N)Z_pluginr?r(rÚ_destroy_instance©rrFrrrÚdestroy_instancems     zPlugin.destroy_instancecCs$t d|j|jf¡| |¡dS)zInitialize an instance.zinitializing instance %s (%s)N)r-Údebugr(Ú_instance_initrIrrrÚinitialize_instancexszPlugin.initialize_instancecCsBt|j ¡ƒD]$}t d|j|jf¡| |¡q|j ¡dS)zDestroy all instances.zdestroying instance %s (%s)N)ÚlistrÚvaluesr-rKr(rHÚclearrIrrrr}s zPlugin.destroy_instancescCs| |¡| |¡dSr)Úrelease_devicesÚ_instance_cleanuprIrrrrH„s zPlugin._destroy_instancecCs tƒ‚dSr©ÚNotImplementedErrorrIrrrrLˆszPlugin._instance_initcCs tƒ‚dSrrSrIrrrrR‹szPlugin._instance_cleanupcCsd|_tƒ|_tƒ|_dS©NF)Ú_devices_supportedÚsetÚ_assigned_devicesÚ _free_devicesrrrrr ’szPlugin._init_devicescCsdS)z’Override this in a subclass to transform a list of device names (e.g. ['sda']) to a list of pyudev.Device objects, if your plugin supports itNr)rÚdevicesrrrÚ_get_device_objects—szPlugin._get_device_objectscCsj|jdurt|j |j|¡ƒS| |¡}|durDt d|j¡tƒS|j  |j|¡}tdd„|DƒƒSdS)Nz¥r=z0Plugin._get_matching_devices..) rCrWr Z match_listrBr[r-Úerrorr(r )rrFrZZ udev_devicesrrrÚ_get_matching_devicesœs  zPlugin._get_matching_devicescCs²|js dSt d|j¡| ||j¡}t|ƒdk|_|jsNt d|j¡n`|j}|j|jkrn|d|j7}t  d|d  |¡f¡|j   |¡|j |O_ |j|8_dS)Nz assigning devices to instance %srz*instance %s: no matching devices availablez (%s)z!instance %s: assigning devices %sú, )rVr-rKr(r_rYÚlenÚactiver.ÚinfoÚjoinÚassigned_devicesÚupdaterX)rrFZ to_assignr(rrrÚassign_free_devices§s  zPlugin.assign_free_devicescCsV|js dS|j|jB|j@}d|_|j ¡|j ¡|j|8_|j|O_dSrU)rVÚprocessed_devicesrerXrbrPrY)rrFZ to_releaserrrrQ¹sÿþ  zPlugin.release_devicescCs$|js dg}|D]}|||ƒqdSr)rV)rrFÚcallbackrZÚdevicerrrÚ_run_for_each_deviceËszPlugin._run_for_each_devicecCsdSrr©rrFZenablingrrrÚ_instance_pre_staticÒszPlugin._instance_pre_staticcCsdSrrrlrrrÚ_instance_post_staticÕszPlugin._instance_post_staticcCs<tj |¡}|j tjtj¡}|D]}| |¡r"dSq"dS©NTF) ÚosÚpathÚrealpathrZget_listÚconstsZCFG_PROFILE_DIRSZCFG_DEF_PROFILE_DIRSÚ startswith)rrqZ profile_pathsÚprrrÚ_safe_script_pathØs   zPlugin._safe_script_pathc CsŠ|dur dSt|ƒdkr0t d|j|f¡dS| d¡sHt d¡dS| |¡sht dd|¡dStj  |¡}d}|D]}tj } |   |j   ¡¡|g} |tjkr²|  d ¡|  |¡t d |t| ƒf¡t d tt|  ¡ƒƒ¡zVt|g| ttd| |dd } |  ¡\} } | jr@t d || j| dd…f¡d}Wq|ttfy‚}z"t d||f¡d}WYd}~q|d}~00q||S)Nrz1Instance '%s': no device to call script '%s' for.ú/zQRelative paths cannot be used in script_pre or script_post. Use ${i:PROFILE_DIR}.Fz?Paths outside of the profile directories cannot be used in the z0script_pre or script_post, ignoring script: '%s'TZ full_rollbackz'calling script '%s' with arguments '%s'zusing environment '%s')ÚstdoutÚstderrZ close_fdsÚenvÚcwdZuniversal_newlineszscript '%s' error: %d, '%s'r#zscript '%s' error: %s)rar-r.r(rtr^rvrprqÚdirnameÚenvironrfrZget_envrsZ ROLLBACK_FULLÚappendrcr6rKrNrArrZ communicateÚ returncodeÚOSErrorÚIOError)rrFZscriptÚoprZÚrollbackZdir_nameÚretÚdevr}Z argumentsÚprocÚoutÚerrÚerrrÚ_call_device_scriptàsL    ÿ      ý zPlugin._call_device_scriptcCsª|js dS|jrZ| ||jd|j¡| |d¡| |¡| |d¡| ||jd|j¡|j rŽ|j   t j t j¡rŽ| |¡| ||j|j¡|j |j¡|j ¡dS)zG Apply static and dynamic tuning if the plugin instance is active. NZapplyT)rbÚhas_static_tuningrŠrDrermÚ_instance_apply_staticrnrEÚhas_dynamic_tuningrÚgetrsÚCFG_DYNAMIC_TUNINGÚCFG_DEF_DYNAMIC_TUNINGÚ_instance_init_dynamicrkÚ_instance_apply_dynamicrhrfrPrIrrrÚinstance_apply_tunings" ÿ    ÿ zPlugin.instance_apply_tuningcCs”|js dSt|jƒdkr.t dd |j¡¡|j ¡}|jrŒ|  ||j d|¡dkrXdS|  |||¡dkrndS|  ||j d|¡dkrˆdSdSdSdS)z< Verify static tuning if the plugin instance is active. Nrz)BUG: Some devices have not been tuned: %sr`ZverifyFT) rbrarer-r^rdrhr,r‹rŠrDÚ_instance_verify_staticrE)rrFÚignore_missingrZrrrÚinstance_verify_tunings  ÿ zPlugin.instance_verify_tuningcCs<|js dS|jr8|j tjtj¡r8| ||j|j   ¡¡dS)z< Apply dynamic tuning if the plugin instance is active. N) rbrrrŽrsrrrkÚ_instance_update_dynamicrhr,rIrrrÚinstance_update_tuning2szPlugin.instance_update_tuningcCs–|tjkrdS|jr8|j tjtj¡r8| ||j|j ¡|j r’|j ||j d|j |d|  |d¡| ||¡| |d¡|j ||jd|j |ddS)z8 Remove all tunings applied by the plugin instance. NZunapply)rƒF)rsZ ROLLBACK_NONErrrŽrrrkÚ_instance_unapply_dynamicrhr‹rŠrErmÚ_instance_unapply_staticrnrD©rrFrƒrrrÚinstance_unapply_tuning;s  þ   zPlugin.instance_unapply_tuningcCs| |¡| ||j¡dSr)Ú _execute_all_non_device_commandsÚ_execute_all_device_commandsrerIrrrrŒMs zPlugin._instance_apply_staticcCs2d}| ||¡dkrd}| |||¡dkr.d}|Sro)Ú_verify_all_non_device_commandsÚ_verify_all_device_commands)rrFr•rZr„rrrr”Qs zPlugin._instance_verify_staticcCs| ||j¡| |¡dSr)Ú_cleanup_all_device_commandsrhÚ _cleanup_all_non_device_commandsr›rrrršYsÿzPlugin._instance_unapply_staticcCsdSrrrIrrrr‘^szPlugin._instance_init_dynamiccsB‡‡‡fdd„ˆjDƒD]}ˆ ˆˆj|ˆ¡qˆ ˆˆ¡dS)Ncs(g|] }ˆ ˆˆj|ˆ¡dur|‘qSr)Ú _storage_getÚ _commands)r\Úopt©rjrFrrrr]br=z2Plugin._instance_apply_dynamic..)rÚ_check_and_save_valuer¤r—)rrFrjÚoptionrr¦rr’aszPlugin._instance_apply_dynamiccCs tƒ‚dSrrS©rrFrjrrrr™gsz Plugin._instance_unapply_dynamiccCs tƒ‚dSrrSr©rrrr—jszPlugin._instance_update_dynamiccCst ¡|_| ¡| ¡dS)z Initialize commands. N)r rr¤Ú_autoregister_commandsÚ_check_commandsrrrrrqs zPlugin._init_commandscCsö|jjD]Æ}| d¡rqt||ƒ}t|dƒs.q|jd}|j |d|i¡}d|jvr‚d|d<||d<|jd|d<|jd|d<nBd |jvr–||d <n.d|jvrÄ||d<|jd|d<|jd|d<||j|<qt  t t |j  ¡ƒd d „d ¡|_dS) zd Register all commands marked using @command_set, @command_get, and @command_custom decorators. Ú__Ú_commandr(rWNÚcustomÚ per_devicer:rŽcSs |ddS)Nr%r:r)Z name_inforrrr<–r=z/Plugin._autoregister_commands..r>) rÚ__dict__rtÚgetattrÚhasattrr­r¤rŽr rr@ÚiterrA)rÚ member_nameÚmemberÚ command_namercrrrrªys*          zPlugin._autoregister_commandscCsFt|j ¡ƒD]2\}}| dd¡r$qd|vs4d|vrtd|ƒ‚qdS)z2 Check if all commands are defined correctly. r®FrŽrWz,Plugin command '%s' is not defined correctlyN)rNr¤rArŽÚ TypeError)rr¶Úcommandrrrr«˜s  zPlugin._check_commandsNcCsJt|ƒj}|durdn|}|dur&dn|}|dur6dn|}d||||fS)NÚz %s/%s/%s/%s)r4r)rZ instance_namer¶Ú device_nameÚ class_namerrrÚ _storage_key¨s ÿzPlugin._storage_keycCs&| |j|d|¡}|j ||¡dS©Nr()r¼r(r rW)rrFr¸r8rºr0rrrÚ _storage_set±szPlugin._storage_setcCs | |j|d|¡}|j |¡Sr½)r¼r(r rŽ©rrFr¸rºr0rrrr£µszPlugin._storage_getcCs | |j|d|¡}|j |¡Sr½)r¼r(r Zunsetr¿rrrÚ_storage_unset¹szPlugin._storage_unsetcCsRdd„t|j ¡ƒDƒD]4}|j |j |dd¡¡}|dur| |||¡qdS)NcSsg|]}|ds|‘qS©r¯r©r\r¸rrrr]Âr=z;Plugin._execute_all_non_device_commands..r()rNr¤rOrÚexpandr/rŽÚ_execute_non_device_command©rrFr¸Ú new_valuerrrrÁsz'Plugin._execute_all_non_device_commandscCs`dd„t|j ¡ƒDƒD]B}|j |j |dd¡¡}|dur@q|D]}| ||||¡qDqdS)NcSsg|]}|dr|‘qSrÁrrÂrrrr]Èr=z7Plugin._execute_all_device_commands..r()rNr¤rOrrÃr/rŽÚ_execute_device_command)rrFrZr¸rÆrjrrrržÇs z#Plugin._execute_all_device_commandscCs`d}dd„t|j ¡ƒDƒD]>}|j |j |dd¡¡}|dur| ||||¡dkrd}q|S)NTcSsg|]}|ds|‘qSrÁrrÂrrrr]Ñr=z:Plugin._verify_all_non_device_commands..r(F)rNr¤rOrrÃr/rŽÚ_verify_non_device_command)rrFr•r„r¸rÆrrrrŸÏsz&Plugin._verify_all_non_device_commandsc Csnd}dd„t|j ¡ƒDƒD]L}|j |j |dd¡¡}|durDq|D]}| |||||¡dkrHd}qHq|S)NTcSsg|]}|dr|‘qSrÁrrÂrrrr]Úr=z6Plugin._verify_all_device_commands..r(F)rNr¤rOrrÃr/rŽÚ_verify_device_command)rrFrZr•r„r¸rÆrjrrrr Øsz"Plugin._verify_all_device_commandsc CsÌ|durÈt|ƒ}t|ƒdkr |S|dd…}|dd…}|durP|dvrL|S|SzN|dkrxt|ƒt|ƒkrp|WSWdSn$|dkrœt|ƒt|ƒkr–|WSWdSWn(tyÆt d||||f¡Yn0|S)Nr%)ú<ú>rËrÊzhcannot compare new value '%s' with current value '%s' by operator '%s', using '%s' directly as new value)r6raÚintÚ ValueErrorr-r.)rrÆÚ current_valueZnwsr‚ÚvalrrrÚ_process_assignment_modifiersãs(     z$Plugin._process_assignment_modifiersFcCs*|dur|d|||dS|d|ƒSdS)NrŽ©r•r)rrFr¸rjr•rrrÚ_get_current_valueûszPlugin._get_current_valuecCs>| |||¡}| ||¡}|dur:|dur:| ||||¡|Sr)rÒrÐr¾)rrFr¸rjrÆrÎrrrr§s  zPlugin._check_and_save_valuecCsV|ddur$|dd||dd|ƒn.| ||||¡}|durR|d|||ddddS©Nr®TFrW©ZsimÚremove©r§)rrFr¸rjrÆrrrrÇs  zPlugin._execute_device_commandcCsR|ddur"|dd|dd|ƒn,| ||d|¡}|durN|d||ddddSrÓrÖrÅrrrrÄs  z"Plugin._execute_non_device_commandcCs.|j t|ƒ¡}t d|¡r*t dd|¡S|S)Nz\s*(0+,?)+([\da-fA-F]*,?)*\s*$z ^\s*(0+,?)+r¹)rÚunquoter6ÚreÚmatchÚsub)rr8ÚvrrrÚ _norm_values zPlugin._norm_valuec Cs|dur dSd}|durN|rN|dur6t tj|¡nt tj||f¡dS|dur| |¡}| |¡}zt|ƒt|ƒk}Wn„tyzt|dƒt|dƒk}WnVtyþt|ƒt|ƒk}|sút|ƒ  d¡}|D]}|  ¡}||k}|rÜqúqÜYn0Yn0|j |||||d|S)NFTéú|)rj) r-rcrsZ STR_VERIFY_PROFILE_VALUE_MISSINGZ'STR_VERIFY_PROFILE_DEVICE_VALUE_MISSINGrÜrÌrÍr6r'ÚstripÚ_log_verification_result) rr(rÆrÎr•rjr„ZvalsrÏrrrÚ _verify_values:      ÿzPlugin._verify_valuecCs¬|rL|dur*t tj|t|ƒ ¡f¡nt tj||t|ƒ ¡f¡dS|dur|t tj|t|ƒ ¡t|ƒ ¡f¡n(t tj ||t|ƒ ¡t|ƒ ¡f¡dSdSro) r-rcrsZSTR_VERIFY_PROFILE_VALUE_OKr6rßZ"STR_VERIFY_PROFILE_DEVICE_VALUE_OKr^ZSTR_VERIFY_PROFILE_VALUE_FAILZ$STR_VERIFY_PROFILE_DEVICE_VALUE_FAIL)rr(ÚsuccessrÆrÎrjrrrrà>s((zPlugin._log_verification_resultcCsv|ddur"|dd||d||ƒS|j||||d}| ||¡}|durLdS|d|||ddƒ}| |d||||¡S)Nr®TrÑrWFr(©rÒrÐrá)rrFr¸rjrÆr•rÎrrrrÉMs  zPlugin._verify_device_commandcCsj|ddur |dd|d||ƒS| ||¡}| ||¡}|durDdS|d||ddƒ}| |d|||¡S)Nr®TrWFr(rã)rrFr¸rÆr•rÎrrrrÈWs   z!Plugin._verify_non_device_commandcCsVtdd„t|j ¡ƒDƒƒD]4}|j |dd¡dusD|d|jvr| ||¡qdS)NcSsg|]}|ds|‘qSrÁrrÂrrrr]br=z;Plugin._cleanup_all_non_device_commands..r()ÚreversedrNr¤rOr/rŽrÚ_cleanup_non_device_command)rrFr¸rrrr¢as $z'Plugin._cleanup_all_non_device_commandscCsdtdd„t|j ¡ƒDƒƒD]B}|j |dd¡dusD|d|jvr|D]}| ||||¡qHqdS)NcSsg|]}|dr|‘qSrÁrrÂrrrr]gr=z7Plugin._cleanup_all_device_commands..r()rärNr¤rOr/rŽrÚ_cleanup_device_command)rrFrZrÕr¸rjrrrr¡fs $z#Plugin._cleanup_all_device_commandscCsb|ddur$|ddd|dd|ƒn:| |||¡}|durP|d|||d|d| |||¡dS©Nr®FrWrÔ©r£rÀ)rrFr¸rjrÕÚ old_valuerrrræls  zPlugin._cleanup_device_commandcCsZ|ddur"|ddddd|ƒn4| ||¡}|durJ|d||ddd| ||¡dSrçrè)rrFr¸rérrrråus   z"Plugin._cleanup_non_device_command)NNN)N)N)N)NF)NN)N)N)F)F)Frr&Ú __qualname__Ú__doc__rrr!Úpropertyr(Ú classmethodr)r+rr1r9rGrJrMrrHrLrRr r[r_rgrQrkrmrnrvrsZ ROLLBACK_SOFTrŠr“r–r˜rœrŒr”ršr‘r’r™r—rrªr«r¼r¾r£rÀrržrŸr rÐrÒr§rÇrÄrÜráràrÉrÈr¢r¡rærårrrrr sŒ          ' ÿ        !ÿ     r)rØZ tuned.constsrsZtuned.profiles.variablesZtunedZ tuned.logsr Ztuned.utils.commandsrrpÚ subprocessrrZlogsrŽr-ÚobjectrrrrrÚs