Puncte:1

flock eșuează cu NFSv4

drapel ph

Nu știu de ce acest cod nu funcționează sub NFS4, folosind NFS3 funcționează perfect. Ideea este de a evita ca fișierul să fie scris în timp ce un proces încă îl citește.

Aș dori să depanez, dar administratorul nostru de sistem nu poate. Ceea ce ar putea fi motivul. În cadrul instalării noastre NFS4, intru întotdeauna în această stare

  dacă (flock(fp,LOCK_EX) == -1)
    printf("Eroare: fisierul %s este deja blocat\n", fileName);

intregul program este:

#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv){

    dacă (argc<2){
        printf("Utilizare:\n a.out fileName\n");
        întoarcere 1;
    }

    char *fileName=argv[1];
    int fp;
     
    /* blochează fișierul, știu că un proces poate scrie 
    făcând informațiile mele inutile*/
    fp=open(fileName,O_RDONLY);

    dacă (flock(fp,LOCK_EX) == -1){
        printf("Eroare: fisierul %s este deja blocat\n", fileName);
    }
    altfel{
        printf("OK: fisierul %s a fost blocat\n",fileName);
    }

    /* citește și analizează numele fișierului 
       alt proces nu ar trebui să poată scrie sau
       modificați numele fișierului în timp ce îl citesc
    */
    returnează 0;    
}

Editați | ×: as vrea sa clarific. Acesta este un fragment din codul pe care îl folosesc. fileName ar trebui să fie un fișier existent valid

Citesc un fileName și fac o copie, editând câteva părți. Știu, în timp ce fac asta, un proces extern poate actualiza fileName. Aș dori să folosesc un semafor pentru a evita modificările asupra acestui fișier până când nu termin cu el. Acest program a funcționat perfect până când nu mai face asta. Singura diferență este sistemul de fișiere în care se află numele fișierelor. A fost actualizat din NFS3 în NFS4. Chiar și sistemul de operare (SLE15.2) este același cu kernel-ul 5.3.18, iar utilizarea strerror(errno) produce o eroare seg pe NFS4. Singurul indiciu când imprimez („%d”, eroare) este 9 care ar trebui să fie „descriptor de fișier greșit”

Multumesc pentru ajutor

Julia

Matthew Ife avatar
drapel jo
Linia ```if (flock(fp,LOCK_EX) == -1){``` vă spune doar dacă blocarea exclusivă a eșuat. De ce nu. Schimbați printf în ```printf("Eroare: fișierul %s este deja blocat: %s\n", fileName, strerror(errno));``` Faceți doar o presupunere că este o problemă de bază cu blocarea dar ați putea avea o eroare mai fundamentală (cum ar fi încercarea de a bloca un fișier care nu există).
drapel de
Ar trebui să tipăriți errno (așa cum au sugerat alții) pentru a vedea de ce cererea de blocare a eșuat.
djdomi avatar
drapel za
Cred că această întrebare s-ar potrivi mai bine pe StackOverflow în schimb pe acest site.
Puncte:0
drapel kz

Tocmai am verificat pagina de manual a flock, în secțiunea NOTE vine partea importantă:

detalii NFS
   În nucleele Linux până la 2.6.11, flock() nu blochează fișierele prin NFS (adică domeniul de aplicare a blocărilor a fost limitat la sistemul local). În schimb, s-ar putea folosi fcntl(2) blocarea intervalului de octeți, ceea ce face
   lucrează peste NFS, având în vedere o versiune suficient de recentă de Linux și un server care acceptă blocarea.

   Începând cu Linux 2.6.12, clienții NFS acceptă blocări flock() prin emularea lor ca blocări fcntl(2) pe intervalul de octeți pe întregul fișier. Aceasta înseamnă că blocările fcntl(2) și flock() interacționează cu unul
   altul prin NFS. De asemenea, înseamnă că pentru a plasa o blocare exclusivă, fișierul trebuie deschis pentru scriere.

   Începând cu Linux 2.6.37, nucleul acceptă un mod de compatibilitate care permite blocărilor flock() (și, de asemenea, blocărilor regiunii de octeți fcntl(2)) să fie tratate ca locale; vezi discuția despre local_lock
   opțiune în nfs(5).

Ai deschis doar fișierul pentru citire, motiv pentru care apelul flock eșuează.

Julia Fischer avatar
drapel ph
mulțumesc. Mi-ai răspuns la întrebare. Trebuie să citesc pagina de manual
Martin avatar
drapel kz
Grozav! Dacă răspunsul meu a rezolvat întrebarea dvs., vă rugăm să o marcați ca răspuns acceptat...
Puncte:0
drapel de

NFS v3 nu are suport de blocare la nivel de protocol. Funcționalitatea este furnizată de un suplimentar (extern protocolului nfs) manager de blocare. Pe de altă parte, NFS v4 are blocarea ca parte a specificațiilor. În plus, există două tipuri de încuietori. Unul este blocarea intervalului de octeți, al doilea este partajare de acces. Deși cel mai târziu este ceea ce căutați, API-ul POSIX nu îl expune, prin urmare nu sunt disponibile pentru Linux și Unix.

Pentru a face blocarea să funcționeze cu nfs v4 și v3, trebuie să utilizați blocarea intervalului de octeți care este disponibil ca fcntl sau lockf funcții.

Verificați codul testului de blocare utilizat de dezvoltatorii nfs (inclusiv eu) pentru a valida comportamentul client/server independent de versiunea protocolului.

http://git.linux-nfs.org/?p=steved/cthon04.git;a=blob;f=lock/tlock.c;h=8c837a87976d17c58a25c9bd08d9f935e4521402;hb=HEAD#l835

Puncte:0
drapel jo

Această secțiune de cod:

dacă (flock(fp,LOCK_EX) == -1){
    printf("Eroare: fisierul %s este deja blocat\n", fileName);
}
altfel{
    printf("OK: fisierul %s a fost blocat\n",fileName);
}

Chiar vă pot spune doar că blocarea a eșuat sau a reușit, dar nu de ce. Ar trebui să-l modificați pentru a raporta greseala motivul eșecului, deoarece ar putea indica o problemă mai fundamentală cu blocarea dvs. - cum ar fi încercarea de a deschide un fișier pentru care nu aveți permisiunea sau nu există.

dacă (flock(fp,LOCK_EX) == -1){
    printf("Eroare: fisierul %s este deja blocat: %s\n", fileName, strerror(errno));
}
altfel{
    printf("OK: fisierul %s a fost blocat\n",fileName);
}

Poate doriți să includeți errno.h și în lista includerilor pentru a vă asigura că ajungeți la variabila corectă.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.