Score:1

Flock ล้มเหลวด้วย NFSv4

ธง ph

ฉันไม่รู้ว่าทำไมรหัสนี้ไม่ทำงานภายใต้ NFS4 การใช้ NFS3 ทำงานได้อย่างสมบูรณ์ แนวคิดคือการหลีกเลี่ยงการเขียนไฟล์ในขณะที่กระบวนการยังคงอ่านอยู่

ฉันต้องการแก้ไขข้อบกพร่อง แต่ผู้ดูแลระบบของเราไม่สามารถทำได้ ซึ่งอาจเป็นเหตุผล ภายใต้การติดตั้ง NFS4 ของเรา ฉันพบเงื่อนไขนี้เสมอ

  ถ้า ( ฝูง (fp, LOCK_EX) == -1)
    printf("ข้อผิดพลาด: ไฟล์ %s ถูกล็อกแล้ว\n", ชื่อไฟล์);

โปรแกรมทั้งหมดคือ:

#รวม <sys/file.h>
#รวม <stdio.h>
#รวม <stdlib.h>
#รวม <unistd.h>

int main (int argc, ถ่าน **argv){

    ถ้า (argc<2){
        printf("การใช้งาน:\n a.out fileName\n");
        กลับ 1;
    }

    ถ่าน *ชื่อไฟล์=argv[1];
    int fp;
     
    /* บล็อกไฟล์ ฉันรู้ว่ากระบวนการสามารถเขียนได้ 
    ทำให้ข้อมูลของฉันไร้ประโยชน์*/
    fp=open(ชื่อไฟล์,O_RDONLY);

    ถ้า ( ฝูง (fp, LOCK_EX) == -1){
        printf("ข้อผิดพลาด: ไฟล์ %s ถูกล็อกแล้ว\n", ชื่อไฟล์);
    }
    อื่น{
        printf("ตกลง: ไฟล์ %s ถูกล็อค\n", ชื่อไฟล์ );
    }

    /* อ่านและแยกวิเคราะห์ชื่อไฟล์ 
       โปรเซสอื่นไม่น่าจะเขียนได้หรือ
       แก้ไขชื่อไฟล์ในขณะที่ฉันกำลังอ่าน
    */
    กลับ 0;    
}

แก้ไข: ฉันอยากจะชี้แจง นี่คือส่วนของรหัสที่ฉันใช้ ชื่อไฟล์ควรจะเป็นไฟล์ที่มีอยู่ที่ถูกต้อง

ฉันกำลังอ่านชื่อไฟล์และทำสำเนา แก้ไขบางส่วน ฉันรู้ว่าในขณะที่ฉันดำเนินการนี้ กระบวนการภายนอกสามารถอัปเดตชื่อไฟล์ได้ ฉันต้องการใช้สัญญาณเพื่อหลีกเลี่ยงการแก้ไขในไฟล์นี้จนกว่าฉันจะทำมันเสร็จ โปรแกรมนี้ทำงานได้อย่างสมบูรณ์จนกระทั่งหยุดทำ ข้อแตกต่างเพียงอย่างเดียวคือระบบไฟล์ที่ชื่อไฟล์ตั้งอยู่ ได้รับการอัปเดตจากรูปแบบ NFS3 เป็น NFS4 แม้แต่ระบบปฏิบัติการ (SLE15.2) ก็เหมือนกันกับเคอร์เนล 5.3.18 และการใช้ strerror(errno) ทำให้เกิดข้อผิดพลาด seg บน NFS4 คำแนะนำเดียวเมื่อฉันพิมพ์ ("%d", ข้อผิดพลาด) คือ 9 ซึ่งควรเป็น "ตัวอธิบายไฟล์ผิด"

ขอบคุณสำหรับความช่วยเหลือของคุณ

จูเลีย

Matthew Ife avatar
jo flag
บรรทัด ```if ( Flock(fp,LOCK_EX) == -1){``` จะบอกให้คุณทราบหากการล็อคพิเศษล้มเหลวเท่านั้น ไม่ทำไม. เปลี่ยน printf เป็น ```printf("Error: file %s is แล้วถูกล็อค: %s\n", fileName, strerror(errno));``` คุณเพียงแค่สันนิษฐานว่ามันเป็นปัญหาพื้นฐานเกี่ยวกับการล็อค แต่คุณอาจมีข้อผิดพลาดพื้นฐานมากกว่านั้น (เช่น การพยายามล็อกไฟล์ที่ไม่มีอยู่จริง)
de flag
คุณควรพิมพ์ errno (ตามที่ผู้อื่นแนะนำ) เพื่อดูว่าเหตุใดคำขอล็อกจึงล้มเหลว
djdomi avatar
za flag
ฉันเชื่อว่าคำถามนี้จะเหมาะสมกับ StackOverflow มากกว่าในเว็บไซต์นี้
Score:0
ธง jo

รหัสส่วนนี้:

ถ้า ( ฝูง (fp, LOCK_EX) == -1){
    printf("ข้อผิดพลาด: ไฟล์ %s ถูกล็อกแล้ว\n", ชื่อไฟล์);
}
อื่น{
    printf("ตกลง: ไฟล์ %s ถูกล็อค\n", ชื่อไฟล์ );
}

สามารถบอกคุณได้ว่าล็อคล้มเหลวหรือสำเร็จ แต่ไม่สามารถบอกได้ว่าทำไม คุณควรแก้ไขเพื่อรายงาน เอ่อ สาเหตุของความล้มเหลวเนื่องจากอาจบ่งบอกถึงปัญหาพื้นฐานเกี่ยวกับการล็อกของคุณ เช่น การพยายามเปิดไฟล์ที่คุณไม่ได้รับอนุญาตหรือไม่มีอยู่จริง

ถ้า ( ฝูง (fp, LOCK_EX) == -1){
    printf("ข้อผิดพลาด: ไฟล์ %s ถูกล็อคแล้ว: %s\n", ชื่อไฟล์, strerror(errno));
}
อื่น{
    printf("ตกลง: ไฟล์ %s ถูกล็อค\n", ชื่อไฟล์ );
}

คุณอาจต้องการรวม เอ่อ ในรายการรวมถึงเพื่อให้แน่ใจว่าคุณเข้าถึงตัวแปรที่ถูกต้อง

Score:0
ธง de

NFS v3 ไม่รองรับการล็อคในระดับโปรโตคอล ฟังก์ชันนี้มีให้โดยเพิ่มเติม (ภายนอกกับโปรโตคอล nfs) ผู้จัดการล็อค. ในทางกลับกัน NFS v4 มีการล็อคเป็นส่วนหนึ่งของข้อมูลจำเพาะ นอกจากนี้ยังมีล็อคสองประเภท หนึ่งคือ ล็อคช่วงไบต์ที่สองคือ ส่วนแบ่งการเข้าถึง. แม้ว่าอันหลังจะเป็นสิ่งที่คุณกำลังมองหา แต่ POSIX API ไม่เปิดเผย ดังนั้นจึงไม่พร้อมใช้งานสำหรับ linux และ unix

ในการล็อคให้ทำงานกับ nfs v4 และ v3 คุณต้องใช้ การล็อคช่วงไบต์ ซึ่งมีให้เลือกเป็น fcntl หรือ ล็อค ฟังก์ชั่น.

ตรวจสอบรหัสของการทดสอบการล็อกที่ใช้โดยนักพัฒนา nfs (รวมถึงตัวฉันเอง) เพื่อตรวจสอบการทำงานของไคลเอ็นต์/เซิร์ฟเวอร์โดยไม่ขึ้นกับเวอร์ชันของโปรโตคอล

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

Score:0
ธง kz

ฉันเพิ่งตรวจสอบ manpage ของฝูง ในส่วนหมายเหตุมีส่วนสำคัญ:

รายละเอียด NFS
   ในเคอร์เนล Linux สูงถึง 2.6.11, Flock() ไม่ล็อกไฟล์ผ่าน NFS (กล่าวคือ ขอบเขตของการล็อกถูกจำกัดไว้ที่ระบบโลคัล) แต่สามารถใช้การล็อคช่วงไบต์ fcntl(2) ซึ่งทำได้
   ทำงานผ่าน NFS โดยกำหนด Linux เวอร์ชันล่าสุดและเซิร์ฟเวอร์ที่รองรับการล็อก

   ตั้งแต่ Linux 2.6.12 ไคลเอนต์ NFS รองรับการล็อก Flock() โดยเลียนแบบเป็นการล็อกช่วงไบต์ fcntl(2) บนไฟล์ทั้งหมด ซึ่งหมายความว่าการล็อก fcntl(2) และ Flock() จะโต้ตอบกับสิ่งใดสิ่งหนึ่ง
   อีกอันผ่าน NFS นอกจากนี้ยังหมายความว่าในการวางล็อกพิเศษ จะต้องเปิดไฟล์เพื่อเขียน

   ตั้งแต่ Linux 2.6.37 เคอร์เนลสนับสนุนโหมดความเข้ากันได้ที่อนุญาตให้ล็อค Flock() (และล็อคพื้นที่ fcntl(2) ไบต์) เป็นแบบโลคัล ดูการสนทนาของ local_lock
   ตัวเลือกใน nfs(5)

คุณเปิดไฟล์เพื่ออ่านเท่านั้น ซึ่งเป็นสาเหตุที่การเรียกฝูงล้มเหลว

Julia Fischer avatar
ph flag
ขอบคุณ. คุณได้ตอบคำถามของฉัน ฉันต้องอ่านหน้าคน
Martin avatar
kz flag
ยอดเยี่ยม! หากคำตอบของฉันแก้ไขคำถามของคุณได้ โปรดทำเครื่องหมายว่าเป็นคำตอบที่ยอมรับ...

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา