o
    •Û_k7  ã                   @   sx   d dl mZ d dlT ddlZd dl mZ ddlmZ ddlm	Z	 ddl
Z
ddlZddlZej ¡ ZG dd„ dejƒZdS )	é   )Úbase)Ú*é    N)Ú
exceptions)Úcommandsc                       sP  e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zedd	„ ƒZd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdGdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zed1ƒd2d3„ ƒZed4ƒd5d6„ ƒZed7ƒd8d9„ ƒZed:dd;d<d=d>„ ƒZ ed?dd;d<d@dA„ ƒZ!edBdd;d<dCdD„ ƒZ"dEdF„ Z#‡  Z$S )HÚBootloaderPluginzÁ
	Plugin for tuning bootloader options.

	Currently only grub2 is supported and reboot is required to apply the tunings.
	These tunings are unloaded only on profile change followed by reboot.
	c                    s:   t j tj¡st d¡‚tt| ƒj	|i |¤Ž t
ƒ | _d S )Nz4Required GRUB2 template not found, disabling plugin.)ÚosÚpathÚisfileÚconstsÚGRUB2_TUNED_TEMPLATE_PATHr   ÚNotSupportedPluginExceptionÚsuperr   Ú__init__r   Ú_cmd)ÚselfÚargsÚkwargs©Ú	__class__© úA/usr/lib/python3/dist-packages/tuned/plugins/plugin_bootloader.pyr      s   
zBootloaderPlugin.__init__c                 C   sB   d|_ d|_d| _d| _d | _d| _d| _|  ¡ | _|  	¡ | _
d S )NFTÚ )Ú_has_dynamic_tuningÚ_has_static_tuningÚupdate_grub2_cfgÚ_initrd_remove_dirÚ_initrd_dst_img_valÚ_cmdline_valÚ_initrd_valÚ_get_grub2_cfg_filesÚ_grub2_cfg_file_namesÚ_bls_enabledÚ_bls©r   Úinstancer   r   r   Ú_instance_init   s   
zBootloaderPlugin._instance_initc                 C   s   d S ©Nr   r$   r   r   r   Ú_instance_cleanup(   s   z"BootloaderPlugin._instance_cleanupc                 C   s   d d d d d d dœS )N)Úgrub2_cfg_fileÚinitrd_dst_imgÚinitrd_add_imgÚinitrd_add_dirÚinitrd_remove_dirÚcmdliner   )Úclsr   r   r   Ú_get_config_options+   s   úz$BootloaderPlugin._get_config_optionsc                 C   s&  |   ¡  ¡ }g }|D ]%}t|ƒ d¡r| |¡ q
||v r$|| ||< q
t d|| jjf ¡ q
d}|D ]P}|| }|du sB|dkrCq4|d }|dd…  	¡ }|dkr^|dkr^|d| 7 }q4|d	kr~|dkr~| 
¡ D ]}	t |	¡}
t d
|
 d d|¡}qjq4|d| 7 }q4| 	¡ }|dkr‘||d< |S )zSMerge provided options with plugin default options and merge all cmdline.* options.r.   z$Unknown option '%s' for plugin '%s'.r   Nr   r   ú+ú ú-z(\A|\s)z	(?=\Z|\s))r0   ÚcopyÚstrÚ
startswithÚappendÚlogÚwarnr   Ú__name__ÚstripÚsplitÚreÚescapeÚsub)r   ÚoptionsÚ	effectiveÚcmdline_keysÚkeyr.   ÚvalÚopÚvalsÚpÚregexr   r   r   Ú_get_effective_options6   s6   
þz'BootloaderPlugin._get_effective_optionsc                 C   s*   g }t jD ]}tj |¡r| |¡ q|S r'   )r   ÚGRUB2_CFG_FILESr   r	   Úexistsr7   )r   Ú	cfg_filesÚfr   r   r   r    U   s   

€z%BootloaderPlugin._get_grub2_cfg_filesc                 C   sD   | j  tj¡}t|ƒdkrt dtj ¡ dS tjd|tj	dd uS )Nr   úcannot read '%s'Fz=^\s*GRUB_ENABLE_BLSCFG\s*=\s*\"?\s*[tT][rR][uU][eE]\s*\"?\s*$©Úflags)
r   Ú	read_filer   ÚGRUB2_DEFAULT_ENV_FILEÚlenr8   Úinfor=   ÚsearchÚ	MULTILINE)r   Úgrub2_default_envr   r   r   r"   \   s   ÿÿzBootloaderPlugin._bls_enabledc                 C   s   | j  tj|¡S r'   )r   Úadd_modify_option_in_filer   ÚBOOT_CMDLINE_FILE)r   Údr   r   r   Ú_patch_bootcmdlinee   s   z#BootloaderPlugin._patch_bootcmdlinec                 C   sŒ   |   tjdtjdi¡ | jst d¡ d S | jD ]}| jj|dtj	 ddtj
 didd q| jd urDt d| j ¡ | j | j¡ d S d S )Nr   úcannot find grub.cfg to patchzset\s+F)Úaddzremoving initrd image '%s')r[   r   ÚBOOT_CMDLINE_TUNED_VARÚBOOT_CMDLINE_INITRD_ADD_VARr!   r8   rT   r   rX   ÚGRUB2_TUNED_VARÚGRUB2_TUNED_INITRD_VARr   Úunlink)r   rM   r   r   r   Ú_remove_grub2_tuningh   s   

(
þz%BootloaderPlugin._remove_grub2_tuningFc                 C   s.   |rt  d¡ |  ¡  |  dddœ¡ d S d S )Nz/removing grub2 tuning previously added by Tunedr   ©Útuned_paramsÚtuned_initrd)r8   rT   rc   Ú_update_grubenv)r   r%   Úfull_rollbackr   r   r   Ú_instance_unapply_statics   s
   
ýz)BootloaderPlugin._instance_unapply_staticc                 C   s®   t  d¡ tjdtj d d|tjd}tjdtj d|tjd}tjdtj d d|tjd}tjdtj d|tjd}tjtjd d|tjd}tjtj	d d|tjdS )	Nzunpatching grub.cfgz
^\s*set\s+z\s*=.*
r   rO   z *\$ú\nz\n+)
r8   Údebugr=   r?   r   r`   rV   ra   ÚGRUB2_TEMPLATE_HEADER_BEGINÚGRUB2_TEMPLATE_HEADER_END)r   Ú	grub2_cfgÚcfgr   r   r   Ú_grub2_cfg_unpatchy   s   
z#BootloaderPlugin._grub2_cfg_unpatchc                 C   sô   t  d¡ dtj d }|D ]}|d| j |¡ d | j || ¡ d 7 }q|tjd 7 }tjd||tj	d	}tj
tjd
œ}|D ]6}tjd| d d||  |tj	d	}tjd| d ||  d d|tj	d	}tjd| d d|tj	d	}qA|S )Nzinitial patching of grub.cfgz\1\n\nÚ
zset z="ú"
rj   z+^(\s*###\s+END\s+[^#]+/00_header\s+### *)\nrO   )ÚlinuxÚinitrdz^(\s*z(16|efi)?\s+.*)$z\1 $z(?:16|efi)?\s+\S+rescue.*)\$z *(.*)$z\1\2z(?:16|efi)?\s+\S+rescue.*) +$ú\1)r8   rk   r   rl   r   r>   rm   r=   r?   rV   r`   ra   )r   rn   rZ   ÚsÚoptÚd2Úir   r   r   Ú_grub2_cfg_patch_initial‚   s   
.$(z)BootloaderPlugin._grub2_cfg_patch_initialc                 C   sÜ   | j  tj¡}t|ƒdkrt dtj ¡ dS tjtjdœ}d}|D ]7}t	j
d| d ||  d |t	jdd u rYd	}|d
 dkrE|d7 }||d | d | d ||  d 7 }q"|rlt dtj ¡ | j  tj|¡ d	S )Nr   rN   F)ÚGRUB_CMDLINE_LINUX_DEFAULTÚGRUB_INITRD_OVERLAYz^[^#]*\bz
\s*=.*\\\$z\b.*$rO   Téÿÿÿÿrq   z="${z:+$z }\$rr   zpatching '%s')r   rQ   r   rR   rS   r8   rT   r`   ra   r=   rU   rV   rk   Úwrite_to_file)r   rW   rZ   Úwritery   r   r   r   Ú_grub2_default_env_patch”   s"   *(€z)BootloaderPlugin._grub2_default_env_patchc                 C   s¬   | j  tj¡}t|ƒdkrt dtj ¡ dS d}tjdtj	 d |tj
drBd}tjdtj	 d d	|tj
d}|d
 dkrB|d7 }|rTt dtj ¡ | j  tj|¡ dS )Nr   rN   Fzb^GRUB_CMDLINE_LINUX_DEFAULT=\"\$\{GRUB_CMDLINE_LINUX_DEFAULT:\+\$GRUB_CMDLINE_LINUX_DEFAULT \}\\\$z"$rO   Tz"$
r   r}   rq   zunpatching '%s')r   rQ   r   rR   rS   r8   rT   r=   rU   r`   rV   r?   rk   r~   )r   rW   r   ro   r   r   r   Ú_grub2_default_env_unpatch§   s4   ÿÿÿÿÿÿz+BootloaderPlugin._grub2_default_env_unpatchc                 C   sB  t  d¡ | jst  d¡ dS | jD ]}| j |¡}t|ƒdkr(t  d| ¡ qt  d| ¡ |}d}|D ]+}tjd| d d	||  d
 |tj	d\}}|dk s^tj
d| |tj	dd u r`d}q5ttjdtj |tj	dƒttjdtj |tj	dƒkrd}|rŠ|  |  |¡|¡}| j ||¡ q| jr›|  ¡  dS |  ¡  dS )Nzpatching grub.cfgr\   Fr   zcannot patch %sz+adding boot command line parameters to '%s'z	\b(set\s+z\s*=).*$z\1"ú"rO   r   z\$T)r8   rk   r!   rT   r   rQ   rS   r=   ÚsubnrV   rU   Úfindallr   r`   ra   rz   rp   r~   r#   r   r€   )r   rZ   rM   rn   Úgrub2_cfg_newÚpatch_initialrw   Únsubsr   r   r   Ú_grub2_cfg_patchº   s:   


,"€ÿÿz!BootloaderPlugin._grub2_cfg_patchc                 C   s8   |   tj| jtj| ji¡ |  tj| jtj| ji¡ d S r'   )	rˆ   r   r`   r   ra   r   r[   r^   r_   ©r   r   r   r   Ú_grub2_updateÚ   s   zBootloaderPlugin._grub2_updatec                 C   ó   t j tj¡S r'   )r   r	   rK   r   ÚBLS_ENTRIES_PATHr‰   r   r   r   Ú_has_blsÞ   ó   zBootloaderPlugin._has_blsc                 C   sZ   t  dt|ƒ ¡ dd„ | ¡ D ƒ}| j g d¢| ¡\}}|dkr+t  d| ¡ dS dS )	Nzupdating grubenv, setting %sc                 S   s$   g | ]\}}d t |ƒt |ƒf ‘qS )z%s=%s)r5   )Ú.0ÚoptionÚvaluer   r   r   Ú
<listcomp>ã   s   $ z4BootloaderPlugin._update_grubenv.<locals>.<listcomp>)zgrub2-editenvr3   Úsetr   zcannot update grubenv: '%s'FT)r8   rk   r5   Úitemsr   Úexecuter9   )r   rZ   ÚlÚrcÚoutr   r   r   rg   á   s   z BootloaderPlugin._update_grubenvc                 C   sb   | j  ¡ }|dkrdS t dtj ¡ | j jtjdgd|id\}}|dkr/t d| ¡ dS d	S )
Nr   Fz4running kernel update hook '%s' to patch BLS entriesr]   ÚKERNEL_INSTALL_MACHINE_ID)Úenvr   zcannot patch BLS entries: '%s'T)r   Úget_machine_idr8   rk   r   ÚKERNEL_UPDATE_HOOK_FILEr•   r9   )r   Ú
machine_idr—   r˜   r   r   r   Ú_bls_entries_patch_initialê   s   
z+BootloaderPlugin._bls_entries_patch_initialc                 C   s6   t  d¡ |  ¡ r|  | j| jdœ¡r|  ¡ rdS dS )Nzupdating BLSrd   TF)r8   rk   r   rg   r   r   rž   r‰   r   r   r   Ú_bls_updateõ   s   
ÿþzBootloaderPlugin._bls_updatec                 C   s,   | j d u rtj tjtj |¡¡| _ d S d S r'   )r   r   r	   Újoinr   ÚBOOT_DIRÚbasename)r   Únamer   r   r   Ú_init_initrd_dst_imgý   s   
ÿz%BootloaderPlugin._init_initrd_dst_imgc                 C   r‹   r'   )r   r	   Úisdirr   ÚPETITBOOT_DETECT_DIRr‰   r   r   r   Ú_check_petitboot  rŽ   z!BootloaderPlugin._check_petitbootc                 C   sœ   |   ¡ r	t d¡ t d| j ¡ tj | j¡}| j 	|| j¡s"dS d| _
| j d¡ ¡ }d}t|ƒ}|rDt dd|¡}t|ƒ|k rD|}tj ||¡| _dS )	NzkDetected Petitboot which doesn't support initrd overlays. The initrd overlay will be ignored by bootloader.zinstalling initrd image as '%s'FTú/proc/cmdlineú/z^\s*BOOT_IMAGE=\s*(\S*/).*$ru   )r§   r8   r9   rT   r   r   r	   r¢   r   r4   r   rQ   ÚrstriprS   r=   r?   r    r   )r   ÚimgÚimg_nameÚcurr_cmdlineÚinitrd_grubpathÚlcr	   r   r   r   Ú_install_initrd  s    
z BootloaderPlugin._install_initrdr)   c                 C   s,   |rd S |r|d urt |ƒg| _d S d S d S r'   )r5   r!   ©r   Úenablingr‘   ÚverifyÚignore_missingr   r   r   Ú_grub2_cfg_file  s
   ÿz BootloaderPlugin._grub2_cfg_filer*   c                 C   s^   |rd S |r)|d ur+t |ƒ| _| jdkrdS | jd dkr-tj tj| j¡| _d S d S d S d S )Nr   Fr   r©   )r5   r   r   r	   r    r   r¡   r±   r   r   r   Ú_initrd_dst_img  s   

ûz BootloaderPlugin._initrd_dst_imgr-   c                 C   s2   |rd S |r|d ur| j  |¡dk| _d S d S d S )NÚ1)r   Úget_boolr   r±   r   r   r   r   *  s
   ÿz#BootloaderPlugin._initrd_remove_dirr+   é
   )Ú
per_deviceÚpriorityc                 C   sL   |rd S |r |d ur"t |ƒ}|  |¡ |dkrdS |  |¡s$dS d S d S d S )Nr   F)r5   r¤   r°   )r   r²   r‘   r³   r´   Úsrc_imgr   r   r   Ú_initrd_add_img2  s   

úz BootloaderPlugin._initrd_add_imgr,   c           
      C   s  |rd S |rˆ|d urŠt |ƒ}|  |¡ |dkrdS tj |¡s(t d| ¡ dS t d| ¡ tj	ddd\}}t 
d| ¡ t |¡ | jjd	| |d
d\}}	t 
d|	 ¡ |dkrkt d¡ | jj|d
d dS |  |¡ | j |¡ | jrŒt d| ¡ | j |¡ d S d S d S d S )Nr   FzFerror: cannot create initrd image, source directory '%s' doesn't existz+generating initrd image from directory '%s'ztuned-bootloader-z.tmp)ÚprefixÚsuffixz+writing initrd image to temporary file '%s'zfind . | cpio -co > %sT)ÚcwdÚshellzcpio log: %sr   zerror generating initrd image)Úno_errorzremoving directory '%s')r5   r¤   r   r	   r¥   r8   ÚerrorrT   ÚtempfileÚmkstemprk   Úcloser   r•   rb   r°   r   Úrmtree)
r   r²   r‘   r³   r´   Úsrc_dirÚfdÚtmpfiler—   r˜   r   r   r   Ú_initrd_add_dir?  s6   



éz BootloaderPlugin._initrd_add_dirr.   c           
      C   sÊ   | j  | j |¡¡}|rN| j d¡}t|ƒdkrd S t| ¡ ƒ}t| ¡ ƒ}| |¡}	|	|kr=t	 
tjdt|ƒf ¡ dS t	 tjdt|	ƒt|ƒf ¡ dS |ra|d urct	 
d¡ d| _|| _d S d S d S )Nr¨   r   r.   TFz;installing additional boot command line parameters to grub2)Ú
_variablesÚexpandr   ÚunquoterQ   rS   r“   r<   Úintersectionr8   rT   r   ÚSTR_VERIFY_PROFILE_VALUE_OKr5   rÃ   ÚSTR_VERIFY_PROFILE_VALUE_FAILr   r   )
r   r²   r‘   r³   r´   Úvr.   Úcmdline_setÚ	value_setÚcmdline_intersectr   r   r   Ú_cmdline]  s$   


ýzBootloaderPlugin._cmdlinec                 C   s,   |r| j r|  ¡  |  ¡  d| _ d S d S d S )NF)r   rŠ   rŸ   )r   r%   r²   r   r   r   Ú_instance_post_staticr  s
   

ýz&BootloaderPlugin._instance_post_static)F)%r:   Ú
__module__Ú__qualname__Ú__doc__r   r&   r(   Úclassmethodr0   rI   r    r"   r[   rc   ri   rp   rz   r€   r   rˆ   rŠ   r   rg   rž   rŸ   r¤   r§   r°   Úcommand_customrµ   r¶   r   r½   rË   rÖ   r×   Ú__classcell__r   r   r   r   r      sN    

	
	 	





r   )r   r   Ú
decoratorsÚ
tuned.logsÚtunedr   Útuned.utils.commandsr   Útuned.constsr   r   r=   rÄ   ÚlogsÚgetr8   ÚPluginr   r   r   r   r   Ú<module>   s    
