Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Installation sur Linux #2386

Closed
vicuna opened this issue Mar 5, 2000 · 4 comments
Closed

Installation sur Linux #2386

vicuna opened this issue Mar 5, 2000 · 4 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Mar 5, 2000

Original bug ID: 49
Reporter: administrator
Status: closed
Resolution: not a bug
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Bonjour,

j'ai installé sans problèmes plusieurs versions d'OCaml sur différentes
plates-formes sans jamais rencontrer aucun problème. Bizarrement, je
n'arrive pas à compiler (version 2.04 et 2.99) sur certaines machines
Linux (les nouvelles machines élèves Linux de l'ENS; pas de problèmes
sur d'autres Linux).

make world se bloque sur:
../boot/ocamlrun ../ocamlc -g -nopervasives -c pervasives.mli
à cause d'une exception "End_of_file" non rattrapée par le compilateur.

Il s'avère que si on lance cette ligne manuellement, on obtient une fois
sur deux un succès et une fois sur deux un échec (avec une vraie
periodicité de periode 2).

strace montre que l'echec est provoqué par un read de 4096 octets
sur pervasives.cmi, après la fin du fichier. Voici la fin de la sortie de
strace lors d'un echec:

open("pervasives.cmi", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
brk(0x808f000) = 0x808f000
brk(0x806d000) = 0x806d000
write(3, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
write(3, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
write(3, "\341\0\1\0031\2\5\365\341\0\1\003"..., 3297) = 3297
open("pervasives.cmi", O_RDONLY) = 4
lseek(4, 0, SEEK_END) = 11540
lseek(4, 0, SEEK_SET) = 0
read(4, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
read(4, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
read(4, "\341\0\1\0031\2\5\365\341\0\1\003"..., 4096) = 3297
read(4, "", 4096) = 0
write(2, "Uncaught exception: End_of_file\n"..., 32Uncaught exception:
End_of_file
) = 32
_exit(2) = ?

et lors d'un succès:

open("pervasives.cmi", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
brk(0x808f000) = 0x808f000
brk(0x806d000) = 0x806d000
write(3, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
write(3, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
write(3, "\341\0\1\0031\2\5\365\341\0\1\003"..., 3297) = 3297
open("pervasives.cmi", O_RDONLY) = 4
lseek(4, 0, SEEK_END) = 11489
lseek(4, 0, SEEK_SET) = 0
read(4, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
read(4, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
read(4, "\341\0\1\0031\2\5\365\341\0\1\003"..., 4096) = 3297
close(4) = 0
brk(0x8071000) = 0x8071000
write(3, "\204\225\246\276\0\0\0\37\0\0\0\4"..., 51) = 51
close(3) = 0
_exit(0) = ?

Je précise que l'on travaille en NFS (le serveur NFS est un Sun sous
Solaris).

Avez-vous une idée d'où cela peut venir ?

Merci de votre aide

--
Alain Frisch

@vicuna
Copy link
Author

vicuna commented Mar 7, 2000

Comment author: administrator

Bonjour,

j'ai installé sans problèmes plusieurs versions d'OCaml sur différentes
plates-formes sans jamais rencontrer aucun problème. Bizarrement, je
n'arrive pas à compiler (version 2.04 et 2.99) sur certaines machines
Linux (les nouvelles machines élèves Linux de l'ENS; pas de problèmes
sur d'autres Linux).

Merci pour le strace, qui m'a permis (je crois) de localiser le probleme.
Mon impression est que c'est un bug... dans Linux!

Explication: l'erreur se produit lorsque OCaml ecrit un fichier d'interface
compilee, en l'occurrence pervasives.cmi. L'algorithme pour ecrire ces
fichiers
est le suivant:

  • ecrire un paquet de donnees binaires
  • rouvrir le fichier en lecture
  • calculer un checksum MD5 des donnees qu'on vient d'ecrire
  • ecrire ce checksum a la fin du fichier.

Sur le strace, dans le cas qui reussit, on voit bien ces etapes:

open("pervasives.cmi", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
creation du fichier en ecriture
write(3, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
write(3, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
write(3, "\341\0\1\0031\2\5\365\341\0\1\003"..., 3297) = 3297
ecriture de 4096+4096+3297=11489 octets
open("pervasives.cmi", O_RDONLY) = 4
reouverture en lecture
lseek(4, 0, SEEK_END) = 11489
lseek(4, 0, SEEK_SET) = 0
determination de la taille courante du fichier = 11489
read(4, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
read(4, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
read(4, "\341\0\1\0031\2\5\365\341\0\1\003"..., 4096) = 3297
calcul du MD5
close(4) = 0
write(3, "\204\225\246\276\0\0\0\37\0\0\0\4"..., 51) = 51
ecriture du MD5 et d'autres infos
close(3) = 0

Sur le strace du cas d'echec, il se produit quelque chose de tres bizarre:

open("pervasives.cmi", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(3, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
write(3, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
write(3, "\341\0\1\0031\2\5\365\341\0\1\003"..., 3297) = 3297
ecriture de 4096+4096+3297=11489 octets, c'est normal
open("pervasives.cmi", O_RDONLY) = 4
lseek(4, 0, SEEK_END) = 11540
mais ici la taille courante du fichier est 11540, et non 11489!!!
lseek(4, 0, SEEK_SET) = 0
read(4, "Caml1999I005\204\225\246\276\0\0"..., 4096) = 4096
read(4, "\365\341\0\1\1\256\260\262\4\367"..., 4096) = 4096
read(4, "\341\0\1\0031\2\5\365\341\0\1\003"..., 4096) = 3297
read(4, "", 4096) = 0
on essaye de lire 11540 octets, et bien sur ca echoue car il n'y
en a que 11489

Je précise que l'on travaille en NFS (le serveur NFS est un Sun sous
Solaris).
Avez-vous une idée d'où cela peut venir ?

Je pense qu'il s'agit d'un probleme de NFS entre Linux et Solaris.
J'ai vaguement entendu parler de problemes de cet ordre, certains pouvant etre
corriges en appliquant un patch de Sun sur la machine Solaris, mais je ne
me souviens pas des details. Peut-etre que les archives de la liste
linux-kernel ou du newsgroup comp.os.linux.development.kernel contiennent
plus d'infos la-dessus.

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Mar 7, 2000

Comment author: administrator

Looks like an NFS incompatibility between Linux and Solaris

@vicuna vicuna closed this as completed Mar 7, 2000
@vicuna
Copy link
Author

vicuna commented Mar 26, 2000

Comment author: administrator

Bonjour,

je vous avais signalé un problème que nous rencontrons pour compiler
OCaml sur les Linux du réseau de l'ENS. Apparemment, il s'agit d'un
problème de NFS, lié à l'algorithme d'écriture des sommes de controle
dans les fichiers signature (le meme fichier est ouvert en ecriture
et en lecture dans 2 fd différents; je ne sais pas si NFS est censé
gérer cela).

J'ai patché env/typing.ml pour fermer le fichier avant de calculer
la somme MD5 et l'ouvrir de nouveau en mode append. J'ai vérifié, cela
fonctionne et permet effectivement de compiler sur les Linux connectés à
un serveur NFS Solaris (avant, nous compilions sur un Linux standalone).

Voici la version modifiée de la fonction concernée:

let save_signature sg modname filename =
Btype.cleanup_abbrev ();
let comps =
components_of_module empty Subst.identity
(Pident(Ident.create_persistent modname)) (Tmty_signature sg) in
let oc = open_out_bin filename in
output_string oc cmi_magic_number;
output_value oc (modname, sg);
flush oc;
close_out oc;
let crc = Digest.file filename in
let crcs = (modname, crc) :: imported_units() in
let oc = open_out_gen
[Open_wronly; Open_append; Open_binary] 0o666 filename in
output_value oc crcs;
close_out oc;
(* Enter signature in persistent table so that imported_unit()
will also return its crc *)
let ps =
{ ps_name = modname; ps_sig = sg; ps_comps = comps; ps_crcs = crcs }
in
Hashtbl.add persistent_structures modname ps

Et le diff avec la version 2.99:
765a766

close_out oc;
767a769,770
let oc = open_out_gen
[Open_wronly; Open_append; Open_binary] 0o666 filename in

(je vois à l'instant, dans le CVS que la fonction a été modifiée depuis la
2.99)

Bien cordialement,

Alain Frisch

@vicuna
Copy link
Author

vicuna commented Mar 27, 2000

Comment author: administrator

je vous avais signalé un problème que nous rencontrons pour compiler
OCaml sur les Linux du réseau de l'ENS. Apparemment, il s'agit d'un
problème de NFS, lié à l'algorithme d'écriture des sommes de controle
dans les fichiers signature (le meme fichier est ouvert en ecriture
et en lecture dans 2 fd différents; je ne sais pas si NFS est censé
gérer cela).

Mais si, mais si, NFS n'est pas MSDOS :-)

Le problème en question semble être un bug connu de Solaris, un patch
est disponible chez Sun:

We had the same problem with Linux<-->Solaris. It was fixed by a patch
fom Sun. The problem would occur when Linux padded the NFS
packet. Solaris used the size of the packet, not the size field of the
packet to determine the amount of data in the packet. Most Linux NFS
requests are block-sized request so this error rarely appears.

J'ai patché env/typing.ml pour fermer le fichier avant de calculer
la somme MD5 et l'ouvrir de nouveau en mode append. J'ai vérifié, cela
fonctionne et permet effectivement de compiler sur les Linux connectés à
un serveur NFS Solaris (avant, nous compilions sur un Linux standalone).

Plutôt que de contourner le bug de Solaris dans Caml, je vous
encourage à patcher votre serveur Solaris. D'autres applications que
Caml peuvent être affectées. Autrement dit, quand on a 40 de fièvre,
il vaut mieux soigner la fièvre que casser le thermomètre :-)

  • Xavier Leroy

@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant