Showing posts with label FreeBSD. Show all posts
Showing posts with label FreeBSD. Show all posts

Wednesday, June 23, 2010

How to change resolver configuration file?

Q: How to change resolver configuration file?
A: I don't know.

ตรงนี้ขอเกริ่นนำกับบ่นๆๆๆๆ ก่อนนะครับ
อยากรู้วิธีแก้ path ของไฟล์คอนฟิก ข้ามไปอ่านข้างล่างได้เลยครับ
เมื่อประมาณต้นปีผมต้องเขียนโปรแกรมนึงให้มันไปเปลี่ยน dns server ของระบบ (FreeBSD) ที่โดนตั้งไว้ ปัญหาคือตอนที่ FreeBSD จะทำการ nslookup ไปที่ dns server มันจะอ่านไฟล์คอนฟิกนึงว่า dns server ของเราคือเครื่องไหน ไฟล์นั้นก็คือ /etc/resolv.conf ซึ่งมันจะอ่านทุกครั้งที่เราจะ nslookup!!! (ใส่เครื่องหมายตกใจทำไม อ้าว ไม่ตกใจเหรอครับ เพราะผมไม่รู้มาก่อน นึกว่ามันจะทำการโหลดค่ามาเก็บไว้ตอนบู๊ทเครื่องทีเดียว ไม่คิดว่ามันจะอ่านไฟล์ใหม่ทุกครั้ง)

เนื่องจากว่านโยบายในการเขียนโปรแกรมครั้งนั้นมีอยู่ว่า โปรแกรมของผมจะไม่แตะต้องไฟล์ใน /etc เพราะมันเป็นไฟล์ของระบบ ถ้าเกิดทำอะไรเสียหายไปเดี๋ยวจะเดือดร้อน (/etc ของ appliance ในความคิดผมควรจะเป็น read-only) ซึ่งจากประสบการณ์ที่ได้แตะเซอร์วิสของ FreeBSD มาบ้าง เซอร์วิสส่วนใหญ่เราสามารถระบุได้ว่าจะให้มันไปอ่านไฟล์คอนฟิกที่ไหน (ระบุได้จากหลายๆทาง เช่น environment variable ฯลฯ) หรือไม่ก็สามารถคอนฟิกในไฟล์คอนฟิกให้มัน include ไฟล์คอนฟิกอื่นเพิ่มเข้าไปได้ เราก็จะได้เขียนไฟล์คอนฟิกนั้นแค่ทีเดียวแล้วไปแก้ไฟล์คอนฟิกอื่นๆที่ include เข้าไปแทน

หลังจากการค้นหาอยู่นานผมก็ค้นพบวิธีการที่ทำให้มันไม่ต้องยุ่งกับ /etc/resolv.conf ได้ด้วยการ
...
...
เลิกเขียนโปรแกรมซะ

โว้ย ทำไมมันไม่มีวิธีวะ หาแทบพลิกแผ่นดินแล้ว สุดท้ายโปรแกรมของผมก็จำต้องไปแก้ไขไฟล์ /etc/resolv.conf ไปก่อนเพราะงานมันเร่งต้องส่งลูกค้าแล้ว

แล้วช่วงนี้ต้องกลับมาแก้ไขโครงสร้างของระบบใหม่ คราวนี้ได้รับคำสั่งมาว่า /etc ต้องโดน mount เป็น read-only ก็เลยต้องกลับมาค้นดูอีกทีว่าจะทำไงดี หลังจากถามพี่ที่บริษัทก็พบว่าตัว resolver ของ FreeBSD นั้นมันใส่ชื่อไฟล์ลงไปในโค้ดเลย โอ้ว แม่เจ้า ทำงี้ได้ไงฟระ

วิธีแก้
หลังจากที่ไล่โค้ดดู (อยู่ใน /usr/include/resolv.h) ก็เห็นส่วนที่ไว้ระบุไฟล์คอนฟิก มันระบุโดยการใช้ define เอาครับ ดังนั้นเราสามารถ define ค่าของตัวแปรใหม่ได้ตอนสั่งคอมไพล์ ค่อยยังชั่วหน่อย ไม่ต้องแก้โค้ด แต่ว่าเราก็ไม่สามารถเปลี่ยน path ของไฟล์คอนฟิกแบบ dynamic ได้อยู่ดี (โลกนี้มันช่างโหดร้ายจริงๆ)

ตัวแปรที่ไว้กำหนด path ของไฟล์คอนฟิกของ resolver นั้นชื่อว่า

_PATH_RESCONF

ขั้นตอนต่อไป เดี๋ยวจะลองคอมไพล์โดย define ตัวแปรนี้ชี้ไปที่อื่นดู
ตัวผมเองก็ไม่เคยคอมไพล์เคอเนลโดยใส่ออปชันอะไรแบบนี้มาก่อนเหมือนกัน ยังไม่ค่อยแน่ใจว่าต้องใส่ยังไง เดี๋ยวลองเสร็จแล้วจะมาสรุปอีกที

Wednesday, April 14, 2010

GNOME บน FreeBSD 8.0

อีกหนึ่งโปรเจกต์ FreeBSD ของผมคือการเอา FreeBSD มาใช้เป็นเดสก์ท็อปครับ (ฮ่าๆๆๆ เท่มั้ยหละ) แน่นอนว่าจะเอามาใช้เป็นเดสก์ท็อปก็ต้องมีการติดตั้ง Desktop Environment ไม่งั้นจะใช้ไงหละ

DE ที่ผมเลือกแบบไม่ต้องคิดเลยก็คือ GNOME ครับ (เห็นบางคนอ่านมันว่า "กะโนม" (คล้ายๆแบบกะนู) แต่ผมอ่านมันว่าจีโนม) ขี้เกียจหาอันใหม่ เอาอันนี้แหละ คุ้นเคยกันดีเพราะผมเคยลองใช้บน FreeBSD 7.x มาก่อนแล้วรอบนึงครับ ก็เลยคิดว่าบน 8.0 ก็คงเหมือนๆเดิม ก็ลงตามเสต็ปเดิม ปรากฏว่าตอนสั่ง GNOME ทำงานมันดันฟ้องว่าไม่มีไฟล์ /var/run/dbus.pid

หลังจากโง่อยู่นานก็พบว่า GNOME บน 8.0 มันต้องการเซอวิส dbus ด้วย (ไอ้ error ที่มันฟ้องแปลว่ามันหาไฟล์ process id dbus ไม่เจอ นั่นเป็นเพราะว่า dbus มันไม่ได้รันอยู่) เพราะงั้นเราต้องสตาร์ทมันก่อนสตาร์ท GNOME

หลังจากที่รัน GNOME ขึ้นมาได้ก็พบปัญหาอีกอย่างนึงคือ touchpad มันไม่ทำงานครับ ผมไม่สามารถควบคุมเคอเซอร์ได้ ตอนแรกก็นึกว่าเป็นปัญหาที่ FreeBSD กับ touchpad ของผม แต่บน X ธรรมดามันดันทำงานได้แฮะ อืม แล้วเป็นเพราะอะไรหละเนี่ย

พอค้นไปค้นมาก็เจอว่า GNOME เนี่ยมันต้องการเซอวิส hald รันด้วย ดังนั้นเราก็ต้องไปสตาร์ทมันก่อนอีกเหมือนกัน
หลังจากที่สตาร์ทเซอวิส 2 ตัวนี้แล้ว GNOME ก็จะใช้งานได้ตามปกติ

ปล[0] การสตาร์ท dbus กับ hald สามารถสตาร์ทได้ด้วย rc script ใน /usr/local/etc/rc.d ชื่อสคิปท์คือ dbus และ hald (ถ้าตอนลงไม่ได้คอนฟิกอะไรเป็นพิเศษมันจะอยู่ที่พาธนี้แหละ)
ปล[1] ปกติผมสั่ง `gdm` จากคอมมานด์ไลน์เลย แต่วันนี้พึ่งนึกได้ มันต้องมี rc script สิ พอลองค้นดูก็เห็นอยู่ที่ /usr/local/etc/rc.d/gdm

Saturday, February 28, 2009

FreeBSD เมื่อ loader.conf มีปัญหา

วันนี้นั่งหาวิธีทำให้ FreeBSD บนโน้ตบุ๊คใช้ไวเลสได้ครับ มาถึงตอนนี้ก็ยังทำไม่ได้ ซ้ำร้ายทำไปทำมา FreeBSD บู๊ทไม่ขึ้นซะอีก

อาการ
ตอนที่ FreeBSD กำลังแสดงข้อความต่าง ๆ ของระบบอยู่ดีมันก็มาหยุดที่ ndis0 (เป็นโมดูลที่เกี่ยวกับเน็ตเวิร์กของ ndis ครับ) ผมสั่งให้มันโหลดขึ้นมาตอนบู๊ท มันก็แจ้งว่า failed แล้วก็ค้างอยู่ตรงนี้

สาเหตุ
เนื่องจากว่าผมไปแก้ไฟล์ loader.conf (/boot/loader.conf) ให้มันโหลดโมดูลไดรเวอร์ของการ์ดแลนผมขึ้นมา แต่ไม่รู้ว่ามันเกิดปัญหาอะไร มันถึงโหลดไม่สำเร็จ ก็เลยเป็นสาเหตุให้ค้างตอนบู๊ทครับ

วิธีแก้
ตอนบู๊ท FreeBSD ขึ้นมาแล้วมีออปชั่นให้เลือก ให้เลือกออปชั่นหมายเลข 6 ครับ (จำไม่ได้ว่ามันเขียนว่าอะไร) แล้วมันก็จะมี prompt ขึ้นมาว่า OK ให้เราป้อนค่าตามนี้ครับ (OK นั่นเป็น prompt นะครับ ไม่ต้องกรอกตาม)

OK unload
OK load kernel
OK snd_hda
OK boot

แล้วเราก็จะบู๊ทได้ โดยไม่อ่าน loader.conf ครับ

แต่เดี๋ยวก่อนครับ ผมยังเจออีกปัญหา ตอนบู๊ทขึ้นมาด้วยวิธีนี้ ปรากฏว่าผมไปแก้ไฟล์ /etc/rc.conf ด้วย และแก้ผิดไปครับ (มีเครื่องหมายคำพูดเกินมาตัว) ทำให้มันแจ้งเตือนว่าไฟล์ /etc/rc.conf ผิด จากนั้นมันให้กรอก path ของ shell ที่จะใช้งานครับหลังจากกรอกเสร็จมันก็เข้าสู่ระบบให้โดยอัตโนมัติ

แต่ผมพบว่ามันไม่ได้ mount file system ให้ซักตัวเลยครับ ผมต้องมา mount เอง ทั้ง /usr /var /tmp เพราะเนื่องจากว่ามันไม่ได้ mount /usr ให้ดังนั้นเราจะไม่เห็นคำสั่งหลาย ๆ คำสั่งครับ รวมถึง vi ด้วย ผมเลยต้อง mount /usr แต่ว่าการใช้ vi นั้นมันจะไปสร้างไฟล์ใน /tmp เลยจำเป็นต้อง mount /tmp ด้วย ส่วน /var นั่นก็ mount เผื่อ ๆ ไปครับ (ตอน mount ก็เรียกดูจากไฟล์ /etc/fstab)

หลังจากนั้นผมก็พยายามแก้ไฟล์ทั้งสองแต่ปรากฏว่าผมไม่สามารถบันทึกได้ครับ มันแจ้งเตือนว่า "Read-Only file system" หลังจากค้นดูก็พบวิธีแก้โดยใช้คำสั่ง

mount -u /

มันจะไปเปลี่ยนจาก Read-Only เป็น Read/Write ครับ ทีนี้เราก็จะสามารถแก้ไขไฟล์ที่เสียได้ตามที่ต้องการ

----

แถม
เนื่องจากตอนที่มันไม่ mount อะไรให้ซักอย่างผมเลยต้องมา mount เอง แต่ตอนค้นเรื่อง Read-Only ผมก็เจอคำสั่ง mount ทั้งหมดให้อัตโนมัติครับ

mount -a

มันจะ mount ตามไฟล์ /etc/fstab ให้อัตโนมัติครับ