Ayant installé de nouveaux disques durs dans le PC chez mes parents, je fais ce que je fais régulièrement, à savoir compiler un Firefox. La compilation échoue sur quelque chose que je ne comprends pas du tout :
pleiades david /usr/local/src/mozilla/obj-i686-pc-linux-gnu/intl/icu/target/data $ LD_LIBRARY_PATH=../lib:../stubdata:../tools/ctestfw:$LD_LIBRARY_PATH ../bin/genrb -k -R -i ./out/build/icudt52l -s /hugetmp/mozilla/intl/icu/source/data/coll -d ./out/build/icudt52l/coll root.txt /hugetmp/mozilla/intl/icu/source/data/coll/root.txt:15: Collation could not be built- U_FILE_ACCESS_ERROR. Make sure ICU's data has been built and is loading properly. /hugetmp/mozilla/intl/icu/source/data/coll/root.txt:15: parse error. Stopped parsing resource with U_FILE_ACCESS_ERROR couldn't parse the file root.txt. Error:U_FILE_ACCESS_ERROR
Comme tout bon Unixien confronté à un comportement bizarre d'un
programme qu'il ne connaît même pas, j'ai le
réflexe strace
. Et là, les choses deviennent encore plus
mystérieuses :
pleiades david /usr/local/src/mozilla/obj-i686-pc-linux-gnu/intl/icu/target/data $ strace -f -o /tmp/dump -E LD_LIBRARY_PATH=../lib:../stubdata:../tools/ctestfw:$LD_LIBRARY_PATH ../bin/genrb -k -R -i ./out/build/icudt52l -s /hugetmp/mozilla/intl/icu/source/data/coll -d ./out/build/icudt52l/coll root.txt strace: ../bin/genrb: command not found
Comment ça, command not found
? Je n'ai
aucune idée de ce que le programme ../bin/genrb
est censé
faire, mais je suis sûr qu'il existe et qu'il s'exécute correctement.
Pourquoi strace
prétend-il ne pas pouvoir le
trouver ?
Et pourquoi le fait d'avoir changé les disques durs de ma machine ferait-il échouer la compilation de Firefox ?
Je vous épargne la manière dont j'ai résolu le mystère (j'ai
commencé par strace strace
lui-même, qui ne m'a montré
aucune erreur, ce qui rendait les choses encore plus incompréhensible,
et j'ai fini par patcher le truc pour afficher la valeur
de errno
). Le secret était que la
partition /hugetmp
sur laquelle je compilais faisait plus
de 2To, et que j'y avais mis un système de fichier XFS.
Or pour les gros systèmes de
fichiers, XFS
utilise des numéros d'inodes de plus que 32-bits. Mon noyau est
64-bits, donc lui n'a pas de problème avec ça, mais sur cette machine
j'ai un userland de 32-bits : dans ces conditions, tout dépend de si
le programme a été compilé avec -D_FILE_OFFSET_BITS=64
ou
non : si ce n'est pas le cas (ce qui, apparemment, vaut pour
le strace
de ma Debian comme pour le programme qui
échouait en premier lieu), lorsque stat()
est appelé sur
un fichier et qu'un des champs de la structure de retour (typiquement,
la taille, ou le numéro d'inode) dépasse le type 32-bits que la
structure prévoit, alors la libc
produit
l'erreur EOVERFLOW
(qui n'apparaît pas dans le strace
du strace
parce que ce n'est pas le noyau qui la renvoie,
c'est la libc
) ; et si on se contente de regarder
si stat()
a réussi ou pas, on a l'impression que le
fichier n'existe pas ou qu'il y a une erreur d'accès.
Moralité :
- Tous les programmes, sur un système 32-bits, devraient
être compilés avec
-D_FILE_OFFSET_BITS=64
(ou en tout cas, tous ceux qui utilisentstat()
, c'est-à-dire, essentiellement, tous les programmes). Ne pas le faire va provoquer les erreurs les plus bizarres et inattendues. Même si on ne manipule pas des fichiers de plus de 2Go (qui sont la cause la plus courante deEOVERFLOW
). - Si on veut utiliser des partitions XFS de plus de 1To sur un système qui risque de faire tourner des programmes 32-bits, on a intérêt à augmenter la taille des inodes (passer à 512 bits à partir de 1To, à 1024 bits à partir de 2To, etc. ; au-delà de 8To, on ne peut plus s'en sortir). Ce n'est pas très satisfaisant, cela fera perdre de la place, mais à moins de vouloir résoudre les bugs (i.e., la non-application du premier point) de la moitié de la distribution, il faudra bien faire un choix.
Noter que contrairement
à ce
que prétend la doc (if no inode size is given on
the command line,
), mkfs.xfs
will attempt to choose a size
such that inode numbers will be < 32 bits. If an inode size is
specified, or if a filesystem is sufficently
large, mkfs.xfs
will warn if this will create inode
numbers > 32 significant bitsmkfs.xfs
n'a,
lorsque j'ai créé le système de fichiers, ni choisi une taille d'inode
suffisante pour rester avec des numéros d'inode de 32-bits, ni affiché
d'avertissement.