340 likes | 424 Views
Operating Systems, 132. Practical Session 11 File Systems & Midterm 201 3. 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)
E N D
Operating Systems, 132 Practical Session 11 File Systems & Midterm 2013
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)
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
Quick recap: i-Nodes General file attributes File Size HardLink count The number of hard-links to the file Usually between 10 and 12
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.
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.
Question 1: i-nodes A similar problem
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.
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.
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).
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); }
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)
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
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
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.
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,242,616 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
Question 1 (35 נקודות) מניעה הדדית (mutual exclusion)
Question 1 נתון אלגוריתם למניעה הדדית (mutual exclusion) לשני תהליכים המשתמש בשני ביטים, אחד לכל תהליך. כל תהליך כותב רק על הביט שלו ויכול לקרוא גם את הביט של התהליך השני. שני הביטים מאותחלים לערך 0. התהליכים מסומנים 0 או 1 והקוד המופיע למטה כתוב עבור תהליך i שמקבל את הערך 0 או 1 לפי התהליך המריץ את הקוד. b[i] := i; while b[0] = ido b[i] := 1; while b[1] = 1-i do b[i] := 0; Critical Section b[i] := 0;
Question 1 א. האם האלגוריתם מקיים מניעה הדדית לשני תהליכים ? הוכיחו או הפריכו בלא יותר מ-10 שורות (15 נק'). פתרון: נדון בשתי אפשרויות בלבד של סדרי ריצה אפשריים בין שני התהליכים :או שתהליך 1 מבצע את שורה 1 שלו לפני שתהליך 0 מבצע את שורה 4, או שלא. • אם לפני, תהליך 0 לא יעבור את שורה 4 עד שתהליך 1 יאפס את b[1] וזה יקרה מחוץ לקוד. • אם אחרי, תהליך 1 יבצע את שורות 2-3 עד שיתאפס b[0] וזה יקרה כשתהליך 0 יהיה מחוץ לקוד.
Question 1 ב. האם האלגוריתם מונע deadlock ? הוכיחו או הפריכו בלא יותר מ-10 שורות (10 נק'). פתרון: נוכיח שלא יתכן deadlock. שורת הקוד היחידה שתהליך 1 עלול ל"היעצר" עליה היא הלולאה שבשורה 2 כי הראינו כבר קודם שאת השורה הרביעית הוא אינו מבצע. אבל שורה 2 מתבצעת על ידי תהליך 1 רק אם b[0] == 1, כלומר שתהליך 0 ביצע את השורה השלישית. אלא שלאחר ביצוע השורה השלישית על ידי תהליך 0 ואם תהליך 1 תקוע בלולאה של שורה 2, תהליך 0 יבצע את שורה 4. תקיעה שלו על שורה 4 תשחרר את תהליך 1 שהנחנו שהוא תקוע על הלולאה שבשורה השניה. גם כאן הגענו לסתירה.
Question 1 ג. האם תתכן הרעבה ? (10 נק') פתרון: הרעבה תיתכן בהחלט. נסתכל במקרה הבא: תהליך 1 בקטע הקריטי ותהליך 0 ממתין על הלולאה בשורה 4. כאשר תהליך 1 בקטע הקריטי מתקיים b[1] == 1. ביציאה תהליך 1 מאפס את הביט שלו אך מיד ממשיך לשורה הראשונה ומחליף את ערכו ל-1. במקרה כזה תהליך 0 ממשיך בלולאה שלו ותהליך 1 אינו מבצע את שורה 2 כלל ונכנס פעם נוספת לקטע הקוד הקריטי. הרעבה תיתכן !!
Question 2 (40נקודות) XV6
Question 2 להלן הקוד של פונקציית ה-sleep בקובץ proc.c שבמערכת XV6. • void sleep(void *chan, struct spinlock *lk) • { • if(proc == 0) • panic("sleep"); • if(lk == 0) • panic("sleep without lk"); • if(lk != &ptable.lock){ • acquire(&ptable.lock); • release(lk); • } 14. proc->chan = chan; 15. proc->state = SLEEPING; 16. sched(); 17. 18. proc->chan = 0; 19. 20. if(lk != &ptable.lock){ 21. release(&ptable.lock); 22. acquire(lk); 23. } 24. }
Question 2 א. האם יש אפשרות ש- process יבצע נעילה (acquire) על יותר מ- spinlock יחיד לפני קריאה לפונקציית sleep? אם כן, האם זה יפגע בריצה התקינה של מערכת ההפעלה? אם לא, מדוע? נמקו את תשובתכם (15 נק'). פתרון: • XV6 לא מגביל מבחינת כמות ה spinlocks הנעולים בו זמנית ולכן ניתן לבצע נעילה על יותר מ- spinlock יחיד לפני קריאה לפונקציית sleep. • בתיך פונקציתsleep קיימת קריאה לפונקציית sched()(שורה 16). פונקציה זו מוודה שה ptable.lock spinlockנעול וזהו ה spinlockהיחיד אשר נעול (ניתן לוודא כמות ה spinlockהנעולים ע"י ספירת פעולות acquire ו release). אם התנאים אינם מתקיימים המערכת הפעלה תעצור בגלל הפעלת פונקציית panic. לכן אם הייתה נעילה על יותר מ- spinlock יחיד לפני קריאה לפונקציית sleep המערכת תתקע (מכיוון שלפחות spinlockאחד לא ישוחרר).
Question 2 פתרון (אלטרנטיבי): • קיימת אפשרות ל deadlock במידה הייתה נעילה על יותר מ- spinlock יחיד לפני קריאה לפונקציית sleep. נניח כי התהליך שביצע קריאה לפונקציית sleep הוא P1 והוא ביצע נעילה על 2 spinlocksA ו B. מכיוון שפונקציית sleep משחררת לכל היותר spinlockאחד נניח בה"כ כי spinlockB לא שוחרר. נניח גם כן כי תהליך P2 צריך "להעיר" את תהליך P1, אבל כדי לבצע זאת הוא חייב spinlockB. כרגע תיארנו תרחיש לdeadlock (תהליך P1מחכה לכך שתהליך P2 יעיר אותו, ותהליך P2מחכה לכך שתהליך P1 ישחרר את ה spinlock B)
Question 2 • ב. מהי הסיבה לשחרור ה- spinlock הישן (lk) ונעילת ptable.lock (שורות 10 ו- 11)? הסבירו בשתי שורות כל פעולה בנפרד (15 נק'). פתרון: • הסיבה לשחרור ה- spinlock הישן (lk) היא למנוע deadlock\נפילה של המערכת (ראה הסבר בסעיף א) • נעילת ה- ptable.lock נועדה לצורך עדכון נתונים ב ptable (שורות 14,15) בנוסף לכך המתזמן (כלומר הקריאה sched()) מצפה שברגע שהוא מקבל זמן cpu יש ברשותו את הנעילה על ה- spinlock של ptable.lock.
Question 2 ג. האם נפגע בהתנהגות של ה- kernel אם נחליף בין השורות 10 ו- 11 (כלומר, כאשר קודם יתבצע release(lk), ולאחר מכן יתבצע (acquire(&ptable.lock)? אם כן, הסבירו בפירוט איך הנכונות תפגע (על ידי תיאור תרחיש שכעת יתבצע בצורה שגויה, או בדרך מפורטת אחרת). אם לא, הסבירו מדוע ריצת מערכת ההפעלה תישאר תקינה (10 נק'). פתרון: כן, התנהגות המערכת עלולה לא להיות נכונה. הסיבה היא שנעילה של מנעול מבטלת Interrupts. תרחיש: אחרי שהתהליך ביצע release ולפני ה- acquire הגיע interrupt שאמור להעיר את התהליך. כיוון שאין ביטול, הביצוע של ההערה לכאורה מתרחש אבל התהליך לעולם ישאר במצב sleeping.
Question 3 (25 נקודות) system calls
Question 3 נתונה התוכנית הבאה : 1. #include <stdio.h> 2. #include <sys/types.h> 3. #include <unistd.h> 4. #include <signal.h> 5. 6. inttst = 0; 7. 8. intsignal_handler(int s) 9. { 10. signal(SIGINT,signal_handler); 12. tst++; 13. } 14. 15. int main() 16. { 17. inti; 18. int p = getpid(); 19. int l = 0; 20. 21.signal(SIGINT,signal_handler); 22. 23. for (i = 0; i < 4; i++) 24. if(fork()==0) 25. l++; 26. 27. if (l == 2) 28. kill(p,SIGINT); 29. 30. while (wait(NULL) > 0); 31. 32. if (l == 0) 33. printf("%d\n", tst); 34. 35. return 0; 36. }
Question 3 א. ציירו את עץ התהליכים שנוצרים כתוצאה מהרצת הקוד. ציינו בציור את ערכי המשתנים i; p; l בכל אחד מהתהליכים בתרשים שלכם (15 נק'). L=0 L=1 L=2 L=3 L=4 P=1 I=4
Question 3 ב. מהם הפלטים האפשריים של התוכנית? מה הסיבה לאי הדטרמיניסטיות של הפלטים? (5 נק') פתרון: הפלטים האפשריים: {1,2,3,4,5,6} (או לא יהיה פלט כלל). הסיבה לכך היא שסיגנלים אינם נצברים, אלא יש רק ביט יחיד שמציין את הגעת/ם של סיגנל/ים. לכן, בתלות בהקצאת זמן הריצה של התהליך הראשון (שורש העץ) יתכן שיקבל סיגנל אחד או יותר.
Question 3 ד. הציעו שינוי במערכת ההפעלה, אשר יגרום לכך שהפלט יהיה דטרמיניסטי? (5 נק') פתרון:נוסיף תמיכה עבור כל תהליך ברשימה של signals שמחכים לטיפול. (בדומה ל- real time signals)