Otimizando um sistema de arquivos Linux com as ferramentas mklibs e prelink

- por Sergio Prado

Categorias: Yocto Project Tags: ,

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

Faça um Comentário

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.