星期二, 5月 06, 2008

[tips] 如何讓你的ext2/ext3在神出鬼沒的地雷戰場上存活.

喜歡用自由軟體的人其實應該都滿常遇到地雷,
通常也練就了一身人間即時掃雷機的本事,
但有些時候實在是地雷太小顆 (但是倒炸的很大力),
又發生在想都想不到的地方, 要讓人不嗚呼哀哉也難.
就像開車時你不超車會有別人超車,
你不想用新版會有別人用新版,
軟體相容性的問題往往是會不請自來的.

lloyd大大今天跟我說了一個最近踩到地雷的故事,
他拿了一顆用ext2格式化過的400g硬碟,
拿到他弟弟灌了ext2 driver的windows上執行,
之前好一陣子都能讀取寫入, 操作上都沒問題,
最近卻怎麼格式化都不能用.
(在windows上會問你要不要重新格式化)
換了小一點的硬碟也不行. 最後他深入追查才發現es2fprogs這個最近更新的套件更新了mkfs.ext2這個程式, 預設的inode改變成256 bytes. 所以要用
mkfs.ext2 -I 128 讓預設的inode設成原本的128 bytes.

ok問題解決了, 聽起來只是windows ext2 driver跟e2fsprogs相容性的問題對不對?
但仔細一想問題可能就很大了, 今天你在debian lenny格式化了一顆ext2硬碟, 要放到穩定的重要server上(恰巧是debian sarge),卻不能讀了.
今天如果你沒有"恰巧"讀到這段,


E2fsprogs 1.40.5 (January 27, 2008)

Fix a potential overflow big in e2image if the device name is too long.

Mke2fs will now create new filesystems with 256 byte inodes and the ext_attr feature flag by default.
This allows for much better future compatibity with ext4 and speeds up extended attributes even on ext3 filesystems.

並把他放在心上的話, 你很可能就炸掉了.
(不過事實上可能就算你讀到這段也還是會被炸掉...)

此外/boot通常有人會用ext2而非格式化成xfs或raiser3什麼的(甚至連ext3都不用, 因為穩定),也免不了會踩到這個雷,
這裡"恰巧"就有個血淋淋的例子. (GRUB vs. the Inodes: Who Needs a Bootable System, Anyway? ) 喔, 只是不能開機而已嘛...orz

備註:
e2fsprogs version:
Gentoo-stable: 1.40.8
lenny (next debian stable): 1.40.8
etch (debian stable): 1.39+1.40

重要指令:

mkfs.ext2 -I 128 /dev/???
mkfs.ext3 -I 128 /dev/???

如果你還要向前相容性的話, 從現在開始別忘了mkfs.ext3時加上-I 128 , 否則... 就歡樂的炸吧... XD

感謝lloyd大大更正: 在debian etch (kernel 2.6.18) 上應該還是可以讀取256 bytes inode的格式, sarge是2.4 kernel可能就不行了. (根據mkfs.ext2的man page說法是2.4 kernel會沒辦法mount)

update: fix link.

星期二, 4月 22, 2008

[tips] poorman's uudecode

For those who cursed by ash and awk, welcome to 80's !

now you can send everything in ASCII -- hooray!!

#!/bin/sh
#
# uudecode.sh
#
# Author: Ximian, Inc.
#
# Modified: by timchen119 at http://timchen119.blogspot.com from Ximian go-gnome's GPL code
#
# Usage: uudecode.sh encodedfile > decodefile
#
# License: GPL
#
# Download: http://kalug.linux.org.tw/~tim/gpl/uudecode.sh
#
# Ref: http://ftp.cesnet.cz/pub/ximian-gnome/installers/go-gnome
#
# The Ximian Desktop Pre-Installer
#
# Comments to:
# distribution@ximian.com
#
# Copyright 2000-2001, Ximian, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
# USA.
#
#
# This script and its embedded programs are distributed with
# absolutely, positively NO WARRANTY WHATSOEVER, without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. The author and Ximian, Inc. take no responsibility for
# the consequences of running this script.
#
#

CACHEDIR=/tmp
_awk="awk"

# poor man's uudecode
_awkprog="$CACHEDIR/uudecode.awk"
# encoded file
_uudecode_in=$1

#awk-script
cat > ${_awkprog} <<EOF
function x(l, p) {
n="!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_";
return index(n,substr(l,p+1,1));
}
/^begin/ {}
/^[^be]/ {
len = x(\$0, 0);
for (i=1;len>0;i+=4) {
a=x(\$0,i);b=x(\$0,i+1);c=x(\$0,i+2);d=x(\$0,i+3);
printf("%c",a*4+b/16);
if (len>1) {
printf("%c",b*16+c/4);
if (len>2) {
printf("%c",c*64+d);
}
}
len-=3;
}
}
EOF
${_awk} -f ${_awkprog} < ${_uudecode_in}
rm -f ${_awkprog}


get uudecode.sh at here.

[funny] [links] [kuso] Python がイマイチ人気にならないたった一つの理由

http://d.hatena.ne.jp/seiunsky/20080417/1208454191

話說不小心點到這... 原本還想認真看看理由的... 結果... @@


1. 日本Python的入門書不好 !?


* 「最初(に読むPython本)はみんPyだよねー」

==> 「最初はみんなおっぱいだいすきからスタートする」

2. 著名書商 O'reilly 也很糟糕 ?!


* 「おれ、今Pyチューで勉強してるんだ!」

==> こんなセリフを女子に聞かれたら間違いなく「おっぱいにチューして何の勉強をしているの!へんたい!」と思われるのですから、これは本当に卑猥ですね。

3. PyPy實作不好 !?

* 「おれ、いま PyPy の開発してるんだ!」
* 「ただの人間には興味ありません。PyPy 開発に興味のある人は私のところに来なさい!以上!」
* 「PyPyを高速で動かす方法を思いついた!」

接下來就開始把python跟おっぱい扯在一起的大爆走了 XD (pychinko, Dive Into Python... 原來Python是完全的成人向啊...orz)

星期二, 4月 15, 2008

[tips] upgrading to gentoo 2008.0

Well just as usuals, you can upgrades to gentoo 2008.0 quickly. (beta?)

#eselect profile list
Available profile symlink targets:
[1] default-linux/x86/2006.1
[2] default-linux/x86/no-nptl
[3] default-linux/x86/2006.1/desktop
[4] default-linux/x86/2007.0
[5] default-linux/x86/2007.0/desktop
[6] hardened/x86/2.6
[7] selinux/2007.0/x86
[8] selinux/2007.0/x86/hardened
[9] default/linux/x86/2008.0
[10] default/linux/x86/2008.0/desktop *
[11] default/linux/x86/2008.0/developer
[12] default/linux/x86/2008.0/no-nptl
[13] default/linux/x86/2008.0/server
[14] hardened/linux/x86

For my case, just type 'eselect profile set 10'
and emerge world again.

I'm not migrating to OpenRC and baselayout2 yet, however I'm using KDE4.0.3 now, so I think I have enough un-stable-ness to worry about. ;0

[tips] using pyrex to do the argv[0] trick in linux using python.

A trick to rename python process in output of 'top' and 'ps'.


set_argv.c:

#include
#include
#include

int get_argc(){
int argc;
char **argv;
Py_GetArgcArgv(&argc, &argv);
return argc;
}

void set_argv_via_number(int num,char *str){
int argc;
char **argv;
Py_GetArgcArgv(&argc, &argv);
strncpy(argv[num], str , strlen(str));
memset(&argv[num][strlen(str)], '\0', strlen(&argv[num][strlen(str)]));
}


set_processname.pyx:

#Warning: this module is not safe and may involve some dirty hacks.
import sys,dl,glob
cdef extern int get_argc()
cdef extern void set_argv_via_number(int num,char *buf)
def set_argv0(thename):
set_argv_via_number(0,thename)

def set_argv(thename):
argc = get_argc()
print argc
for i in xrange(argc+1):
if i==0:
set_argv0(thename)
else:
pass
def set_name(thename):
if sys.platform == 'linux2':
# Set process name. Only works on Linux >= 2.1.57.
try:
libc_loc = glob.glob("/lib/libc.so*")[0]
libc = dl.open(libc_loc)
libc.call('prctl', 15, thename, 0, 0, 0) # 15 is PR_SET_NAME
except:
pass

def set_processname(thename):
space_padding_num = len(sys.argv[0])-len(thename)
if space_padding_num < 0:
#thename is longer than original name
newname = thename[:len(sys.argv[0])]
else:
#thename is shorter. add padding.
newname = thename + " " * space_padding_num

set_name(newname)
set_argv(newname)

compile.sh:
#!/bin/sh
CC=mipsel-linux-gcc

pyrexc set_processname.pyx
$CC -c -fPIC -I/usr/include/python2.5/ set_argv.c
$CC -c -fPIC -I/usr/include/python2.5/ set_processname.c
$CC -shared set_argv.o set_processname.o -o set_processname.so

[tips] building psyco on non-x86 platform. (ie. linux mips little endian)

The trick is to build psyco in ivm mode. The mode slower than the native mode(ivm mode involves a prolog generated-vm, you guess), however it's the only way to compile psyco on non-x86 system. And cross-compiling with distutils is not a trivial stuff, so I just compile it directly.


mipsel-linux-gcc -pthread -fno-strict-aliasing -DNDEBUG -fPIC -DALL_STATIC=1 -Ic/ivm -I/usr/include/python2.5 -c c/psyco.c -o build/temp.linux-mipsel-2.5/c/psyco.o
mipsel-linux-gcc -pthread -fno-strict-aliasing -DNDEBUG -fPIC -DALL_STATIC=1 -Ic/ivm -I/usr/include/python2.5 -c c/platform.c -o build/temp.linux-mipsel-2.5/c/platform.o
mipsel-linux-gcc -pthread -shared build/temp.linux-i686-2.5/c/psyco.o build/temp.linux-mipsel-2.5/c/platform.o -L/usr/lib -lpython2.5 -o build/lib.linux-i686-2.5/psyco/_psyco.so


This generates the C-module extension, and just copy all of py files to correct path and enjoy psyco speed-up! (well, not quite a case for me. It just use way too much memory on our embedded system. But I think maybe it'll useful in other project.)

ps: I should mentioned that I'm doing this on a uclibc linux system.

[tips] if as a pure function in python

http://okmij.org/ftp/Scheme/if-function.txt

here is a trick that we could rewrite a customized not-a-special-form IF in python.


iftrick.py:

#!/usr/bin/env python
def func_true():
print "true!"

def func_false():
print "false!"

def my_if(my_cond,then_func,else_func):
eval((then_func, else_func)[not my_cond].func_code,vars())

condition = True

my_if(condition,func_true,func_false)

condition = False

my_if(condition,func_true,func_false)

===
#python iftrick.py
true!
false!

星期三, 2月 06, 2008

Am I getting old or ....The lenny is coming this year???

根據 http://lwn.net/Articles/267722/的說法,

下一個版本的 debian (lenny) 將在今年9月release.

這可真是出乎我預期的快... etch... 不是去年四月才出的嗎?

**<小孩勿看>** 大便 難道真的落屎了嗎? **< / 小孩勿看>**

然後話說 /bin/sh link to dash 有了ubuntu帶頭衝之後 還真的debian就跟進了.

我的預言(詛咒)成真?! 看來lloyd大又要怨恨了 :P

(話說 難道再下版inittab也是難逃upstart之手了嗎??? ...有待下回茅房分解...)

這一行果然是很難混的啊.... XD

還有python 2.5.X 啥時要給我進default啊... 時間也該到了吧...

星期四, 1月 31, 2008

Arc is released. and is it a Blub?

http://arclanguage.org/

這兩天幾乎網路上所有lisp programmers都在討論Arc,
這個著名lisp hacker, Paul Graham所發明的lisp dialect, 一度被認為是vaporware的語言,在前天release了.

Paul Graham對於lisp社群的貢獻是無庸致疑的,
但這次他所公開release的Arc則是讓不少人大失所望.
畢竟這是他從他首次宣稱Arc is a better lisp以來已經過了6-7年之後釋出的版本,
"just another lisp dialect"似乎是不少lisp programmers的一致意見,
另外此次版本不支援unicode只支援ascii也引發大波瀾.
我自己最近時間不多, 但也小試了一下, and just didn't 'get' it.
我當然理解PG的"Syntax Do Matters",
但我也不完全同意less typing是higher level programming language唯一的路,
非常希望時間能證明, 這只是我們這些 "Blub" programmers的愚昧, 而Arc is indeed a better lisp and a better programming language.

註: Blub是PG發明的字眼. 在著名的Beating the Averages一文裡用來回答一個有趣的問題: "如果lisp這麼好,為什麼都沒人用?" 而描述出一個所謂的Blub弔詭的情境:
Blub是任一種介於比lisp低階 而比machine language高階之間的一個一般強度(power)的程式語言. (比如: python,java,ruby,perl,C/C++,haskell,ML-family,erlang,php,javascript,fortran,cobol.....anything not in lisp-family)
Blub programmer則是Blub programming language的支持/使用者,
Blub programmer的想法是, Blub語言 擁有某些特性X,
他無法想像更低階語言怎麼能夠沒有特性X而能拿來認真的使用.
同一時間他則認為Blub語言已經擁有所有他所需要的特性, 覺得所有比Blub語言更高階的特性全是無用而浪費時間的.

註2: 我的標題意思是Paul Graham在文章裡說他自認為他的Arc語言已經好到可以讓他不想用CL或scheme才release了, 是否也是陷入了Blub弔詭裡?

btw: you need patches to run current Arc on latest mzscheme(352+) or you're on windows(sadly),
see http://arclanguage.org/item?id=319 and http://jfkbits.blogspot.com/2008/01/digging-into-arc-in-24-macros-or-less.html

星期一, 1月 07, 2008

Python: programming language of 2007!

January Headline: TIOBE declares Python as programming language of 2007!

"""
Python has been declared as programming language of 2007. It was a close finish, but in the end Python appeared to have the largest increase in ratings in one year time (2.04%). There is no clear reason why Python made this huge jump in 2007. Last month Python surpassed Perl for the first time in history, which is an indication that Python has become the "de facto" glue language at system level. It is especially beloved by system administrators and build managers. Chances are high that Python's star will rise further in 2008, thanks to the upcoming release of Python 3.
"""

well, the reason is so obvious to me...it's all about gravity thingy ;)