1 / 40

Operating Systems, 112

Operating Systems, 112. Practical Session 11 File Systems & Midterm 2011. Quick recap. Files are an abstraction mechanism Several file types: User files (regular),Directory files, Special files (Block, Char) Access: sequentially (e.g. tapes) or random access (disk)

zaza
Download Presentation

Operating Systems, 112

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Operating Systems, 112 Practical Session 11 File Systems & Midterm 2011

  2. Quick recap • Files are an abstraction mechanism • Several file types: User files (regular),Directory files, Special files (Block, Char) • Access: sequentially (e.g. tapes) or random access (disk) • Data: structured (records) or unstructured (set of bits and bytes)

  3. File system layout (Tanenbaum)

  4. Quick recap: Index-Nodes (i-nodes) • The superblock object represents the entire file system and provides access to index-nodes. • Each i-node is a data structure containing pointers to the disk blocks that contain the actual file contents. • An i-node corresponds to a single file. • An i-node needs to be in the main memory only if the correspondent file is open. • Besides the data blocks pointers, the i-node also contains information on the file permissions, owner, etc

  5. Quick recap: i-Nodes General file attributes File Size HardLink count The number of hard-links to the file Usually between 10 and 12

  6. Question 1: i-nodes How many time will the disk be accessed when a user executes the following command: more /usr/tmp/a.txt Assume that: • The size of 'a.txt' is 1 block. • The i-node of the root directory is not in the memory. • Entries 'usr', 'tmp' and 'a.txt' are all located in the first block of their directories.

  7. Question 1: i-nodes Accessing each directory requires at least 2 disk accesses: reading the i-node and the first block. In our case the entry we are looking for is always in the first block so we need exactly 2 disk accesses. According to assumption 2 the root directory's  i-node is located on the disk so we need 6 disk accesses (3 directories) until we reach a.txt'si-node index. Since "more" displays the file's content, for a.txt we need its i-node + all the blocks of the file (1 block, according to assumption). Total disk accesses: 6 + 2 = 8.

  8. Question 1: i-nodes A similar problem

  9. Question 2: i-nodes The Ofer2000 Operating Systems, based on UNIX, provides the following system call: rename(char *old, char *new) This call changes a file’s name from ‘old’ to ‘new’. What is the difference between using this call, and just copying‘old’ to a new file, ‘new’, followed by deleting‘old’? Answer in terms of disk access and allocation.

  10. Question 2: i-nodes • rename- simply changes the file name in the entry of  its directory. • copy -  will allocate a new i-node and the blocks for the new file, and copy the contents of the old file blocks to the new ones. • delete - will release the i-node and blocks of the old file. • copy + delete - is a much more complicated operation for the Operating System, note that you will not be able to execute it if you do not have enough free blocks or i-nodes left on your disk.

  11. Question 3: i-nodes Write an implementation (pseudo code) of the system call: delete(i-node node) Which deletes the file associated with node. Assume that: • nodeis associated with a regular file, and that delete is not recursive. • The i-node has 10 direct block entries, 1 single indirect entry and 1 double indirect entry. • You may use the system calls: read_block(block b) which reads block b from the disk. free_block(block b) andfree_i-node(i-node node).

  12. Question 3: i-nodes delete(i-node node){ // remove the direct blocks for each block b in node.direct do free_block(b); // remove the single indirect blocks single <-- read_block(node.single_indirect) for each entry e in single do free_block(e); free_block(single); // remove the double indirect blocks double <-- read_block(node.double_indirect) for each entry e in double do single <-- read_block(e) for each entry ee in single do free_block(ee); free_block(single); free_block(double); // remove the i-node free_i-node(node); }

  13. Question 4: i-nodes What would be the maximal size of a file in a UNIX system with an address size of 32 bits if : • The block size is 1K • The block size is 4K (The i-node has 10 direct block entries)

  14. Question 4: i-nodes • Block size: 1K • Direct: 10·1K • Single indirect: each address is 32 bit = 4 byte then we have 256 pointers to blocks of size 1K (i.e. 256·1K) • The same idea is applied for double and triple indirect. In total: 10·1K+256·1K+256·256·1K+256·256·256·1K

  15. Question 4: i-nodes • Block size: 4K • Direct: 10·4K • Single indirect: each address is 32 bit = 4 byte then we have 1024 pointers to blocks of size 4K (i.e. 1024·4K) • The same idea is applied for double and triple indirect In total: 10·4K+1024·4K+1024·1024·4K+1024·1024·1024·4K

  16. Question 5: i-nodes Assuming that the size of each block is 1K and the address size is 32 bits (4 bytes). Convert byte address (offset) 1,515,000 in our file to the physical address.

  17. Question 5: I-Nodes Byte number 1,515,000 is calculated as follows: • 1st byte of the double indirect block is 10k+256k = 272,384 • byte number 1,515,000 is number 1,242,616 in the double indirect block • every single indirect block has 256k bytes --> byte 1,515,000 is in the 5th single indirect block (4*256k = 1,048,576) • Every entry is 1k, so byte 194,040 is in the 189th block – assume that it points to block 123 on the disk • within block 123 , it is byte #504

  18. Operating SystemsMIDTERM 2011

  19. Question 1A • א. (25 נ') . כתבי קוד עבור n>1 תהליכים שיבצע עבורם Barrier Synchronization. כלומר, כל התהליכים מגיעים עד למחסום (Barrier) ומחכים לתהליך האחרון. כאשר מגיע התהליך ה-n, כולם עוברים. כתבי את הקוד כך שלאחר השלמת המעבר של כל התהליכים מתאפשרת הצבת אותו מחסום במקום הבא בקוד לכל אחד מן התהליכים. במלים אחרות, מצב המשתנים המרכיבים את המחסום לאחר שכל התהליכים עברו אותו זהה בדיוק למצב בהתחלה. השתמשי בשני סמפורים בינאריים in ו- out ובמשתנה counter מסוג integer המשמש כמונה. כל התהליכים יודעים את מספרם הכולל n.

  20. Question 1A הדרכה:השתמשי בסמפור in המאותחל ל-1 כבמחסום הכניסה ל- Barrier ובסמפור out המאותחל ל-0 כבמחסום המעבר ל"צד השני" של המחסום. הניחי כי הקוד מתחיל בשורות הבאות: down(in); counter++; .... .... השלימי את הקוד בלא יותר מ-8 שורות נוספות. כמובן שנדרש להשתמש במספר התהליכים n.

  21. Solution 1A down(in); counter++; If(counter < n) then up(in) else up(out); down(out); counter--; if(counter > 0) then up(out) else up(in);

  22. Question 1B להלן הקוד של אלגוריתם ה-Bakery אשר ראינו בכיתה: int numer[n] initially {0,…, 0} boolean choosing[n] initially {false,…,false} Code for procssi{1,…,n} 1 choosing[i]:=true 2 number[i]:=1+max{number[j] | 1 ≤ j ≤ n} 3 choosing[i]:=false 4 for j:=1 to n do 5 await choosing[j]=false 6 await (number[j]=0 OR (number[j], j)  (number[i],i)) 7 od 8 Critical Section 9 number[i]:=0

  23. Question 1B נניח כי נחליף את שורה 5 בקוד לעיל בשורה הבאה: 5 if j<i then await choosing[j]=false האם האלגוריתם החדש עדיין נכון? נמקו במדוייק את תשובתכם.

  24. Solution 1B P3 : max = 0, number[3] = 0 int numer[n] initially {0,…, 0} boolean choosing[n] initially {false,…,false} Code for procssi{1,…,n} 1 choosing[i]:=true 2 number[i]:=1+max{number[j] | 1 ≤ j ≤ n} 3 choosing[i]:=false 4 for j:=1 to n do 5 if j<i then await choosing[j]=false 6 await (number[j]=0 OR (number[j], j)  (number[i],i)) 7 od 8 Critical Section 9 number[i]:=0

  25. Solution 1B P3 : number[3] = 0, max = 0 P2 : number[2] = 1 int numer[n] initially {0,…, 0} boolean choosing[n] initially {false,…,false} Code for procssi{1,…,n} 1 choosing[i]:=true 2 number[i]:=1+max{number[j] | 1 ≤ j ≤ n} 3 choosing[i]:=false 4 for j:=1 to n do 5 if j<i then await choosing[j]=false 6 await (number[j]=0 OR (number[j], j)  (number[i],i)) 7 od 8 Critical Section 9 number[i]:=0

  26. Solution 1B P3 : number[3] = 0, max = 0 P2 : number[2] = 1 int numer[n] initially {0,…, 0} boolean choosing[n] initially {false,…,false} Code for procssi{1,…,n} 1 choosing[i]:=true 2 number[i]:=1+max{number[j] | 1 ≤ j ≤ n} 3 choosing[i]:=false 4 for j:=1 to n do 5 if j<i then await choosing[j]=false 6 await (number[j]=0 OR (number[j], j)  (number[i],i)) 7 od 8 Critical Section 9 number[i]:=0 P1 : number[1] = 2

  27. Solution 1B P3 : number[3] = 0, max = 0 P2 : number[2] = 0 int numer[n] initially {0,…, 0} boolean choosing[n] initially {false,…,false} Code for procssi{1,…,n} 1 choosing[i]:=true 2 number[i]:=1+max{number[j] | 1 ≤ j ≤ n} 3 choosing[i]:=false 4 for j:=1 to n do 5 if j<i then await choosing[j]=false 6 await (number[j]=0 OR (number[j], j)  (number[i],i)) 7 od 8 Critical Section 9 number[i]:=0 P1 : number[1] = 2

  28. Solution 1B P3 : number[3] = 1 P2 : number[2] = 0 int numer[n] initially {0,…, 0} boolean choosing[n] initially {false,…,false} Code for procssi{1,…,n} 1 choosing[i]:=true 2 number[i]:=1+max{number[j] | 1 ≤ j ≤ n} 3 choosing[i]:=false 4 for j:=1 to n do 5 if j<i then await choosing[j]=false 6 await (number[j]=0 OR (number[j], j)  (number[i],i)) 7 od 8 Critical Section 9 number[i]:=0 P1 : number[1] = 2 Mutual Exclusion Violation

  29. Question 2 A • int a = 0; • void* funcZ(void* p) { • inti = *(int*)p; • 2. int b = 0; • 3. a++; b++; • 4. printf("child says: • id = %d a = %d • b = %d\n",i,a,b); • // endless loop • 5. while (1); • } • int main(){ • pthread_t t1, t2; • 6. int x1 = 1; • 7. int x2 = 2; • 8. a++; • 9. printf("Parent says a: %d\n", a); • 10 pthread_create(&t1, NULL, funcZ, (void *)&x1); • 11 pthread_create(&t2, NULL, • funcZ, (void *)&x2); • 12 pthread_join(t1, NULL); • 13 pthread_join(t2, NULL); • 14 printf("Parent says: all • done\n"); • }

  30. Question 2 B • int a = 0; • void* funcZ(void* p) { • 1. int i = *(int*)p; • 2. int b = 0; • 3. a++; b++; • 4. printf(“child • says: id = • %d a = %d b = • %d\n”,i,a,b); • // endless loop • 5. while (1); • } int main(){ • 6. int x1 = 1; • 7. int x2 = 2; • 8. int pid1, pid2; • 9. a++; • 10. printf("Parent says a: • %d\n“, a); • 11 if (0==(pid1=fork())) { • 12 funcZ((void *)&x1); • } • 13 if (0==(pid2=fork())) { • 14 funcZ((void *)&x2); • } • 15 wait(&status); • 17 wait(&status); • 18 printf("Parent says: all done\n"); • }

  31. Question 2 עבור כל אחד מהמקרים הבאים ציינו עבור כל אחת משתי התוכניות האם קיים פלט (הדפסות) אפשרי אחד או יותר. אם קיים רק פלט אפשרי אחד – כתבו את הפלט. אם קיימים לפחות שני פלטים אפשריים –כתבו שניים מהם. הסבירו את תשובתכם. הניחו כי במערכת יש preemtion. הניחו כי כאשר תהליך אב יוצר תהליך בן, תהליך הבן נכנס ל–ready queue ואילו תהליך האב ממשיך. בדומה, הניחו כי כאשר חוט יוצר חוט חדש, החוט החדש נכנס ל-ready queue. • משתמשים באלג' תזמון מסוג round robin כאשר ידוע • שפרוסת הזמן מספיקה להרצת כל שורות הקוד של funcZ • וכמו כן נתון שסדר תזמון התהליכים הוא FIFO. (15 נ') • 2. משתמשים באלג' תזמון מסעיף א' ובנוסף השורות "while(1)" • נמחקו מהתוכניות. (15 נ')

  32. Solution 2.a • א. עבור תוכנית A פלט יחיד: Parent says a: 1child says: id = 1 a = 2 b = 1child says: id = 2 a = 3 b = 1 עבור תוכנית B פלט יחיד: Parent says a: 1child says: id = 1 a = 2 b = 1child says: id = 2 a = 2 b = 1

  33. Solution 2.b • ב. עבור תוכנית A פלט יחיד: Parent says a: 1child says: id = 1 a = 2 b = 1child says: id = 2 a = 3 b = 1 • Parent says: all done

  34. Solution 2.b עבור תוכנית B מספר פלטים אפשריים: • Parent says a: 1 child says: id = 1 a = 2 b = 1child says: id = 2 a = 3 b = 1 Parent says: all done • Parent says: all done • child says: id = 2 a = 2 b = 1 Parent says: all done • Parent says: all done • Parent says a: 1 child says: id = 1 a = 2 b = 1child says: id = 2 a = 3 b = 1 • child says: id = 2 a = 2 b = 1 Parent says: all done • Parent says: all done Parent says: all done • Parent says: all done

  35. Solution 2.b Parent says a: 1child says: id = 1 a = 2 b = 1child says: id = 2 a = 2 b = 1 child says: id = 2 a = 3 b = 1Parent says: all done Parent says: all doneParent says: all done Parent says: all done

  36. Question 3 להלן 3 פונקציות מרכזיות הלקוחות מתוך קוד המתזמן (scheduler) של Xv6: 01 void scheduler(void){ 02 struct proc *p; 03 for(;;){ 04 sti(); 05 acquire(&ptable.lock); 06 for(p = ptable.proc; p <&ptable.proc[NPROC]; p++){ 07 if(p->state != RUNNABLE) 08 continue; 09 proc = p; 10 switchuvm(p); 11 p->state = RUNNING; 12 swtch(&cpu->scheduler, proc->context); 13 switchkvm(); 14 proc = 0; 15 } // for 16 release(&ptable.lock); 17 } // for 18 }

  37. Question 3 להלן 3 פונקציות מרכזיות הלקוחות מתוך קוד המתזמן (scheduler) של Xv6: 19 void sched(void){ 20 int intena; 21 if(!holding(&ptable.lock)) 22 panic("schedptable.lock"); 23 if(cpu->ncli != 1) 24 panic("sched locks"); 25 if(proc->state == RUNNING) 26 panic("sched running"); 27 if(readeflags()&FL_IF) 28 panic("sched interruptible"); 29 intena = cpu->intena; 30 swtch(&proc->context, cpu->scheduler); 31 cpu->intena = intena; 32 } 33 void yield(void){ 34 acquire(&ptable.lock); 35 proc->state = RUNNABLE; 36 sched(); 37 release(&ptable.lock); 38 }

  38. Question 3 • 1. (3 נ') איזה אלגוריתם תזמון משמש את Xv6? • 2. (6 נ') הסבירו מהו אלגוריתם תזמון preemptive ומהו אלגוריתם תזמון non-preemprtive. האם האלגוריתם המשמש את Xv6 הוא אלגוריתם preemptive? נמקו במדויק את תשובתכם. • Xv6 uses Round Robin (note that xv6 does not maintain a proper queue and blindly follows array cells. As a result a newly added process is not inserted to the end of the queue and may run before other, already existing processes). • 2. Preemptive scheduling is a scheduling system in which the kernel may interrupt a task and reschedule it for a later time. In non preemptive scheduling switching is done by either explicitly calling a yield function, a blocking operation or when a task is terminated.xv6 uses a preemptive round robin scheduling where each process receives a time quantum of a single tick (defined as 100 msec in timer.c, timerinit()). The timer interrupt is handled by the kerenel and results in the execution of the yield function described in the question.

  39. Question 3 • 3. (16 נ') בשאלה הבאה הניחו כי המערכת כבר רצה עם מספר תהליכים בה (כלומר, כל תהליך קיבל זמן ריצה לפחות פעם אחת). • סטודנט א' טען בפני סטודנט ב' כי לבו של אלגוריתם התזמון מצוי בשורה 12 שלאחריה ירוץ הקוד הקשור בתהליך החדש ( התהליך לאחר ההחלפה). האם צדק סטודנט א'? במידה וכן רשמו מהי השורה שתרוץ לאחר שורה 12. אחרת רשמו איזה חלק (או חלקים) בקוד אחראים על החלפת התהליך. (8 נ') • סטודנט ב' חושד שהמימוש הנתון אינו יעיל. לטענתו, המנעול הנתפס בשורה 5 משתחרר רק בשורה 16, כלומר רק לאחר שהתהליך המתוזמן מסיים את פרוסת הזמן שלו. משמעות הדבר היא שבמערכת עם חומרה מרובת מעבדים תזמון התהליכים אינו יעיל – כל מעבד אחר נאלץ להמתין כל עוד לא שוחרר המנעול. האם צדק סטודנט ב'? במידה וכן הציעו דרך להגברת המקביליות בעת ריצת המערכת על חומרה מרובת מעבדים. במידה וטענתו שגויה הסבירו כיצד דואגת המערכת לשחרור הנעילה. תארו תרחיש המצדיק את תשובתכם. (8 נ')

  40. Solution 3.3 • Student A is correct. After line 12 is executed a different process’ state (instruction pointer) is loaded and the next line will be 31. • Student B is wrong. After lines 12 is executed, a new process is loaded, and that process continues with its previous flow of execution. That is, execution resumes to lines 31-32 and from there to line 37 which is in charge of releasing the lock (the lock is released by a “different process” than the one acquiring it).

More Related