Bah, je ne pense pas, c'est un peu du hasard: est-ce que le scheduler va
changer de processus actif entre le copy et le truncate et le cas
échéant est-ce que le process qui écrit dans le log va reprendre la
main et écrire dans le log. Ca ne me semble pas très prédictible et
l'incidence de la vitesse de la machine ne me semble pas claire du tout.
Mais comme ça se passe dans le cache, le risque doit en effet être assez
faible si la machine n'est pas trop chargée.
Bah, je ne pense pas, c'est un peu du hasard: est-ce que le scheduler va
changer de processus actif entre le copy et le truncate et le cas
échéant est-ce que le process qui écrit dans le log va reprendre la
main et écrire dans le log. Ca ne me semble pas très prédictible et
l'incidence de la vitesse de la machine ne me semble pas claire du tout.
Mais comme ça se passe dans le cache, le risque doit en effet être assez
faible si la machine n'est pas trop chargée.
Bah, je ne pense pas, c'est un peu du hasard: est-ce que le scheduler va
changer de processus actif entre le copy et le truncate et le cas
échéant est-ce que le process qui écrit dans le log va reprendre la
main et écrire dans le log. Ca ne me semble pas très prédictible et
l'incidence de la vitesse de la machine ne me semble pas claire du tout.
Mais comme ça se passe dans le cache, le risque doit en effet être assez
faible si la machine n'est pas trop chargée.
no_spam wrote in message :Bah, je ne pense pas, c'est un peu du hasard: est-ce que le scheduler va
changer de processus actif entre le copy et le truncate et le cas
échéant est-ce que le process qui écrit dans le log va reprendre la
main et écrire dans le log. Ca ne me semble pas très prédictible et
l'incidence de la vitesse de la machine ne me semble pas claire du tout.
Mais comme ça se passe dans le cache, le risque doit en effet être assez
faible si la machine n'est pas trop chargée.
Si c'est bien fait, ils refont un test sur la taille du fichier juste avant
le truncate, et complètent la copie si ça a changé. Avec un sched_yield
juste avant en prime, sur une machine monoprocesseur, on doit avoir une
fiabilité vraiment bonne.
Sur un multiprocesseur, en revanche, c'est perdu.
no_spam wrote in message <pan.2004.11.25.00.55.39.745828@magic.fr>:
Bah, je ne pense pas, c'est un peu du hasard: est-ce que le scheduler va
changer de processus actif entre le copy et le truncate et le cas
échéant est-ce que le process qui écrit dans le log va reprendre la
main et écrire dans le log. Ca ne me semble pas très prédictible et
l'incidence de la vitesse de la machine ne me semble pas claire du tout.
Mais comme ça se passe dans le cache, le risque doit en effet être assez
faible si la machine n'est pas trop chargée.
Si c'est bien fait, ils refont un test sur la taille du fichier juste avant
le truncate, et complètent la copie si ça a changé. Avec un sched_yield
juste avant en prime, sur une machine monoprocesseur, on doit avoir une
fiabilité vraiment bonne.
Sur un multiprocesseur, en revanche, c'est perdu.
no_spam wrote in message :Bah, je ne pense pas, c'est un peu du hasard: est-ce que le scheduler va
changer de processus actif entre le copy et le truncate et le cas
échéant est-ce que le process qui écrit dans le log va reprendre la
main et écrire dans le log. Ca ne me semble pas très prédictible et
l'incidence de la vitesse de la machine ne me semble pas claire du tout.
Mais comme ça se passe dans le cache, le risque doit en effet être assez
faible si la machine n'est pas trop chargée.
Si c'est bien fait, ils refont un test sur la taille du fichier juste avant
le truncate, et complètent la copie si ça a changé. Avec un sched_yield
juste avant en prime, sur une machine monoprocesseur, on doit avoir une
fiabilité vraiment bonne.
Sur un multiprocesseur, en revanche, c'est perdu.
Ca ne change pas grand chose. Comme tout syscall impliquant des IO est
susceptible d'entrainer un reschedule, ça ne fait que déplacer le
problème entre le stat (pour vérifier la taille) et le truncate...
Ca ne change pas grand chose. Comme tout syscall impliquant des IO est
susceptible d'entrainer un reschedule, ça ne fait que déplacer le
problème entre le stat (pour vérifier la taille) et le truncate...
Ca ne change pas grand chose. Comme tout syscall impliquant des IO est
susceptible d'entrainer un reschedule, ça ne fait que déplacer le
problème entre le stat (pour vérifier la taille) et le truncate...
no_spam wrote in message :Ca ne change pas grand chose. Comme tout syscall impliquant des IO est
susceptible d'entrainer un reschedule, ça ne fait que déplacer le
problème entre le stat (pour vérifier la taille) et le truncate...
Dans ce cas particulier, il s'agit de deux actions qui portent en tout
premier lieu sur l'inode : au retout du stat, on peut être à peu près
certain que l'inode est dans le cache, il ne devrait pas y avoir de
changement de contexte avant le ftruncate, donc l'inode sera toujours dans
le cache. Dans ces conditions, je dirais qu'il y a de bonnes chances pour
qu'on puisse, en examinant le code à fond, affirmer que ça marche dans tous
les cas.
no_spam wrote in message <pan.2004.11.25.11.19.27.537773@magic.fr>:
Ca ne change pas grand chose. Comme tout syscall impliquant des IO est
susceptible d'entrainer un reschedule, ça ne fait que déplacer le
problème entre le stat (pour vérifier la taille) et le truncate...
Dans ce cas particulier, il s'agit de deux actions qui portent en tout
premier lieu sur l'inode : au retout du stat, on peut être à peu près
certain que l'inode est dans le cache, il ne devrait pas y avoir de
changement de contexte avant le ftruncate, donc l'inode sera toujours dans
le cache. Dans ces conditions, je dirais qu'il y a de bonnes chances pour
qu'on puisse, en examinant le code à fond, affirmer que ça marche dans tous
les cas.
no_spam wrote in message :Ca ne change pas grand chose. Comme tout syscall impliquant des IO est
susceptible d'entrainer un reschedule, ça ne fait que déplacer le
problème entre le stat (pour vérifier la taille) et le truncate...
Dans ce cas particulier, il s'agit de deux actions qui portent en tout
premier lieu sur l'inode : au retout du stat, on peut être à peu près
certain que l'inode est dans le cache, il ne devrait pas y avoir de
changement de contexte avant le ftruncate, donc l'inode sera toujours dans
le cache. Dans ces conditions, je dirais qu'il y a de bonnes chances pour
qu'on puisse, en examinant le code à fond, affirmer que ça marche dans tous
les cas.
Tu peux très bien être schedulé deux fois, dans cet intervalle:
une première fois au retour du stat, une seconde en faisant l'appel
ftruncate. Si ta machine est chargée et fait beaucoup d'IOs, rien ne
garantit que l'inode sera encore dans le cache après un seul reschedule.
je viens de regarder le code de logrotate, il est tout sauf safe...
- il n'y a pas de gestion des erreurs EINTR / EGAIN dans les read/write
qui font la copie. Ce sont typiquement des choses qui arrivent sur des
systèmes chargés....
- il n'y a aucun test quel qu'il soit entre le dernier write de la copie
et le ftruncate.
La copie pouvant prendre un certain temps, notement le dernier write,
il n'y a vraiment aucune garantie d'avoir un log valide à l'arrivée.
Je pense toujours que de passer par un mmap serait plus sain...
Tu peux très bien être schedulé deux fois, dans cet intervalle:
une première fois au retour du stat, une seconde en faisant l'appel
ftruncate. Si ta machine est chargée et fait beaucoup d'IOs, rien ne
garantit que l'inode sera encore dans le cache après un seul reschedule.
je viens de regarder le code de logrotate, il est tout sauf safe...
- il n'y a pas de gestion des erreurs EINTR / EGAIN dans les read/write
qui font la copie. Ce sont typiquement des choses qui arrivent sur des
systèmes chargés....
- il n'y a aucun test quel qu'il soit entre le dernier write de la copie
et le ftruncate.
La copie pouvant prendre un certain temps, notement le dernier write,
il n'y a vraiment aucune garantie d'avoir un log valide à l'arrivée.
Je pense toujours que de passer par un mmap serait plus sain...
Tu peux très bien être schedulé deux fois, dans cet intervalle:
une première fois au retour du stat, une seconde en faisant l'appel
ftruncate. Si ta machine est chargée et fait beaucoup d'IOs, rien ne
garantit que l'inode sera encore dans le cache après un seul reschedule.
je viens de regarder le code de logrotate, il est tout sauf safe...
- il n'y a pas de gestion des erreurs EINTR / EGAIN dans les read/write
qui font la copie. Ce sont typiquement des choses qui arrivent sur des
systèmes chargés....
- il n'y a aucun test quel qu'il soit entre le dernier write de la copie
et le ftruncate.
La copie pouvant prendre un certain temps, notement le dernier write,
il n'y a vraiment aucune garantie d'avoir un log valide à l'arrivée.
Je pense toujours que de passer par un mmap serait plus sain...
no_spam wrote in message :Tu peux très bien être schedulé deux fois, dans cet intervalle:
une première fois au retour du stat, une seconde en faisant l'appel
ftruncate. Si ta machine est chargée et fait beaucoup d'IOs, rien ne
garantit que l'inode sera encore dans le cache après un seul reschedule.
Mais si ! Je parle bien d'une machine monoprocesseur : dans ce cas, après le
retour de stat, il y a un processus et un seul qui s'exécute pendant
quelques instant : logrotate, justement. Et ce qu'il a à faire avant le
ftruncate (tester la valeur de retour de stat, comparer la taille actuelle
avec la taille copiée) prend très largement moins d'un time-slice, de sorte
que le noyau n'aura certainement rien fait entretemps.
Donc je maintiens que c'est plausible.
je viens de regarder le code de logrotate, il est tout sauf safe...
Ah, là je te fais confiance : je n'ai pas regardé, je ne parlais que sur la
possibilité théorique. En pratique, les programmeurs codent comme des porcs,
c'est bien connu.- il n'y a pas de gestion des erreurs EINTR / EGAIN dans les read/write
qui font la copie. Ce sont typiquement des choses qui arrivent sur des
systèmes chargés....
Euh, une écriture sur le filesystem ne peut pas donner lieu à un EINTR ou un
EAGAIN, il n'y a pas de problème là.
- il n'y a aucun test quel qu'il soit entre le dernier write de la copie
et le ftruncate.
La copie pouvant prendre un certain temps, notement le dernier write,
il n'y a vraiment aucune garantie d'avoir un log valide à l'arrivée.
C'est plus génant.Je pense toujours que de passer par un mmap serait plus sain...
J'ai du mal à voir pourquoi.
Ceci dit, il y a une manière de faire ça tout à fait fiablement :
mount -o remount,mand /var
chmod g+s /var/log/$file
Je viens de tester, ça marche parfaitement.
no_spam wrote in message <pan.2004.11.25.22.30.16.954194@magic.fr>:
Tu peux très bien être schedulé deux fois, dans cet intervalle:
une première fois au retour du stat, une seconde en faisant l'appel
ftruncate. Si ta machine est chargée et fait beaucoup d'IOs, rien ne
garantit que l'inode sera encore dans le cache après un seul reschedule.
Mais si ! Je parle bien d'une machine monoprocesseur : dans ce cas, après le
retour de stat, il y a un processus et un seul qui s'exécute pendant
quelques instant : logrotate, justement. Et ce qu'il a à faire avant le
ftruncate (tester la valeur de retour de stat, comparer la taille actuelle
avec la taille copiée) prend très largement moins d'un time-slice, de sorte
que le noyau n'aura certainement rien fait entretemps.
Donc je maintiens que c'est plausible.
je viens de regarder le code de logrotate, il est tout sauf safe...
Ah, là je te fais confiance : je n'ai pas regardé, je ne parlais que sur la
possibilité théorique. En pratique, les programmeurs codent comme des porcs,
c'est bien connu.
- il n'y a pas de gestion des erreurs EINTR / EGAIN dans les read/write
qui font la copie. Ce sont typiquement des choses qui arrivent sur des
systèmes chargés....
Euh, une écriture sur le filesystem ne peut pas donner lieu à un EINTR ou un
EAGAIN, il n'y a pas de problème là.
- il n'y a aucun test quel qu'il soit entre le dernier write de la copie
et le ftruncate.
La copie pouvant prendre un certain temps, notement le dernier write,
il n'y a vraiment aucune garantie d'avoir un log valide à l'arrivée.
C'est plus génant.
Je pense toujours que de passer par un mmap serait plus sain...
J'ai du mal à voir pourquoi.
Ceci dit, il y a une manière de faire ça tout à fait fiablement :
mount -o remount,mand /var
chmod g+s /var/log/$file
Je viens de tester, ça marche parfaitement.
no_spam wrote in message :Tu peux très bien être schedulé deux fois, dans cet intervalle:
une première fois au retour du stat, une seconde en faisant l'appel
ftruncate. Si ta machine est chargée et fait beaucoup d'IOs, rien ne
garantit que l'inode sera encore dans le cache après un seul reschedule.
Mais si ! Je parle bien d'une machine monoprocesseur : dans ce cas, après le
retour de stat, il y a un processus et un seul qui s'exécute pendant
quelques instant : logrotate, justement. Et ce qu'il a à faire avant le
ftruncate (tester la valeur de retour de stat, comparer la taille actuelle
avec la taille copiée) prend très largement moins d'un time-slice, de sorte
que le noyau n'aura certainement rien fait entretemps.
Donc je maintiens que c'est plausible.
je viens de regarder le code de logrotate, il est tout sauf safe...
Ah, là je te fais confiance : je n'ai pas regardé, je ne parlais que sur la
possibilité théorique. En pratique, les programmeurs codent comme des porcs,
c'est bien connu.- il n'y a pas de gestion des erreurs EINTR / EGAIN dans les read/write
qui font la copie. Ce sont typiquement des choses qui arrivent sur des
systèmes chargés....
Euh, une écriture sur le filesystem ne peut pas donner lieu à un EINTR ou un
EAGAIN, il n'y a pas de problème là.
- il n'y a aucun test quel qu'il soit entre le dernier write de la copie
et le ftruncate.
La copie pouvant prendre un certain temps, notement le dernier write,
il n'y a vraiment aucune garantie d'avoir un log valide à l'arrivée.
C'est plus génant.Je pense toujours que de passer par un mmap serait plus sain...
J'ai du mal à voir pourquoi.
Ceci dit, il y a une manière de faire ça tout à fait fiablement :
mount -o remount,mand /var
chmod g+s /var/log/$file
Je viens de tester, ça marche parfaitement.
Si ta machine est chargée, tu
auras très peu de cache donc il est tout à fait plausible que ton inode
soit discardée du cache avant que tu fasse ton second syscall.
potentiellement pas mal de raison pour celà: même si tu viens de
commencer ton timeslice, il y a des IRQ et des timers qui se déclenchent
de façon complètement asynchrones.
Tu ne peux jamais te baser sur de telles afirmations si tu considère que
ton code est sensible pour la sécurité.
EAGAIN, il n'y a pas de raison, vu que c'est un fd bloquant. EINTR, par
contre peut arriver n'importe quand.
Tu travailles alors sur de la mémoire virtuelle et tu peux travailler en
mode copy-on-write, ce qui te garanti déjà que ta copie de travail est
saine. Tu peux même gérer assez finement le comportement de la mémoire
virtuelle: bloquer les pages en RAM, par ex, (mais il faut faire attention
à la taille du fichier !) ce qui garantira que les pages ne pourront pas
être discardées entre deux accès. Ca ne rend pas le risque nul, mais
ça le réduit.
D'une part, tu ne peux pas forcément faire celà sur une machine de prod.
D'autre part, tu bloque l'autre process pendant tout ce temps, ce qui
n'est pas toujours acceptable: si ta copie dure plusieurs heures, voire
même seulement plusieurs minutes, acceptes tu que tes démons soient
bloqués ? Pas moi.
La seule solution à ce genre de problème, ce serait un syscall qui
ferait un "swap" de fichier en updatant (ou pas, ça pourrait être une
option....) les fd des process qui ont ouvert ce fichier.
Si ta machine est chargée, tu
auras très peu de cache donc il est tout à fait plausible que ton inode
soit discardée du cache avant que tu fasse ton second syscall.
potentiellement pas mal de raison pour celà: même si tu viens de
commencer ton timeslice, il y a des IRQ et des timers qui se déclenchent
de façon complètement asynchrones.
Tu ne peux jamais te baser sur de telles afirmations si tu considère que
ton code est sensible pour la sécurité.
EAGAIN, il n'y a pas de raison, vu que c'est un fd bloquant. EINTR, par
contre peut arriver n'importe quand.
Tu travailles alors sur de la mémoire virtuelle et tu peux travailler en
mode copy-on-write, ce qui te garanti déjà que ta copie de travail est
saine. Tu peux même gérer assez finement le comportement de la mémoire
virtuelle: bloquer les pages en RAM, par ex, (mais il faut faire attention
à la taille du fichier !) ce qui garantira que les pages ne pourront pas
être discardées entre deux accès. Ca ne rend pas le risque nul, mais
ça le réduit.
D'une part, tu ne peux pas forcément faire celà sur une machine de prod.
D'autre part, tu bloque l'autre process pendant tout ce temps, ce qui
n'est pas toujours acceptable: si ta copie dure plusieurs heures, voire
même seulement plusieurs minutes, acceptes tu que tes démons soient
bloqués ? Pas moi.
La seule solution à ce genre de problème, ce serait un syscall qui
ferait un "swap" de fichier en updatant (ou pas, ça pourrait être une
option....) les fd des process qui ont ouvert ce fichier.
Si ta machine est chargée, tu
auras très peu de cache donc il est tout à fait plausible que ton inode
soit discardée du cache avant que tu fasse ton second syscall.
potentiellement pas mal de raison pour celà: même si tu viens de
commencer ton timeslice, il y a des IRQ et des timers qui se déclenchent
de façon complètement asynchrones.
Tu ne peux jamais te baser sur de telles afirmations si tu considère que
ton code est sensible pour la sécurité.
EAGAIN, il n'y a pas de raison, vu que c'est un fd bloquant. EINTR, par
contre peut arriver n'importe quand.
Tu travailles alors sur de la mémoire virtuelle et tu peux travailler en
mode copy-on-write, ce qui te garanti déjà que ta copie de travail est
saine. Tu peux même gérer assez finement le comportement de la mémoire
virtuelle: bloquer les pages en RAM, par ex, (mais il faut faire attention
à la taille du fichier !) ce qui garantira que les pages ne pourront pas
être discardées entre deux accès. Ca ne rend pas le risque nul, mais
ça le réduit.
D'une part, tu ne peux pas forcément faire celà sur une machine de prod.
D'autre part, tu bloque l'autre process pendant tout ce temps, ce qui
n'est pas toujours acceptable: si ta copie dure plusieurs heures, voire
même seulement plusieurs minutes, acceptes tu que tes démons soient
bloqués ? Pas moi.
La seule solution à ce genre de problème, ce serait un syscall qui
ferait un "swap" de fichier en updatant (ou pas, ça pourrait être une
option....) les fd des process qui ont ouvert ce fichier.