Proxmox 4 PERL error

Use of uninitialized value $raw in pattern match (m//) at /usr/share/perl5/PVE/JSONSchema.pm line 1153, line 751.

ตั้งแต่ Proxmox 4 (ใน pvetest) kernel อัพเป็นรุ่น 4.1.3 ก็จะเจอ error นี้จาก Cron ส่งมาทุกคืน

Cron <root@server> test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

/etc/cron.daily/pve:
Use of uninitialized value $raw in pattern match (m//) at /usr/share/perl5/PVE/JSONSchema.pm line 1153, line 751.

วิธี reproduce คือลองรัน /etc/cron.daily/pve ดูจะเจอ Warning เหมือนในอีเมลเลย

จะแก้ให้ redirect null แบบคลีนก็ไม่ง่ายนัก เพราะมันเป็นสคริปต์สำเร็จอยู่ใน /etc/cron.daily ไม่ได้เป็นคำสั่งแบบที่อยู่ใน crontab ที่จะเติม >> /dev/null ต่อท้ายเองได้ ก็เลยต้องลงเอยที่การ patch script มันชั่วคราวไปก่อน

แก้ usr/share/perl5/PVE/JSONSchema.pm แถวๆ บรรทัด 1153

จากเดิม

    while ($raw =~ /^\s*(.+?)\s*$/gm) {
    my $line = $1;

    next if $line =~ /^#/;

    if ($line =~ m/^(\S+?):\s*(.*)$/) {
        my $key = $1;
        my $value = $2;
        if ($schema->{properties}->{$key} &&
        $schema->{properties}->{$key}->{type} eq 'boolean') {

        $value = 1 if $value =~ m/^(1|on|yes|true)$/i;
            $value = 0 if $value =~ m/^(0|off|no|false)$/i;
        }
        $cfg->{$key} = $value;
    } else {
        warn "ignore config line: $line\n"
    }
    }

เติม if ครอบก้อนข้างบนเข้าไปเลย

    if (defined($raw)) { ## rtsp patch ##

    while ($raw =~ /^\s*(.+?)\s*$/gm) {
        ...................
    }

    } ## rtsp patch ##

ลองรัน /etc/cron.daily/pve ดู ถ้าไม่มี Warning อะไรพ่นออกมาก็โอเคแล้วครับ

ป.ล. เหมือนต้นน้ำจะแก้ Warning นี้แล้ว แต่ขี้เกียจรอ แก้เองก่อนละ

Proxmox boot error: grub/i386-pc/boot.mod not found

สาเหตุ

ปัญหาสำหรับคนใช้ Proxmox VE เท่านั้น เนื่องจากแพคเกจ grub2 ที่ติดตั้งจาก proxmox repo มันมีบั๊กไม่รู้จัก partition ของ mdraid แล้วถ้าสั่ง aptitude upgrade หรือปล่อย auto upgrade มันจะอัพ grub2 จาก proxmox repo มาทับตัว official ของ Debian เสร็จแล้วพอรีบูทเครื่อง… มันจะบูทไม่ขึ้น! อาการคือพอถึงหน้า grub จะเจอ error ประมาณนี้

error: file /grub/i386-pc/boot.mod' not found
Entering rescue mode...
grub rescue>

ตรวจสอบ

เช็คเครื่องที่ยังรันอยู่ ว่า grub เป็นรุ่นอะไร โดยสั่ง

dpkg -l "grub*" | grep ^ii

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

  • ถ้าเป็น 1.99-27+deb7u2 = grub ของ official debian wheezy = ปลอดภัย
  • ถ้าเป็น 2.02~bpo70+3 = grub ของ proxmox wheezy = อันตราย
  • ถ้าเป็น 2.02~beta2-21 = grub ของ official debian jessie = ปลอดภัย
  • ถ้าเป็น 2.02-pve1 = grub ของ proxmox jessie= อันตราย

ถ้าเป็นรุ่นอันตราย ห้ามรีบูทเครื่องเด็ดขาดจนกว่าจะแก้เสร็จ ถ้าเป็นรุ่นปลอดภัยก็อย่าลืมทำ Pinning ก่อนเพื่อความชัวร์ว่าจะไม่เผลอไปอัพเกรดทับ (ดูท้าย blog นี้)

ทางแก้

Case #1 ถ้าเครื่องยังทำงานปกติอยู่ (ยังไม่ได้รีบูท)

ติดตั้ง grub ของ official debian ทับตัวของ proxmox เสร็จแล้วอย่าลืม grub-install ให้ครบทุก disk แล้วสั่ง update-grub2 ด้วย

สคริปนี้เป็นอันของ debian wheezy ที่ใช้ซ่อมบนระบบจริง ถ้าจำนวน disk ไม่ตรงกันอย่าลืมแก้ก่อนเอาไปใช้ด้วยนะครับ

ถ้าใช้ grub-efi (จะเห็นได้จาก output ของ dpkg ข้างบน) อย่าลืมเปลี่ยนแพคเกจให้ตรงด้วยนะครับ

ถ้าใช้ jessie ก็อย่าลืมเปลี่ยนรุ่นของ grub ทุกตัวให้ตรงด้วย (เช็ครุ่นที่ถูกได้แถวนี้)

wget http://ftp.debianclub.org/debian/pool/main/g/grub2/grub-common_1.99-27+deb7u2_amd64.deb
wget http://ftp.debianclub.org/debian/pool/main/g/grub2/grub2-common_1.99-27+deb7u2_amd64.deb
wget http://ftp.debianclub.org/debian/pool/main/g/grub2/grub-pc_1.99-27+deb7u2_amd64.deb
wget http://ftp.debianclub.org/debian/pool/main/g/grub2/grub-pc-bin_1.99-27+deb7u2_amd64.deb
dpkg -i grub-common_1.99-27+deb7u2_amd64.deb grub2-common_1.99-27+deb7u2_amd64.deb grub-pc_1.99-27+deb7u2_amd64.deb grub-pc-bin_1.99-27+deb7u2_amd64.deb
grub-install /dev/sda
grub-install /dev/sdb
update-grub2

อัพเสร็จแล้วอย่าลืมทำ Pinning (ดูท้าย blog)

Case #2 เผลอรีบูทไปแล้ว ตอนนี้บูทแล้วโดน  ‘/grub/i386-pc/boot.mod’ not found อยู่

แบบ TL;DR: บูทเข้า rescue ไปลง grub ตัว official ที่อยู่ในแผ่นติดตั้ง Debian เสร็จแล้วอย่าลืม grub-install + update-grub2 ด้วย

แบบยาวๆ

  1. โหลดแผ่นติดตั้ง Debian มา เช่น debian-7.8.0-amd64-netinst.iso แล้วไรท์ หรือถ้าอยากบูทจาก usb ก็ใช้ rufus สร้างโดยเลือกไฟล์ iso มาเขียนครับ
  2. บูทเข้าแผ่นติดตั้ง แล้วเลือก Rescue mode (อาจจะซ่อนอยู่ในเมนู Advanced)
  3. พวกคอนฟิกพื้นฐานจะคล้ายกับตอนติดตั้ง กด next รัวๆได้เลย network ก็ช่างหัวมัน
  4. พอถึงหน้าที่ให้เลือก Root filesystem ให้เลือก Assemble RAID Array > Automatic เสร็จแล้วเลือก /dev/mdX อันที่เป็น / ของเรา
  5. พอถึงหน้าที่ให้เลือกว่าจะรัน shell ที่ไหน เลือกเป็น Execute shell in installer environment
  6. ก้อปไฟล์ 4 ตัวจาก /cdrom/pool/main/g/grub2/ มาแปะใน root filesystem เรา ซึ่งน่าจะอยู่ที่ /target แหละนะ (ถ้าไม่มี mount มือโลด)
    cd /cdrom/pool/main/g/grub2/
    cp grub-common* grub-pc* grub2-common* /target/
    exit
    
  7. เสร็จแล้ว exit ออกมาแล้ว Execute shell in /dev/mdX แทน
  8. ติดตั้งไฟล์ที่ก้อปออกมาเมื่อกี้โดย dpkg -i grub*.deb แล้ว grub-install ลง hardisk ให้ครบ + update-grub2 ด้วย
    cd /
    dpkg -i grub*.deb
    grub-install /dev/sda
    grub-install /dev/sdb
    update-grub2
    exit
    
  9. reboot!
  10. พอบูทขึ้นแล้วอย่าลืมทำ Pinning

การทำ Pinning เพื่อป้องกันการ upgrade ในอนาคต

Debian 7 Wheezy

cat << EOF > /etc/apt/preferences.d/grub-bugfix
Package: grub-common grub2-common grub-pc grub-pc-bin
Pin: release c=main
Pin-Priority: 1001

Package: grub-common grub2-common grub-pc grub-pc-bin
Pin: release c=pve-no-subscription
Pin-Priority: -1
EOF

Debian 7 Wheezy (สำหรับคนที่ใช้ EFI)

cat << EOF > /etc/apt/preferences.d/grub-bugfix
Package: grub-common grub2-common grub-efi-amd64 grub-efi-amd64-bin
Pin: release c=main
Pin-Priority: 1001

Package: grub-common grub2-common grub-efi-amd64 grub-efi-amd64-bin
Pin: release c=pve-no-subscription
Pin-Priority: -1
EOF

Debian 8 Jessie

cat << EOF > /etc/apt/preferences.d/grub-bugfix
Package: grub-common grub2-common grub-pc grub-pc-bin
Pin: release c=main
Pin-Priority: 1001

Package: grub-common grub2-common grub-pc grub-pc-bin
Pin: release c=pvetest
Pin-Priority: -1
EOF

ตรวจสอบว่า Pin ถูกต้อง

apt-cache policy grub-common grub2-common grub-pc grub-pc-bin

ถ้าการ Pin ถูกต้อง output ควรจะประมาณนี้ (ดูตรง Package pin)

grub-common:
  Installed: 1.99-27+deb7u2
  Candidate: 1.99-27+deb7u2
  Package pin: 1.99-27+deb7u2
  Version table:
     2.02~bpo70+3 1001
        500 http://mirror.applebred.net/debian-pve/ wheezy/pve-no-subscription amd64 Packages
 *** 1.99-27+deb7u2 1001
        500 http://ftp.debianclub.org/debian/ wheezy/main amd64 Packages
        100 /var/lib/dpkg/status
grub2-common:
  Installed: 1.99-27+deb7u2
  Candidate: 1.99-27+deb7u2
  Package pin: 1.99-27+deb7u2
  Version table:
     2.02~bpo70+3 1001
        500 http://mirror.applebred.net/debian-pve/ wheezy/pve-no-subscription amd64 Packages
 *** 1.99-27+deb7u2 1001
        500 http://ftp.debianclub.org/debian/ wheezy/main amd64 Packages
        100 /var/lib/dpkg/status
grub-pc:
  Installed: 1.99-27+deb7u2
  Candidate: 1.99-27+deb7u2
  Package pin: 1.99-27+deb7u2
  Version table:
     2.02~bpo70+3 1001
        500 http://mirror.applebred.net/debian-pve/ wheezy/pve-no-subscription amd64 Packages
 *** 1.99-27+deb7u2 1001
        500 http://ftp.debianclub.org/debian/ wheezy/main amd64 Packages
        100 /var/lib/dpkg/status
grub-pc-bin:
  Installed: 1.99-27+deb7u2
  Candidate: 1.99-27+deb7u2
  Package pin: 1.99-27+deb7u2
  Version table:
     2.02~bpo70+3 1001
        500 http://mirror.applebred.net/debian-pve/ wheezy/pve-no-subscription amd64 Packages
 *** 1.99-27+deb7u2 1001
        500 http://ftp.debianclub.org/debian/ wheezy/main amd64 Packages
        100 /var/lib/dpkg/status

เป็นอันเรียบร้อยครับ ขอให้ทุกท่านโชคดี

PHP Session Handler: memcache vs memcached

ว่ากันด้วย Memcache ใน PHP มันมีโมดูลอยู่ 2 ตัว ซึ่งคอนฟิกต่างกันนิดหน่อย

ถ้าเอามาใช้เป็น session.save_handler แล้วเขียนผิดหรือเขียนสลับกัน มันจะพังเงียบๆ เลยจ้า

Memcache

PECL: http://pecl.php.net/memcache

Debian/Ubuntu: php5-memcache

session.save_handler = memcache
;session.save_path = "unix:///var/run/memcached/memcached.sock:0"
session.save_path = "tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

Memcached

PECL: http://pecl.php.net/memcached

Debian/Ubuntu: php5-memcached

session.save_handler = memcached
session.save_path = "127.0.0.1:11211"

smartctl: อ่านค่า S.M.A.R.T. จาก HDD ที่อยู่หลัง Hardware RAID


smartctl -d megaraid,0 -a /dev/sda
smartctl -d megaraid,1 -a /dev/sda

อันนี้สำหรับพวก RAID card ของ Dell PowerEdge

ตรงโมดูล megaraid เปลี่ยนไปตาม Hardware RAID ที่ใช้อยู่ ส่วนเลข 0,1 ข้างหลังคือลำดับของ Harddisk

รายชื่อโมดูลของแต่ละ HW RAID ดูที่นี่

ป.ล. อย่าลืมลง smartmontools