Otimizando um sistema de arquivos Linux com as ferramentas mklibs e prelink
- por Sergio Prado
O Poky, sistema de build do Yocto Project, utiliza as ferramentas mklibs e prelink para otimizar o rootfs gerado no processamento de uma receita de imagem.
Esta otimização é habilitada por padrão ao herdar as classes image-mklibs e image-prelink no local.conf:
USER_CLASSES ?= "buildstats image-mklibs image-prelink" |
O mklibs é uma ferramenta capaz de identificar as bibliotecas mínimas necessárias para executar determinado binário.
Com esta ferramenta, é possível remover do rootfs as bibliotecas dinâminas (*.so) não utilizadas pelo sistema.
O Poky faz isso através da função mklibs_optimize_image_doit(), implementada na classe image-mklibs da camada OpenEmbedded-Core:
mklibs_optimize_image_doit() { rm -rf ${WORKDIR}/mklibs mkdir -p ${WORKDIR}/mklibs/dest cd ${IMAGE_ROOTFS} du -bs > ${WORKDIR}/mklibs/du.before.mklibs.txt for i in `find .`; do file $i; done \ | grep ELF \ | grep "LSB *executable" \ | grep "dynamically linked" \ | sed "s/:.*//" \ | sed "s+^\./++" \ > ${WORKDIR}/mklibs/executables.list case ${TARGET_ARCH} in powerpc | mips | microblaze ) dynamic_loader="${base_libdir}/ld.so.1" ;; powerpc64) dynamic_loader="${base_libdir}/ld64.so.1" ;; x86_64) dynamic_loader="${base_libdir}/ld-linux-x86-64.so.2" ;; i586 ) dynamic_loader="${base_libdir}/ld-linux.so.2" ;; arm ) dynamic_loader="${base_libdir}/ld-linux.so.3" ;; * ) dynamic_loader="/unknown_dynamic_linker" ;; esac mklibs -v \ --ldlib ${dynamic_loader} \ --libdir ${baselib} \ --sysroot ${PKG_CONFIG_SYSROOT_DIR} \ --gcc-options "--sysroot=${PKG_CONFIG_SYSROOT_DIR}" \ --root ${IMAGE_ROOTFS} \ --target `echo ${TARGET_PREFIX} | sed 's/-$//' ` \ -d ${WORKDIR}/mklibs/dest \ `cat ${WORKDIR}/mklibs/executables.list` cd ${WORKDIR}/mklibs/dest for i in * do cp $i `find ${IMAGE_ROOTFS} -name $i` done cd ${IMAGE_ROOTFS} du -bs > ${WORKDIR}/mklibs/du.after.mklibs.txt echo rootfs size before mklibs optimization: `cat ${WORKDIR}/mklibs/du.before.mklibs.txt` echo rootfs size after mklibs optimization: `cat ${WORKDIR}/mklibs/du.after.mklibs.txt` } |
Mais informações na página de manual do mklibs.
Já a ferramenta prelink é capaz de otimizar (diminuir) o tempo de carga de bibliotecas linkadas dinamicamente ao executar determinado binário.
Durante a geração do rootfs, o Poky utiliza esta ferramenta para otimizar os binários do rootfs.
Esta funcionalidade está implementada na função prelink_image() da classe image-prelink, disponível na camada OpenEmbedded-Core:
prelink_image () { # export PSEUDO_DEBUG=4 # /bin/env | /bin/grep PSEUDO # echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" # echo "LD_PRELOAD=$LD_PRELOAD" pre_prelink_size=`du -ks ${IMAGE_ROOTFS} | awk '{size = $1 ; print size }'` echo "Size before prelinking $pre_prelink_size." # We need a prelink conf on the filesystem, add one if it's missing if [ ! -e ${IMAGE_ROOTFS}${sysconfdir}/prelink.conf ]; then cp ${STAGING_DIR_NATIVE}${sysconfdir_native}/prelink.conf \ ${IMAGE_ROOTFS}${sysconfdir}/prelink.conf dummy_prelink_conf=true; else dummy_prelink_conf=false; fi # prelink! ${STAGING_DIR_NATIVE}${sbindir_native}/prelink --root ${IMAGE_ROOTFS} -amR -N -c ${sysconfdir}/prelink.conf # Remove the prelink.conf if we had to add it. if [ "$dummy_prelink_conf" = "true" ]; then rm -f ${IMAGE_ROOTFS}${sysconfdir}/prelink.conf fi pre_prelink_size=`du -ks ${IMAGE_ROOTFS} | awk '{size = $1 ; print size }'` echo "Size after prelinking $pre_prelink_size." } |
Mais informações na página de manual do prelink.
Como estas ferramentas são genéricas, podemos aplicar os mesmos conceitos em um rootfs gerado manualmente ou por outras ferramentas de build.
Have fun!
Sergio Prado