分類彙整: 電腦資訊

踩到 FreeBSD 6.1 的地雷…

昨天裝了台機器,由於有兩台相同容量的 18G 硬碟,此裝好之後順手替 root partition 加上了 Software RAID….

沒想到一時疏忽,修改 fstab 時忘了加上 /mirror/ …

/dev/mirror/gm0s1b none swap sw 0 0
/dev/mirror/gm0s1a / ufs rw 1 1

所以重開機時開不起來了…
原本根據 這篇 的說明,只要在 mountroot> prompt 下,重新指定 root partition 位置就可以進去修正了…

但是,沒想到好像踩到 FreeBSD 6.1 的地雷了:
kern/98910: [kbd] keyboard not working at mountroot prompt on IBM T42P

也就是 mountroot> 下鍵盤不能動了…. 我用的是研華的伺服器,問題跟上面這個 PR 一模一樣…

偏偏我這台機器的光碟和軟碟又都壞了…. 只好很苦命的再把機器搬出機櫃來拆開,外接光碟重新修正了事….

svndumpfilter with wildcards support ?

Subversionsvnadmin obliterate 功能一直沒有實作出來,這實在是有點麻煩,尤其是當負責管理一個 repository 時,常常就會有人把 *.exe, *.obj, *.lib, *.a 統統給 commit 進去了….

然後你就會發現整個 repository 長大的速度越來越快,就算事後用 svn delete 把它砍掉還是無濟於事,因為那已經成為無法抹滅的歷史了

雖然可以事先設定 svn:ignore 來解決,不過偶而還是會有漏網之魚,官方提供的解決方法是使用 svndumpfiler 來把不要的檔案徹底從歷史記憶中濾除

# svnadmin create REPOS2
# svnadmin dump REPOS1 | svndumpfilter exclude XX.exe | svnadmin load REPOS2

這方法當然沒有 svnadmin obliterate 好,不過也是目前狀況下不得不的作法

但是這個方法最大的問題在於 svndumpfilter 無法接受 wildcards (萬用字元),也就是你無法指定 svndumpfilter exclude ‘*.exe’

所以,萬一不小心遇上了機車的狀況,你可能要一個一個把檔名找出來濾掉 XD

所以不久前就想辦法修改了 svndumpfilter 的程式,把它加上直接濾除特定副檔名檔案的功能…

[patch to subversion/svndumpfilter/main.c]
(the filename with leading dot will be matched against filename extension)

--- subversion/svndumpfilter/main.c.orig
+++ subversion/svndumpfilter/main.c
@@ -111,7 +111,12 @@
       pfx_len = strlen(pfx);
       if (path_len < pfx_len)
         continue;
-      if (strncmp(path, pfx, pfx_len) == 0)
+      if( pfx[0] == '.' )
+      {
+        if( strncmp( path+path_len-pfx_len, pfx, pfx_len ) == 0 )
+          return TRUE;
+      }
+      else if (strncmp (path, pfx, pfx_len) == 0)
         return TRUE;
     }
 
@@ -1257,7 +1262,8 @@
             style, and absolute. */
        SVN_INT_ERR(svn_utf_cstring_to_utf8(&prefix, os->argv[i], pool));
        prefix = svn_path_internal_style(prefix, pool);
-       prefix = svn_path_join("/", prefix, pool);
+       if( prefix[0] != '.' )
+          prefix = svn_path_join("/", prefix, pool);
        APR_ARRAY_PUSH(opt_state.prefixes, const char *) = prefix;
      }
  }

這個 patch 有點投機取巧,因為我懶得真的去實作 wildcards,我需要的功能只要能濾除指定的副檔名就可以了…

所以這個 patch 把原來 svndumpfilter include/exclude 後面接的檔名參數作特殊判斷,只要第一字元是小數點,就當作要去 match 的副檔名,因此,要濾除 *.exe 只要這樣作就可以了:

# svnadmin create REPOS2
# svnadmin dump REPOS1 | svndumpfilter exclude .exe | svnadmin load REPOS2

剛好看到前幾天也有人寫了個 PATCH 讓 svndumpfilter 完全支援 wildcards… 不過我沒試過,相信不久的將來應該會被整合進正式版本中

當然最希望還是 svmadmin obliterate 能早日被支援,就不用這麼辛苦了

使用 bcompiler 來編譯(加密)您的 PHP 原始碼

Using bcomipler to compile (encode) your PHP script (in FreeBSD)

eAccelerator 的 encoder 在 PHP 5.1 以後就無法運作了,使是最新的版本 0.9.5 也不行,因此如果您還想用 eAccelerator 的 encoder,乖乖待在 PHP 4.x or PHP 5.0 吧,相關資訊可參考之前的兩篇文章:

根據 mailing list 上面作者最新的說法,短期內應該都還不會修復,甚至有可能還會放棄支援 encoder 部份,作者還推薦大家改用 bcompiler … orz
所以如果你跟我一樣必須要用 PHP 5.1 的話,就跟我一起來玩看看 bcompiler

附帶一提,原本是要買 ionCube 公司開發的 PHP Encoder 的,這看來是目前編譯(加密)PHP 原始碼最好的選擇,價格也不算貴,而且花的是公司的錢,不過還是先試用看看 bcompiler 好了,真的不好用的話,再來買囉

以下的安裝與使用說明均以 FreeBSD 為範例,其他作業系統應該也差不多,請自己試看看吧

在正式安裝之前提醒你,bcompiler 會用到 bzip2 這個 extension,所以先安裝一下 php5-bz2:

# cd /usr/ports/archivers/php5-bz2
# make install clean

bcompiler 是一個收容於 PECL 的 PHP extension,您可以直接使用 pecl 這個命令來安裝,而 pecl 的使用方法與 pear 相同,因此你必須先安裝 pear :

# cd /usr/ports/devel/pear
# make install clean

pear 安裝好後,同時會有一個 pecl 命令可用 (/usr/locel/bin/pecl),可用它來安裝 bcompiler

pecl install channel://pecl.php.net/bcompiler-0.8

不過呢,我發現直接執行 pecl 會發生錯誤(至少在 FreeBSD 下是如此):

# pecl
Fatal error: Call to undefined function preg_match() in ...

問題出在 /usr/local/bin/pecl 這個 script 的最後一行:

exec $PHP -C -n -q $INCARG -d output_buffering=1 -d safe_mode=0 ...

這一行的 -n 這個選項代表不載入 php.ini 設定檔,因此 pcre.so 就沒有被載入,
然後你就看到上面的錯誤了,所以自己去改一下程式把 -n 拿掉吧….

拿掉之後,安裝程式應該就可以正常運作了了:

pecl install channel://pecl.php.net/bcompiler-0.8

安裝好後,記得要改設定把 bcompiler 這個 extension 載入

# echo "extension=bcompiler.so" >> /usr/local/etc/php/extensions.ini

bcompiler 全名是 PHP bytecode Compiler,詳細的使用方法可以參考 PHP 網站上的詳細說明: PHP bytecode Compiler: http://www.php.net/manual/en/ref.bcompiler.php

看不懂的話,bcompiler_write_file() 這個 function 的說明裡面有範例:

$fh = fopen("example.phb", "w");
bcompiler_write_header($fh);
bcompiler_write_file($fh, "example.php");
bcompiler_write_footer($fh);
fclose($fh);

為了易於使用,我寫了一個簡單的 script,使用方法如下:

BENCODER v1.3 - Encode your PHP script using bcompiler

Usage: bencoder [-f] [-q] -o FILE    file1.php
       bencoder [-f] [-q] -o OUTDIR  file1.php file2.php ...
       bencoder [-f] [-q] -o OUTDIR  -s SRCDIR  [-e SUFFIX] [-r] [-c] [-l]

  -o FILE   : the file name to write the encoded script
              (default to '-encoded.XXX' suffix)
  -o OUTDIR : the directory to write all encoded files

  -a SRCDIR
  -s SRCDIR : encode all files in this source directory

  -r        : encode directories recursively (no by default)
  -f        : force overwriting even if the target exists
  -e SUFFIX : encode the files with the SUFFIX extension only (default: php)
              (regular expression allowed, ex: "php|inc")
  -c        : copy files those shouldn't be encoded (no by default)
  -l        : follow symbolic link (no by default)
  -q        : do not print the file name while encoding or copying
  -b
  -bz2      : compress the encoded files with bz2 (needs bzip2-extension)

想用的人到 這邊 自己抓回去玩玩看吧

# wget http://bencoder.urdada.net/bencoder
# chmod 755 bencoder
# mv bencoder /usr/local/bin/

在把程式使用 bcompiler 編碼之後,執行的時候發覺 $_SERVER 以及 $_ENV 的變數都不見了,後來查了資料,才發現要把 auto_globals_jit 關掉 (Off) 才行,請直接修改您的 php.ini :

; When enabled, the SERVER and ENV variables are created when they're first
; used (Just In Time) instead of when the script starts. If these variables
; are not used within a script, having this directive on will result in a
; performance gain. The PHP directives register_globals, register_long_arrays,
; and register_argc_argv must be disabled for this directive to have any affect.
auto_globals_jit = Off

FreeBSD Software RAID-1 (gmirror)

手邊某台伺服器的 root 硬碟太小了(只有 8GB),然後上面又丟了很多重要的東西,所以一直想把它給換成大一點的,剛好手邊有一些換下來的 18GB 硬碟備品,就決定來換一下,並玩玩 Software RAID-1 (Mirror)

首先是把系統碟先換到比較大顆的硬碟,步驟請參考:

FreeBSD Handbook: How do I move my system over to my huge new disk?

接下來就要玩玩 Software RAID-1 (Mirror) 了

過去 FreeBSD 下面 Software RAID 的作法大多使用 vinum,但 vinum 的用法比較複雜,而且似乎只能適用新的分割區,無法對原有的硬碟直接建立一份 Mirror。

GEOM Mirror (gmirror) 是一種從 FreeBSD 5.3 開始支援的新 Software RAID-1,尤其適用於系統碟 (root partition)。

關於 FreeBSD 下面幾種 Disk Mirroring 的作法,可參考:

FreeBSD System Disk Mirroring – How to establish a RAID-1 for the system partitions

詳細的作法可參考這篇文章:

ONLamp.com: Using Software RAID-1 with FreeBSD

對舊硬碟設定一下,然後重開機後,把新硬碟加上去,再稍微設定一下,十分鐘內就搞定了!

最方便的是,使用 GEOM Mirror 建立的系統碟在系統內部並不會有特殊設定檔,所有的設定是直接放在硬碟最後一個磁區的 metadata 內,而且使用 gmirror RAID-1 的系統碟可以隨時切換用任何一顆開機,不會有任何問題

除了 gmirror 提供 RAID-1 之外,同樣採用 GEOM 架構的程式還有 gstripe (RAID-0) 及 graid3 (RAID-3),有興趣的人可以玩看看…

eAccelerator 無法使用於 PHP 5.1

上個月 PHP 5.1 正式發表了

昨天一時興起,把 PHP 5.0 利用 portupgrade 升級成 PHP 5.1,過程沒遇到什麼阻礙
安裝完後也覺得應該沒什麼問題,但是後來卻發現 eAccelerator 無法使用了

不管是 eAccelerator 0.9.3 或者 0.9.4-rc1 都一樣不能使用(連編譯都會發生錯誤)

根據 討論區 上面的說法,要修復這個問題似乎還需要一段時間

即使是將要發表的 0.9.4 版本,也不會支援 PHP 5.1

因此,有重度依賴 eAccelerator 的使用者,請乖乖先待在 PHP 4.4 或者 PHP 5.0 吧

Ref: eAccelerator – PHP 網頁加速及編碼

在 Dell PE 2850 上面安裝 FreeBSD 6.0

公司最近進了一些 Dell PowerEdge 2850 的伺服器…

今天第一次嚐試在 Dell PowerEdge 2850 上面安裝 FreeBSD 6.0

安裝過程並沒有甚麼問題,但是安裝完成、並重新開機之後,發現 console 的鍵盤竟然不能動了!

同樣的情況似乎也存在於 FreeBSD 5.3FreeBSD 5.4 的樣子(不確定,有人說 FreeBSD 5.3 沒這問題)

經過一番搜尋,發覺是因為這台機器上面有一張 “Dell Remote Access Card (DRAC)”,這個裝置會被系統辨識成一個 USB Keyboard,所以導致開完機之後,正常的 PS/2 鍵盤反而不能動了!

解決方式如下:

  1. 先以 Single User Mode 進入系統
  2. 在命令列模式下,先執行下列命令:
    # fsck -y  /
    # mount -u  /
  3. 然後編輯 /etc/devd.conf,把對於 USB Keyboard 的支援暫時拿掉,也就是把下面幾行開頭加上 #
    # When a USB keyboard arrives, attach it as the console keyboard ...
    #attach 100 {
    #       device-name "ukbd0";
    #       action "kbdcontrol -k /dev/ukbd0 < /dev/console ...
    #};
    #detach 100 {
    #       device-name "ukbd0";
    #       action "kbdcontrol -k /dev/kbd0 < /dev/console";
    #};
  4. 然後輸入 exit 離開 Single User Mode 之後,就可以順利進入系統,而且 console 鍵盤也可以正常運作,下次開機也不會有問題!

目前看起來,Dell PE-2850 使用 FreeBSD 6.0 當作業系統,除了上面這個 console 鍵盤問題之外,還沒遇到其他問題,系統也還算穩定