Planet TLWG

Subscribe to Planet TLWG feed
Planet TLWG - http://debianclub.org/planet-tlwg
Updated: 2 months 4 days ago

Kitt: GRUB timeout options

13 February, 2015 - 17:19
There are many timeout configuration for grub2 that you can put in /etc/default/grub GRUB_TIMEOUT GRUB_HIDDEN_TIMEOUT GRUB_RECORDFAIL_TIMEOUT The last one may help to boot normally in case power loss.

Thep: Pretty Feb Calendar Solution

12 February, 2015 - 15:14

ใน blog ที่แล้ว ผมได้ตั้งคำถามเกี่ยวกับปฏิทินที่ลงตัวของเดือนกุมภาพันธ์ว่ามีปีใดบ้าง ปรากฏว่ามีผู้ร่วมสนุกมาใน คอมเมนต์ โดยคิดแยกเป็นกรณีต่าง ๆ ของการเลื่อนวันในสัปดาห์ของวันที่เดิมของแต่ละปี

ก่อนอื่น เงื่อนไขของปีปฏิทินสวยก็คือ วันที่ 1 กุมภาพันธ์ของปีนั้นจะตรงกับวันอาทิตย์ และปีนั้นต้องเป็นปีปกติสุรทิน คือเดือนกุมภาพันธ์มี 28 วัน

คุณ Hisoft Manager ได้ตรวจสอบการเลื่อนวันในสัปดาห์ของวันที่ 1 กุมภาพันธ์ของแต่ละปีที่ติดกัน และแยกอธิบายเป็นกรณี ๆ ความคิดเริ่มแรกผมก็คิดด้วยวิธีคล้าย ๆ กันนี้ โดยคิดเป็นเศษเหลือจากการหารด้วย 7 โดยในปีปกติสุรทินซึ่งมี 365 วัน จะทำให้ 1 กุมภาพันธ์ของปีถัดไปเลื่อนวันในสัปดาห์ไป 1 วัน (365 หารด้วย 7 เหลือเศษ 1) และในปีอธิกสุรทินซึ่งมี 366 วัน จะทำให้ 1 กุมภาพันธ์ของปีถัดไปเลื่อนวันในสัปดาห์ไป 2 วัน (366 หารด้วย 7 เหลือเศษ 2) จากนั้นก็ใช้เงื่อนไขนี้ตรวจสอบรูปแบบการเลื่อนที่ทำให้ 1 กุมภาพันธ์เลื่อนกลับมาตรงกับวันอาทิตย์อีกครั้ง โดยมีเงื่อนไขเพิ่มเติมว่าปีนั้นต้องไม่เป็นปีอธิกสุรทินด้วย

ผลที่ได้คือ ปีปฏิทินสวยจะเป็นลำดับที่สมาชิกเพิ่มค่าเป็นรูปแบบ 6-11-11 คือปี 2009, 2015, 2026, 2037, 2043, 2054, 2065, ... คิดเป็นสูตรทั่วไปได้ว่า เป็น ค.ศ. ที่หารด้วย 28 แล้วเหลือเศษ 10, 21 หรือ 27 แต่ลำดับนี้จะเปลี่ยนรูปแบบเมื่อผ่านจุดที่เป็นข้อยกเว้น คือเมื่อ ค.ศ. หารด้วย 100 ลงตัว แต่หารด้วย 400 ไม่ลงตัว คำตอบจึงต้องแบ่งเป็นช่วง ๆ เช่น ระหว่าง ค.ศ. 1801-1899 จะเป็นปีที่หารด้วย 28 แล้วเหลือเศษ 9, 15, 26 เป็นต้น และจะต้องพิจารณาตรงช่วงรอยต่อระหว่างช่วงเป็นจุด ๆ ไป

ผมจึงพยายามหาสูตรทั่วไปที่ครอบคลุมทุกช่วง โดยเริ่มตั้งแต่ ค.ศ. 1753 ซึ่งเป็นปีแรกที่ปฏิทินนับเป็นปกติหลังจากที่ เริ่มใช้ปฏิทิน Gregorian แทนปฏิทิน Julian ตามที่คำสั่ง cal ของ GNU ได้ implement โดยตัดวันที่ 3-13 กันยายน 1752 ออกจากปฏิทิน:

$ cal 9 1752
    กันยายน 1752
อา จ. อ. พ. พฤ ศ. ส.
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30



จุดเริ่มต้นของเราจึงเป็นวันที่ 1 กุมภาพันธ์ 1753 ซึ่งเป็นวันพฤหัสบดี:

$ cal 2 1753
  กุมภาพันธ์ 1753
อา จ. อ. พ. พฤ ศ. ส.
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28

ผมกำหนดให้เศษเหลือจากการหารด้วย 7 แทนวันต่าง ๆ ในสัปดาห์ โดย 0 แทนวันอาทิตย์, 1 แทนวันจันทร์, 2 แทนวันอังคาร, ... 6 แทนวันเสาร์ ดังนั้น เศษเหลือเริ่มต้นในปี 1753 ของเราจึงเป็น 4 คือวันพฤหัสบดี

สมมุติให้ y แทนปีที่ต้องการพิจารณา นับจากปี 1753 ถึงปี y ถ้าทุกปีมี 365 วัน วันในสัปดาห์จะเลื่อนไปข้างหน้าปีละ 1 วัน (365 หารด้วย 7 เหลือเศษ 1) นับได้ y - 1753 วัน หากนำมาบวกวันเริ่มต้นคือวันพฤหัสบดี (เศษ 4) แล้วหารด้วย 7 เพื่อดูเศษเหลือ ก็จะรู้วันในปฏิทินของปีนั้นว่าเป็นวันอะไร แต่นี่คือกรณีที่ทุกปีมี 365 วัน โดยยังไม่คิดปีอธิกสุรทิน:

วันในสัปดาห์ของ 1 ก.พ. ปี y = (4 + (y - 1753)) mod 7 ถ้าทุกปีเป็นปกติสุรทิน

ปีอธิกสุรทินที่เกิดแต่ละครั้งจะทำให้วันในปฏิทินเลื่อนเพิ่มอีก 1 วัน หากรู้จำนวนปีอธิกสุรทินตั้งแต่ปี 1753 ถึงปี (y - 1) ก็จะนำมาบวกเพิ่มเข้ากับการเลื่อนวันในสูตรข้างต้นนี้ก่อนหารด้วย 7 เอาเศษ

จำนวนปีอธิกสุรทินตั้งแต่ปี 1753 ถึงปี (y - 1) คำนวณได้จากจำนวนปีอธิกสุรทินตั้งแต่ปี 1 ถึงปี (y - 1) ลบด้วยจำนวนปีอธิกสุรทินตั้งแต่ปี 1 ถึงปี 1753

จำนวนปีอธิกสุรทินตั้งแต่ปี 1 ถึงปี (y - 1) = floor((y-1)/4) - floor((y-1)/100) + floor((y-1)/400)

จำนวนปีอธิกสุรทินตั้งแต่ปี 1 ถึงปี 1753 = floor(1753/4) - floor(1753/100) + floor(1753/400) = 438 - 17 + 4 = 425

จำนวนปีอธิกสุรทินตั้งแต่ปี 1753 ถึงปี (y - 1) = floor((y-1)/4) - floor((y-1)/100) + floor((y-1)/400) - 425

ดังนั้นจึงได้ว่า วันที่ 1 ก.พ. ปี y จะตรงกับวัน: (4 + (y - 1753) + floor((y-1)/4) - floor((y-1)/100) + floor((y-1)/400) - 425) mod 7

หักลบตัวเลขแล้วจะได้เป็น (y - 2174 + floor((y-1)/4) - floor((y-1)/100) + floor((y-1)/400)) mod 7

และในเมื่อ 2174 mod 7 = 4 จึงแทน 2174 ด้วย 4 ใน modulo ได้ ได้เป็น:

วันในสัปดาห์ของ 1 ก.พ. ปี y = (y - 4 + floor((y-1)/4) - floor((y-1)/100) + floor((y-1)/400)) mod 7

และได้ว่า ปีปฏิทินสวย คือปีที่เป็นปกติสุรทิน และวันในสัปดาห์ของ 1 ก.พ. เป็น 0 ซึ่งเขียนเป็นนิพจน์เงื่อนไขภาษา C ได้เป็น:

  ((y % 4 != 0) || (y % 100 == 0 && y % 400 != 0)) &&
  (y - 4 + floor((y-1)/4) - floor((y-1)/100) + floor((y-1)/400)) % 7 == 0

QED.

Thep: Feb 2015 Calendar

8 February, 2015 - 22:32

เมื่อเดือนที่แล้ว ผมได้รับข้อความจากเพื่อน ซึ่งส่งต่อมาจากคนอื่นอีกที ความว่า:

ปีนี้เดือนกุมภาพันธ์ มี 4 อาทิตย์, 4 จันทร์, 4 อังคาร, 4 พุธ, 4 พฤหัส, 4 ศุกร์ และ 4 เสาร์ ซึ่งจะเกิดได้ทุก 823 ปี ชาวจีนถือเป็นปีถุงเงิน ถ้าส่งให้เพื่อนหรือ กลุ่มเพื่อน อย่างน้อย 5 คน จะมีเงินไหลเข้ามาใน 4 วัน ส่งภายใน 11 นาที หลังอ่านจบ

เพื่อนคงส่งมาขำ ๆ แต่ความ geek ในตัวผมไม่เข้าใครออกใคร เลยตอบเพื่อนไปว่า ความจริงแล้วมันเกิดได้ทุกปี ยกเว้นปีที่ ค.ศ. หารด้วย 400 ลงตัว หรือไม่ก็หารด้วย 4 ลงตัว แต่หารด้วย 100 ไม่ลงตัว ผมซีเรียสนะเฟ้ย! ;-P

ก็ปีไหนเดือนกุมภาพันธ์มี 28 วัน ก็ปีนั้นแหละ กุมภาพันธ์จะมี 4 อาทิตย์, 4 จันทร์ ฯลฯ 4 เสาร์ (4*7 = 28) ซึ่งมันก็แทบทุกปี

แต่อย่างไรก็ตาม ปฏิทินเดือนกุมภาพันธ์ปีนี้ก็ยังมีอะไรพิเศษที่น่าสนใจ:

$ cal 2 2015
  กุมภาพันธ์ 2015     
อา จ. อ. พ. พฤ ศ. ส.  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  


คือเรียงสี่สัปดาห์ลงตัวสวยงาม ไม่ขาดไม่เกิน จึงเกิดคำถามที่น่าสนใจว่า ปฏิทินอย่างนี้จะเกิดได้ในปีไหนบ้าง?

ตัวอย่างของปีที่ว่าก็เช่น:

$ cal 2 2009
  กุมภาพันธ์ 2009
อา จ. อ. พ. พฤ ศ. ส.
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28


$ cal 2 2026
  กุมภาพันธ์ 2026
อา จ. อ. พ. พฤ ศ. ส.
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28


$ cal 2 2037
  กุมภาพันธ์ 2037
อา จ. อ. พ. พฤ ศ. ส.
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28


$ cal 2 2043
  กุมภาพันธ์ 2043
อา จ. อ. พ. พฤ ศ. ส.
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28


แล้วจะมีปีไหนอีกนะ?

หมายเหตุ: ยังไงรอบก็ยังไม่ถึง 823 ปีอย่างที่เขาว่าอยู่ดี ก็ยังเดาไม่ออกว่าปีถุงเงิน เขาเอามาจากตำราไหน :-P

ข้อสังเกต:

  • ปฏิทินโหราศาสตร์จีนเป็นปฏิทินจันทรคติ
  • ข้อความเรื่องปีถุงเงินนี้ มีแพร่ในอินเทอร์เน็ตมาหลายรอบแล้ว

ขอบคุณเพื่อนที่ส่งข้อความนี้มา ทำให้ผมได้อะไรคิดเล่นสนุก ๆ ผมทิ้งไว้ให้ผู้อ่านลองคิดกันดูนะครับ

Thep: Yet Another LibThai Optimization Effort

5 February, 2015 - 15:06

ความพยายามในการ optimize libthai ยังคงดำเนินต่อไป หลังจากที่ได้ ปรับอัลกอริทึม ไปแล้วในรุ่น 0.1.21 ที่ได้ลดเวลาการ recover จาก error ลง

ทำแคชให้กับกระบวนการ recover (ไม่สำเร็จ)

รอบนี้ ผมได้พยายามลดจำนวนการ recover ลง แต่ต้องล้มเลิกในที่สุด

แนวคิดคือ การ recover จากจุดใดจุดหนึ่งจะได้คำตอบเหมือนเดิมไม่ว่าจะคำนวณกี่ครั้ง และในเมื่ออัลกอริทึมที่ผมใช้มีการพิจารณากรณีต่าง ๆ หลายกรณี จึงมีโอกาสที่กรณีเหล่านั้นจะมาพบ error ที่จุดเดียวกัน การเก็บแคชของจุด recover ไว้จึงช่วยให้ไม่ต้องคำนวณซ้ำอีก

ในโค้ดเดิมของ libthai มีการทำแคชอย่างง่ายไว้ โดยเก็บผลการ recover ครั้งล่าสุดไว้ ซึ่งแม้ hit rate จะต่ำมาก แต่ก็กลับช่วยลดเวลาได้ ถ้าเอาโค้ดนี้ออกเวลาที่ใช้จะเพิ่มขึ้น แนวคิดที่จะทำครั้งนี้คือขยายแคชให้ครอบคลุมทั้งข้อความ ซึ่งจากการทดลอง ผลที่ได้คือสามารถลดจำนวนการ recover ได้มากขึ้นจริง แต่โสหุ้ยของการทำแคชก็เพิ่มขึ้นด้วย และด้วย hit rate ที่ยังต่ำอยู่ ทำให้เวลาที่ลดได้ไม่สามารถหักลบกับเวลาที่เพิ่มขึ้นจากการ access แคชทุกรอบได้ ไม่ว่าจะลดโสหุ้ยต่าง ๆ ของแคชลงเท่าใดก็ตาม สรุปคือผมต้องโยนแพตช์นี้ทิ้ง เพราะการทำแคชกลับทำให้ใช้เวลาเพิ่มขึ้น!

อย่างไรก็ดี สิ่งที่ได้คือการได้พิสูจน์ว่าวิธีนี้ใช้ไม่ได้ ไม่ต้องพยายามอีก ไปหาวิธีอื่นต่อไป แต่ก็ขอเขียนบันทึกเป็น blog เพื่อช่วยเตือนความจำตัวเองในอนาคต

บทเรียน:

  • จะทำแคช ให้ระวังโสหุ้ยของแคชด้วย
  • ถูกย้ำเตือนอีกครั้งว่า malloc() นั้นโสหุ้ยสูงมาก (แพตช์แรกผมใช้ malloc() จองแคช ปรากฏว่าเวลาพุ่งกระฉูด แพตช์ต่อมาจึงปรับเป็น fixed array แทน)
  • แนวคิดในการ optimize ไม่สามารถสรุปเอาเองด้วยหลักเหตุผลได้ ควรพิสูจน์ด้วย profiler เสมอ
Micro-optimization ด้วย LIKELY/UNLIKELY

แนวคิดถัดมาคือการใช้ ส่วนขยายของ GCC คือ __builtin_expect() ที่ใช้ช่วยทำให้ branch prediction ของ CPU ทำได้ดีขึ้น โค้ดในโครงการต่าง ๆ ได้สร้างเป็นแพตเทิร์น LIKELY และ UNLIKELY ไว้ใช้ เช่น Linux kernel, GLib ของ GNOME, MFBT ของ Mozilla

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

มีคนเขียน blog เรื่อง How much do __builtin_expect(), likely(), and unlikely() improve performance? ไว้ พร้อมโค้ดทดสอบ ผมลองเลียนแบบตามเล่น ๆ เมื่อนานมาแล้ว ก็ไม่พบความแตกต่างอย่างมีนัยสำคัญ ทั้งนี้เพราะเครื่องมือที่ใช้วัด คือคำสั่ง time ไม่ได้ละเอียดพอ และเวลาที่ใช้รันโปรแกรมแต่ละครั้งก็ไม่เท่ากัน ขึ้นอยู่กับโหลดของระบบในขณะนั้นด้วย แต่รอบนี้ผมต้องการคำตอบจริงจังขึ้น จึงเปลี่ยนไปใช้ callgrind วัด ซึ่งได้ค่าละเอียดและเที่ยงตรงกว่า

โค้ดทดสอบ:

#include <stdio.h>

#ifndef NOLIKELY
#define LIKELY(expr) (__builtin_expect (!!(expr), 1))
#define UNLIKELY(expr) (__builtin_expect (!!(expr), 0))
#else
#define LIKELY(expr) (expr)
#define UNLIKELY(expr) (expr)
#endif

#define N_LOOP 10
#define N_DATA 8300000

static __attribute__ ((noinline)) int
count (int a)
{
  return ++a;
}

int main ()
{
  char p[N_DATA];
  int i, j;
  int c1, c2;

  for (i = 0; i < N_DATA; i++) {
    p[i] = (i % 10 == 0) ? 1 : 0;
  }

  c1 = c2 = 0;
  for (j = 0; j < N_LOOP; j++) {
    for (i = 0; i < N_DATA; i++) {
      if (LIKELY (p[i] == 0)) {
        c1 = count (c1);
      } else {
        c2 = count (c2);
      }
    }
  }

  printf ("Likely: %d, Unlikely: %d\n", c1, c2);

  return 0;
}

คอมไพล์:

$ cc -O2 likely.c -o likely
$ cc -O2 -DNOLIKELY likely.c -o nolikely

ทดสอบด้วยคำสั่ง time:

$ time ./nolikely
Likely: 74700000, Unlikely: 8300000

real 0m0.282s
user 0m0.272s
sys 0m0.008s
$ time ./likely
Likely: 74700000, Unlikely: 8300000

real 0m0.280s
user 0m0.272s
sys 0m0.004s

ไม่ได้แตกต่างกันมาก และวัดแต่ละเที่ยวก็ได้ค่าต่างกันจนถือว่าผลหยาบเกินไป ไม่สามารถเทียบกันได้

ทดสอบด้วย callgrind ซึ่งวัดแต่ละเที่ยวได้ค่าเดิมอย่างสม่ำเสมอ:

$ valgrind --tool=callgrind ./nolikely
==16287== Callgrind, a call-graph generating cache profiler
==16287== Copyright (C) 2002-2013, and GNU GPL'd, by Josef Weidendorfer et al.
==16287== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==16287== Command: ./nolikely
==16287== 
==16287== For interactive control, run 'callgrind_control -h'.
Likely: 74700000, Unlikely: 8300000
==16287== 
==16287== Events    : Ir
==16287== Collected : 938005876
==16287== 
==16287== I   refs:      938,005,876
$ valgrind --tool=callgrind ./likely
==16313== Callgrind, a call-graph generating cache profiler
==16313== Copyright (C) 2002-2013, and GNU GPL'd, by Josef Weidendorfer et al.
==16313== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==16313== Command: ./likely
==16313== 
==16313== For interactive control, run 'callgrind_control -h'.
Likely: 74700000, Unlikely: 8300000
==16313== 
==16313== Events    : Ir
==16313== Collected : 938005846
==16313== 
==16313== I   refs:      938,005,846

ผลที่ได้คือ callgrind วัดความแตกต่างของเวลาที่ใช้เมื่อใช้ LIKELY และ UNLIKELY ได้ แต่มีข้อสังเกตคือ

  • สามารถลดเวลาลงได้เพียงเล็กน้อยเท่านั้น (ซึ่งก็ควรเป็นเช่นนั้น เรารู้ว่านี่คือ micro-optimization)
  • ต้องคอมไพล์แบบออปติไมซ์ (-O2 ขึ้นไป ซึ่งเปิดใช้ตัวเลือก -freorder-blocks) ถ้าไม่ออปติไมซ์ ผลจะไม่แน่นอน บางกรณีได้โค้ดที่ทำงานเร็วขึ้น บางกรณีได้โค้ดที่ทำงานช้าลง
  • ถ้าใช้ LIKELY/UNLIKELY ในทางกลับกับที่ควรจะเป็น จะได้โค้ดที่ทำงานช้าลงเสมอ

นั่นคือสิ่งที่สังเกตได้ และเมื่อนำมาใช้กับ LibThai จริง ๆ ก็ได้พบกับความงุนงง เพราะจุดแรกที่ผมนำมาใช้ก็คือ การลดโสหุ้ยของแคชของการ recover ดังที่กล่าวไปข้างต้น โดยได้วัด hit rate คร่าว ๆ ซึ่งต่ำกว่า 2% และแน่ใจว่าการ hit cache นั้นควรใช้ UNLIKELY แน่ ๆ แต่ผลที่ได้คือ มันใช้เวลาเพิ่มขึ้น! (การใช้ LIKELY แทนก็ให้ผลไม่ต่างกัน)

ผมยังไม่สามารถเข้าใจได้ว่าทำไม มันอาจไปรบกวน dynamic branch prediction ของ CPU หรืออย่างไรก็ไม่ทราบได้

หลังจากโยนแพตช์เรื่องแคชของการ recover ทิ้งไปแล้ว ผมก็ถอยกลับมาลอง LIKELY และ UNLIKELY กับกรณีอื่นที่มีความแน่นอน 100% เช่น กับ lazy initialization ที่ทำงานเพียงครั้งเดียวเท่านั้น และกับ error handling ในกรณีที่ malloc() ไม่สำเร็จ ซึ่งปรากฏว่า มันลดเวลาได้จริง ๆ แฮะ

กล่าวคือ ลดเวลาที่ callgrind วัดได้ จาก 44,313,933 ลงเหลือ 44,307,666 คิดเป็น 0.014%

ถือว่าน้อยนิดสำหรับเป้าประสงค์ที่ต้องการ คือการ optimize LibThai แต่สิ่งที่ผมได้มากกว่านั้นคือการได้เรียนรู้ธรรมชาติของ LIKELY/UNLIKELY ว่าควรใช้กับเงื่อนไขที่แน่ใจ 100% เท่านั้น อย่าใช้พร่ำเพรื่อ!

และได้เข้าใจลึกซึ้งถึงสิ่งที่คู่มือ GCC เขียนไว้ว่า...

...as programmers are notoriously bad at predicting how their programs actually perform...

เข้าใจแล้วคร้าบ... <(_ _)>

หมายเหตุ: commit ไปแล้วครับ โครงการต่อไปคือ หาทาง optimize libdatrie

Kitt: Term Ended

31 January, 2015 - 14:13
วันนี้เป็นวันสุดท้ายของการทำงานในตำแหน่งผู้ช่วยอธิการบดีฝ่ายเทคโนโลยีสารสนเทศ และ ผู้อำนวยการสำนักนวัตกรรมการเรียนการสอน มหาวิทยาลัยขอนแก่น พยายามสำรวจตัวเองว่ารู้สึกยังไง .. แล้วก็พบว่า ไม่มีความรู้สึกอะไรกับเรื่องนี้เลย อาจจะเป็นเพราะตระหนักดีอยู่แล้วว่า วาระมีเริ่มต้น-สิ้นสุดเป็นปกติธรรมดา ก็เลยได้แต่บันทึกปักหมุดไว้เฉยๆ

Neutron: RahuNAS จัดเต็ม

18 January, 2015 - 09:00


ระบบ ติดตั้งให้ มหาวิทยาราชภัฏเทพสตรี จ.ลพบุรี
เป็นระบบที่เป็น OpenSource Software ทั้งระบบ

ตามแผนผังแล้ว เป็นระบบใหญ่ชุดแรก ที่ผมติดตั้งเองทุกส่วน เพราะตอนทำร่วมกับ มหาวิทยาลัยขอนแก่น ผมทำแค่หน้าด่าน (RahuNAS) ส่วนหลังบ้าน ม.ข. จัดไว้หมดแล้ว

ณ ปัจจุบัน ม.ข. ไม่ได้ใช้ RahuNAS แล้ว แต่ก็เป็นเรื่องที่น่ายินดี เพราะทาง ม.ข. มีบุคคลากรที่มีความสามารถ ทุกคนช่วยกัน และเลือกใช้ระบบที่เหมาะสมกับความต้องการของทางมหาวิทยาลัยได้เป็นอย่างดี และผมยินดีเป็นอย่างยิ่ง ที่เคยร่วมงานกับทุกท่าน ช่วงเวลาที่แก้ปัญหาด้วยกัน ทำให้ RahuNAS ยังเดินต่อไป และยังประโยชน์สำหรับผู้ใช้งาน ณ ที่อื่น ๆ ผมขอขอบคุณทีมงานทุกท่านครับ

เข้าเรื่อง ในแผนผังนี้ มีหลายส่วนที่ผมต้องเรียนรู้ใหม่ ซึ่งเป็นส่วนที่สำคัญ ๆ ของระบบ

* LDAP - OpenLDAP ใช้เป็น Backend ให้ FreeRADIUS ซึ่งก่อนหน้านี้ผมใช้ PostgreSQL เป็น Backend ไม่ใช่ PostgreSQL ไม่ดี แต่นี่ คือ ความต้องการของสถานศึกษา ส่วนนี้ เป็นส่วนที่ใช้เวลาพอสมควร ต้องเริ่มเรียนรู้ จนค่อย ๆ เข้าใจการทำงาน และนำไปใช้งานได้ในที่สุด

* LDAP Replica - ส่วนนี้ ติดตั้งเป็น Master - Consumer(s) ด้วยเหตุผลที่ว่า ฐานข้อมูลนี้ เขียนไม่บ่อย แต่อ่านบ่อย เพื่อลดความยุ่งยาก Master - Consumer(s) จึงเป็นทางเลือกที่ไม่เลว

* LDAP Loadbalancer - HAProxy - ไม่มีเหตุผลอะไรมากสำหรับส่วนนี้ เหตุผลเดียวนั้นคือ มีตัวอย่าง มีคนทำ และมันใช้งานได้ ^_^

* Radius Loadbalancer - ใช้ FreeRADIUS กำหนดค่าให้ทำหน้าที่เป็น Proxy ซึ่งในส่วนนี้ FreeRADIUS มีความพร้อมที่จะทำได้อยู่แล้ว แต่กว่าจะตบให้เข้าที่ก็เล่นเอาเหงื่อตกเหมือนกัน

ส่วนพระเอกของงาน หนีไม่พ้น RahuNAS

RahuNAS ที่ติดตั้งที่นี่ เป็นรุ่นที่ปรับปรุงล่าสุด ที่เตรียมการไว้ว่า จะออกรุ่น 1.0.0 ส่วนตอนนี้ ก็อยู่ในขั้น beta แล้วหละ(มั้ง)

ปรับปรุง หลายส่วนพอสมควร (จริง ๆ ก็ทำเรื่อย ๆ มา)

* ระบบ command message ที่ Web Login คุยกับ RahuNAS Bakend ยังเป็น xmlrpc แต่ปรับใช้ JSON-Base64 encoded เป็น message ทำให้เวลาปรับเปลี่ยน ส่งข้อมูลเพิ่มเติม ทำได้สะดวกขึ้นมาก

* PHP Web Login - ปรับมาใช้ Smarty template engine ทำให้ code ในส่วน PHP ดู clean ขึ้นเยอะ และ Smarty ยังมีส่วนของ caching ทำให้แสดงผลได้เร็วขึ้นด้วย

* เพิ่มส่วนของการทำ MAC Address Authen ซึ่งไม่ใช่แค่ MAC Allow (Bypass) แต่เป็นการทำ Authentication ด้วย MAC Address มีผูก MAC Address กับผู้ใช้งาน และมีการบันทึก Account ด้วยชื่อผู้ใช้งานนั้นเข้าในระบบด้วย ส่วนนีพัฒนาโดยใช้ความสามารถของ Netfilter และแน่นอนที่สุดสำหรับ RahuNAS คือ ถึงเพิ่มส่วน MAC Authen ต้องไม่ทำให้ระบบช้าไปกว่าที่เคยเป็น ^_^

* มีส่วนของการทำ Cross Network Roaming - ในระบบที่มีหลาย VLAN ซึ่งผู้ใช้งาน ที่เกาะแต่ละ VLAN จะได้ IP คนละชุด ทำให้เมื่อผู้ใช้งานเปลี่ยน VLAN ในระบบเดิม จะต้องทำการ login ใหม่ทุกครั้ง ส่วนนี้ จึงถูกสร้างขึ้นมาเพื่อช่วยให้ผู้ใช้งาน ไม่ต้อง login ใหม่ แต่ทำการย้ายผู้ใช้งานข้ามเครือข่ายให้เลย โดยหลักการคือ logout จากที่เดิม และ login (automatic) เข้าเครือข่ายใหม่

ข้อจำกัด คือ
1. ยังไม่สามารถย้ายเครือข่าย ข้ามเครื่อง Authen ได้ เช่น ย้ายจาก Authen1 ไป Authen2 ไม่ได้ แต่การย้ายเครือข่ายภายในเครื่องเดียวกันทำได้
2. เครื่องผู้ใช้ และ Browser จะต้องทำการเปิดรับ Cookies เนื่องจากระบบจำเป็นต้องฝาก token ไว้กับผู้ใช้เพื่อใช้ยืนยันตัวตน

* เพิ่มส่วนของการทำ IP accounting มีการบันทึก จำนวนการรับส่งข้อมูลของผู้ใช้แต่ละราย และจัดเก็บลง Radius Accounting เพื่อใช้ในการวิเคราะห์ และทำรายงานต่อไป ... ส่วนนี้ ใช้ pmacctd (ยังหวั่น ๆ ว่ามันจะไหวไหม แต่ก็ยังไม่เจอปัญหาอะไร)

* แก้ Bugs ในส่วนการบันทึก accounting ซึ่งพบว่า เกิดข้อผิดพลาดในการบันทึกซ้ำ ซึ่งจะส่งผลต่อการตรวจสอบ จำนวน session ของผู้ใช้ที่ใช้งานพร้อมกัน และส่งผลต่อ "users ค้าง"

ถัดไป คือ พระรอง DarkSolar Control Panel

ความสำคัญของ DarkSolar สำหรับผู้ดูแลระบบนั้น ไม่ยิ่งหย่อนกว่า RahuNAS

* เพิ่มการ Sync ลง LDAP Backend ซึ่งรอดตายด้วย ldapjs และด้วยความโชคดีที่วางระบบไว้ ว่าเดิม ให้เก็บ information ไว้ใน mongodb แล้วค่อย sync ลง PostgreSQL ทำให้ ตอน sync ลง LDAP ก็ทำในลักษณะเดียวกัน

* เพิ่มส่วนในการ นำเข้าข้อมูลจาก CSV ไฟล์ และมีส่วนสำหรับการ revert ในกรณีนำเข้าพลาด (ใช้เวลา 2 วันเต็ม ๆ อดหลับอดนอน) จนได้ระบบนี้ และใช้ระบบนี้ ในการนำเข้าผู้ใช้งาน กว่า 6 หมื่นรายการเข้าระบบ ^_^

* สำหรับคนที่ได้ใช้ DarkSolar มาก่อน จะพบว่าในส่วน Online Users ยังขาดส่วนของการค้นหา ซึ่งสำหรับระบบที่มีผู้ใช้เข้าใช้งานพร้อมกันระดับหลายพันราย เป็นการไม่สะดวกอย่างยิ่ง ในการค้นหาผู้ใช้เอง ทีละหน้า -_-''

* แก้ Bugs ในส่วนอื่น ๆ ทั้งที่เป็น error หรือแม้แต่ performance ซึ่งในส่วนของ performance ก็จะมาเจอก็ตอนมี 60k users อยู่ในฐานข้อมูล :)

และนั่นคืองาน สำหรับหลายเดือนที่ผ่านมา รวมอายุแล้ว RahuNAS ก็ค่อย ๆ เข้าใกล้ 1 ทศวรรษ และแน่นอน RahuNAS ก็โตเป็นผู้ใหญ่ขึ้นเรื่อย ๆ ตามกำลังของ 1 สมอง และ 2 มือ

ขอขอบคุณทุกท่าน ที่ยังไว้วางใจ RahuNAS
หวังว่า เราจะคบกันไป จนกว่า "จะเลิกรักกัน"

Happy Hacking

Thep: Thanks

7 January, 2015 - 12:26

สวัสดีปีใหม่ครับ ชีวิตหลังแต่งงานของผมยังอยู่ระหว่างปรับจูนการใช้เวลาระหว่างครอบครัวกับงาน รวมถึงเคลียร์ภารกิจต่าง ๆ ที่เกี่ยวเนื่องกับงานแต่งงาน ทำให้งานคืบหน้าช้ากว่าที่เคย คาดว่าไม่นานคงจะเข้าที่เข้าทางครับ

ขอขอบคุณย้อนหลัง สำหรับผู้สนับสนุนงานพัฒนาซอฟต์แวร์เสรีของผมในช่วงเดือนตุลาคม 2557 ถึงต้นมกราคม 2558 ที่ผ่านมาครับ คือ:

  • เดือนตุลาคม 2557
    • ผู้ไม่แสดงตน 2 ท่าน
    • ผู้ไม่ประสงค์จะออกนาม 1 ท่าน
  • เดือนธันวาคม 2557
  • ต้นเดือนมกราคม 2558

ขอให้ทุกท่านการงานราบรื่น มีสุขภาพดีทั้งคนทั้งระบบคอมพิวเตอร์ที่ใช้นะครับ

และในโอกาสขึ้นปีใหม่นี้ ก็ขออวยพรให้ผู้อ่าน blog ของผมทุกท่านมีความสุข คิดสิ่งใดก็ขอให้สมความปรารถนาครับ

สำหรับงานในช่วงที่ผ่านมา ผมพยายามเจียดเวลาว่างเล็ก ๆ น้อย ๆ มาทำงานแปล โดยได้ตรวจทานคำแปลของ GNOME และเครื่องมือพื้นฐานของ Debian และปรับคำแปลของ Xfce ตามข้อความใหม่ที่เกิดขึ้น

และระหว่างการเดินทางไปทำภารกิจต่าง ๆ ก็ได้ปรับแผนที่ OpenStreetMap ในตัวเมืองขอนแก่นไปด้วย

งานหนึ่งที่ยังไม่ลืม คือ Iceweasel Challenge (Bug #425915) ที่ได้รับคำท้าของพี่โดมไว้ตั้งแต่เดือนกันยายนที่ผ่านมา แต่คอมพิวเตอร์ที่ผมใช้ทำงานเกิดมีปัญหาเปิดไม่ติด ว่าจะยกไปซ่อมก็ยังไม่มีเวลา เนื่องจากมีภารกิจทางบ้านอย่างต่อเนื่องในช่วงที่ผ่านมา คาดว่าสักพักคงซาลง และสามารถกลับมาทำต่อได้ครับ

Kitt: 2015 leap second

6 January, 2015 - 12:26
อ้างอิงจาก IERS : A positive leap second will be introduced at the end of June 2015. Leap second (ภาษาไทย: อธิกวินาที) เป็นการชดเชยเวลา ระหว่างการวัด 1 วันของ เวลาตามนาฬิกาที่เราใช้ (24 * 60 * 60 = 86400 วินาที/วัน) กับ mean solar time ซึ่งวัดตามนิยามหมุนรอบตัวเองของโลกครบ 1 รอบ ทีนี้ การหมุนรอบตัวเองของโลกมันไม่ได้ลงตัวที่ 86400 วินาทีทุกวันหรอก มันเป็นการหมุนของวัตถุเหมือนๆ กับลูกข่างที่เรียนในฟิสิกส์นั่นแหละ มันเปลี่ยนแปลงได้ถ้ามีแรงมาบวกหรือลบ moment of inertia และก็พบกันว่า แรงเสียดทานจากกระแสน้ำ แผ่นดินไหว สึนามิ การเคลื่อนตัวของเปลือกโลก และอื่นๆ … Continue reading 2015 leap second →

Kitt: A Year of Goat

4 January, 2015 - 18:29
ได้ปฏิทินมาจากสถาบันขงจื่อ มข. อ่านออกแค่สามตัวแรก(三 สาม 羊 แพะ 开 เริ่ม/เปิด)  เลยไปค้นๆ คำนี้ดู ประโยค 三羊开泰 แปลได้ความประมาณ ‘สามแพะนำความรุ่งเรือง/ยิ่งใหญ่’ ใช้เป็นคำอวยพรและใช้รูปแพะ(สามตัว)ประกอบอย่างที่เห็น ที่มาของประโยคนี้จริงๆ มาจากประโยค 三阳开泰 หรือ 三陽开泰 ในตำราอี้จิง (易经) ทั้งนี้ อักษร 羊 และ 阳/陽 (พระอาทิตย์) อ่านออกเสียง หยาง เหมือนกัน ในปีแพะเลยใช้รูปแพะแทน ในตำราอี้จิง 三陽 หมายถึง ‘สาม(พลัง)หยาง ตรงกับสัญลักษณ์ ䷊ (☰  ฟ้า/☷  ดิน) เรียกว่า 泰 ตามตำรา หมายถึง สงบสุข ยิ่งใหญ่ คำว่า 三陽开泰 จึงแปลได้ว่า ‘สาม(พลัง)หยางนำความสงบสุข’ ตามตำรา三陽 ยังหมายถึงเดือนสาม (กุมภาพันธ์ ตามปฏิทินจีน) ซึ่งตรงกับวันตรุษของจีนด้วย จึงเป็นอีกเหตุหนึ่งที่มักใช้ 三羊开泰 / 三阳开泰 อวยพรวันปีใหม่ นัยว่า ‘ฤกษ์ดีปีใหม่ (เดือนสาม)’ กันด้วย

Kitt: The Return of the Condor Heroes

31 December, 2014 - 05:21
问世间、情是何物?直教生死相许。 天南地北双飞客,老翅儿几回寒暑。 欢乐趣,离别苦,就中更有痴儿女。 君应有语,渺万里层云,千山暮雪,只影向谁去? ถามไถ่ทั่วโลกหล้า อันว่ารักเป็นฉันใด? จึงมอบให้กันและกันด้วยชีวิต วิหคคู่เคียงจากดินอุดรฟ้าทักษิณ เทียบปีกโผผินบินกี่ฤดูกาล ร่วมหรรษาเริงรื่น ขื่นขมยามพลัดพรากหาย กอปรด้วยบุตรธิดางมงาย ท่านพึงหมายจำนรรจา ชั้นเมฆสูงหมื่นลี้ ทัศนีย์ภูผาไศล เงาเดียวดายดำรงอยู่ได้อย่างไร?

LookHin: เสรีภาพของนกในกรง

25 December, 2014 - 09:26

ณ ดินแดนอันสงบสุข มีนกตัวหนึ่งถูกเลี้ยงไว้ในกรงด้วยบุรุษผู้ใจดี เขาให้อาหารเมื่อมันต้องการ ให้ความอบอุ่นเมื่อมันหนาว เจ้านกถูกเลียงดูดูแลอย่างดี ไม่เคยมีอะไรที่มันอยากได้แล้วจะไม่ได้ บุรุษผู้เลียงนกตัวนี้บอกกับมันเสมอว่ามันเป็นนกที่โชคดีที่สุด มีเสรีภาพมากที่สุด ไม่มีนกตัวไหนในโลกที่จะโชคดีได้อย่างมันแล้ว
อยู่มาวันหนึ่ง มีนกอีกตัวบินมาแต่ไกล ร่างกายซูบผอม ปีกขาดรุ่งริ่ง มันเห็นเจ้านกที่อยู่ในกรงจึงได้แวะเข้ามาคุยด้วย มันทักด้วยความสงสัยว่าเจ้านกที่อยู่ในกรงมันทนอยู่ได้อย่างไรโดยไม่มีเสรีภาพ มันพยายามเล่าให้เจ้านกในกรงฟังว่าข้างนอกนั้นมันสามารถบินไปกินเม็ดทานตะวันสดๆจากต้น ตื่นเช้ามาได้รับแสดงแดดออนๆ อันอบอุน ได้โบยบินไปไหนก็ได้ที่อยากจะไป แต่ไม่ว่าจะเล่าอย่างไรเจ้านกในกรงก็ไม่เชื่อ มันเชื่อโดยสนิทใจว่าในกรงที่่มันอยู่นี้หละดีที่สุดแล้ว เจ้านกที่มาจากข้างนอกจะชวนมันไปดูมันก็ไม่ยอมไป “มันเลือกที่จะอยู่กับเสรีภาพที่มันรู้จัก”

Kitt: slimfold soft shell wallet

20 December, 2014 - 00:48
Thin . Light . Strong

Kitt: A New Wheel Set

16 December, 2014 - 18:42
สอยมาจนได้ Campagnolo Scirocco 35mm CX

LookHin: ติดตั้งและใช้งาน Tor + Vidalia บน Linux Mint

14 December, 2014 - 16:42

ผมเคยเขียนวิธีติดตั้งและใช้งาน Tor บน windows ไปแล้ว วันนี้มาดูการติดตั้งและใช้งาน Tor บน Linux กันบ้างครับ และเหมือนเดิมในตัวอย่างผมจะใช้ Linux Mint โดยเราจะติดตั้ง Vidalia ซึ่งจะทำให้เราจัดการกับ Tor ได้ง่ายขึ้น ผ่านโปรแกรมที่เป็นกราฟฟิก ไม่ต้องไปแก้ไขไฟล์คอนฟิกอะไรให้ยุ่งยาก

เนื่องจากเคยเขียนไปแล้วรอบหนึ่ง ฉะนั้นรอบนี้ก็มาเริ่มติดตั้งกันเลย ไม่ต้องพูดอะไรกันยาว ถ้าอยากอ่านยาวๆ ไปอ่านได้จากบทความเก่านะครับ http://www.unzeen.com/article/2629/

ทำการติดตั้ง Tor และ Vidalia

1
sudo apt-get install tor vidalia

เมื่อติดตั้งเสร็จแล้วให้ทำการเปิดโปรแกรม Vidalia ขึ้นมา แล้วคลิกเข้าไปที่ Setting

คลิกเลือกที่ Sharing และเลือก Run as a client only

จากนั้นคลิกที่ Advanced ในช่อง Tor Control ให้เลือกเป็น Use Unix domain socket (ControlSocket) คลิก OK เพื่อบันทึกข้อมูล

ถ้าหากในขั้นตอนนี้คลิก OK เพื่อบันทึกข้อมูลไม่ได้ แสดงว่า Tor Service ยังไม่ถูก start ขึ้นมา ให้เราทำการ start service ของ tor ด้วยคำสั่งต่อไปนี้ก่อนครับ

1
$ sudo service tor start

จากนั้นคลิก Start Tor

ขั้นตอนถัดไปให้ทำการคอนฟิกบราวเซอร์ให้เรียกใช้งาน Tor ในตัวอย่างผมจะใช้ Firefox นะครับ ให้เข้าไปที่ Preferences -> Advanced -> Network และทำการคลิกที่ Settings ในส่วนของ Connection

ในหน้า Connection Settings ให้เลือกมาที่ Manual proxy configuration และใส่ค่าในช่อง SOCKS Host เป็น 127.0.0.1 และ port 9050

เรียบร้อยแล้วครับ ให้ทดสอบเปิด URL https://check.torproject.org/ เพื่อทดสอบว่าเราใช้งานระบบของ Tor แล้วหรือยัง

LookHin: การติดตั้ง Burg Boot Loader บน Linux Mint

14 December, 2014 - 15:28

จากครั้งที่แล้วที่เราได้ทำการแก้ไขหน้า GRUB Boot Loader จะเห็นว่าแก้ไขอะไรได้ไม่มาก วันนี้เราจะมาลองใช้โปรแกรมอีกตัวหนึ่งคือ Burg Boot Loader ซึ่งจะช่วยให้หน้าจอ Boot Loader ที่ใช้ในการเลือกเข้า OS ต่างๆ ในเครื่องของเราดูดีขึ้นกว่าแต่ก่อน โดยในตัวอย่างนี้ผมจะทำการติดตั้งบน Linux Mint 17.1 คิดว่าถ้าเป็น Debian หรือ Ubuntu ก็น่าจะติดตั้งแบบเดียวกันทั้งหมด

ขั้นตอนไม่ยุ่งยากครับ เริ่มจากการเพิ่ม repo เข้าไป จากนั้นก็ทำการติดตั้งได้เลย

1
2
3
$ sudo add-apt-repository ppa:n-muench/burg
$ sudo apt-get update
$ sudo apt-get install burg burg-themes

ในระหว่างติดตั้งจะมีหน้าจอขึ้นมาถามเกียวกับค่าคอนฟิกต่างๆในระบบนะครับ เราไม่ต้องแก้ไขค่าอะไรให้เรากด OK ไปให้หมดเลยครับ จนถึงหน้าจอสุดท้ายที่จะให้เราเลือก Harddisk ที่เราจะติดตั้ง MBR โดยเราสามารถเลือก Harddisk ที่ต้องการได้โดยการกด Space Bar ให้ช่องด้านหน้ากลายเป็นเครื่องหมายดอกจัน จากนั้นกด OK เป็นอันเสร็จเรียบร้อยครับ (ปกติของคนอื่นจะติดตั้งไปที่ /dev/sda แต่ของผมติดตั้งลงใน Harddisk ตัวที่ 2 เลยได้เป็น /dev/sdb นะครับ)

ถ้าหากในขั้นตอนการติดตั้ง ระบบไม่ได้ถามให้เราเลือกติดตั้ง Burg ไปที่ MBR ของ Harddisk ตัวไหน ให้เราทำการติดตั้งเองโดยใช้คำสั่งต่อไปนี้

1
$ sudo burg-install /dev/sdb

ขั้นตอนถัดไป ต้องทำการเลือก Theme และปรับความละเอียดของหน้าจอกันอีกเล็กน้อย

1
$ sudo burg-emu

เมื่อเข้าไปแล้วจะเจอหน้าจอเหมือนในรูปนะครับ ให้ทำการกด F2 เพื่อเลือก Theme

หลังจากเลือก Theme เสร็จเรียบร้อยแล้ว เดียวเรามาปรับความละเอียดของหน้าจอกันต่อครับ โดยให้เข้าไปแก้ไขที่ไฟล์ /etc/default/burg ซึ่งเราจะแก้กัน 2 จุด คือ

1. เอา # หน้า GRUB_DISABLE_LINUX_RECOVERY=”true” เพื่อไม่ให้แสดงตัวเลือก Recovery
2. ทำการแก้ไขความละเอียดของหน้าจอ โดยแก้ GRUB_GFXMODE=saved เป็น GRUB_GFXMODE=1366×768 (ความละเอียดของจอตัวเองเท่าไรก็ใส่ตามนั้นนะครับ)

1
$ sudo nano /etc/default/burg

ส่วนรูปโลโกของ OS ต่างๆ ถ้าเราไม่ชอบอันที่เขาให้มา เราสามารถเข้าไปเปลี่ยนได้เองที่ /boot/burg/themes/icons นะครับ

หลังจากแก้ไขไฟล์เสร็จแล้วให้สั่ง

1
$ sudo update-burg

เพียงเท่านี้เราก็จะได้หน้าจอ Boot Loader ที่ดูดีขึ้นมาทันที อย่างของผมเลือก Theme refit และเปลี่ยนโลโกจาก Linux Mint เป็นรูปเพนกวินก็จะได้หน้าจอประมาณนี้ครับ

หากต้องการกลับไปใช้ GRUB ใหม่อีกรอบ ให้ใช้คำสั่งดังนี้ครับ

1
sudo grub-install /dev/sdb

Kitt: Skillet Sausage and Potatoes

11 December, 2014 - 05:45

LookHin: เทคนิคการใช้งานคำสั่ง wget เพื่อดาวน์โหลดไฟล์

8 December, 2014 - 09:16

wget เป็นคำสั่งที่ใช้ในการดาวน์โหลดไฟล์ที่นิยมใช้กันบน Linux ซึ่งปกติเราก็จะใช้ในการดาวน์โหลดไฟล์ซอสโค้ดหรือไฟล์โปรแกรมต่างๆ แต่ว่า wget ไม่ได้มีความสามารถแค่นั้น เรายังสามารถสั่งให้โหลดเฉพาะไฟล์ .pdf หรือไฟล์นามสกุลอื่นๆ จากทั้งเว็บไซต์มาเก็บไว้ที่เครื่องเราได้ หรือจะทำสำเนาทั้งเว็บไซต์ลงมาเก็บไว้เลยก็ยังได้ เดียวใช้งานยังไงมาดูกัน

1. อันนี้พื้นฐาน สั่งดาวน์โหลดไฟล์แค่ไฟล์เดียว ใช้คำสั่ง wget แล้วตามด้วย URL ของไฟล์ที่ต้องการ

1
$ wget http://www.linuxmint.com/documentation/user-guide/Cinnamon/english_17.0.pdf

2. หากต้องการเปลี่ยนชื่อไฟล์ด้วยหละก็ให้เพิ่มออปชั่น -O เข้าไป

1
$ wget -O Cinnamon.pdf http://www.linuxmint.com/documentation/user-guide/Cinnamon/english_17.0.pdf

3. จำกัดความเร็วของการดาวน์โหลดด้วยออปชั่น –-limit-rate

1
$ wget --limit-rate=200k http://www.linuxmint.com/documentation/user-guide/Cinnamon/english_17.0.pdf

4. ถ้าหากว่าโหลดไฟล์ไม่เสร็จเครื่องหยุดทำงานไปก่อน ให้เพิ่ม -c เพื่อสั่งให้โหลดต่อจากของเดิม

1
$ wget -c -O Cinnamon.pdf http://www.linuxmint.com/documentation/user-guide/Cinnamon/english_17.0.pdf

5. สั่งให้โหลดเป็นแบ็คกราวโพรเซส โดยเพิ่มออปชั่น -b โดยตัว wget จะสร้างล็อกไฟล์ชื่อ wget-log ขึ้นมา เราสามารถดูว่าโหลดถึงไหนแล้วได้จากล็อกไฟล์นี้

1
$ wget -b http://www.linuxmint.com/documentation/user-guide/Cinnamon/english_17.0.pdf

ดูล็อกไฟล์ว่าดาวน์โหลดถึงไหนแล้ว

1
$ tail -f wget-log

6. สำหรับบางเว็บไซต์ถูกจำกัดว่าจะต้องโหลดจากบราวเซอร์บางตัวเท่านั้น ให้เพิ่มออปชั่น -–user-agent เพื่อกำหนดให้เป็นบราวเซอร์ที่ต้องการ

1
$ wget --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36" http://www.linuxmint.com/documentation/user-guide/Cinnamon/english_17.0.pdf

7. คราวนี้มาลองโหลดทีละหลายๆไฟล์บ้าง ให้ทำการใส่ชื่อ URL ที่ต้องการดาวน์โหลดไว้ในเท็กไฟล์ ในตัวอย่างผมตั้งชื่อว่า download-list.txt

download-list.txt

1
2
3
4
http://www.linuxmint.com/documentation/user-guide/Cinnamon/english_17.0.pdf
http://www.linuxmint.com/documentation/user-guide/Cinnamon/chinese_16.0.pdf
http://www.linuxmint.com/documentation/user-guide/Cinnamon/dutch_17.0.pdf
http://www.linuxmint.com/documentation/user-guide/Cinnamon/german_17.0.pdf

จากนั้นสั่งดาวโหลดทีละหลายๆไฟล์โดยเพิ่มออปชั่น -i แล้วตามดวยชื่อเท็กไฟล์ที่เราได้สร้างเตรียมไว้

1
$ wget -i download-list.txt

8. ต่อไปมาลองดาวน์โหลดเว็บไซต์ทั้งเว็บมาเก็บไว้ดูในเครื่องกันบ้าง โดยใช้ออปชั่น –mirror และ ./www-local คือไดเร็กทอรี่ที่ต้องการให้เก็บข้อมูล

1
$ wget --mirror -p --convert-links -P ./www-local http://www.lookhin.com

9. คราวนี้ถ้าเราอยากได้แค่ไฟล์ที่มีนามสกุล .pdf จากเว็บไซต์ทั้งเว็บ เราก็ใช้คำสั่ง -r –no-parent -A และตามด้วยนามสกุลของไฟล์ที่ต้องการ

1
$ wget -r --no-parent -A.pdf http://www.linuxmint.com/documentation/user-guide/

10. หากต้องการดาวน์โหลดไฟล์จาก FTP ก็สามารถทำได้เช่นกัน

1
$ wget --ftp-user=USERNAME --ftp-password=PASSWORD ftp://ftp.yourdomain.com/document/linux.pdf

LookHin: เปลี่ยนสีตัวอักษรและใส่ภาพพื้นหลังให้เมนูของ GRUB Bootloader

6 December, 2014 - 20:57

ปกติแล้วหลังจากที่เราติดตั้ง Linux เสร็จเรียบร้อย เวลาที่บูตเข้าระบบจะเจอกับหน้าจอของ GRUB Bootloader ซึ่งจะมีตัวอักษรสีขาวบนพื้นดำ หรือไม่ก็จะมี background ที่ติดมากับ Linux ที่เราติดตั้ง เราอาจจะไม่ค่อยชอบมันเท่าไรแต่ก็ต้องเจอทุกครั้งที่บูตเครื่องแน่นอน หลายคนอาจจะไม่ทราบว่าเราสามารถเปลี่ยนรูป background ตรงนี้ได้ ซึ่งขั้นตอนก็ไม่ได้ยุ่งยากอะไร เดียววันนี้เรามาลองทำการเปลี่ยนดู (ผมทดลองบน Linux Mint 17.1 นะครับ เข้าใจว่าสาย debian ก็น่าจะมีวิธีการคล้ายๆกันทั้งหมด)

เริ่มแรกหาภาพที่จะเอามาใช้เป็น background กันก่อนครับ โดยให้ใช้เป็นภาพ .PNG ขนาด 640*480 pixel และสี 8-Bit อันนี้ภาพตัวอย่างของผมนะครับ ไฟล์ภาพตัวอย่าง

เมื่อได้ภาพที่ต้องการแล้วให้ทำการแก้ไขไฟล์ /etc/default/grub.d/50_linuxmint.cfg

1
$ sudo nano /etc/default/grub.d/50_linuxmint.cfg

ให้ทำการเพิ่มคำสั่ง GRUB_BACKGROUND เข้าไป โดยในตัวอย่างผมจะเอาภาพไปไว้ที่ /usr/share/backgrounds/linuxmint-qiana/grub-boot.png นะครับ

1
GRUB_BACKGROUND="/usr/share/backgrounds/linuxmint-qiana/grub-boot.png"

เมื่อทำการใส่ภาพพื้นหลังเรียบร้อยแล้ว เรามาจะทำการแก้ไขสีของตัวอักษรและสีพื้นหลังให้มันเข้ากับภาพที่เราใส่เข้าไปเมื่อสักครู่นี้

1
$ sudo nano /etc/grub.d/06_mint_theme

เพิ่มบรรทัดต่อไปนี้ลงไปในส่วนของ set_mono_theme() โดยมี format เป็น สีตัวอักษร/สีพื้นหลัง แต่เราถ้าใส่พื้นหลังเป็น black มันจะเป็น transparent นะครับ งงกับมันเหมือนกัน – -‘

1
2
3
set menu_color_highlight=black/green
set menu_color_normal=black/black
set color_normal=black/black

โดยสีที่เราสามารถใส่ได้มีทั้งหมดดังนี้

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
black
blue
brown
cyan
dark-gray
green
light-cyan
light-blue
light-green
light-gray
light-magenta
light-red
magenta
red
white
yellow

ขั้นตอนสุดท้ายสั่ง update-grub

1
$ sudo update-grub

เรียบร้อยแล้วครับ บูตเครื่องครั้งหน้าจะเจอกับหน้าจอ GRUB Bootloader ประมาณนี้ครับ

Thep: FOSS Behind my Wedding

25 November, 2014 - 16:08

blog นี้เป็น blog แรกที่ผมเขียนภายใต้สถานภาพ สมรส หลังจากที่ได้เข้าพิธีแต่งงานไปเมื่อวันที่ 26 ต.ค. ที่ผ่านมา (นับถึงวันที่ 25 พ.ย. ที่เขียน blog นี้ ก็ครบ 30 วันพอดี)

ชีวิตผมซึ่งอยู่กับ ซอฟต์แวร์เสรี และ โอเพนซอร์ส อยู่แล้ว ก็เป็นธรรมดาที่จะมีสิ่งนี้เข้ามาพัวพันกับงานครั้งนี้

วีดิทัศน์

เริ่มจากการเตรียมวีดิทัศน์แนะนำตัวบ่าว-สาว ผมกับเจ้าสาวช่วยกันคัดรูปถ่ายของพวกเราตั้งแต่วัยเด็กจนโต แล้วนำมาสร้างเป็นวีดิทัศน์เล่นภาพสไลด์พร้อมเพลงประกอบ

เครื่องมือแรกที่ใช้คือ dvd-slideshow ซึ่งเป็นชุด command-line สำหรับสร้างวีดิทัศน์จากแฟ้ม spec ซึ่งเป็น text file แต่ติดปัญหาว่ามันมี error message และ gen video ไม่สำเร็จ จึงได้ file Debian #750626 พร้อมเสนอแพตช์แก้ ซึ่งเริ่มมีผลในรุ่น 0.8.4.2-3 ของ Debian

นั่นเป็นการทดลองเครื่องมือก่อน แต่เมื่อเริ่มได้รูปภาพจำนวนหนึ่งมา การจะนั่งจัดเรียงภาพด้วยการ edit text file พร้อมกับเจ้าสาวซึ่งไม่ใช่นักคอมพิวเตอร์ มันก็ลำบากอยู่ จึงได้ไปหาเครื่องมือตัวอื่น จนกระทั่งพบ imagination ซึ่งเป็น GUI โดยใช้ GTK+ 2.0 ซึ่งทำให้สามารถลากจัดลำดับรูปภาพได้ พร้อมกับมี transition ที่หลากหลายกว่า

ปัญหาเกิดขึ้นเมื่อจะ gen video กลับ gen ไม่ได้ เพราะหา FFmpeg ไม่เจอ เนื่องจาก FFmpeg ได้ถูกตัดออกจาก Debian ไปแล้ว จึงได้ไปค้นบั๊กของ Debian พบ Debian #722293 ซึ่งมีผู้รายงานไว้ และได้ forward bug ไปที่ต้นน้ำ (Imagination #78) จึงตามไปคุยและเสนอแพตช์ที่ต้นน้ำ พร้อมกลับมาแปะแพตช์ไว้ที่ Debian ด้วย

ผู้พัฒนาต้นน้ำดูจะไม่กระตือรือร้นสักเท่าไรกับแพตช์ที่เสนอ หลังจากตรวจสอบไปก็พบว่า FFmpeg ยังไม่ตาย ไม่ได้เปลี่ยนชื่อเป็น libav อย่างที่ผู้ดูแลแพกเกจใน Debian และ Ubuntu พยายามจะสื่อถึงผู้ใช้ แต่ libav เป็น fork หนึ่งของ FFmpeg ซึ่งทีม Debian เลือกมาใช้แทน แต่ในดิสโทรอื่นยังคงใช้กันอยู่ และผู้ใช้ Debian/Ubuntu บางส่วนก็ต้องการกลับไปใช้ FFmpeg เหมือนเดิม (อ่าน ตัวอย่างเรื่องเล่าสถานการณ์) และมีนักพัฒนา Debian เสนอกลับเข้ามาใหม่ จนกระทั่ง ได้เข้า experimental และ sid ในที่สุด (แต่ไม่ทัน Jessie freeze จึงไม่มีใน Jessie)

อย่างไรก็ดี ในขณะที่ผมทำวีดิทัศน์ของผมอยู่นั้น Debian ไม่มี FFmpeg ทั้งใน testing และ unstable จึงได้ผลักดันแพตช์ให้ imagination กลับมาทำงานได้ โดยเพิ่มระดับความรุนแรงของ Debian #722293 จาก important เป็น grave เพื่อให้มันกลายเป็น RC bug เพราะถึงอย่างไร FFmpeg ก็จะไม่มีใน Jessie ถ้า Debian จะออก Jessie พร้อมกับ imagination ที่ต้องการ FFmpeg มันก็จะไม่สามารถ gen video ได้เลย จนในที่สุด แพตช์ก็เริ่มมีผลในรุ่น 3.0-5 ของ Debian ส่วนที่ต้นน้ำนั้น ผมเข้าใจแล้วว่าบั๊กนี้ไม่ถือว่ารุนแรงนอก Debian/Ubuntu

เป็นอันว่า กว่าผมจะเริ่มทำวีดิทัศน์ได้ ก็ได้แก้ RC bug ใน Debian ไปแล้ว 2 bug และสามารถสร้างวีดิทัศน์ได้ตามที่ต้องการ

พิมพ์ซอง

ตัวการ์ดเชิญนั้น แน่นอนว่าผมพิมพ์เองไม่ได้ ก็สั่งร้านพิมพ์ให้ แต่การพิมพ์ชื่อแขกที่จะเชิญลงที่หน้าซองนั้น จำเป็นต้องทำระบบให้เป็นอัตโนมัติสักหน่อย

ผมเริ่มจากเขียน shell script เอง โดยอ่านรายชื่อจาก text file มาสร้างแฟ้ม LaTeX ก่อนคอมไพล์เป็น PDF ทีละราย แต่นั่นทำให้จำนวนไฟล์เยอะมาก PDF 1 แฟ้มต่อแขก 1 คน

ผมจึงมองหาวิธีทำ mail merge ใน LaTeX ดู ก็พบแพกเกจ mailmerge แต่ปรากฏว่าต้องใส่รายชื่อใน LaTeX source เลย แทนที่จะแยกออกมาข้างนอกต่างหาก กลายเป็นว่า PDF ไฟล์เดียวมีซองของแขกทุกคน ทำให้เพิ่มแขกที่จะเชิญทีละกลุ่มได้ลำบาก (คุณนึกออกไหม? เวลาที่นึกได้ว่าควรเชิญญาติคนนั้นเพิ่ม เพื่อนคนนู้นทวงการ์ดเชิญ เพื่อนที่ได้การ์ดแนะนำว่าควรเชิญคนนั้นคนนี้เพิ่มอีก ฯลฯ ผมจึงต้องเตรียมพร้อมที่จะพิมพ์ซองเพิ่มได้ตลอดเวลา)

จนกระทั่งพบแพกเกจ textmerg ที่ตอบโจทย์ของผม เพราะสามารถทำ master file ของซองเอาไว้ แล้วจัดการรายชื่อแขกในแฟ้มภายนอกต่างหาก จากนั้นสั่งคอมไพล์และจัดพิมพ์ซองทีละกลุ่ม หนึ่งกลุ่มหนึ่งไฟล์ ทำให้จำนวนไฟล์ไม่เยอะเกินไป และสามารถคัดแยกได้สะดวก ว่ากลุ่มไหนพิมพ์ซองไปบ้างแล้ว กลุ่มไหนยังไม่พิมพ์

สำหรับ LaTeX ไม่พบบั๊กอะไรครับ ใช้งานได้ราบรื่นดี รายละเอียดการใช้งานสามารถศึกษาจากเอกสารของแพกเกจได้ไม่ยาก (บน Debian ก็แค่สั่ง texdoc ชื่อแพกเกจ บนเทอร์มินัล) หรือถ้ามีเวลา ผมอาจจะเขียนวิธีการในภายหลัง

นั่นคือการใช้ FOSS ในการเตรียมงานแต่งงานของผมครับ ผ่านมาได้ด้วยดี ก็บันทึกไว้เป็นกรณีศึกษาเสียหน่อย :-)

Kitt: when it happens, it happens ..

23 November, 2014 - 23:35
เมื่อคราวปี 49 “เคย” มีเหตุมาแล้ว มันก็เลยกลายเป็นตำนานต่อๆ กันมา

Pages

Creative Commons License ลิขสิทธิ์ของบทความเป็นของเจ้าของบทความแต่ละชิ้น
ผลงานนี้ ใช้สัญญาอนุญาตของครีเอทีฟคอมมอนส์แบบ แสดงที่มา-อนุญาตแบบเดียวกัน 3.0 ที่ยังไม่ได้ปรับแก้