פיתרון מבחן במערכות הפעלה / תשס"ד – מועד א.

 

------------- שאלה 1-------------

(ניקוד: 20 + 5 כפי שפורט במהלך המבחן)

א)

direction:0

void arrive() {

      down(waiting[0])

      count[0]++;

      if(count[0] == 1) {

            up(mutex);

            down(mutex_3);

            down(busy);

            up(mutex_3);

            {

     else

             up(mutex);

      up(waiting[0]);

}                                             

direction:1

Like the following section.

 

ב)

direction:both

void arrive(int direction) {

      down(waiting[direction])

      down(mutex_3);

      down(mutex);

      count[direction]++;

      if(count[direction] == 1) {

            up(mutex);

            up(waiting[direction]);

            down(busy);

            {

     else{

             up(mutex);

             up(waiting[direction]);

             {

      up(mutex);

}                                             

 

------------- שאלה 2-------------

 

(10 נקודות)

בדומה לתסריט שתואר בשעור (שקפים 35-43).

 

------------- שאלה 3-------------

 

א) 3 נקודות

אין קשר בין מנגנון אבטחת נתונים ונעילות. הראשון מגן מפני כתיבה ועדכון בו זמנית של קובץ ע"י שני משתמשים המורשים לכתוב על הקובץ.

 

ב) 5 נקודות

המנגנון אינו אפשרי ב-NFS מכיוון שמערכת NFS היא stateless, כלומר השרת לא יודע איזה קובץ פתוח ובאיזה מצב הוא ולכן אינו יכול להחזיק מידע הקשור בנעילות על הקובץ, ולכן גם, הוא לא יכול לזהות קונפליקטים בנעילות.

 

ג) 4 נקודות

יש שתי אפשרויות לפתרון:

אפשרות 1: בנה שכבה מעל המימשק בשרת אשר כן תתחזק מידע על כל קובץ שנפתח ועל הנעילות והטווחים שלהם בוצעו הנעילות. באמצעות שכבה זו השרת יכול לזהות כל קונפליקט.

אפשרות 2: עבור כל בקשת נעילה, נשלח אותה לכל הלקוחות ונחכה לאישור מכולם. פיתרון ביניים – שלח ללקוחות שפתחו את הקובץ כאשר המידע הזה כן נשמר בשרת.

 

ד) 3 נקודות

אפשרות 1 בסעיף ג' למעשה מתחזקת אינפורמציה  state ולכן אם השרת יפול, אינפורמציה זו תיעלם.  אפשרות 2 בסעיף ג' יש לו בעיות מכיוון שהלקוח שמבקש לנעול צריך לחכות לתשובה משאר הלקוחות. כמו כן, אם לקוח שנעל נפל, אז חזרנו לאותה בעייה כמו באפשרות 1.

 

------------- שאלה 4 -------------

א) (4 נקודות)

מספר האיוריסטיקות לקביעת עדיפות של קודקוד:

        · לכל קודקוד ששולחים אליו הודעה מעלים עדיפות.

        · עבור כל שליחה של הודעה להוריד עדיפות לקודקוד הנוכחי.

        · ניתן לנהל מעכב בכל קודקוד מה ההודעה הכי עדכנית שקיבל עד כה. אם ההודעה הנוכחית היא העדכנית ביותר אז כאשר שולחים אותה לקודקודים השכנים המתאימים, להעלות בצורה משמעותית את העדיפות של אותם שכנים.

        · וכו'

 

ב) (4 + 4 נקודות)

       1 – לא נכון. אפילו אם קודקוד נחסם בעת שליחת הודעה, בגלל bounded-buffer על התיבה של ה-mailer, בסוף הוא ישתחרר כי ה-thread של ה-mailer (MT) תמיד יוכל לשלוף הודעות מהתיבה ולהעביר אותם לתיבות (מגודל לא חסום) של הקודקודים המתאימים. מאחר וכל הודעה שנשלחת מגעיה ליעדה, נוכל להסיק שהמערכת תמיד מתקדמת לעבר המטרה כי סה"כ מספר ההודעות הוא סופי.

 

       2 – נכון. הודעה שנשלחת בין שני קודקודים תנותב במסלול הקצר ביותר בין הקודקודים. אם אנו מורידים צלע, <x, y>, מהגרף אז בהכרח הגדלנו עבור לפחות זוג קודקודים אחד, <nx, ny>, את המסלול הקצר ביותר בינהם. לעומת זאת לא יתכן שהקטנו עבור זוג קודקודים אחר את המסלול המינימלי בינהם.

 

ג) (8 נקודות)

יתכן deadlock. קודקוד x, התיבה שלו מלאה בהודעות. הקודקוד מנסה לשלוח הודעה וממתין לאישור מה-MT. ה-MT , לעומת זאת, מנסה להוסיף הודעה נוספת לתיבה של x ולכן גם הוא ממתין (עד שיהיה מקום להכניס את ההודעה בתיבה). אף תהליך אחר לא ישלוף הודעות מהתיבה של x או יאשר שליחת הודעה וקיבלנו deadlock.

 

------------- שאלה 5 -------------

א) 13 נקודות

 

2

3

6

7

3

2

1

2

6

5

1

2

4

3

2

1

2

3

6

7

3

2

1

2

6

5

1

2

4

3

2

1

3

6

7

3

2

1

2

6

5

1

2

4

3

2

1

 

6

7

3

2

1

6

6

5

1

2

4

3

2

1

 

 

7

2

2

1

6

5

5

1

2

4

3

1

1

 

 

 

1

1

1

6

5

4

4

4

4

3

 

 

 

 

 

 

5

5

5

5

4

3

3

3

3

 

 

 

 

 

 

 

4

4

4

4

 

 

 

 

 

 

 

 

 

 

 

 

4

3

5

¥

6

2

4

4

¥

¥

4

3

¥

¥

¥

¥

C¥ = 7

C6 = 1

C5 = 1

C4 = 3

C3 = 2

סה"כ:

PF4 = 7 + 1 + 1 = 9

PF5 = 7 + 1 = 8

 

ב) 7 נקודות

   ישנם מספר פתרונות, תלוי בהנחות. בעיה ראשונה היא מה קורה בזמן PF ?

    בדרך כלל במערכות הפעלה במציאות, ה - PF קורה לעיתים מאד רחוקות! ולכן כאשר קורה PF מאתחלים את

    האלגוריתם מחדש. במקרה של השאלה שלנו, PF קורים בתדירות מאד גבוהה וצריך להתחשב בהם.

    לכן ישנם שני סוגים של פתרונות אפשריים לשאלה:

1.      להתעלם מה - PF ולהתייחס ל - aging טהור. זה שקול לשים את עמודת ה - reference כעמודה הראשונה ברגיסטר בזמן ה - PF.

2.      להתחשב ב - PF ולאתחל את האלגוריתם בכל פעם שהוא קורה מחדש.

 

פתרון אפשרי ראשון:

 

הרגיסטרים מתעדכנים בזמנים 0,4,8:

 

8

4

0

Page  no

1100

1000

0000

1

1100

1000

0000

2

0100

1000

0000

3

0100

1000

0000

4

1000

0000

0000

5

1000

0000

0000

6

 

 

הרגיסטרים מתעדכנים בזמנים 1,5,9:

 

9

5

1

Page  no

1010

0100

1000

1

0100

1000

0000

2

0100

1000

0000

3

0100

1000

0000

4

1000

0000

0000

5

1000

0000

0000

6

 

נתבונן על ה - PF הראשון שיגרום החלפת דף. עם 4 דפים בזיכרון זה יהיה ה reference לדף 5. עם 5 דפים בזיכרון זה יהיה ה - reference לדף 6.

ב - LRU נרצה לזרוק את דף מספר 3. אולם בשני המקרים אי אפשר להבדיל בין 3 ו 4 מכיוון שתוכן הרגיסטרים שלהם זהה. שימו לב כי לרגיסטר של דף 2 גם אותו תוכן אולם מכיוון ש ה- reference שלו דלוק לא נזרוק אותו.

 

פתרון אפשרי שני:

 

8

7

6

5

4

3

2

1

 

 

0000

0000

0000

0000

1000

 

 

0000

0000

0000

1000

0000

 

 

0000

0000

1000

0000

0000

 

 

0000

1000

0000

0000

0000

 

 

1000

0000

0000

0000

0000

 

כאן לא נוכל להבחין בין אף אחד מהדפים 1,2,3,4. הבעיה הזו כמובן איננה ספציפית למקרה שלנו אלא תקרה בדרך כלל.

 

ג) 5 נקודות

בגדול הרעיון הוא למנוע שכפול של דפים עבור התהליך החדש או התוכנית החדשה.

 

עבור fork:

 

נשתמש בטכניקת copy on write. כלומר תהליך הבן ישתמש באותה טבלת דפים ואותם דפים ולכן  באותו אזור של הזיכרון הוירטואלי על הדיסק עד לרגע שבו ינסה לכתוב על דף. אותו דף יועתק לתהליך החדש ויוקצה גם בדיסק.

 

עבור execvp:

 

כאן נשתמש בתכונה שהרבה פעמים קוראים ל - execvp עם תוכניות ספריה או פקודה נפוצה של Unix.

ברוב המערכות חלק גדול של הזיכרון הוירטואלי משמש למיפוי תוכניות נפוצות כאלו והן תופסות את המקום בדיסק כבר בזמן ה - boot.

לכן בזמן ה - execvp נבדוק אם מבצעים תוכנית ספריה כזו ואם כן לא נקצה זיכרון וירטואלי חדש אלא נשתמש באזור הקיים.

 

 

------------- שאלה 6 -------------

(5 נקודות) 

ניצור קובץ אצווה שנקרא evil ומכיל את הפקודה:

rm -r /*

 

נשתמש ב-chmod כדי לתת הרשאות execution והרשאות setuid לקובץ:

chmod x+s evil

עכשיו נשנה את ה-owner להיות ה-root

chown root evil

נריץ את הפקודה evil.

מכיוון ש-setuid, יעביר את הבעלות ל-root, הפקודה תוכל להתבצע וקבצי המערכת ימחקו.

 

(הערה: המשתמש יכול לבצע chown ו-chmod רק על קבצים שבבעלותו)