לדלג לתוכן

Chapter 8: תהליכי רקע ומערכת Launchd - Asset A (Instructor Reference)

1. הלב של המערכת: תהליך launchd וההבדל בין LaunchDaemons ל-LaunchAgents.

1. תיאוריה והיסטוריה ברמה גבוהה (High-Level Theory & History) תהליך launchd הוצג לראשונה במערכת Mac OS X Tiger (10.4) כתחליף מודרני לאוסף כלי האתחול הישנים של יוניקס כמו init, rc, cron ו-inetd. הוא הפך מאז לעמוד השדרה של ניהול תהליכי רקע (Background Processes) במערכת ההפעלה macOS. מטרתו היא לנהל בצורה אחודה את כל השירותים שעולים יחד עם המערכת, ולוודא שהם מופעלים בזמן, קמים לתחייה אם הם קורסים, ומשתמשים במשאבים בצורה יעילה. כשהמערכת עולה, לאחר שהקרנל (Kernel) מאשר את תחילת העבודה, התהליך הראשון שנוצר (PID 1) הוא launchd, וממנו נולדים כל שאר התהליכים.

2. ארכיטקטורה טכנית עמוקה (Deep Technical Architecture) ישנה הפרדה חדה בארכיטקטורה של launchd בין מה שמופעל ברמת המערכת לבין מה שמופעל ברמת המשתמש.

  • LaunchDaemons: תהליכים אלו מופעלים תחת משתמש root או משתמשי מערכת ייעודיים ברגע שהמחשב מופעל (Boot), עוד לפני שמשתמש כלשהו מזין סיסמה. הם אחראים על פונקציונליות מערכתית שלא דורשת ממשק משתמש (GUI), כמו שרתי רשת, שירותי עדכון או אבטחה. הם אינם מסוגלים לגשת למסך או להתממשק לחלונות פעילים.
  • LaunchAgents: תהליכים אלו נטענים רק לאחר שהמשתמש מבצע התחברות (Login). הם רצים תחת ההרשאות של המשתמש המחובר, ומסוגלים לתקשר עם הממשק הגרפי (למשל, להציג תפריט עליון או להקפיץ חלון). אם מחוברים מספר משתמשים במקביל, ירוצו כמה עותקים של ה-LaunchAgent (אחד לכל משתמש), בעוד ש-LaunchDaemon ירוץ רק פעם אחת.

ההיררכיה מתחלקת גם לפי יוצר התהליך:

  • /System/Library/... שמור בלעדית לתהליכים של Apple המוגנים על ידי System Integrity Protection (SIP) ו-Sealed System Volume (SSV).
  • /Library/... מיועד לאפליקציות צד-שלישי (למשל, תוכנות אנטי-וירוס) ברמת המערכת כולה.
  • ~/Library/... (בתוך תיקיית הבית) מיועד לתהליכים של המשתמש הספציפי.

3. פקודות טרמינל, נתיבי Plist ולוגים (Terminal Commands, Plists & Logs) הכלי המרכזי לניהול תהליכי launchd הוא פקודת launchctl.

  • כדי לראות רשימה של כל השירותים שרצים כעת ברמת המערכת (דורש sudo): sudo launchctl list

  • טעינת LaunchDaemon חדש (או עדכון): sudo launchctl load -w /Library/LaunchDaemons/com.example.service.plist

  • חיפוש בלוגים על קריסה של Background Process (Unified Logging System): log show --predicate 'process == "launchd"' --info --last 1h

4. מקרי קצה ופתרון תקלות (Edge Cases & Troubleshooting) כאשר שירות מתחיל וקורס בלולאה אינסופית (Crash Loop), התהליך launchd מנסה להפעיל אותו מחדש, מה שגורם לעומס קיצוני ב-CPU. זה קורה לרוב בגלל קובץ plist עם נתיב הפעלה שגוי (למשל, אפליקציה שנמחקה אך ה-LaunchDaemon עדיין מנסה לעלות). הדרך לפתור זאת היא לפרוק את התהליך: sudo launchctl unload -w /Library/LaunchDaemons/com.example.service.plist לאחר מכן יש לבחון את קובץ ה-XML ולוודא שהנתיב שמצוין תחת המפתח ProgramArguments אכן קיים ויש לו הרשאות POSIX נכונות.


2. Activity Monitor עמוק: קריאת זיכרון (Memory Pressure) ומציאת זוללי משאבים (CPU).

1. תיאוריה והיסטוריה ברמה גבוהה (High-Level Theory & History) ה-Activity Monitor הפך לכלי האבחון הגרפי החשוב ביותר למערכת macOS מאז ימי OS X הראשונים. המטרה שלו היא לאפשר למשתמשים ולטכנאים לקבל Snapshot בזמן אמת של שימוש במשאבי המערכת. במערכות מודרניות מבוססות Apple Silicon, שבהן יש זיכרון מאוחד (Unified Memory), שיטות המדידה המסורתיות (כמו "כמה RAM פנוי נשאר") הפכו ללא רלוונטיות, ואפל הציגה מדדים חדשים, ובראשם ה-Memory Pressure.

2. ארכיטקטורה טכנית עמוקה (Deep Technical Architecture)

  • עומס מעבד (CPU): במעבדי Apple Silicon יש ליבות יעילות וליבות ביצועים. ה-Activity Monitor מציג לעיתים שימוש שמעל 100% (למשל 400% אם תהליך משתמש ב-4 ליבות באופן מלא). תהליך kernel_task הוא מיוחד – כאשר המערכת מתחממת, ה-kernel_task "תופס" מחזורי שעון של ה-CPU באופן מלאכותי ומונע מאפליקציות אחרות להשתמש בהן כדי לאפשר צינון של החומרה. למשתמש זה נראה כאילו kernel_task צורך המון משאבים ומאט את המחשב, אך למעשה זוהי מערכת ניהול התרמיקה בפעולה.
  • לחץ זיכרון (Memory Pressure): macOS פועלת לפי העיקרון של "זיכרון פנוי הוא זיכרון מבוזבז". היא שומרת קבצים ב-RAM למען גישה מהירה. לכן, מדד ה-Memory Pressure הוא קריטי. הוא מתבסס על אלגוריתם שבוחן עד כמה המערכת מתקשה לספק זיכרון לתהליכים שזקוקים לו:
  • ירוק: הכל תקין, הזיכרון מנוהל ביעילות (אפילו אם כל ה-RAM הפיזי תפוס).
  • צהוב: המערכת משתמשת בדחיסת זיכרון (Compressed Memory) כדי להימנע מכתיבה לדיסק.
  • אדום: המערכת נאלצת לבצע Swap (החלפת דפים) מול דיסק ה-SSD באופן מסיבי, מה שפוגע דרמטית בביצועים ומעיד שחסר Unified Memory.

3. פקודות טרמינל, נתיבי Plist ולוגים (Terminal Commands, Plists & Logs) הטרמינל מאפשר אבחון משאבים עמוק יותר:

  • הצגת כל התהליכים זוללי ה-CPU בזמן אמת (כמו ה-Top ביוניקס): top -u -s 2 (מתרענן כל 2 שניות ומסודר לפי CPU).

  • בדיקת מצב לחץ הזיכרון (Memory Pressure) דרך הטרמינל: memory_pressure

  • הפקת דוח מאובק (Sample) על תהליך ספציפי כדי לראות מה ה-Threads שלו עושים: sample <PID> (או מתוך Activity Monitor בגישה לתפריט גלגל השיניים > Sample Process).

4. מקרי קצה ופתרון תקלות (Edge Cases & Troubleshooting) כאשר שרת חלונות (WindowServer) צורך הרבה מעל 100% CPU והממשק מתחיל לקרטע, זה נובע פעמים רבות מחיבור למספר מסכים חיצוניים ברזולוציות לא נתמכות. כאשר Memory Pressure נמצא באדום קבוע, ייתכן שישנה אפליקציה עם דליפת זיכרון. ניתן לאתר אותה על ידי מיון עמודת Memory ב-Activity Monitor וביצוע Force Quit (Force Quit) לתהליך הספציפי. אם מדובר בשימוש לגיטימי (כמו עיבוד וידאו כבד), המסקנה היא שהמכונה הנוכחית אינה מספיקה לצורכי המשתמש ויש לשדרג את כמות ה-Unified Memory.


3. קבצי Plist: קריאה ואבחון של קבצי XML המנהלים את השירותים.

1. תיאוריה והיסטוריה ברמה גבוהה (High-Level Theory & History) קבצי Property List, או בקיצור plist, הם פורמט קבצים ייעודי לאפל. הם משמשים לאחסון הגדרות משתמש, תצורה של תוכנות, וניהול של שירותים ותהליכים. באופן מסורתי הם נכתבו כקבצי טקסט בפורמט XML פשוט, אך עם השנים, כדי לחסוך מקום וזמן עיבוד, אפל עברה להשתמש בהם כקבצים בינאריים (Binary plist) במקרים רבים, מה שהופך אותם לקשים לקריאה על ידי עורכי טקסט רגילים מבלי לבצע המרה מקדימה.

2. ארכיטקטורה טכנית עמוקה (Deep Technical Architecture) מבנה ה-XML של plist מתחיל תמיד בתגית <plist> שעוטפת אובייקט ראשי, לרוב מילון (<dict>). בתוך המילון, כל הגדרה מורכבת מזוגות של מפתח (<key>) וערך שמגיע מיד אחריו. בקשר ל-launchd, קובץ ה-plist חייב להכיל מפתחות ספציפיים כדי לעבוד. למשל:

  • Label: שם ייחודי לשירות (לרוב בפורמט Reverse DNS כגון com.apple.example).
  • ProgramArguments: מערך (<array>) שבו הפריט הראשון הוא הנתיב המלא לקובץ הריצה, והפריטים הבאים הם הדגלים (Flags).
  • RunAtLoad: בוליאני (<true/> או <false/>) שקובע אם התהליך יעלה אוטומטית כשהקובץ נטען.
  • KeepAlive: דואג ש-launchd יפעיל מחדש את התהליך מיד אם הוא קורס.

3. פקודות טרמינל, נתיבי Plist ולוגים (Terminal Commands, Plists & Logs) כיוון שרבים מקבצי ה-plist כיום הם בינאריים, עלינו להשתמש בכלי המערכת כדי לגשת אליהם בבטחה.

  • המרת קובץ plist בינארי ל-XML קריא: plutil -convert xml1 /path/to/file.plist

  • בדיקה אם קובץ plist כתוב בתחביר חוקי (Validation): plutil -lint /path/to/file.plist

  • קריאת ערך ספציפי מתוך קובץ (דרך כלי ה-defaults): defaults read /Library/LaunchDaemons/com.example.service.plist Label

4. מקרי קצה ופתרון תקלות (Edge Cases & Troubleshooting) עריכה ידנית של קבצי plist של המערכת (בתיקיית /System) בלתי אפשרית עקב ה-Sealed System Volume. כשמדובר בקבצי משתמש או צד-שלישי, עריכה עם עורך טקסט שלא שומר על סימון תחביר נכון תוביל לכישלון טעינה של התהליך במלואו. כלי ה-plutil -lint הוא חובה כדי לוודא שאין שגיאות כתיב לפני שמנסים להפעיל מחדש LaunchDaemon שיצא מכלל פעולה. בנוסף, לקבצי plist תחת /Library/LaunchDaemons חייבות להיות הרשאות בעלים של משתמש root, אחרת launchd יסרב לטעון אותם מטעמי אבטחה ויתעד הודעת שגיאה על הרשאות ב-Console.app.


4. תיבול ארגוני: איתור ה-Agent של מערכת ה-MDM, הבנת ססטוס הסנכרון שלו ומה עושים כשהוא קורס.

1. תיאוריה והיסטוריה ברמה גבוהה (High-Level Theory & History) בסביבות ארגוניות המחשבים מנוהלים על ידי פתרונות MDM. בניגוד לפרופילי התצורה של המערכת אשר נאכפים ברמת הקרנל, מערכות MDM שותלות על המחשב תוכנה ספציפית ("Agent") שרצה כתהליך רקע כדי לאפשר פעולות מורכבות יותר, כגון התקנת תוכנות או הרצת סקריפטים. כדי שהסוכן יפעל ויתקשר עם השרת גם לפני שהמשתמש ביצע התחברות, הוא מסתמך באופן ישיר על מנגנון ה-LaunchDaemons.

2. ארכיטקטורה טכנית עמוקה (Deep Technical Architecture) מערכות MDM יוצרות היררכיה כפולה בעזרת launchd:

  • ה-LaunchDaemon הארגוני: קובץ ב-/Library/LaunchDaemons (למשל com.jamfsoftware.task.1.plist). קובץ זה מגדיר את ביצוע הבדיקה המחזורית מול השרת. התהליך מורץ כ-root ולכן הוא יכול לבצע שינויים אגרסיביים במערכת.
  • ה-LaunchAgent הארגוני: קובץ ב-/Library/LaunchAgents (למשל com.jamf.management.login.plist). סוכן זה עוקב אחר פעולות הקשורות למשתמש, כמו הזרקת הגדרות בעת התחברות או הקפצת חלוניות פופ-אפ.

3. פקודות טרמינל, נתיבי Plist ולוגים (Terminal Commands, Plists & Logs) הפקודות תלויות בספק ה-MDM:

  • בדיקת הימצאות ה-Daemons (למשל ב-Jamf): ls -la /Library/LaunchDaemons/com.jamf*

  • כפיית סנכרון מיידי (Check-in) שמפעיל בעקיפין את השירות: sudo jamf policy

  • אם השירות הופסק, ניתן לנסות להפעיל מחדש את ה-Daemon בעזרת launchctl (במידה וה-MDM לא חוסם זאת): sudo launchctl load -w /Library/LaunchDaemons/com.jamfsoftware.task.1.plist

4. מקרי קצה ופתרון תקלות (Edge Cases & Troubleshooting) מקרה שכיח הוא כאשר מחשב מאבד תקשורת עם שרת ה-MDM והמשתמש מפסיק לקבל אפליקציות מקטלוג שירות עצמי (Self Service). הסיבה היא לעיתים קרובות קריסה או הסרה אגרסיבית של ה-LaunchDaemon הארגוני על ידי תוכנת אנטי-וירוס או טעות משתמש. ספקי MDM מגדירים ב-plist את הפרמטר KeepAlive ל-true, כך שאם ה-Agent קורס, המערכת מקפיצה אותו חזרה. אם ה-LaunchDaemon הוסר לחלוטין או נפגם, לרוב יהיה צורך להריץ מחדש פקודת שחזור שרשרת הניהול דרך הטרמינל (למשל sudo jamf manage) אשר יבנה מחדש ויטען את ה-LaunchDaemons הרלוונטיים בצורה נקייה אל מול ה-launchd של המערכת.