Vous voulez améliorer la vitesse d'exécution de pacman, le gestionnaire de paquet d'Archlinux ? Vous ne comprenez pas pourquoi pacman est si lent ?
Allez : hop, hop, hop, améliorons tout ça.
La base de donnée de pacman repose sur l'utilisation de petits fichiers. Il a été conçu comme ça et est de reste extrêmement puissant pour les tâches auquel il est destiné.
Ces fichiers se fragmentent rapidement et entraîne le ralentissement de pacman, au point d'attendre 30 secondes pour obtenir le résultat d'une recherche faîte à l'aide d'un pacman -Ss. C'est anormal. Voyons comment y remédier.
Étant donné que pacman utilise un nombre important de petits fichiers, il est préférable d'utiliser une partition de type reiserfs, du moins pour la partition qui accueillera la base de donnée de pacman ( qui se trouve dans /var/lib/pacman ). Le format reiserfs gère en effet mieux les petits fichiers, en évitant que ceux-ci fragmentent le disque, ce qui rend la lecture plus lente.
Reiserfs est offert lors de l'installation d'Arch Linux. Sinon, il est possible de formater une partition en reiserfs en suivant ces 2 étapes :
$ mkreiserfs /dev/sda4
Attention! : Le formatage d'une partition détruira l'ensemble des fichiers qui s'y trouvent, assurez-vous de faire vos sauvegardes avant et de bien désigner la bonne partition.
pacman-optimize est un petit script bash inclus avec pacman depuis la version 3.0 . Celui-ci tente de relocaliser l'ensemble des petits fichiers de la base de donnée de pacman sur une section continue du disque dur, ce qui diminue les déplacements de la tête de lecture du disque et réduit donc le temps de lecture.
Pour utiliser la commande, il suffit de la lancer directement :
$ pacman-optimize
Il peut être pratique de lancer pacman-optimize de façon périodique, par exemple tous les mois. Pour ce faire, vous pouvez créer un lien vers /usr/bin/pacman-optimize dans /etc/cron.monthly/
$ ln -s /usr/bin/pacman-optimize /etc/cron.monthly/
Assurez-vous que le service cron est activé sur votre système. Le service 'cron' doit être ajouté à la liste DAEMONS= du fichier /etc/rc.conf s'il n'y figure pas déjà.
Note : pacman sera bien sûr indisponible pendant que pacman-optimize tournera.
yaourt -B
pacman-cage a été écrit par ody. Ce programme publié depuis longtemps sur le forum anglais permet d'accélérer incroyablement le fonctionnement de pacman (et donc de yaourt, qui utilise pacman).
Vous trouverez une version améliorée sur le dépôt [archlinuxfr] à ajouter à la fin de pacman.conf :
[archlinuxfr] Server = http://repo.archlinux.fr/i686
ou
[archlinuxfr] Server = http://repo.archlinux.fr/x86_64
selon votre architecture.
Utilisation:
modprobe loop
A ne faire qu'une fois, pour le prendre en compte sans redémarrer.
Vérifier ce point avant de lancer pacman-cage.
Ajoutez 'pacmandb' à votre fichier /etc/rc.conf dans la liste des daemons (avant 'nvidia' si vous utilisez le paquet nvidia-driver pour kernel perso).
Les améliorations apportées à la version du dépôt [archlinuxfr] sont:
- vérification du support de loopback device dans le kernel
- utilisation d'un démon pour lancer au démarrage une vérification de l'intégrité de la base avant le montage du fichier loopback
- vérification de sécurité dans pacman-uncage
Pacman-drive est un script qui a été écrit par gandalf, un membre du forum anglais d'archlinux
Ce script se charge de sauvegarder la base de données de pacman de lui créer un espace réservé et enfin de l'y copier.
Cela permet de ne plus se préoccuper de la fragmentation
Le script peut-être récupéré sur le sujet du forum anglais, sur le dépôt archlinux.fr ou ci-dessous.
Il suffit de se connecter en tant que root, de copier le script récupérer dans le répertoire sbin (par exemple) # cp /home/user/pacman-drive /sbin/pacman-drive, de le rendre exécutable par la commande # chmod +x /sbin/pacman-drive, et enfin de l'exécuter : # /sbin/pacman-drive create.
Le script :
#!/bin/sh ### # This script will create a small drive for pacman usage # It will increase pacman speed around 60% # Copyright (C) 2006, Wael Nasreddine <wael@phoenixlinux.org> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ### # $Author: wael $ # $Revision: 348 $ # $Date: 2006-06-26 01:54:37 +0200 (Mon, 26 Jun 2006) $ . /etc/rc.conf . /etc/rc.d/functions . /etc/makepkg.conf myver='1.0' pacman_db="/var/lib/pacman" pacman_drive="/var/lib/pacman.img" pacman_backup="/root/pacman-database.tar.bz2" img_size=200 # In Mega-byte ### # Ripped from Phoenix pacman-functions ### plain() { local msg i for i in ${@}; do msg="${msg} ${i}" done if [ "$USE_COLOR" = "Y" -o "$USE_COLOR" = "y" ]; then echo -e " \033[1;1m${msg}\033[1;0m" >&2 else echo " ${msg}" >&2 fi } msg() { local msg i for i in ${@}; do msg="${msg} ${i}" done if [ "$USE_COLOR" = "Y" -o "$USE_COLOR" = "y" ]; then echo -e "\033[1;32m==>\033[1;0m \033[1;1m${msg}\033[1;0m" >&2 else echo "==> ${msg}" >&2 fi } warning() { local msg i for i in ${@}; do msg="${msg} ${i}" done if [ "$USE_COLOR" = "Y" -o "$USE_COLOR" = "y" ]; then echo -e "\033[1;33m==> WARNING:\033[1;0m \033[1;1m${msg}\033[1;0m" >&2 else echo "==> WARNING: ${msg}" >&2 fi } error() { local msg i for i in ${@}; do msg="${msg} ${i}" done if [ "$USE_COLOR" = "Y" -o "$USE_COLOR" = "y" ]; then echo -e "\033[1;31m==> ERROR:\033[1;0m \033[1;1m${msg}\033[1;0m" >&2 else echo "==> ERROR: ${msg}" >&2 fi } Pdie() { [[ ! -z $1 ]] && error $@ exit 2 } check_root() { if [ "$(id -u)" -ne 0 ]; then return 1 fi } ### # End alternate copyright ### die () { cleanup rm -f /tmp/pacman.lck if [ "${action}" = "delete" ]; then # If we were trying to delete the pacman-drive # we should mount back the database! mount -t ext2 -o loop "${pacman_drive}" "${pacman_db}" >/dev/null 2>&1 fi Pdie "$@" } usage () { echo "pacman-drive $myver" echo "usage: $0 <action>" echo "action can be:" echo " create create the pacman-drive and use it." echo " delete delete the pacman-drive and use the usual folder." echo "" echo "This script will create a small (200 Mb) image to use it as" echo "pacman database, the file will have an ext2 filesystem." } ### Generate md5sum of a directory and print it into a file # @param directory to get the md5 for # @param file to put the output in ## get_dir_md5() { [ -z "${1}" -o -z "${2}" ] && \ return 1 [ ! -d "${1}" -o -f "${2}" ] && \ return 1 find "${1}" -type f | sort | xargs md5sum > "${2}" 2>/dev/null || \ die "Error generating md5sum of ${1}" return 0 } prepare_drive() { if [ -f "${pacman_backup}" ]; then die "${pacman_backup} file already exists, please remove it first." else msg "backing up the pacman database." tar cjf "${pacman_backup}" "${pacman_db}" >/dev/null 2>&1 || \ die "Error creating the backup tarball." fi pacdrivetmp="$(mktemp -d /tmp/pacdrivetmp.XXXX)" paclibtmp="$(mktemp -d /tmp/paclibtmp.XXXX)" old_md5="$(mktemp /tmp/pac-db-old.XXXX)" new_md5="$(mktemp /tmp/pac-db-new.XXXX)" touch /tmp/pacman.lck } cleanup() { if grep -q "${pacdrivetmp}" /proc/mounts &>/dev/null; then umount "${pacdrivetmp}" >/dev/null 2>&1 fi rm -rf "${pacdrivetmp}" "${paclibtmp}" "${old_md5}" "${new_md5}" /tmp/pacman.lck } create_drive() { prepare_drive if [ -f "${pacman_drive}" ]; then die "${pacman_drive} already exist." fi msg "creating pacman.img loopback file..." dd if=/dev/zero of="${pacman_drive}" bs=1M count="${img_size}" > /dev/null 2>&1 || \ die "Error create the pacman image drive." yes | mkfs.ext2 -O dir_index -b 1024 -i 1024 -m 0 "${pacman_drive}" > /dev/null 2>&1 || \ die "Could not create image filesystem." msg "mounting pacman-drive to a temporary mount point." mount -t ext2 -o loop "${pacman_drive}" "${pacdrivetmp}" >/dev/null 2>&1 || \ die "Error mounting pacman drive to a temporary mount point." msg "Copying pacman database to the temporary mount point." cp -a "${pacman_db}/." "${pacdrivetmp}/" >/dev/null 2>&1 || \ die "Error copying the database." msg "Generating md5sum of the old and new database." get_dir_md5 "${pacman_db}" "${old_md5}" get_dir_md5 "${pacdrivetmp}" "${new_md5}" msg "Unmount the temporary mount point." umount "${pacdrivetmp}" || \ die "Error while unmounting the temporary mount point." msg "Comparing the old and new database." diff "${old_md5}" "${new_md5}" &>/dev/null if [ $? -ne 0 ]; then rm -f "${pacman_drive}" die "md5 of the old and new database does not match, Aborting..." fi # Ok now let's remove the old database folder, and finishing the task msg "removing the old database folder." rm -rf "${pacman_db}" # mounting the new db mkdir -p "${pacman_db}" mount -t ext2 -o loop "${pacman_drive}" "${pacman_db}" || \ die "Error mounting pacman-drive." # adding the loop device to fstab if ! grep -q "${pacman_drive}" /etc/fstab &>/dev/null; then msg "Adding loop device to fstab." echo "${pacman_drive} ${pacman_db} ext2 loop,defaults 0 0" >> /etc/fstab else warning "pacman-drive entry already exist in fstab. Skipping..." fi msg "Removing leftover files." cleanup msg "Done..." } delete_drive() { prepare_drive if [ ! -f "${pacman_drive}" ]; then die "${pacman_drive} does not exist, aborting..." fi msg "Unmounting pacman database." umount "${pacman_db}" >/dev/null 2>&1 || \ die "Error while unmounting the old database." msg "mounting pacman-drive to a temporary mount point." mount -t ext2 -o loop "${pacman_drive}" "${pacdrivetmp}" >/dev/null 2>&1 || \ die "Error mounting pacman drive to a temporary mount point." msg "Copying pacman-database to a new folder." cp -a "${pacdrivetmp}/." "${paclibtmp}/" >/dev/null 2>&1 || \ die "Error while copying pacman-database to a new folder." msg "Generating md5 of the old and new database." get_dir_md5 "${pacdrivetmp}" "${old_md5}" get_dir_md5 "${paclibtmp}" "${new_md5}" msg "Unmount the temporary mount point." umount "${pacdrivetmp}" || \ die "Error while unmounting the temporary mount point." msg "Comparing the old and new database." diff "${old_md5}" "${new_md5}" &>/dev/null if [ $? -ne 0 ]; then die "md5 of the old and new database does not match, Aborting..." fi # Ok everything checked let's continue msg "Unmounting pacman database (if mounted)" umount "${pacman_db}" >/dev/null 2>&1 msg "Removing the pacman-drive loopback file..." rm -rf "${pacman_db}" || \ die "Couldn't remove the old pacman database..." rm -f "${pacman_drive}" || \ die "Couldn't remove the pacman-drive loopback file..." msg "moving the new one to ${pacman_db}" mv "${paclibtmp}" "${pacman_db}" >/dev/null 2>&1 || \ die "Error while moving the new one to ${pacman_db}." # We don't need the lost+found folder rm -rf "${pacman_db}/lost+found" >/dev/null 2>&1 msg "Removing pacman-drive entry from fstab" sed -e "s@.*${pacman_drive}.*${pacman_db}.*@@g" -i /etc/fstab msg "Removing leftover files." cleanup msg "Done..." } # Sanity checks check_root || die "You must be root to run pacman-drive" # Check if kernel has BLK_DEV_LOOP support if [ -f /proc/config.gz ]; then unset temp temp="$(zcat /proc/config.gz | grep "BLK_DEV_LOOP")" if [ "${temp}" != "CONFIG_BLK_DEV_LOOP=y" -a "${temp}" != "CONFIG_BLK_DEV_LOOP=m" ]; then error "Your kernel does not support loopback device, please recompile your kernel" plain "and make sure that CONFIG_BLK_DEV_LOOP equal m or y (NOT n)" exit 1 fi unset temp else unset agree warning "/proc/config.gz does not exist.. Cannot check for BLK_DEV_LOOP support." plain "If you are sure that your kernel support loopback device, type :" while [ "${agree}" != "I AM SURE THAT MY KERNEL SUPPORT LOOPBACK DEVICE" ]; do plain "I AM SURE THAT MY KERNEL SUPPORT LOOPBACK DEVICE" read agree agree="${agree}" #trim spaces... done unset agree fi if [ -f /tmp/pacman.lck ]; then error "Cannot run pacman-drive while using pacman." exit 1 fi action="${1}" if [ -z "${action}" -o \( "${action}" != "create" -a "${action}" != "delete" \) ]; then usage exit 1 fi case "${action}" in create) create_drive ;; delete) delete_drive ;; *) usage; exit 1 ;; esac # End Of File # vim: set ft=sh ts=4 sts=4 sw=4 expandtab:
— harold 23/09/2006 22:54