a ”ˆ«hCã@slddlZddlmZddlTddlZddlmZddlm Z ddl Z ddl Z ej   ¡ZGdd„dejƒZdS)éNé)Úhotplug)Ú*)ÚcommandscsøeZdZdZ‡fdd„Z‡fdd„Zdd„Zdd „Zed d „ƒZ d d „Z dd„Z ‡fdd„Z ‡fdd„Z ‡fdd„Zedd„ƒZedd„ƒZdd„Zdd„Z‡fdd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Z‡fd.d/„Zd0d1„Zd\d3d4„Zd5d6„Zed7d8d9d:d;„ƒZ e!d7ƒd]d=d>„ƒZ"ed?d8d9d@dA„ƒZ#e!d?ƒd^dBdC„ƒZ$edDd8d9dEdF„ƒZ%e!dDƒd_dGdH„ƒZ&dIdJ„Z'dKdL„Z(edMd8d9dNdO„ƒZ)e!dMƒd`dPdQ„ƒZ*e+dRd8d9dSdT„ƒZ,dUdV„Z-edWd8d9dXdY„ƒZ.e!dWƒdadZd[„ƒZ/‡Z0S)bÚ DiskPlugina. Plug-in for tuning various block device options. This plug-in can also dynamically change the advanced power management and spindown timeout setting for a drive according to the current drive utilization. The dynamic tuning is controlled by the [option]`dynamic` and the global [option]`dynamic_tuning` option in `tuned-main.conf`. The disk plug-in operates on all supported block devices unless a comma separated list of [option]`devices` is passed to it. .Operate only on the `sda` block device ==== ---- [disk] devices=sda ---- ==== The [option]`elevator` option sets the Linux I/O scheduler. .Use the bfq I/O scheduler on the `xvda` block device ==== ---- [disk] device=xvda elevator=bfq ---- ==== The [option]`scheduler_quantum` option only applies to the CFQ I/O scheduler. It defines the number of I/O requests that CFQ sends to one device at one time, essentially limiting queue depth. The default value is 8 requests. The device being used may support greater queue depth, but increasing the value of quantum will also increase latency, especially for large sequential write work loads. The [option]`apm` option sets the Advanced Power Management feature on drives that support it. It corresponds to using the `-B` option of the `hdparm` utility. The [option]`spindown` option puts the drive into idle (low-power) mode, and also sets the standby (spindown) timeout for the drive. It corresponds to using `-S` option of the `hdparm` utility. .Use a medium-agressive power management with spindown ==== ---- [disk] apm=128 spindown=6 ---- ==== The [option]`readahead` option controls how much extra data the operating system reads from disk when performing sequential I/O operations. Increasing the `readahead` value might improve performance in application environments where sequential reading of large files takes place. The default unit for readahead is KiB. This can be adjusted to sectors by specifying the suffix 's'. If the suffix is specified, there must be at least one space between the number and suffix (for example, `readahead=8192 s`). .Set the `readahead` to 4MB unless already set to a higher value ==== ---- [disk] readahead=>4096 ---- ==== The disk readahead value can be multiplied by the constant specified by the [option]`readahead_multiply` option. csNtt|ƒj|i|¤Žgd¢|_gd¢|_t|jƒ|_d|_d|_t ƒ|_ dS)N) éþéáéÃé¥é‘é}éiéUéFé7éé) réúéæéÒé¾éªé–é‚énéZré<ég{®Gáz„?) ÚsuperrÚ__init__Ú _power_levelsÚ_spindown_levelsÚlenÚ_levelsÚ _level_stepsÚ_load_smallestrÚ_cmd)ÚselfÚargsÚkwargs©Ú __class__©ú=/usr/lib/python3.9/site-packages/tuned/plugins/plugin_disk.pyrUs   zDiskPlugin.__init__cs`tt|ƒ ¡d|_d|_tƒ|_tƒ|_|j   d¡D]}|  |¡r6|j  |j ¡q6tƒ|_dS)NTÚblock)rrÚ _init_devicesZ_devices_supportedÚ _use_hdparmÚsetZ _free_devicesÚdictÚ_hdparm_apm_device_supportÚ_hardware_inventoryZ get_devicesÚ_device_is_supportedÚaddZsys_nameZ_assigned_devices©r'Údevicer*r,r-r/_s zDiskPlugin._init_devicescs‡fdd„|DƒS)Ncsg|]}ˆj d|¡‘qS)r.)r4Z get_device)Ú.0Úx©r'r,r-Ú kóz2DiskPlugin._get_device_objects..r,)r'Zdevicesr,r;r-Ú_get_device_objectsjszDiskPlugin._get_device_objectscCsÈ|js dS||jvr|j|S|jjddd|gtjgdd\}}}|tj krdt d¡d|_dS|r–t d|¡t  d ||f¡d|j|<dSd |vrºt d |¡d|j|<dSd|j|<dS) NFÚhdparmú-Cú/dev/%sT)Ú no_errorsZ return_errz4hdparm command not found, ignoring for other devicesz#Device '%s' not supported by hdparmz(rc: %s, msg: '%s')Úunknownz3Driver for device '%s' does not support apm command) r0r3r&ÚexecuteÚerrnoÚENOENTÚlogÚwarningÚinfoÚdebug)r'r8ÚrcÚoutÚerr_msgr,r,r-Ú_is_hdparm_apm_supportedms,  ÿ      z#DiskPlugin._is_hdparm_apm_supportedcCs2|jdko0|j dd¡dko0|jdup0|jjdvS)NÚdiskZ removableó0)ZscsiZvirtioZxenZnvmeZmmc)Z device_typeZ attributesÚgetÚparentZ subsystem)Úclsr8r,r,r-r5„s  ÿ  ýzDiskPlugin._device_is_supportedcCs|j |d|j¡dS)Nr.)r4Z subscribeÚ_hardware_events_callbackr;r,r,r-Ú_hardware_events_initŒsz DiskPlugin._hardware_events_initcCs|j |¡dS©N)r4Z unsubscriber;r,r,r-Ú_hardware_events_cleanupsz#DiskPlugin._hardware_events_cleanupcs(| |¡s|dkr$tt|ƒ ||¡dS)NÚremove)r5rrrT)r'Zeventr8r*r,r-rT’sz$DiskPlugin._hardware_events_callbackcs,|jdur|j |¡tt|ƒ ||¡dSrV)Ú _load_monitorZ add_devicerrÚ_added_device_apply_tuning©r'ÚinstanceÚ device_namer*r,r-rZ–s  z%DiskPlugin._added_device_apply_tuningcs,|jdur|j |¡tt|ƒ ||¡dSrV)rYZ remove_devicerrÚ_removed_device_unapply_tuningr[r*r,r-r^›s  z)DiskPlugin._removed_device_unapply_tuningcCsddddddddœS)NT)ÚdynamicÚelevatorÚapmÚspindownÚ readaheadÚreadahead_multiplyÚscheduler_quantumr,©rSr,r,r-Ú_get_config_options sùzDiskPlugin._get_config_optionscCsddgS)Nrarbr,rfr,r,r-Ú#_get_config_options_used_by_dynamic¬sþz.DiskPlugin._get_config_options_used_by_dynamiccCs.d|_d|_d|_d|_| |jd¡|_dS)NTrr_)Z_has_static_tuningÚ _apm_errcntÚ_spindown_errcntrYZ _option_boolÚoptionsZ_has_dynamic_tuning©r'r\r,r,r-Ú_instance_init³s zDiskPlugin._instance_initcCs"|jdur|j |j¡d|_dSrV)rYÚ_monitors_repositoryÚdeleterlr,r,r-Ú_instance_cleanup¼s zDiskPlugin._instance_cleanupcs>tt|ƒ |¡i|_i|_i|_i|_|j d|j ¡|_ dS)NrO) rrÚ_instance_init_dynamicZ _device_idleÚ_statsÚ_idleÚ_spindown_change_delayedrnZcreateZassigned_devicesrYrlr*r,r-rqÁsÿz!DiskPlugin._instance_init_dynamiccCs˜|rd}|j}n d}|j}|tjkr(dS|dkr6d}nL|tj krbtjd|_|_t d¡dS|d7}|tjkr‚t d|¡|rŽ||_n||_dS)NrbrarrzIhdparm command not found, ignoring future set_apm / set_spindown commandsz5disabling set_%s command: too many consecutive errors) rjriÚconstsÚERROR_THRESHOLDrErFrGrHrI)r'rKrbÚsZcntr,r,r-Ú_update_errcntÊs&    zDiskPlugin._update_errcntcCsNt d|¡|jjdd|d|gtjgd\}}| |d¡d|j|<dS)Nzchanging spindown to %dr?z-S%drA©rBTF)rGrJr&rDrErFrxrt)r'r\r8Únew_spindown_levelrKrLr,r,r-Ú_change_spindownâs& zDiskPlugin._change_spindowncCs2|jjddd|gtjgd\}}d|vo0d|vS)Nr?r@rAryZstandbyZsleeping)r&rDrErF)r'r8rKrLr,r,r-Ú_drive_spinningès"zDiskPlugin._drive_spinningc Cs&| |¡sdS|j |¡}|dur&dS||jvr<| ||¡| |||¡| ||¡|j|}|j|}|dd|jkrž|d|j krž|d|j kržd}n.|ddkrÈ|ddksÂ|ddkrÈd}nd}|dkr°|d|7<|j |d}|j |d}t   d|d¡|jtjkr`| |¡sR|dkrRt   d|¡d |j|<n| |||¡|jtjkrät   d |¡|jjd d |d |gtjgd\} } | | d¡n4|j|rä| |¡rä|j |d}| |||¡t   d||d|df¡t   d||d|d|df¡dS)NÚlevelrÚreadÚwriteréÿÿÿÿztuning level changed to %dz;delaying spindown change to %d, drive has already spun downTzchanging APM_level to %dr?z-B%drAryFz %s load: read %0.2f, write %0.2fz$%s idle: read %d, write %d, level %d)rNrYZget_device_loadrrÚ_init_stats_and_idleÚ _update_statsÚ _update_idlersr#r$r r!rGrJrjrurvr|rtr{rir&rDrErFrx) r'r\r8ÚloadZstatsZidleZ level_changeZnew_power_levelrzrKrLr,r,r-Ú_instance_update_dynamicìsF       .$  &z#DiskPlugin._instance_update_dynamiccCsDddgddgddgdœ|j|<ddddœ|j|<d|j|<dS)Né rr)ÚnewÚoldÚmax)r}r~rF)rrrsrt©r'r\r8r,r,r-rs$zDiskPlugin._init_stats_and_idlecCsÄ|j|d|j|d<}||j|d<dd„t||ƒDƒ}||j|d<|j|d}dd„t||ƒDƒ}||j|d<t|dƒt|dƒ|j|d <t|d ƒt|d ƒ|j|d <dS) Nr‡rˆcSsg|]}|d|d‘qS)rrr,)r9Znew_oldr,r,r-r<(r=z,DiskPlugin._update_stats..Údiffr‰cSsg|] }t|ƒ‘qSr,)r‰)r9Zpairr,r,r-r<-r=rr~ér)rrÚzipÚfloat)r'r\r8Znew_loadZold_loadr‹Z old_max_loadZmax_loadr,r,r-r‚#s"zDiskPlugin._update_statscCsHdD]>}|j|||jkr4|j||d7<qd|j||<qdS)N)r~rrr)rrr%rs)r'r\r8Z operationr,r,r-rƒ4szDiskPlugin._update_idlecs0| |¡st d|¡ntt|ƒ ||¡dS)Nzt d |tj ¡}|r¦zt |  d ¡ƒ}Wnt y¤d}Yn0|r¸t  d |¡|S) Nr©Fr?rªr«ryrTz .*=\s*(\d+).*rz2could not get current APM settings for device '%s')rNrGrIr&rDrErFÚreÚmatchÚSÚintÚgroupÚ ValueErrorÚerror) r'r8r\r§r¢ÚerrrKrLÚmr,r,r-Ú_get_apmqs( "   zDiskPlugin._get_apmrbcCs|| |¡s(|s t d|¡dSt|ƒS|jtjkrt|sl|jjddt|ƒd|gt j gd\}}|  |d¡t|ƒSdSdS)Nú0spindown option is not supported for device '%s'r?z-Sr«ryT) rNrGrIr¬rjrurvr&rDrErFrxr­r,r,r-Ú _set_spindown‰s  ( zDiskPlugin._set_spindowncCs$| |¡s |st d|¡dSdS)Nr¹éý)rNrGrI)r'r8r\r§r,r,r-Ú _get_spindown™s  zDiskPlugin._get_spindowncCs | |d¡S)Nzqueue/read_ahead_kbrr7r,r,r-Ú_readahead_file¢szDiskPlugin._readahead_filecCs^t|ƒ dd¡}zt|dƒ}Wnty4YdS0t|ƒdkrZ|dddkrZ|d}|S)Nrrrwé)r¬Úsplitr²r´r")r'r¢ÚvalÚvr,r,r-Ú _parse_ra¥s zDiskPlugin._parse_rarccCsZ| |¡}| |¡}|dur0t d||f¡n&|sV|jj|d||rNtjgndd|S)Nz,Invalid readahead value '%s' for device '%s'ú%dFrŸ)r½rÂrGrµr&r rErF)r'r¢r8r\r£rXr¤rÀr,r,r-Ú_set_readahead°s  ÿzDiskPlugin._set_readaheadcCs6| |¡}|jj||d ¡}t|ƒdkr.dSt|ƒS)NrŸr)r½r&r¦Ústripr"r²©r'r8r\r§r¤r¢r,r,r-Ú_get_readahead¼s   zDiskPlugin._get_readaheadrdc Csž|rdS|jd|d}|rd| ||¡}|dur2dStt|ƒ|ƒ} |j ||¡| | ||dd¡n6|j |¡}|dur|dS| |||dd¡|j |¡dS)Nrd)Z command_namer]F) Z _storage_keyrÇr²rŽZ_storager1rÄrQZunset) r'ZenablingZ multiplierr8Zverifyr§r\Z storage_keyZ old_readaheadZ new_readaheadr,r,r-Ú_multiply_readaheadÄs$þ  zDiskPlugin._multiply_readaheadcCs | |d¡S)Nzqueue/iosched/quantumrr7r,r,r-Ú_scheduler_quantum_fileÙsz"DiskPlugin._scheduler_quantum_filerecCs8| |¡}|s4|jj|dt|ƒ|r,tjgndd|S)NrÃFrŸ)rÉr&r r²rErFr¡r,r,r-Ú_set_scheduler_quantumÜs  ÿz!DiskPlugin._set_scheduler_quantumcCsH| |¡}|jj||d ¡}t|ƒdkr@|sdisk_scheduler_quantum option is not supported for device '%s')rÉr&r¦rÅr"rGrIr²rÆr,r,r-Ú_get_scheduler_quantumäs  z!DiskPlugin._get_scheduler_quantum)r‘)F)F)F)F)F)1Ú__name__Ú __module__Ú __qualname__Ú__doc__rr/r>rNÚ classmethodr5rUrWrTrZr^rgrhrmrprqrxr{r|r…rr‚rƒrrrœržZ command_setr¥Z command_getr¨r®r¸rºr¼r½rÂrÄrÇZcommand_customrÈrÉrÊrËÚ __classcell__r,r,r*r-r snH         2                  r)rEÚrZ decoratorsZ tuned.logsZtunedZ tuned.constsruZtuned.utils.commandsrr”r¯ZlogsrQrGZPluginrr,r,r,r-Ús