2007年12月17日星期一

XDMCP迷思

我相信XDMCP是个好东西,基于X Windows伟大的C/S架构,速度、易用性都很强,但是,我的Gutsy主机、Gutsy客户端怎么就个小问题呢?

主机上的/etc/gdm/gdm.conf中[xdmcp]组中开启设置:

[xdmcp] Enable=true 

至于下面这两个选项我看是否设置没什么影响:

RemoteGreeter=/usr/lib/gdm/gdmlogin DisallowTCP=false 

设置好以后,用客户端,在登录界面Actions->Remote Login via XDMCP…,能看到主机,连接以后就是错误:

There already appears to be an X server running on display :2. Should another display number tried? Answering no will cause GDM to attempt starting the server on :2 again. (You can change console by pressing Ctrl-Alt plus a function key, such as Ctrl-Atl-F7 to go to console 7. X servers usually run on consoles 7 and higher. 

不管选Yes还是No,最终都是重新回到GDM登录界面。

但是,但是啊,不管是在主机本机,还是在客户端,居然都可以用命令连接上:

X :1 -query host_machine_name 

真是奇怪。另外如果一处远程桌面关闭,也会同时关闭使用相同 :? 标号的桌面,用的时候尽量错开。

Source: http://www.fwolf.com/blog/post/376

安装配置fluxbox桌面环境

安装

基本系统Ubuntu 7.10 Gutsy,Xfce桌面。直接安装源里的fluxbox:

aptitude install fluxbox 

版本1.0.0-1,大小只有1058k。安装完成后,检查一下/usr/share/xsessions/fluxbox.desktop文件,里面已经有Exec=/usr/bin/startfluxbox,不用修改了。重启X,(应该会自动创建~/.fluxbox/startup配置文件。

在X登录界面,Sessions选择Fluxbox,并设置为默认session。输入用户名密码进入系统之后,只看见一个光板的桌面,下面有一条工具栏,想截屏来着,可按PrintScreen键没反应,作罢。不过说真的,进入桌面的速度真的很快。工具栏上点右键可以调出工具栏的设置,桌面上点中键可以调出虚拟桌面的设置,但在桌面上点右键没反应,原来是fluxbox默认配置的问题( 害我瞎折腾半天)。

菜单

fluxbox安装完成后默认的菜单配置文件~/.fluxbox/menu内容如下:

[begin] (fluxbox) [include] (/etc/X11/fluxbox/fluxbox-menu) [end] 

而include的这个菜单文件根本就不存在,所以就没有菜单出现喽。现在我来手工加点内容吧:

[begin] (fluxbox) [exec] (Firefox) {/usr/bin/firefox} [exec] (Bash) {x-terminal-emulator -T "Bash" -e /bin/bash --login} [include] (/etc/X11/fluxbox/fluxbox-menu) [end] 

现在,不用重启或重开X,在桌面上点右键,怎么样,一个小小的菜单出来了吧,内容只有两项:Bash和Firefox,选中后会打开相应的程序。不过真要这样一个一个的把菜单配置全可就累死了,本来fluxbox自带一个菜单生成程序fluxbox-generate_menu的,但在Gutsy中没有,虽然它只是一个脚本,可以自己去下载一个单独用,不过手动一下:

sudo update-menus 

然后再重启Fluxbox就好了,根据当前系统中原有桌面系统(比如Gnome、Xfce)软件安装情况,自动把menu项建好了,生成了刚才缺少的/etc/X11/fluxbox/fluxbox-menu这个文件。

利用这种方式,或者使用fluxbox-generate_menu的好处就是可以随系统中软件安装情况变化,再搭配个人的一些优化设置,使用起来就更顺手了。

关机与重启

Fluxbox菜单中的restart和exit分别对应"重启窗口管理器"和"退出X,回到GDM界面",没有直接关机或重启的选项,需要自己手工添加:

[submenu]     [exec] (Reboot System) {sudo /sbin/shutdown -r now}     [exec] (Reboot System) {sudo /sbin/reboot}      #和上面一句作用相同     [exec] (Shutdown System) {sudo /sbin/shutdown -h now} [end] 

先别着急用,命令不都带着sudo了么,还要赋予用户不需密码就能够使用/sbin/shutdown的权限,修改/etc/sudoers,添加:

Cmnd_Alias REBOOT = /sbin/reboot Cmnd_Alias SHUTDOWN = /sbin/shutdown  fwolf ALL=(ALL) NOPASSWD: REBOOT, SHUTDOWN 

再调用关机或重启,虽然使用到sudo,也不再需要输入密码,而是直接就执行了。(参考1 参考2

如果一定要需要用户输入自己的密码才能关机的话,也是可以实现的,那就是通过shell来执行sudo,在新开的shell窗口中会提示用户输入sudo时的密码,输入密码不正确时就拒绝执行sudo了,比如这样(参考):

[exec] (Shutdown) {konsole -T "Shutdown" -e sudo shutdown now -h} [exec] (Shutdown) {gnome-terminal -t "Shutdown" -e "sudo shutdown now -h"} [exec] (Shutdown) {xfce4-terminal -t "Shutdown" -e "sudo shutdown now -h"} 

挂起与休眠

首先安装hibernate,源里有的,然后用root命令运行hibernate或者hibernate-disk就是休眠(信息写入磁盘,不耗电),运行hibernate-ram就是挂起(信息写入内存,会耗一点点的电)。如果运行了gnome-power-manager(在状态栏上会有电池图标),就可以设定合上笔记本时就休眠。菜单项和sudoers文件的修改和上面的关机和重启一样:

Cmnd_Alias SUSPEND = /usr/sbin/hibernate-ram Cmnd_Alias HIBERNATE = /usr/sbin/hibernate-disk  fwolf ALL=(ALL) NOPASSWD: REBOOT, SHUTDOWN, SUSPEND, HIBERNATE 

感觉挂起没有休眠好用,有时候从挂起状态恢复时会死掉,得重启X。

rxvt-uincode的daemon模式

超节省资源的fluxbox当然要搭配同样节省资源的rxvt-unicode来使用才更好,rxvt-unicode的daemon模式就更好了,可以在菜单中这样配置:

[exec] (rxvt-unicode) {urxvtc "$@"; if [ $? -eq 2 ]; then urxvtd -q -o -f; urxvtc "$@"; fi} 

这样就可以自动启动守护程序urxvcd了(参见官方文档)。使用中rxvt-unicode到gedit或者scribes这样的程序粘贴内容有点问题,Ctrl-V不管用,不过用鼠标中键可以粘贴过来,而Shift+Insert只在rxvt-unicode里起作用。 也有人说可以用autocutsel来同步两个剪贴板。

其它设置

快捷键

快捷键设置的默认定义文件为$HOME/.fluxbox/keys,注意Mod1代表Alt, Control代表Ctrl, Mod4代表Windows键,Mouse2是鼠标中键,Mouse4、5则是鼠标滚轮下滚、上滚。比如音量调节:

Control Mod1 Up :Exec amixer sset Master 1+ unmute Control Mod1 Down :Exec amixer sset Master 1- unmute Control Mod1 Left :Exec amixer sset Master mute 

界面字体

默认设置下,如果菜单中有中文,那么配置完成后只能看见两个小方框,这并不是说fluxbox菜单不支持中文,而是字体没设置好。其它窗口标题栏等地方的中文也是类似的情况。可以在$HOME/.fluxbox/overlay文件中设置字体、字号的选项(这个文件的本来作用是定义Style切换中的保留设置),比如如下的内容:

# 菜单标题的字体 menu.title.font: Simsun-10 # 菜单组标题的对齐方式 menu.title.justify: center # 菜单项目的字体 menu.frame.font: Simsun-10 # 菜单项目的对齐方式 menu.frame.justify: left # 窗口标题栏文字的字体 window.font: Simsun-10 # 窗口标题栏文字的对齐方式 window.justify: center # 窗口标题聚焦时的背景颜色|5/5/f window.label.focus.color: rgb:4e/8f/cf window.label.focus.colorTo: rgb:4e/8f/cf # 时钟的字体 toolbar.clock.font: Simsun-10 # 工作区名称的字体 #toolbar.workspace.font: Simsun # 图标栏的字体 toolbar.iconbar.focused.font: Simsun-10 toolbar.iconbar.unfocused.font: Simsun-10 

字体名称后面-11为字体大小,再后面跟:bold表示黑体显示,中间都没有空格。

自启动程序

自启动程序可以在$HOME/.fluxbox/startup中配置,写在exec /usr/bin/fluxbox一句的前面,并且**一定要在后面加上表示后台运行的&符号。比如为了优化GTK程序的运行,可以加上:

GSDPID=`pidof gnome-settings-daemon` if [ "x$GSDPID" == "x" ]; then     gnome-settings-daemon & fi gnome-power-manager gnome-volume-manager -daemon=yes & 

gnome-power-manager是电源管理程序,用来管理笔记本的电源,台式机可以不用;gnome-volume-manager则是卷管理器,只有加载了它,插入u盘或者移动硬盘之后才能自动挂载。

程序属性apps

$HOME/.fluxbox/apps这个文件我还是第一次见过,它可以定义窗口的各项属性,比如:

[app] (name=xfce4-terminal) [Position]  (LOWERLEFT) {0 55} [end]  [group]     [app] (name=urxvt) (class=URxvt)         [Position] (LOWERLEFT) {0 25} [end] 

第一个[app]是定义了程序xfce4-terminal启动时的窗口位置为相对于屏幕左下角0,55的坐标,这样每次启动程序的时候就不用再手工移动窗口到自己舒服的位置了。fluxbox没有gnome那样窗口自动dock到屏幕边缘的功能,这算是另外一种方式的补充。

第二个[group]则是定义在本group范围之内的app,启动之后自动tab到一起,tab是fluxbox的特有功能,有点类似xfce4-terminalgnome-terminal开多个tab的功能(我也正是利用这点来模拟rxvt-unicode的多tab),这样打开多个rxvtc的时候,就自动tab到一个窗口去了,不用再手工按鼠标中键把一个标题栏拖到另外一个标题栏上。如果再在keys文件中配上Ctrl+PageDown切换到下一个Tab的功能:

Control Prior :PrevTab Control Next :NextTab 

多Tab shell窗口功能就近乎完美了,几乎可以完全淘汰xfce4-terminal了(字体颜色设置上还略有些不太习惯)(这样还把xfce4-terminal自身的tab切换功能给屏蔽了,调成用Mod1/Alt来组合也不错)。如果你想,在group中加上其它程序也是可以的。

apps文件很重要,不过如果手工在设定窗口保存属性的话,会被系统自动改写,为了保存手工编写代码的美观性,可以把这个文件的属性设置为444,编辑时再用w!强行写入。

桌面图片随机轮换

这一点简直太适合我了,我就喜欢设定一个目录,用里面的图片随机作为桌面,只需要把下面这个命令仍到crontab里就可以了:

env DISPLAY=":0.0" fbsetbg -F -R /path/to/your/wallpaper/ 

注意这个目录中不能有非图片文件。记得安装feh,虽然不装的话也能用,装上以后图片显示速度和拉伸效果都更好一些。

参考

Source: http://www.fwolf.com/blog/post/375

2007年12月11日星期二

Xfce桌面上不显示图标了怎么办?

环境:Ubuntu 7.10 Gutsy, Xfce桌面。

这个现象已经很久了,桌面上不显示图标,点鼠标右键也没反应,虽然在Desktop Settings中选择Allow Xfce to manage the desktop的话,能显示桌面,但这是xfce自己用xfdesktop接管了桌面管理,不是根本之道。网上似乎很多人遇到类似问题,多半是升级Ubuntu搞出来的,推荐的解决方法无外乎删除xfce配置文件云云。

Xfce具备保存session功能(其实,我都不之道如何开始一个新的session),也好也不好,不过利用这个特性倒是能解决桌面上不显示图标的问题。

首先换上一个新的windows manager,过渡用一下而已:

x-window-manager --replace & 

然后就可以再替换为nautilus来管理桌面了:

nautilus 

把打开的文件管理器窗口关掉,你会发现桌面图标已经出来了。

有时候还会出现窗口无标题栏等问题,也能解决,首先在User Interface Preference中换一款主题,不管用的话再手工启动metacity:

metacity --replace & 

另外,在Sessions and StartupAdvanced中记得勾选Launch Gnome services on startup,要想桌面漂亮,这个好像还没法优化。

现在退出登录并且记得选上Save session for future logins,貌似一切恢复平静。

老实说,其实我是在换了Fluxbox后,右键依然唤不出菜单,才想起来找这里的原因,但这边解决以后发现fluxbox根本没有变化,大概还是fluxbox配置的问题。用了一段时间的xfce后感觉还是脱不开gnome的种种类类,希望fluxbox能好一些,让我的老机器跑快一点。

Source: http://www.fwolf.com/blog/post/374

2007年12月6日星期四

纪念老妈的半颗大牙

本来想让老妈尝点好吃东东的,买了点99辣鸭脖,还"逼"着老妈一定要吃。老妈倒也卖力,边看电视边啃,《金婚》演完了以后告诉我们一个坏消息,一颗牙齿(左边、上面,尖牙后面的第一颗大牙)不幸断裂了大半个下来。

老妈从小爱吃糖,可惜那时候条件不好,把牙都吃坏了,后来刷牙也不知道正确的方法(上下刷),还把牙给刷出一道横向的沟,牙齿更不结实了。后来牙齿出毛病,也补过、镶过牙齿,现在吃饭全靠假牙。今天吃鸭爪的时候,可能太认真,鸭骨头就把这颗本来就不太结实的牙给"撬"断了,看着这半颗牙齿,心里真不是滋味儿,早知道不买这些费牙的东东了。

在这里还要批评我老爸,记得去年过年的时候,买过一袋"老奶奶××豆",打开一尝,哪是什么老奶奶吃的豆啊,我吃都咬不动,遂扔在一边。后来一没留神,发现老爸边斗地主边在啃这个豆,也就仗着老爸牙好,咧着嘴咖蹦咖蹦的费劲咬着豆,看得我是又心疼又生气,一把就把豆给扔了,还数落了老爸半天,这么大岁数了也不知道心疼牙齿。要知道牙不好,食物无法充分咀嚼,胃的负担就重,胃累坏了,消化、吸收就不好,进而影响健康。其实最该死的就是生产这豆的厂家,应该改名叫"铁蛋"豆子。

再说《金婚》这电视剧,我挺喜欢,推荐给老妈和lp,她们也都很爱看,我尤其喜欢看改革开放之前的部分,感觉很真实,描写那些年代的影视不多。

唉,牙断了也接不上,后悔也没用,和老爸老妈一起生活的时候可要注意了,不要买太费牙的东东给他们吃,尤其是鸡鸭这种带小棒子骨的。

Source: http://www.fwolf.com/blog/post/373

2007年12月4日星期二

Linux下使用华为h3c Aolynk WuB320G无线网卡

我搜到的国内唯一的两篇参考文章(之所以说是唯一,是因为内容基本一致,大概是同一个人写的):

不过这位老大写得比较模糊,具体操作的时候还是费了不少周折。加上本本上的迅驰无线捣乱,由于本本比较老了,自带无线网卡是Intel PRO/Wireless 2100,只支持802.11b,好像还不支持WPA(WPA是2004年提出的,比本本的岁数小),所以在它身上也浪费了不少时间。

华为3com的Aolynk WUB320g usb无线网卡芯片组应该是Ralink(它的台湾分站)的RT73,虽然Ubuntu Gutsy自带了驱动,并且识别出了网卡,但注意,这个自带的驱动不好用,或者说 没法用,仍然需要自己到http://rt2×00.serialmonkey.com/下载开源的驱动,编译使用。(编译前后,用 iwpriv wlan0看列出的可用参数就知道这两个驱动的区别了)

编译需要内核相应的头文件,比如linux-headers-2.6.22-14-generic,解压后按照README文件的内容:

$ tar xzf rt73-cvs-daily.tar.gz $ cd rt73-cvs-YYYYMMDDHH/Moduls $ make $ make install 

就算编译安装完成了,手工挂载:modprobe rt73 ifname=wlan0,在/etc/modules中添加一句rt73,每次启动就能够自动挂载了。还可以在/etc/modprobe.d/blacklist中增加一句:blacklist rt73usb,禁用系统自带的驱动。

如果要和采用WPA-PSK认证方式的AP连接,还要修改一下/etc/network/interfaces文件,比如:

auto wlan0 iface wlan0 inet static     address 192.168.0.13     netmask 255.255.255.0     gateway 192.168.0.1      pre-up ifconfig wlan0 up     pre-up ifconfig wlan0 down     pre-up ifconfig wlan0 up     pre-up iwconfig wlan0 essid "my_essid"     pre-up iwconfig wlan0 mode Managed     pre-up iwpriv wlan0 set AuthMode=WPAPSK     pre-up iwpriv wlan0 set EncrypType=TKIP     pre-up iwpriv wlan0 set WPAPSK="my_wpa_passphrase"     pre-up ifconfig wlan0 up 

这个设置是从WifiDocs/Driver/RalinkRT73抓过来的,大体意思知道,但为什么写成这个格式不是非常明白,不过这样的确就可以使用了 :-)。

配置无线连接还可以使用其它工具,比如wifi-radar,或者专门为Ralink开源驱动设计的RutilT也不错。

试着用两块Wub320g配置Ad-Hoc对等网,但失败了,配置如下(两端的配置是一样的):

auto wlan0 iface wlan0 inet static     address 192.168.0.13     netmask 255.255.255.0     gateway 192.168.0.1      pre-up ifconfig wlan0 up     pre-up ifconfig wlan0 down     pre-up ifconfig wlan0 up     pre-up iwconfig wlan0 mode Ad-Hoc     pre-up iwconfig wlan0 channel 2     pre-up iwconfig wlan0 essid "fwolf_home"     pre-up iwconfig wlan0 key 1234567890     #pre-up iwpriv wlan0 set NetworkType=Adhoc     #pre-up iwpriv wlan0 set AuthMode=OPEN     #pre-up iwpriv wlan0 set EncrypType=NONE     #pre-up iwpriv wlan0 set SSID="fwolf_home"     # Break 802.11i's 11m/s limit     #pre-up iwpriv wlan0 set AdhocOfdm=1     pre-up ifconfig wlan0 up 

注释中是另外一种方式,两种方式下网卡都能够连通,从iwconfig或者其它工具中都能看到已连接的状态,ifconfig也能看到发送和接收的流量,但两块网卡之间就是ping不通(属于同一网段)。把两端的机器都重启,偶尔能从还连接着局域网的机器上ping通另外一台只连接了无线网的机器,而反过来ping不通,提示:

Destination Host Unreachable 

有时候还会提示:

ping: sendmsg: No buffer space available 

对等网计划只好暂时搁浅,先找个AP用着。

最后总结,在为linux操作系统选购硬件时,一定要先上网看看相应的功能好不好配置,优先选择应用比较广泛、驱动比较开放、配置容易的产品。

参考

Source: http://www.fwolf.com/blog/post/372

Bash script中的命令行参数处理

Bash中的script是强大的,但如果想让写出的脚本更加实用、灵活,不能简单的堆砌命令,势必要加上一些命令行参数。命令行参数除了实际的操作对象以外,还可能是一些选项(通常是用-开头的),如果还是用$1、$2这样的方式一个一个的判断参数到底是不是选项、是哪个选项就太低效了,更好的方式是用getopts,先看简单的例子:

#!/bin/bash while getopts 'd:Dm:f:t:' OPT; do     case $OPT in         d)             DEL_DAYS="$OPTARG";;         D)             DEL_ORIGINAL='yes';;         f)             DIR_FROM="$OPTARG";;         m)             MAILDIR_NAME="$OPTARG";;         t)             DIR_TO="$OPTARG";;         ?)             echo "Usage: `basename $0` [options] filename"     esac done  shift $(($OPTIND - 1)) 

getopts后面的字符串就是可以使用的选项列表,每个字母代表一个选项,后面带:的意味着选项除了定义本身之外,还会带上一个参数作为选项的值,比如d:在实际的使用中就会对应-d 30,选项的值就是30;getopts字符串中没有跟随:的是开关型选项,不需要再指定值,相当于true/false,只要带了这个参数就是true。如果命令行中包含了没有在getopts列表中的选项,会有警告信息,如果在整个getopts字符串前面也加上个 :,就能消除警告信息了。

使用getopts识别出各个选项之后,就可以配合case来进行相应的操作了。操作中有两个相对固定的"常量",一个是OPTARG,用来取当前选项的值,另外一个是OPTIND,代表当前选项在参数列表中的位移。注意case中的最后一个选择──?,代表这如果出现了不认识的选项,所进行的操作。

选项参数识别完成之后,如果要取剩余的其它命令行参数,可以使用shift把选项参数抹去,就像例子里面的那样,对整个参数列表进行左移操作,最左边的参数就丢失了(已经用case判断并进行了处理,不再需要了),位移的长度正好是刚才case循环完毕之后的OPTIND - 1,因为参数从1开始编号,选项处理完毕之后,正好指向剩余其它参数的第一个。在这里还要知道,getopts在处理参数的时候,处理一个开关型选项,OPTIND加1,处理一个带值的选项参数,OPTIND则会加2。

最后,真正需要处理的参数就是$1~$#了,可以用for循环依次处理。

使用getopts处理参数虽然是更加方便了,但仍然有两个小小的局限:

  1. 选项参数的格式必须是-d val,而不能是中间没有空格的-dval
  2. 所有选项参数必须写在其它参数的前面,因为getopts是从命令行前面开始处理,遇到非-开头的参数,或者选项参数结束标记--就中止了,如果中间遇到非选项的命令行参数,后面的选项参数就都取不到了。

参考

Source: http://www.fwolf.com/blog/post/371

2007年11月19日星期一

加速Ubuntu

  • 将localhost化名为主机名,编辑hosts文件,把127.0.0.1等于localhost和本机名写到一行中,比如:

    127.0.0.1 localhost 127.0.1.1 fwolf_pcname ==> 变成 127.0.0.1 localhost fwolf_pcname 
  • 禁用ipv6,编辑/etc/modprobe.d/aliases

    alias net-pf-10 ipv6 ==> alias net-pf-10 off #ipv6 
  • 并行运行开机启动脚本,编辑/etc/init.d/rc

    CONCURRENCY=none ==> CONCURRENCY=shell 

    但据说这种方法可能会造成启动问题,慎用,建议多核cpu才使用。

  • 禁用Pango的输出和文本渲染,主要针对mozilla和firefox,可能会导致cpu占用过高。编辑/etc/environment,添加一行:

    MOZ_DISABLE_PANGO="1" 

    关闭之后明显感觉到firefox的显示速度变快了,但显示形式也有了一些变化,比如


    、网页标题的黑体字现在能体现了,但也感觉字体渲染略微"模糊"了一点点。
  • 安装preload,它可以把一些常用到的库文件预加载到内存,用部分内存空间换取应用程序启动速度的提升。另外注意,prelink从Feisty 7.04起就没用了:

    sudo apt-get install preload 
  • 禁用多余的虚拟终端,编辑/etc/inittab,把getty部分只留一个就可以了:

    1:2345:respawn:/sbin/getty 38400 tty1 #2:23:respawn:/sbin/getty 38400 tty2 #3:23:respawn:/sbin/getty 38400 tty3 #4:23:respawn:/sbin/getty 38400 tty4 #5:23:respawn:/sbin/getty 38400 tty5 #6:23:respawn:/sbin/getty 38400 tty6 

    Ctrl+Alt+F2-F6就没东西了,F1是我们保留的终端,用于应急处理,F7就是正常的图形环境啦。
    注:有些情况下这样好像不行,还要编辑/etc/event.d/tty2,把start开头的两行都注释掉,3456都如法炮制,依然只保留1,再用热键切换过去就是空空的一个提示符了。

  • 调整hdparm加速硬盘,编辑/etc/hdparm.conf,参考内容如下:

    /dev/sda { dma = on io32_support = 1 mult_sect_io = 32 } 
  • 对于内存充足的机器减少对swap的使用,编辑/etc/sysctl.conf,添加:

    vm.swappiness=10 

    这个数值的默认值为60,越小对swap的写入可能就越小,有网友说1G内存调整为5感觉最合适,建议至少512M内存以上再调整这个数值,设为0的话就几乎等于不实用swap了。

  • 使用LVM,但暂时没有进一步的资料。

  • 用bootchart协助,优化系统启动过程,对耗时较多的过程进行优化。

  • 使用bum关闭掉不需要的服务,不推荐用sysv-rc-conf的原因是bum对服务、进程有比较详细的解释说明。

  • 如果fstab中挂有外部磁盘,启动时不需要检测,可以把pass设置为0(fstab中最后一列)。如果在安装系统时就选用更合理的分区方案、分区类型(比如XFS)效果更佳。

  • 现在应该都在用6.10 Edgy之后的发行版了,如果是486机器,请选用386内核;P4以后的机器,包括同期的AMD,请选用generic内核;服务器请选用linux-server内核,会有一点点的性能提升,maybe。参考Difference between linux-generic, linux-386

  • 用deborphan删除不用的库文件:

    sudo deborphan | xargs sudo apt-get -y remove --purge 

参考

Source: http://www.fwolf.com/blog/post/370

2007年11月16日星期五

在无线网络中使用RADIUS服务器+mysql进行用户认证

安全性

无线网络使用非常方便,但方便之余还要考虑安全性的问题。

首先是传输的安全线,WEP方式现在已经是不安全的了,容易被黑客破解密钥,监听通讯数据,所以现在以WPA及其衍生方式为主。

取消SSID自动播放功能也是一个好的习惯,所有无线局域网都有一个缺省的SSID(服务标识符)或网络名。如果企业具有网络管理能力,应该定期更改SSID;或者取消SSID自动播放功能。

然后就是接入的安全性了,即通过认证的用户才允许使用网络,除了网络设备自身具备的MAC绑定、ACL等功能之外,还可以选择RADIUS来进行认证,甚至完成计费等其他任务。

RADIUS的全称为Remote Authentication Dial-In User Service,是一种能够让服务器验证各种接入用户身份的协议(基于udp),RADIUS可以对用户身份进行集中管理,安全性更好,策略也更灵活,同时还可以记录用户的网络使用情况用于网管分析或者计费,已经成为比较常用的工业标准。在使用中,路由器、交换机等设备在需要验证用户身份的时候,向RADIUS服务器发送请求,RADIUS服务器则返回用户的相关信息,交给路由器、交换机等设备处理。

提供RADIUS服务的软件,windows下可以选IAS(Internet Authentication Service/Internet验证服务),Linux下则是FreeRADIUS,另外还有Cisco的ACS(听起来像是基于硬件设备的?)等等。

Windows下的IAS,RADIUS服务器

在本文中,我们将架设一个RADIUS服务器,并采用用户名、口令的方式验证无线上网用户。服务器为Ubuntu Gutsy 7.10。

安装radius

$ sudo aptitude install freeradius freeradius-dialupadmin freeradius-mysql   Setting up freeradius (1.1.3-3ubuntu1) ... Adding group `freerad' (GID 120) ... Done. Adding system user `freerad' (UID 112) ... Adding new user `freerad' (UID 112) with group `freerad' ... Not creating home directory `/etc/freeradius'. Adding user `freerad' to group `shadow' ... Done.  * Starting FreeRADIUS daemon freeradius                                        Wed Nov  7 11:35:36 2007 : Info: Starting - reading configuration files ...                                                                          [ OK ]  Setting up freeradius-dialupadmin (1.1.3-3ubuntu1) ... Setting up freeradius-mysql (1.1.3-3ubuntu1) ...  * Reloading configuration files for FreeRADIUS daemon...                        * HUP sent...                                                           [ OK ] 

现在安装是完成了,但用这种方式配置下去,最终用winxp客户端登录的时候,会提示没有用户密码的失败请求,即使你输入了正确的用户名/密码:

Login incorrect: [t/] (from client home_wlan port 1 cli 00-16-6F-6C-53-2C) 

或者在启动服务器时看见这样的错误:

rlm_eap: Failed to link EAP-Type/tls: rlm_eap_tls.so: cannot open shared object file: No such file or directory 

这并不是因为是使用了PEAP、EAP-MSCHAPv2协议,AP没有发送密码明文,而是RADIUS服务器端没有打开tls, ttls, peap模块,或者打开了但没有生效,再深层次的原因就是大概因为版权或协议问题,debian中的freeradius没有把openssl编译进去,用户若想使用,只能手工下载源码编译。参见(

简言之,还得从freeradius官网下载最新版源码再编译安装一遍,过程倒也不复杂:

tar zxvf freeradius-1.1.7.tar.gz cd freeradius-1.1.7/  dpkg-buildpackage -rfakeroot # 提示缺少什么包,就装上什么包  dpkg -i freeradius_1.1.7-0_i386.deb freeradius-mysql_1.1.7-0_i386.deb 

另外说明,是否能够直接编译安装,跳过apt安装我没有试验过,主要是怕证书文件和用户、组什么的不能准备好。

配置radius

修改配置文件:/etc/freeradius/radiusd.conf(注意如果在文件末尾修改的话,后面的值不会覆盖前面的值,所以要直接在原位置上修改),先打开几个log选项:

log_auth = yes log_auth_badpass = yes log_auth_goodpass = yes 

适当延长发送认证失败消息之前的暂停秒数,防止暴破,默认为1秒。

reject_delay = 5 

把authorize、accounting、session、post-auth几个部分中sql一句前的注释取消掉,启用mysql认证。

更改clients.conf,设置允许使用radius服务的设备,一般是AP的地址,secret是AP连接radius的密码,比如:

client 192.168.0.0/24 {     secret = some_pass     shortname = wlan     nastype = other } 

把eap.conf中的tls, ttls, peap三段的注释全部取消,这是启用peap的关键,也是上面手工编译安装的目的。

还有文档说使用mysql认证的情况下,需要注释掉users文件中的如下内容:

DEFAULT Auth-Type = System     Fall-Through = 1 

个人理解如果不这样的话,由于sql认证的顺序排在后面,所以前面的认证失败之后就去验证system的用户账号去了,mysql认证实际等于是没起到作用,但我没修改这个文件,也能够正常使用。

更改sql.conf,设置与mysql相关的信息:

server = "localhost" login = "mysql_user" password = "mysql_pass" 

现在重启freeradius服务,应该就可以正常服务了,可以简单测试一下(test/test是错误的用户名/密码,testing123是默认在clients.conf中定义的本机用户的secret):

# radtest test test localhost 0 testing123 Sending Access-Request of id 5 to 127.0.0.1 port 1812         User-Name = "test"         User-Password = "test"         NAS-IP-Address = 255.255.255.255         NAS-Port = 0 Re-sending Access-Request of id 5 to 127.0.0.1 port 1812         User-Name = "test"         User-Password = "test"         NAS-IP-Address = 255.255.255.255         NAS-Port = 0 rad_recv: Access-Reject packet from host 127.0.0.1:1812, id=5, length=20 

可以看到服务器接受到了请求,并返回了用户/密码=test/test的reject信息。

现在来准备mysql,先建库和用户:

$ mysql -u root -p mysql> set names 'utf8'; mysql> show variables where variable_name like '%character_set%'; mysql> create database radius; mysql> CREATE USER 'radius'@'localhost' IDENTIFIED BY '**********'; mysql> GRANT USAGE ON * . * TO 'radius'@'localhost' IDENTIFIED BY '**********' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ; mysql> GRANT ALL PRIVILEGES ON `radius` . * TO 'radius'@'localhost'; 

然后创建radius相关的表和初始数据,表结构可以从Freeradius官网下载,本机也有一份/usr/share/doc/freeradius/examples/mysql.sql.gz,解压就行。表结构创建好之后,就可以创建使用者账号了,默认是存储在radcheck 表中的,可以使用这样的sql语句:

insert into radcheck (username,attribute,op,value) values ('user1','Password','==','password1'); 

其中参数attribute对应的值PasswordUser-Password也行,op对应的值用:=也行。

AP端设置

我使用的AP为H3C Aolynk WAP500ag,关闭a网,只开g网,主要设置为:

Secrity Mode: WPA Clipher Type: AES(比TKIP方式更加安全) RADIUS Server IP/Secret: RADIUS服务器所在的ip以及`clients.conf`中设置的对应`secret`。 Access Control: Disable 

客户端设置

aolynk WUB320g

认证方法:WPA,加密设置:AES,在802.1x验证中,设置验证方式为PEAP,验证ID好像无用,但不让置空(查看mysql中的记录,好像是登录成功后所显示的user名,依然用处不大),不使用Client证书,Tunnel协议为EAP-MSCHAP v2,ID和密码为RADIUS设置(存储在mysql中)的用户名/密码,如图:

迅驰笔记本

我用的这台笔记本上,Inter PROSet/Wireless 9.0.1.4(1999-2005)好像版本太旧,不支持我所设置的验证方式,在配置式里面能够设定"网络验证=WPA-企业、数据加密=AES-CCMP、验证类型=PEAP、身份验证协议=MS-CHAP-V2、用户身份凭证=用户名+密码",但连接上之后提示"未知的验证状态",无法传输数据,然后过一会儿被断开连接,所以只能使用winxp的网络连接设置。

WinXP的设置:无线网络连接属性->无线网络配置Tab页->首选网络(属性)->关联Tab页,网络验证:WPA,数据加密:AES,然后在"关联"Tab页,EAP类型:受保护的EAP(PEAP),在属性中,不选"验证服务器证书",选择"启用快速重新连接",验证方法:安全密码(EAP-MSCHAP v2),并在"配置"中不选择"自动使用windows登录名和密码"。写的迷糊吧,还是看图好了:

登录的时候,如果验证失败,就会提示用户点状态栏上的小图标,更换其他凭证,其实就是输入新的用户名/密码。

这种方式会自动记录下成功的用户名和密码,没有取消自动记录的选项,不过我在上海交大无线网-使用802.1x认证时注意密码泄漏问题中找到一个 注册表文件,可以清空密码,其实内容也是非常的简单:

REGEDIT4  [-HKEY_CURRENT_USER\Software\Microsoft\Eapol\UserEapInfo] 

上海交通大学网络中心 无线网还有一些无线网络使用方面的资料,非常值得参考。

连接成功,服务器上的log,供参考

rad_recv: Access-Request packet from host 192.168.0.201:1168, id=9, length=227         Message-Authenticator = 0xd183f5b181b63e0d6a8f4e73f39af43b         Service-Type = Framed-User         User-Name = "t"         Framed-MTU = 1488         State = 0x8e35307b622be9576b22872d13e0814b         Called-Station-Id = "00-0F-E2-51-41-70:WAP500g_1"         Calling-Station-Id = "00-16-6F-6C-53-2C"         NAS-Identifier = "wap500ag_1"         NAS-Port-Type = Wireless-802.11         Connect-Info = "CONNECT 54Mbps 802.11g"         EAP-Message = 0x020900261900170301001b307b40587df20edfbd63f7bbfe1b56600d799d610ba835f3e1f8f3         NAS-IP-Address = 192.168.0.201         NAS-Port = 1         NAS-Port-Id = "STA port # 1"   Processing the authorize section of radiusd.conf modcall: entering group authorize for request 29   modcall[authorize]: module "preprocess" returns ok for request 29   modcall[authorize]: module "chap" returns noop for request 29   modcall[authorize]: module "mschap" returns noop for request 29     rlm_realm: No '@' in User-Name = "t", looking up realm NULL     rlm_realm: No such realm "NULL"   modcall[authorize]: module "suffix" returns noop for request 29   rlm_eap: EAP packet type response id 9 length 38   rlm_eap: No EAP Start, assuming it's an on-going EAP conversation   modcall[authorize]: module "eap" returns updated for request 29     users: Matched entry DEFAULT at line 153     users: Matched entry DEFAULT at line 172   modcall[authorize]: module "files" returns ok for request 29 radius_xlat:  't' rlm_sql (sql): sql_set_user escaped user --> 't' radius_xlat:  'SELECT id, UserName, Attribute, Value, op           FROM radcheck           WHERE Username = 't'           ORDER BY id' rlm_sql (sql): Reserving sql socket id: 1 radius_xlat:  'SELECT radgroupcheck.id,radgroupcheck.GroupName,radgroupcheck.Attribute,radgroupcheck.Value,radgroupcheck.op  FROM radgroupcheck,usergroup WHERE usergroup.Username  = 't' AND usergroup.GroupName = radgroupcheck.GroupName ORDER BY radgroupcheck.id' radius_xlat:  'SELECT id, UserName, Attribute, Value, op           FROM radreply           WHERE Username = 't'           ORDER BY id' radius_xlat:  'SELECT radgroupreply.id,radgroupreply.GroupName,radgroupreply.Attribute,radgroupreply.Value,radgroupreply.op  FROM radgroupreply,usergroup WHERE usergroup.Username  = 't' AND usergroup.GroupName = radgroupreply.GroupName ORDER BY radgroupreply.id' rlm_sql (sql): Released sql socket id: 1   modcall[authorize]: module "sql" returns ok for request 29 rlm_pap: Found existing Auth-Type, not changing it.   modcall[authorize]: module "pap" returns noop for request 29 modcall: leaving group authorize (returns updated) for request 29   rad_check_password:  Found Auth-Type EAP auth: type "EAP"   Processing the authenticate section of radiusd.conf modcall: entering group authenticate for request 29   rlm_eap: Request found, released from the list   rlm_eap: EAP/peap   rlm_eap: processing type peap   rlm_eap_peap: Authenticate   rlm_eap_tls: processing TLS   eaptls_verify returned 7   rlm_eap_tls: Done initial handshake   eaptls_process returned 7   rlm_eap_peap: EAPTLS_OK   rlm_eap_peap: Session established.  Decoding tunneled attributes.   rlm_eap_peap: Received EAP-TLV response.   rlm_eap_peap: Tunneled data is valid.   rlm_eap_peap: Success   rlm_eap: Freeing handler   modcall[authenticate]: module "eap" returns ok for request 29 modcall: leaving group authenticate (returns ok) for request 29 Login OK: [t/] (from client hbzbb_wlan port 1 cli 00-16-6F-6C-53-2C)   Processing the post-auth section of radiusd.conf modcall: entering group post-auth for request 29 rlm_sql (sql): Processing sql_postauth radius_xlat:  't' rlm_sql (sql): sql_set_user escaped user --> 't' radius_xlat:  'INSERT into radpostauth (user, pass, reply, date) values ('t', 'Chap-Password', 'Access-Accept', NOW())' rlm_sql (sql) in sql_postauth: query is INSERT into radpostauth (user, pass, reply, date) values ('t', 'Chap-Password', 'Access-Accept', NOW()) rlm_sql (sql): Reserving sql socket id: 0 rlm_sql (sql): Released sql socket id: 0   modcall[post-auth]: module "sql" returns ok for request 29 modcall: leaving group post-auth (returns ok) for request 29 Sending Access-Accept of id 9 to 192.168.0.201 port 1168         Framed-IP-Address = 255.255.255.254         Framed-MTU = 576         Service-Type = Framed-User         MS-MPPE-Recv-Key = 0x578ab49877c333d5c8c93124e9d76c463a0abc2facc7ae25347a0d97490b6869         MS-MPPE-Send-Key = 0x019b5f44bb5dcb0b2c8f2af449215f548af6c63a8ecb692e79342d60a2131d08         EAP-Message = 0x03090004         Message-Authenticator = 0x00000000000000000000000000000000         User-Name = "t" Finished request 29 

其余未解决的问题

  • 使用dialupadmin管理账号等
  • 实现用户的MAC地址绑定

参考

Source: http://www.fwolf.com/blog/post/369

2007年11月13日星期二

Openoffice连接mysql数据库的具体方法

作用就相当与ms office里面的access,不过功能应该更强大一些,因为可以连接外部数据源直接进行操作。其他的form、query、report之类的功能应该大体类似。

设置其实不难(难的是连接上以后如何利用好功能),但对于不熟悉java的人(包括我)来说就未必了,所以记录在这里分享。系统环境:Ubuntu
7.10 Gutsy, Openoffice.org 2.3.0, Mysql 5.0.45-1ubuntu3。

首先要在openoffice.org中启用java,菜单Tools->Options,Openoffice.org组的最后一项,ooo应该自动监测出了系统中已有的jre环境,如图:

选中合适的jre环境,比如我选择的1.6.0_03,然后点旁边的Class Path按钮,设置类路径,由于要使用到JDBC Driver
for MySQL (Connector/J),所以下载解压之后,在这里把jar文件路径设置进来,ooo在需要的时候会自动调用,如图:

然后就可以新建数据库文件了,File->New->Database,注意其实ooo创建的只是一个数据库的"控制"文档。打开数据库创建向导之后,首选选择JDBC连接,然后继续:

然后输入数据源地址和java类名称,针对使用JDBC Driver for MySQL
(Connector/J)连接mysql数据库的情况,数据源地址格式为:
jdbc:mysql://[host][,failoverhost...][:port]/[database]
[?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...

所以我连本机mysql库就是:jdbc: mysql://localhost/db_name,端口默认为3306。JDBC driver
class要填com.mysql.jdbc.Driver,可以用Test Class测试一下类是否加载正常。

再下一步就是设置用户名以及密码了,可以点Test
Connection测试是否能够正常连接,如果不正常可以检查一下mysql的监听地址、端口以及用户名/密码是否正确。

最终确认,保存,就可以在ooo中看到mysql库中所有的table,以及进行下一步操作了。

如果要更改数据库连接信息,使用Edit->Database菜单就可以了。
参考

连接OpenOffice.org和MySQL就是这么简单
把OpenOffice连接到MySQL

Fwolf Mon, 12 Nov 2007 10:38:59 +0000
________________________________
Source: http://www.fwolf.com/blog/post/368

2007年11月6日星期二

Vim的奇怪问题

把Ubuntu升级到了7.10 Gutsy,基本顺利,接着得寸进尺,想顺便把compiz启用试试,让我的LeadTek Gforce2 GTS也发一下飙,没想到彻底失败,提示没有Xgl,或者说没有开Composite,天,我这块卡不关掉Composite还无法启动glx呢:
# Add this line in xorg.conf
Section "Extensions"
Option "Composite" "Disable"
EndSection

抱着一线希望鼓捣半天,重启n次之后,放弃,卸载,开始把玩gaim的升级换代产品pidgin,不错的东东,不用开LumaQQ了,问题就是好友太多(尤其是不在线或隐身的)分组、聊天信息都没了,一个人也不认识了。pidgin的新配置记录在~/.purple目录下,原来的~/.gaim下的内容都拷贝过来了,logs和smiles也link到了这个新的目录下。在尝试把这么目录配置到unison同步配置文件当中时,发现刚才不知道折腾啥了,vim出了奇怪的问题:

Vim的奇怪问题

vim在编辑文件的时候,只要一用方向键,或者是jkhl键移动光标,屏幕内容就向上移动一行,下面多出一个空行,还没等挪动光标到要编辑的位置呢,文件内容已经乱得没法看了。

怀疑是compiz造成的效果,卸载它,未果,重开Xfce Session,也不行,又重启了n回,居然发现了一个让我啼笑皆非的原因。

把鼠标移动到xfce4-terminal窗口的边缘,当鼠标从指针变成其它状态,也就是改变窗口大小的时候,按住鼠标左键,terminal窗口的中央就会显示当前terminal的行、列数,我的大小是78×23,而默认窗口的大小是多少呢?是80×24。再来看vim默认的状态栏,也就是屏幕上显示的最后一行:12,1 Top,前面的数字是当前光标所在位置的行、列号,Top后面还有一空格;再看我那出了问题的terminal窗口,每次移动光标多出来的一行第一个字母都是p,明白了吧,这个p就是Top中的第三个字母,由于屏幕宽度不够,每次vi刷新屏幕显示的时候,一行显示不下,就给挤到第二行了。

terminal窗口宽度至少设置为79,就没有问题了,着实让我弱智了一把。

另外,找到两篇不错的compiz使用方法介绍,对kde或xfce用户尤其有用,英文:

Source: http://www.fwolf.com/blog/post/367

2007年11月2日星期五

Linux下的firefox如何播放在线媒体

印象中,我Ubuntu下的firefox上网时,从来没有看到在线视频"动"过,包括观看十七大转播的时候,虽然cctv专门把首页都改成了报告专栏,但视频直播我看不到,只能看看文字转播。linux下的firefox就不能看在线视频么?显然不是,只是需要额外作点工作而已。

首先,我找到了mplayerplug-in,嫌编译太麻烦,直接下载了它为Fedora Core 6准备的rpm包,用alien转成deb,dpkg -i安装,倒是都顺利,可仍然不能播放。 Mozilla Plugin Support on Linux (x86)页面上给这个插件标的状态是"Untested",看来似乎还不够完善。

然后,又找到了别人说不错的Firefox Addon MediaPlayerConnectivity,也许是我网速太慢,居然在安装的时候遇到了错误,无法继续。

最后,又看到网上别人说装个mplayer-plugin包就可以了,apt一搜索,压根就没有嘛,不过拐了个小弯,用apt搜索了一下mplayer,发现了mozilla-mplayer,安装试试,安装时还会自动提示把刚才装的mplayerplug-in卸载,看来有戏,完成后一试,果然不错,能用,并且还挺好用呢。

想测试一下的话,可以到这里打开个在线视频试试,注意标着Inline才是在线的,External是直接提供下载的。缓存的时候如果着急,可以点右键选"Play"先看着;还有好处就是有很多选项可以定制,甚至能指定视频缓存保存位置──想保存在线视频的话就省事多了。

另外说点题外话,在制作网站时,嵌入媒体建议使用相对标准的语法,就像符合web 标准的媒体播放器代码一文中推荐的那样,比如我嵌入的wmv视频代码:

 

使用标准的代码即简单明了,又有利于跨平台、跨浏览器的兼容。

Source: http://www.fwolf.com/blog/post/365

WordPress升级到2.3.1

以前用的是2.2版本,现在最新版是2.3.1,我看重的主要改进是添加了tag的支持,就升过来了。

升级过程非常简单,下载包,解压,覆盖,然后执行一下wp-admin/upgrade.php就可以了。

忘记了WordPress从哪个版本开始支持Widgets功能的,可我用的这个模板是从1.5版本的默认主题,一路改过来的,虽然没有动大手术,琐碎的修改还是有一些的。对于我这个懒人来说,重新套模板然后更改显然是不划算的,虽然后来学聪明了,有些修改作成了插件,剩下的好像也不少,所以尽可能的在旧模板的基础上更改。

Widgets好像就是个可高度自定义的sidebar,在我现在的模板中,打开Widgets页面总是提示"No Sidebars Defined",不支持,好在我的要求也不高,咱自己动手,丰衣足食。

Wordpress的wp-includes/widgets.php这个文件,是Widgets的主要实现代码,所以修改主要是参照了这个文件的内容。好了,开始编辑现在这个旧模板的sidebar文件。

首先,要把存档archive改成下拉列表框,月份多了实在看着不舒服,widgets.php中有这么一段:

function wp_widget_archives($args) {
extract($args);
$options = get_option('widget_archives');
$c = $options['count'] ? '1' : '0';
$d = $options['dropdown'] ? '1' : '0';
$title = empty($options['title']) ? __('Archives') : $options['title'];

echo $before_widget;
echo $before_title . $title . $after_title;

if($d) {
?>

可以看出,内置的wp_get_archives函数的参数,原来只有type=monthly,现在多了format=optionshow_post_count=$c,前者应该代表是否下拉列表框形式显示,值的定义为$options['dropdown'];后者是是否显示本月文章计数,值的定义为 $options['count'],并且都是用1代表真,0代表假,所以修改就简单了,把原来的:

 

更改为:

         

就行了。

然后,把archive月份存档和category分类列表的位置互换,分类列表放在上面,直接调整代码顺序即可,同时给分类列表也加上分类计数的显示:

            
  • Categories

  • 最后,添加Tag Cloud,没有这个升级就白作了,参照widgets.php中的:

    function wp_widget_tag_cloud($args) {
    extract($args);
    $options = get_option('widget_tag_cloud');
    $title = empty($options['title']) ? __('Tags') : $options['title'];

    echo $before_widget;
    echo $before_title . $title . $after_title;
    wp_tag_cloud();
    echo $after_widget;
    }

    没什么太复杂的,直接调用wp_tag_cloud()函数,连参数都没有,最终代码为:

                
  • Tags Cloud

  • 这样就大功告成了,虽然模板不支持Widgets,侧边栏倒也符合我的基本使用需要了。

    Source: http://www.fwolf.com/blog/post/366

    2007年10月31日星期三

    真正的“AI”,是不是可以这样?

    看到Cat Chen S.T.A.L.K.E.R中胡侃这个游戏的AI如何优秀,不禁产生了一种念头,一种新的AI实现思路。

    AI就是人工智能,通俗一点说就是控制游戏中NPC如何行动的指令,简单的AI很容易公式化,比如反恐精英cs中的bot,基本上都是按照脚本的规定来行动,更复杂和高级的AI会加入思考、互动的因素,也就更"聪明"一些。

    AI往高了说,属于计算机科学的尖端领域,但往简单了说,只不过是科学家设计好公式,利用计算机运算速度快的优势来模拟的思考过程罢了,高深也就高深在了公式/算法和了,计算机只是一个跑得比较快,会先飞的笨鸟罢了。但在很多时候,AI还无法达到普通人的程度,这也就是我的念头了,能否在游戏中,用玩家行为来作为AI,或者为AI提供数据呢?

    假想一个游戏,分为两个阵营,拉据战的格局,苏、德双方展开坦克大战,攻夺据点。把游戏分为两个服务器,苏服和德服,苏服上的玩家都是苏军,敌人是AI,不过这个AI就是德服上扮演德军的玩家。这样,以往的NPC就不会再笨呼呼的了,而是"像"真实的玩家一样战斗,甚至血少的时候也会偷懒等等。

    最关键的,就是要体现不同于单机游戏的,真实的模拟另一个服务器上玩家的行为模式,同时还要和玩家之间对战区分开来。比如坦克的配置是copy玩家数据,而作为AI的坦克被打爆了玩家可不会掉经验等等。能够把这两点都体现出来,现在的游戏好像还没有。

    还想到一个更远一点的例子,在mmorpg中打怪的时候,怪物一般都形成规律了,在什么地方、有什么招数,怎么配置队伍就能打倒它,甚至捡到相同的宝贝。。。这样不腻么?为高级玩家开通变身为怪的功能吧。呼呼,别人组队再来打toj的时候,怎么怪物变了?以前都呆着不动的,今天满大街溜达,也不发招。。。如此这般,也等于是在这段时期内用人的智慧让npc更加完善了,如果聪明的玩家还会在变身为怪物的时候,模拟真实怪物的以为,诱骗其它玩家上钩的话就更加有趣了。

    想法扯完了,写完再想实现起来还是有些难度的,不过算是一个思路吧,不要一味钻进如何完善npc自身"功能"的死胡同,引入玩家的隐式互动。关于那个苏德坦克大战的游戏,以前倒还真是玩过(直接玩家对抗的),不过好像网站上不去了,http://www.blitz1941.com/ ,我这里也仅存三张截图,还算有一定代表性,一起怀念一下吧:



    Go to ImageShack® to Create your own Slideshow

    Source: http://www.fwolf.com/blog/post/364

    2007年10月30日星期二

    将情感进销存的编码从gb2312改变为utf8

    应一个朋友的需要,用免费开源的情感进销存给他开小店用,刚开始嘛,先试试看好用不。好像情感是国内仅存的免费、开源,又能用,还有人继续维护的进销存软件了,挺难得的。

    情感进销存默认的编码全部都是gb2312的,从数据库到html,而我的环境自然是全utf8编码的ubuntu,如果是一次性转换的话,手工也是可以作的,但情感进销存如果出新版,还得从头改过,所以搞了个小脚本来自动转换:

    #!/bin/bash

    find . -name "*.txt" |xargs -I '{}' iconv_gb2u '{}'
    find . -name "*.htm" |xargs -I '{}' iconv_gb2u '{}'
    find . -name "*.php" |xargs -I '{}' iconv_gb2u '{}'
    find . -name "*.sql" |xargs -I '{}' iconv_gb2u '{}'

    #echo "Modify libs/mysql.class.php, change set names gbk to utf8."
    # echo "Modify tpls/head.htm, head.emp.html, change http-equiv gbk to utf9"
    replace "charset=gbk" "charset=utf8" -- install/*.php
    replace "CHARSET=gbk" "charset=utf8" -- install/*.php
    replace "SET NAMES 'gbk'" "SET NAMES 'utf8'" -- libs/mysql.class.php
    replace "charset=gbk" "charset=utf8" -- tpls/*.htm

    # For safe
    chmod -x `basename $0`

    其中用到的iconv_gb2u也是一个小脚本,作用是使用iconv命令把gb2312编码的文件转换为utf8,原生的iconv只能转换,不能回写同名文件,用这个脚本写到临时文件再拷回来覆盖。

    再转回来说咱们的php程序的编码转换,首先要把所有的文件编码都转换了,包括txt类型的readme说明文件,htm类型的模板,php类型的程序,主要是为了看里面的注释,以及sql类型的数据库定义,里面还有初始化的数据,所以必须进行编码转换。这些转换用iconv就可以了,用 find配合xargs一次性全部转换完毕。

    接下来install/*.php中替换的是html页面的编码,以及执行安装sql创建数据表时指定表的默认编码;libs/mysql.class.php是连接数据库后指定客户端连接的字符集;tpls/*.htm则是替换html页面中的编码定义。这些用到了replace命令,replace可以把文件中的一个字符串替换为另外一个字符串,好像是mysql附带的实用小程序,在本例中够用了,再复杂一点的情况可以考虑使用 sed,多行、正则替换都能够完成。

    最后一句就简单了,如果对一个文件执行两次iconv,第一次把gb2312转成了utf8,可第二次就不知道转换成哪国编码了,所以为了避免程序被误运行两次,去掉可执行属性。

    以后用起来就简单了,如果情感进销存再发布新版,先解压到一个临时文件夹,用这个脚本进行转换之后,再覆盖拷贝过来就可以了。

    Source: http://www.fwolf.com/blog/post/363

    2007年10月26日星期五

    磁带机的简单使用

    环境:Ubuntu 7.04 feisty, HP DAT-72 usb外置磁带机。

    基本概念

    • 磁带是线性存储设备,没有什么分区表的概念,磁头在哪里,就从哪里开始读。
    • 磁带机好像只能用root用户操作。
    • 磁带上可以划分存储空间,每个存储空间有一个file number,从0开始顺序排列。
    • 磁头在存储空间中的位置用block number来表示,0代表开始,大于0的整数代表块,比如39代表磁头在本file number的第39块的位置,而-1则代表磁头位于本file number的结尾。
    • 同样一部磁带机,用/dev/st0时是当自动回卷设备使用,每次操作完成之后,磁头都返回file number=0, block number=0, BOT的位置;而用/dev/nst0调用时,操作完成时磁头就停在那个位置,不会回到开头。
    • 使用nst非回卷方式,用tar tvf列文件,只有当block number=0时才能出内容,并且列完之后block number为大于0的整数,注意这并不代表本段存储空间的结尾(-1)。

    由于磁带机本身具有压缩功能,所以添加文件的时候不建议指定zip或者bz2压缩,因为如果一点点压缩后的数据损坏,会导致全部内容不可识别;如果的确需要压缩的话,可以压缩成本地文件再存储到磁带上,减少对其他文件的影响。

    自动回卷的使用方式

    这种方式比较简单,用tar直接操作即可,基本上和tar操作本地文件相同。

    往新磁带上存储文件,注意如果磁带上已有文件,会被覆盖掉:

    tar cvf /dev/st0 file_to_store

    向磁带上添加文件:

    tar rvf /dev/st0 file_to_store

    更新磁带上的同名文件:

    tar uvf /dev/st0 file_to_store

    列出磁带上的现有文件:

    tar tvf /dev/st0

    删除磁带上的文件:

    tar vf /dev/st0 --delete file_to_delete

    但我使用这个命令的时候总是提示错误,文件倒是删掉了,可查看的时候也总有错误信息,难道是无法删除,或者只能全部xvf出来再存到磁带上?不过我们也应当养成一个好的习惯,每次向磁带机存储文件的时候一定要在文件名中带上日期标记。

    非自动回卷的使用方式

    一般这样使用,都是用到多个存储空间file number的时候;如果还是一个存储段,只是手工移动文件指针就没有什么意义了。

    在操作上,文件的存储方式和自动回卷是基本相同的,不同之处在于要注意磁头的位置,并且手工进行必要的位移,以一个新磁带的操作为例来说明(status我只截取有用的部分显示):

    # mt -f /dev/nst0 status
    file number = 0
    block number = 0
    General status bits on (41010000):
    BOT ONLINE IM_REP_EN

    存入一个新的文件A:

    # tar cvf /dev/nst0 A
    A
    # mt -f /dev/nst0 status
    file number = 1
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    注意这时磁头已经移动到了第二段存储空间了,现在再存入一个新的文件B,当然B和A是不在一个存储空间中的:

    # tar cvf /dev/nst0 B
    B
    # mt -f /dev/nst0 status
    file number = 2
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    磁头又移动到第三段存储空间了,如果要查看刚才存的第二段存储空间中的内容,需要先移动磁头:

    # mt -f /dev/nst0 bsf 2
    # mt -f /dev/nst0 status
    file number = 0
    block number = -1
    General status bits on (1010000):
    ONLINE IM_REP_EN

    # mt -f /dev/nst0 fsf 1
    # mt -f /dev/nst0 status
    file number = 1
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    由于有存储空间结束标记,所以这里采用退2进1的方式,详细的磁头移动方式可以看man mt。然后查看文件列表:

    # tar tvf /dev/nst0
    -rw-r--r-- root/root 21194792 2007-10-24 11:37 B
    # mt -f /dev/nst0 status
    file number = 1
    block number = 2070
    General status bits on (1010000):
    ONLINE IM_REP_EN

    列出文件列表之后,磁头停在了文件结束的位置,但不是存储空间的结尾。现在移动磁头到本段存储空间的开始,并且添加文件C:

    # mt -f /dev/nst0 bsf 1
    # mt -f /dev/nst0 status
    file number = 0
    block number = -1
    General status bits on (1010000):
    ONLINE IM_REP_EN

    # mt -f /dev/nst0 fsf 1
    # mt -f /dev/nst0 status
    file number = 1
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    # tar rvf /dev/nst0 C
    C
    # mt -f /dev/nst0 status
    file number = 2
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    首先还是要移动磁头,到这里基本上可以发现mt的fsf和bsf的规律了,fsf是磁头向前移动,并且总是停留在block number = 0的位置,而bsf是磁头向后移动,总是停留在 block number = -1的位置。添加完成文件之后,磁头又定位到了第三个存储空间(下一个)的开始。现在我们依然是移动磁头到第二段存储空间开始,并且用覆盖方式添加文件D:

    # mt -f /dev/nst0 bsf 2
    # mt -f /dev/nst0 fsf 1
    # mt -f /dev/nst0 status
    file number = 1
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    # tar cvf /dev/nst0 D
    D
    # mt -f /dev/nst0 status
    file number = 2
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    文件D是用覆盖方式添加的,所以刚才添加的文件B和C现在应该都消失了:

    # mt -f /dev/nst0 bsf 2
    # mt -f /dev/nst0 fsf 1
    # mt -f /dev/nst0 status
    file number = 1
    block number = 0
    General status bits on (81010000):
    EOF ONLINE IM_REP_EN

    # tar tvf /dev/nst0
    -rw-r--r-- root/root 34201298 2007-10-24 11:57 D
    # mt -f /dev/nst0 status
    file number = 1
    block number = 3341
    General status bits on (1010000):
    ONLINE IM_REP_EN

    完成,回卷磁带,从开始一直tvf:

    # mt -f /dev/nst0 rewind
    # tar tvf /dev/nst0
    -rw-r--r-- root/root 341054 2007-10-24 11:37 A

    # tar tvf /dev/nst0
    # tar tvf /dev/nst0
    -rw-r--r-- root/root 34201298 2007-10-24 11:57 D

    # tar tvf /dev/nst0
    # tar tvf /dev/nst0

    # tar tvf /dev/nst0
    tar: /dev/nst0: Cannot read: Input/output error
    tar: At beginning of tape, quitting now
    tar: Error is not recoverable: exiting now

    # mt -f /dev/nst0 status
    file number = 2
    block number = -1
    General status bits on (9010000):
    EOD ONLINE IM_REP_EN

    现在,能看懂这个了么?我用空行隔开的位置正好是block number为0的位置。还有一些其他的操作就比较简单了:

    出带,将磁带卷至初始位置然后从磁带机内弹出
    # mt –f /dev/nst0 offline

    清除磁带中的所有内容,特慢,还伤带,轻易不要用
    # mt –f /dev/nst0 erase

    我的几个疑问

    • 如何删除file number?
    • 既然磁带是线性存储,如果向前面一个file number中添加中间,存储空间不够怎么办?
    • 如何查看磁带剩余空间?

    小结

    搞明白磁带机的存储方式和基本操作,用起来就简单了。个人感觉如果要存的文件数量不多,尤其是只需要存几个大文件的情况,直接用自动回卷方式,只使用一个存储空间就可以了,这样操作比较简单。如果一定要用磁带存储复杂结构的数据,可以考虑手工在各个存储空间之间来回切换的方式,原理都是一样,只是更高一点点的技巧和小心。

    参考

    Source: http://www.fwolf.com/blog/post/362

    转换AVCHD的m2ts文件到avi

    Sony的硬盘录像机是好东西,高清晰、宽屏幕录像,大容量存储,可录的时候爽了,后期浏览和加工转换实在是不方便(这位仁兄也有同样感受: Jeff Cai的流水账 - Play with AVCHD,机型都是Sony HDR-SR1),无论想在哪台电脑上浏览录像,都要装一个Sony Handycam Application Software软件(安装盘仅400M),这个软件也相当霸道,不让选择安装位置、安装哪些组件,甚至不允许单独安装其中的某一个程序,安装完成后居然还提示要重启xp,当然不重启我试了也能使用。注册媒体库位置的时候不让选择网上邻居资源或者映射的网络驱动器。

    如果这些都不是问题的话,录像文件拷出来能用其他工具浏览或加工也行啊,可偏偏他的录像格式m2ts(扩展名MTS)目前支持的工具还相当少,不过还是在网上找到了一些文章,能够用开源工具进行转换。Sony自带软件也能转换成通用格式,不过我的印象是会损失一些清晰度,用肉眼就能轻易的分辨出来的差异。参考文章:

    基本思路都是这样的:

    • 用xporthdmv把m2ts转换为mpv和mpa格式
    • 用ldecod把mpv转换为yuv格式
    • 用yuv4mpeg把yuv转换为y4m格式
    • mpa直接当ac3格式的音频使用
    • 用ffmpeg合成视频和音频部分为avi格式(avi就是一个容器)

    讨论中还有一些其他的提示:

    • ffmpeg可以用mencoder替代
    • ldecod生成的yuv文件大小可以达到4G/分钟,不过可以用命名管道(named pipe)来省去使用中间文件
    • 视频和音频的同步,pal格式录像可以设定fps为25,ntsc格式录像可以使用参数-r 29.97。

    参考文章中的第一篇给了一个附件,这个很好用,下载下来解包,里面的readme.txt和Makefile解释了使用方法,不过在ubuntu下使用的话,建议先作以下几步准备工作:

    • 安装svn客户端
    • 用apt安装x264-bin和ffmpeg以及mplayer
    • 在'src/JM/ldecod'目录下创建一个空的子目录'obj'
    • 脚本运行之后会自动转换samplevideo.avi,会用去一些时间,想省略的话把这个文件删除或改名即可
    • download文件中有一句set version=12.2,现在的jm版本已经是12.4了,更新之,不然下载不到(404错误)

    然后就简单了:

    • ./download
    • ./compile
    • ./install

    或者再用installasroot安装,你就可以使用m2tstoavi了:

    $ m2tstoavi
    usage: /usr/local/bin/m2tstoavi filename.m2ts ...

    我也转了一个自己录的文件,完成后发现视频、音频不同步,并且播放速度很慢,可能是一些设置参数的问题,转换方式肯定是没有问题的,并且好像是目前最好的方式了。(修改/usr/local/bin/m2tstoavi,注意上面说的pal和ntsc制式的区别)mplayer播放最终生成的avi文件,信息如下:

    Playing samplevideo.avi.
    AVI file format detected.
    VIDEO: [h264] 1440x1080 24bpp 29.970 fps 13323.1 kbps (1626.4 kbyte/s)
    Clip info:
    Software: MEncoder 2:1.0~rc1-0ubuntu9.1
    open: No such file or directory
    [MGA] Couldn't open: /dev/mga_vid
    open: No such file or directory
    [MGA] Couldn't open: /dev/mga_vid
    [VO_TDFXFB] Can't open /dev/fb0: No such file or directory.
    [VO_3DFX] Unable to open /dev/3dfx.
    It seems there is no Xvideo support for your video card available.
    Run 'xvinfo' to verify its Xv support and read DOCS/HTML/en/video.html#xv!
    See 'mplayer -vo help' for other (non-xv) video out drivers. Try -vo x11
    Opening video filter: [screenshot]
    ==========================================================================
    Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
    Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)
    ==========================================================================
    ==========================================================================
    Forced audio codec: mad
    Opening audio decoder: [liba52] AC3 decoding with liba52
    Using SSE optimized IMDCT transform
    Using MMX optimized resampler
    AUDIO: 48000 Hz, 2 ch, s16le, 448.0 kbit/29.17% (ratio: 56000->192000)
    Selected audio codec: [a52] afm: liba52 (AC3-liba52)
    ==========================================================================
    AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
    Starting playback...
    VDec: vo config request - 1440 x 1080 (preferred colorspace: Planar YV12)
    VDec: using Planar YV12 as output csp (no 0)
    Movie-Aspect is 1.78:1 - prescaling to correct movie aspect.
    SwScaler: reducing / aligning filtersize 5 -> 4
    SwScaler: reducing / aligning filtersize 5 -> 4
    SwScaler: reducing / aligning filtersize 1 -> 1
    SwScaler: reducing / aligning filtersize 5 -> 4

    SwScaler: BICUBIC scaler, from yuv420p to bgr24 using MMX2
    SwScaler: using 4-tap MMX scaler for horizontal luminance scaling
    SwScaler: using 4-tap MMX scaler for horizontal chrominance scaling
    SwScaler: using n-tap MMX scaler for vertical scaling (BGR)
    SwScaler: using MMX2 YV12->BGR24 Converter
    SwScaler: 1440x1080 -> 1920x1080
    VO: [x11] 1440x1080 => 1920x1080 Planar YV12
    A:4358.2 V: 2.9 A-V:4355.240 ct: 0.297 89/ 89 148% 0% 1.1% 37 0

    有时间了再仔细研究视频、音频不同步和播放速度很慢的问题。不过还是那句话,技术都是好东西,可对商业利益的无止境追求使他们变成了恶魔。

    软件环境:Ubuntu 7.04 Feisty

    Source: http://www.fwolf.com/blog/post/361

    2007年10月22日星期一

    通过代理更新Gregarius

    Gregarius是我现在使用的rss阅读器,其它在线的比如google reader、zhuaxia我网速太慢,使用不顺畅,纯离线方式的吧,比如liferea,在浏览的时候依然要解析html和联网(feed内容中有图像),还是在本机架一个Gregarius,cron定时更新,然后用firefox看方便,保存有价值的文章也更方便。

    原先更新都是用wget:

    wget --no-check-certificate -O /tmp/gregarius.update https://my_local_machine_name/gregarius/update.php  

    wget的输出会已本地用户邮件形式被mutt收下来,设定好之后,有一段没时间看rss也没在意,这天忽然发现原来wget只要retry 3、4次就能更新完全部feed,现在需要十几次,而我的feed增长显然没达到这种程度;并且有些网站在Gregarius中看到已经很久没有更新了(-t 1可以指定只retry一次,默认是20次,-t 0为无限制retry下去)。同时在feed管理中看到,很多网站的名字都加上了删除线,比如" 月光博客",最后终于发现,这些名字打上了删除线的blog的feed全部托管在feedburner,并且内容全部没有更新,原因,自然是开始于前段时间的feedburner无法访问。

    feedburner无法访问我倒不怕,我一直都在本机用squid、privoxy、tor智能中转web访问请求,现在只要让gregarius更新feed时用上我这个本地的代理服务器squid就可以了,看了一下gregarius的代码,远程读取rss使用的是 Snoopy类,本地文件为extlib/Snoopy.class.inc,调用是在extlib/rss_fetch.inc文件中,大概第317行,function _fetch_remote_file 部分,在这里添加如下内容即可:

    $client->read_timeout = MAGPIE_FETCH_TIME_OUT;
    $client->use_gzip = MAGPIE_USE_GZIP;

    // 这几行是添加的内容,其它是原文件中的 Modify by Fwolf @ 2007-10-14
    // Use proxy localhost:3128 when fetch feed
    $client->proxy_host = "localhost";
    $client->proxy_port = "3128";
    $client->_isproxy = true;
    $client->read_timeout = 0; // tor via squid is slow
    //

    if (is_array($headers) ) {
    $client->rawheaders = $headers;
    }

    就这么简单,$client的设置参照Snoopy类的定义即可,然后调用不再使用wget,而是直接运行update.php:

    cd /local/path/to/gregarius; php -f update.php

    这样更新的结果会清晰的输出:

    Engadget Simplified Chinese ...
    OK (HTTP 200), 3 New Items

    玩意儿 ...
    OK (304 Not modified), 0 New Items

    津津乐道 ...
    HTTP Timeout (Local cache), 0 New Items

    小众软件 ...
    OK (HTTP 200), 0 New Items

    如果加上-- --silent就没有输出了,第一个--是给截止php接收参数的参数,--silent才是给update.php用的。

    本文针对Gregarius 0.5.5 revision1761。

    Source: http://www.fwolf.com/blog/post/360

    2007年10月14日星期日

    Feisty下的alsa怎么不响了?

    我的Ubuntu feisty是从dapper直接升级过来的,现在好像还记得刚升级完之后,用mplayer放电影没声音,声音驱动换oss就没事了,也没太在意。后来开始用mame玩模拟器游戏 ,一直没有声音,就以为是mame或者rom的问题。再后来发现mame有关于声音的设置,而别人的介绍里面说的mame没有声音的问题不是好几年之前的,就是一些rom中本来就不包含声音的情况。从这里开始察觉,是我机器的问题,具体说就是alsa声音驱动不响了。

    硬件不会有问题,驱动换oss马上放电影就出声,所以问题在软件上,到网上一查,alsa没有声音的情况还不少,但好像都不顶用。

    最后翻到了ubuntu Edgy升级到Feisty后系统没有声音,问题解决,我和他的情况相同,果然是$HOME/.asoundrc文件的问题。

    升级到Feisty之后,在$HOME下有两个文件,.asoundrc.asoundconf和.asoundrc,.asoundrc的有效内容只有一行:

     

    就是引用.asoundrc.asoundconf的内容,相当于一个Include语句,而.asoundrc.asoundconf的内容有4行:

    !defaults.pcm.card I82801BAICH2
    defaults.ctl.card I82801BAICH2
    defaults.pcm.device 0
    defaults.pcm.subdevice -1

    这个是系统默认的配置,此文件系统也不建议直接修改,只要注释/取消注释.asoundrc文件中的那一句就可以了。不用重启机器,甚至也不用重启X,只要注释掉.asoundrc中那一句,alsa立刻就好了,mame里也有声音了,mplayer里选择alsa声音驱动也有声音了;而只要取消注释,mame和mplayer里就没有声音了,所以确定就是这里的问题。

    看了一下.asoundrc.asoundconf配置文件选项的官方解释,感觉那4句哪一句都挺正确的,可就是只起反作用。

    所以,下次alsa不响的时候,记得先看看这两个配置文件。

    Source: http://www.fwolf.com/blog/post/359

    单网卡双ip连接nfs服务器,好像不行

    环境:防火墙作为网关,下设两个网段,A网段为192.168.0.0/24,防火墙上的网关地址为192.168.0.1,有一服务器地址为192.168.0.2;B网段为192.168.2.0/24,防火墙上的网关地址为192.168.2.1,有一客户机地址为192.168.2.5,只有一块网卡,需要增设一个ip,连接A网段服务器上的nfs服务。服务器和客户机操作系统均为ubuntu 7.04。

    nfs服务器比较好架,apt安装nfs-kernel-server及相关包即可,默认服务端口2049不动,配置文件/etc/exports的内容为:

    /home/fwolf     192.168.0.5(rw,sync,subtree_check)
    /home/share *(ro,subtree_check)

    不要装成了nfs-user-server,那个是nfs v2,不是nfs v3,不支持4G以上的文件。限制了/home/fwolf只有主机192.168.0.5才能访问。客户端可以收工mountnfs服务器:

    sudo mount -t nfs svrname:/home/fwolf local_mount_point

    也可以写到fstab中:

    svrname:/home/fwolf        local_mount_point nfs     defaults 0 0

    如果现在用B网段的客户机访问A网段的服务器,因为路由走的是防火墙(防火墙的配置好像也有点问题,不过改不了,不行的根源可能就在于此),防火墙上看到客户机的地址是防火墙上配置的另外一个C网段地址,所以要给客户机增加一个A网段的ip,不通过防火墙直接访问。

    单网卡增加双ip要用到别名,所以/etc/network/interfaces文件的内容如下:

    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet static
    address 192.168.2.5 netmask 255.255.255.0 auto eth0:0 iface eth0:0 inet static address 192.168.0.5 netmask 255.255.255.0

    两个地址都不设置gateway,然后在rc.local中添加静态路由设置:

    route add -net  192.168.0.0/24  gw   192.168.0.1     dev eth0:0
    route add default gw 192.168.2.1 dev eth0

    然后重启网络并执行rc.local:

    sudo /etc/init.d/networking restart; sudo /etc/rc.local

    现在,看一下路由表:

    $ route
    Kernel IP routeing table
    Destination Gateway Genmask Flags Metric Ref Use Iface
    192.168.0.0 192.168.0.1 255.255.255.0 UG 0 0 0 eth0
    192.168.0.0 * 255.255.255.0 U 0 0 0 eth0
    192.168.2.0 * 255.255.255.0 U 0 0 0 eth0
    default 192.168.2.1 0.0.0.0 UG 0 0 0 eth0

    按照设想,如果从客户机上访问A网段,那么应该对应路由表的第一行,使用网关192.168.0.1,服务器上看到的地址自然就是192.168.0.5,如果访问其他网段,应该走默认网关192.168.2.1,对应本机ip地址192.168.2.5。但是,我的实践证明并不是这样,甚至在rc.local加上了下面几句中任何一句或者全部也不行:

    route add -net 192.168.0.0/24 dev eth0:0
    route add -host 192.168.0.2 dev eth0:0
    route add -host 192.168.0.2 gw 192.168.0.1 dev eth0:0

    偶尔的时候,能够成功,但是感觉不稳定,所以算是失败了,感觉有3种可能:

    • 防火墙工作方式问题,这个自然没法改动了
    • 路由命令添加得不对,我觉得应该没错误吧
    • 此路根本不通,单网卡不能设多ip,只能用多网卡,我觉得这个不太可能

    暂时的,只能放宽nfs地址限制,或者用速度较慢(尤其在局域网内)的sshfs来实现了。

    参考

    Source: http://www.fwolf.com/blog/post/358

    2007年10月8日星期一

    在Ubuntu上安装sybase ASE 15.0.2


    开始之前

    先把ubuntu装上,用7.04的server安装盘默认安装即可,先装i386的,如果sybase安装顺利,再试试64位的sybase是否好用。

    从sybase网站上注册免费用户之后,可以下载免费的ASE Express Edition 下载页面),目前的版本是15.0.2,限制只能使用1个cpu,2G内存和管理5G数据,更详细的资料在快速安装手册中。

    如果您也想自己装一个试试,建议您先跳过下面这一段。

    安装

    下载后的ase1502_xe_linux.tgz,直接解压到一个目录,比如ase1502中,然后运行./setup就可以开始安装了。默认的安装是java图形界面的,而我是远程ssh上去装的,所以加上-console参数运行setup。首先是欢迎信息:

    Welcome to the InstallShield Wizard for Sybase Adaptive Server Enterprise Suite
    version 15.0.2 GA

    The InstallShield Wizard will install Sybase Adaptive Server Enterprise Suite
    on your computer. Shut down all Sybase products, then click Next to begin
    installation.

    Press 1 for Next, 3 to Cancel or 4 to Redisplay [1]

    按1继续,接着是选择用户协议类型:

    What would you like to install?

    Product License

    1. Adaptive Server Enterprise for evaluation
    2. Adaptive Server Enterprise (Developer Edition)
    3. Adaptive Server Enterprise (Express Edition)

    Enter one of the options above : [1] 3

    1是体验版,应该是有时间限制,2是开发者版,有连接数限制,所以选3继续:

     1)  All regions
    Please enter the number of the location you are installing. (1-1) [1]

    选择自己所在的地区,只有1可选,应该没什么用处。但如果你仔细看了用户协议,会看到被美国实行贸易禁运的国家比如伊朗、伊拉克等等是禁止下载使用的。选择后会出现完整的用户协议,可以按回车一屏一屏的读完,或者用q退出,然后记得按y同意此用户协议,

    Please enter the directory where you would like to install the products or
    press ENTER to accept the default.

    Destination Directory [/opt/sybase]

    选择安装目录,我觉得用默认的就可以,如果目录不存在,还得确认创建新目录;如果目录已经存在,也会让你确认,不过是确认删除其中的所有文件:

          1. Yes
    2. No

    The directory does not exist. Do you want to create it? [2] 1

    然后就是选择安装哪些内容了:

    Choose the setup type that best suits your needs.

    [X] 1 - Typical
    The program will be installed with the suggested configuration.
    Recommended for most users.

    [ ] 2 - Full
    The program will be installed with all the products and features.

    [ ] 3 - Custom
    The program will be installed with the features you choose.
    Recommended for advanced users.

    To select an item enter its number, or 0 when you are finished: [0]

    如果没有特殊要求,Typical就够用了,如果想自行选择安装内容,可以选3 - Custom:

    Select the features for "Sybase Adaptive Server Enterprise Suite" you would
    like to install:

    Sybase Adaptive Server Enterprise Suite

    To select/deselect a feature or to view its children, type its number:

    1. +[x] Sybase Servers
    2. +[x] Connectivity
    3. +[x] ASE Data Providers
    4. +[x] Language Modules
    5. +[x] jConnect for JDBC
    6. [ ] Shared
    7. +[x] Sybase Software Asset Management
    8. +[x] Sybase Unified Agent
    9. +[x] ASE Administration Tools

    Other options:

    0. Continue installing

    Enter command [0]

    默认就是除了6 Shared,其他的都安装。最后,安装程序会把所有选项列出来供检查:

    Sybase Adaptive Server Enterprise Suite will be installed in the following
    location:

    /opt/sybase

    with the following features:

    Sybase Servers
    Adaptive Server Enterprise
    ASE Agent Plugin
    Replicator
    Connectivity
    Open Client
    Common ctlib files
    Common dblib files
    Common Connectivity Components
    ASE Data Providers
    ASE ODBC Driver
    Unicode/MultiByte Conversion Support
    Sample Programs
    Language Modules
    English Language Module
    jConnect for JDBC
    JDBC Driver
    Sybase Software Asset Management
    SySAM License Utilities
    Sybase Unified Agent
    Unified Agent Server
    Agent Management Console
    ASE Administration Tools
    Interactive SQL
    Sybase Central
    Adaptive Server Plugin
    SySAM Plugin

    for a total size:

    410.8 MB

    Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

    然后终于开始安装了,进度条作得蛮可爱的:

    Installing Sybase Adaptive Server Enterprise Suite. Please wait...

    |-----------|-----------|-----------|------------|
    0% 25% 50% 75% 100%
    ||||||||||||||||||||||||||||||||||||||||||||||||||

    Creating uninstaller...

    -------------------------------------------------------------------------------
    The InstallShield Wizard has successfully installed Sybase Adaptive Server
    Enterprise Suite. Choose Next to continue the wizard.

    Press 1 for Next, 3 to Cancel or 4 to Redisplay [1]

    接下来是配置向导,首先是email alert,用于接收数字资产变化的更新通知,显然对个人用户来讲没什么用处:

    Please configure the Sybase Software Asset Management (SySAM) email alert
    mechanism. When configured, specified recipients will receive email
    notifications about SySAM events that may need administrator attention.

    Do you want to configure email alerts?

    1. Yes
    2. No

    Enter one of the options above : [1]
    SMTP server host name [smtp] smtp.gmail.com SMTP server port number [25] 465 Sender email [root] sybase@svr6 Recipient emails [root] svr6@gmail.com Message Severity for email alerts(信息发送级别,达到级别的才会发送邮件,1为最低/敏感的级别,3为最高/不敏感的级别)

    1. INFORMATIONAL
    2. WARNING
    3. ERROR

    Enter one of the options above : [2]

    确认后就进入创建服务器的向导了,天知道上面的邮件设置能否正常发信:

    The Adaptive Server Enterprise suite contains a number of programs in addition
    to the Adaptive Server Enterprise database server. At this point in the
    installation you can choose to configure various products. If you select the
    options on this screen, you will be given the option of specifying
    configuration options for each product or to allow the installer to set default
    values for these on the next screen. If you do not choose to configure the
    products at this time, you can configure them using the ASE configuration
    utility at a later time.

    Please deselect any products that you do not want to configure now :

    [X] 1 - Configure new Adaptive Server
    [X] 2 - Configure new Backup Server
    [X] 3 - Configure new Monitor Server
    [X] 4 - Configure new XP Server
    [X] 5 - Configure Unified Agent

    To select an item enter its number, or 0 when you are finished: [0]

    直接确认,安装全部服务器:

    You have chosen to configure the products listed below. You can accept default
    configuration values or provide customized values for the configuration options
    required by each product. If you do not select custom configuration below, this
    installer will configure the products you have selected with default values. If
    you accept default values at this time you can change the configuration values
    for a product at a later time.

    Please select the products that you want to custom configure.

    [ ] 1 - Custom configure new Adaptive Server
    [ ] 2 - Custom configure new Backup Server
    [ ] 3 - Custom configure new Monitor Server
    [ ] 4 - Custom configure new XP Server
    [ ] 5 - Custom configure Unified Agent

    To select an item enter its number, or 0 when you are finished: [0]

    看上去和刚才的选择类似,不过这里是选择哪些服务器要用自定义设置,否则就采用默认设置快速创建了。我全部采用自定义设置([]里是默认设置,什么不输入就使用这个值了):

    Please enter custom configuration values for the new Adaptive Server

    Adaptive Server Name [SVR6]
    Port Number [5000]
    Error Log [/opt/sybase/ASE-15_0/install/SVR6.log] /home/sybase/svr6.log
    Page Size

    1. 2k
    2. 4k
    3. 8k
    4. 16k

    Select a page size : [1]
    Master Device [/opt/sybase/data/master.dat] /home/sybase/master.dat
    Master Device Size (MB) [30] 60
    Master Database Size (MB) [13] 30
    System Procedure Device [/opt/sybase/data/sysprocs.dat] /home/sybase/sysprocs.dat
    System Procedure Device Size (MB) [132] 150 (系统存储过程库比以前的11.9.2版本大了很多)
    System Procedure Database Size (MB) [132] 150
    System Device [/opt/sybase/data/sybsysdb.dat] /home/sybase/sybsysdb.dat
    System Device Size (MB) [1] 20
    System Database Size (MB) [1] 10

    Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

    然后是backup server的设置:

    Please enter custom configuration values for the new Backup Server

    Backup Server Name [SVR6_BS]
    Port Number [5001]
    Error Log [/opt/sybase/ASE-15_0/install/SVR6_BS.log] /home/sybase/svr6_bs.log

    Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

    Monitor Server:

    Please enter custom configuration values for the new Monitor Server

    Monitor Server Name [SVR6_MS]
    Port Number [5002]
    Error Log [/opt/sybase/ASE-15_0/install/SVR6_MS.log] /home/sybase/svr6_ms.log

    Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

    XP Server:

    Please enter custom configuration values for the new XP Server

    Port Number [5003]
    Error Log [/opt/sybase/ASE-15_0/install/SVR6_XP.log] /home/sybase/svr6_xp.log

    Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

    然后是选择发现sybase服务的方法(这样客户端就不需要interface文件了),JINI需要架设单独的服务器,个人测试用UDP方式就够了,不过只能发现同一子网中的服务:

    Discovery Services provide client applications the ability to find Sybase
    resources within an enterprise environment without the need for local interface
    file definitions. UA currently supports two discovery methods: JINI and UDP.

    JINI requires a dedicated JINI server to provide discovery services and can
    provide these services throughout the enterprise. UDP does not require a
    dedicated server but is limited to discovery within the local subnet.

    Adaptor

    1. JINI
    2. UDP

    Select the adaptor for the Self Discovery Service. [2]

    然后是选择用户统一认证方式,我觉得没有特殊理由,就用默认的好了,和11.9.2的使用习惯应该是相同的:

    Please select and order the security login modules for the Unified Agent.

    Simple Login: authenticates user ID/password against entries within a UA
    configuration file.

    ASE Login Module: delegates authenticationto an appropriate role ( e.g.,
    sa_role, sso_role, etc.) within the ASE.

    NT/Unix Proxy login Module: delegates authentication to a user group in the
    underlying operating system (e.g., Administrators, root, etc.).

    1. Simple Login Module true
    2. ASE Login Module true
    3. Unix Proxy Login Module false

    Select a login module to modify. Enter "0" when you are done: [0]

    最后,依然是把所有设置print出来检查,其中Unified Agent部分的有些内容应该以后会用到:

       Unified Agent - Security Login Modules

    CSI.loginModule.1.provider com.sybase.ua.services.security.simple.SimpleLoginModule
    CSI.loginModule.1.controlFlag sufficient
    CSI.loginModule.1.options.moduleName Simple Login Module
    CSI.loginModule.1.options.username uafadmin
    CSI.loginModule.1.options.password ******
    CSI.loginModule.1.options.roles uaAgentAdmin,uaPluginAdmin
    CSI.loginModule.1.options.encrypted false

    CSI.loginModule.2.provider com.sybase.ua.services.security.ase.ASELoginModule
    CSI.loginModule.2.controlFlag sufficient
    CSI.loginModule.2.options.moduleName ASE Login Module

    终于又开始创建服务器了,不幸又遇到了错误:

    Building Adaptive Server 'SVR6':
    Writing entry into directory services...
    Directory services entry complete.
    Building master device...
    Task failed
    Server 'SVR6' was not created.
    /opt/sybase/ASE-15_0/bin/dataserver: error while loading shared libraries:
    libstdc++.so.5: cannot open shared object file: No such file or directory

    其它服务器创建倒是很正常,除了连不上主服务器:

    Building Backup Server 'SVR6_BS':
    Writing entry into directory services...
    Directory services entry complete.
    Writing RUN_SVR6_BS file...
    RUN_SVR6_BS file complete.
    Starting server...
    Server started.
    Server 'SVR6_BS' was successfully created.

    Building Monitor Server 'SVR6_MS':
    Writing entry into directory services...
    Directory services entry complete.
    Writing RUN_SVR6_MS file...
    RUN_SVR6_MS file complete.
    Unable to log in to Adaptive Server 'SVR6'.
    Unable to boot 'SVR6_MS' because Monitor Server must be able to log in to
    Adaptive Server.
    Server 'SVR6_MS' was not created.

    Building XP Server 'SVR6_XP':
    Writing entry into directory services...
    Directory services entry complete.
    Server 'SVR6_XP' was successfully created.
    'SVR6_XP' will be started when needed by the Adaptive Server.

    主服务器可能是缺少库文件,安装上libstdc++5包(会自动安装gcc-3.3-base包),用sybase用户进入,设定好环境变量,在.bashrc里添加上两行:

    . ~/SYBASE.sh
    . ~/ASE150.sh

    再用rs文件创建服务器(记得先关掉已经启动的backup服务器,删掉/opt/sybase目录)。但,依然是错误:

       Building Adaptive Server 'SVR6':
    Writing entry into directory services...
    Directory services entry complete.
    Building master device...
    Task failed
    dataserver: master device size for this server: 60.0 Mb
    Server 'SVR6' was not created.
    dataserver: master database size for this server: 13.0 Mb
    dataserver: model database size for this server: 3.0 Mb

    log的最后部分是:

       00:00000:00000:2007/09/17 02:31:14.28 kernel Encryption provider
    initialization succeeded on engine 0.
    00:00000:00000:2007/09/17 02:31:14.28 kernel engine 0, os pid 28397 online
    Segmentation fault

    上网查资料,又加上了LD_POINTER_GUARD=0参数(这个是0或者1得来回试试,看哪个行),终于行了:

    Building Adaptive Server 'SVR6':
    Writing entry into directory services...
    Directory services entry complete.
    Building master device...
    Master device complete.
    Writing RUN_SVR6 file...
    RUN_SVR6 file complete.
    Starting server...
    Server started.
    Building sysprocs device and sybsystemprocs database...
    sysprocs device and sybsystemprocs database created.
    Running installmaster script to install system stored procedures...
    installmaster: 10% complete.
    installmaster: 20% complete.
    installmaster: 30% complete.
    installmaster: 40% complete.
    installmaster: 50% complete.
    installmaster: 60% complete.
    installmaster: 70% complete.
    installmaster: 80% complete.
    installmaster: 90% complete.
    installmaster: 100% complete.
    installmaster script complete.
    Creating two-phase commit database...
    Two phase commit database complete.
    Installing common character sets (Code Page 437, Code Page 850, ISO Latin-1,
    Macintosh and HP Roman-8)...
    Character sets installed.
    Setting server name in Adaptive Server...
    Server name added.
    Server 'SVR6' was successfully created.

    安装小结

    Sybase对服务器环境比较挑剔,我的服务器操作系统是Ubuntu 7.04:

    • 首先libaio是需要的,apt安装即可,表现为libaio-devlibaio1两个包。
    • 设置shmmax,在/etc/sysctl.conf中加入kernel.shmmax=2147483648(2G共享内存),重启,或者直接echo 2147483648 > /proc/sys/kernel/shmmax,或者用sysctl -p直接加载。查询目前的共享内存设置用sysctl kernel.shmmax ,单位为字节,sybase应该是需要至少64M,建议根据机器配置情况,设置为总内存的一半,或者256M以上。
    • 安装上libstdc++5包,会自动安装gcc-3.3-base包。
    • 手工创建sybase用户,把/home/sybase的权限设给它,并设置$HOME/opt/sybase,当然,这一步也可以在安装完sybase、创建服务器之前作。
    • 在sybase用户的bashrc中添加LD_POINTER_GUARD=0(注:我把sybase的默认shell从sh改成bash了,好像RHEL中需要指定这个环境变量为1),在bashrc增加两个sh脚本的调用(. ~/SYBASE.sh. ~/ASE150.sh)。
    • 文档中建议使用sybase用户来进行安装,不过我是用root用户安装的,好像也没有遇到太多问题,安装完成后把/opt/sybase整体chown一下。

    服务器设置

    更改sa密码

    格式为sp_password oldpassword,newpassword,比如:

    >sp_password null,"new_password"
    >go

    服务器的字符集

    默认字符集是"iso_1 (ISO 8859-1), a binary sort order, and English as the default language.",我们一般使用的字符集是cp936或者utf8,下面就把服务器字符集调整为utf8。

    没有用sp_configure来配置服务器字符集,而是采用sqlloc.rs方式,rs文件内容如下:

    sybinit.release_directory: /opt/sybase
    sqlsrv.server_name: SVR6
    sqlsrv.sa_login: sa
    sqlsrv.sa_password:
    sqlsrv.default_language: us_english
    sqlsrv.language_install_list: USE_DEFAULT
    sqlsrv.language_remove_list: USE_DEFAULT
    sqlsrv.default_characterset: utf8
    sqlsrv.characterset_install_list: USE_DEFAULT
    sqlsrv.characterset_remove_list: USE_DEFAULT
    sqlsrv.sort_order: binary

    运行之:

    sybase@svr6:~$ sqllocres -r sqlloc.rs
    Installing sort order 'Binary ordering, for the ISO 10646-1, UTF-8 multibyte
    encodin...' in the Adaptive Server...
    Sort Order 'Binary ordering, for the ISO 10646-1, UTF-8 multibyte encodin...'
    was successfully installed in the Adaptive Server.
    Making 'UTF-8' the Adaptive Server's default character set...
    Making 'Binary ordering, for the ISO 10646-1, UTF-8 multibyte encodin...' the
    Adaptive Server's default sort order...
    The Adaptive Server's default character set is now 'UTF-8'.
    The Adaptive Server's default sort order is now 'Binary ordering, for the ISO
    10646-1, UTF-8 multibyte encodin...'.
    Done

    在isql中检查转换结果:

    1> sp_helpsort
    2> go
    ...
    Character Set = 190, utf8
    Unicode 3.1 UTF-8 Character Set
    Class 2 Character Set
    Sort Order = 50, bin_utf8
    Binary sort order for the ISO 10646-1, UTF-8 multibyte encodin
    g character set (utf8).
    (return status = 0)
    1> select @@client_csname
    2> go

    ------------------------------
    utf8

    (1 row affected)

    简单试了一下,客户端是cp936字符集的时候,服务器能够正常的转换编码。

    还有一个问题需要在数据转移时考虑,原来的服务器字符集是cp936,在转移数据的时候应该会遇到字段长度不够的情况,需要把字段长度增加为现在的3/2倍。

    Adaptive Server Enterprise 15.0 - Datatypes

    客户端的字符集设置需要修改$SYBASE/locales/locales.dat,在指定的操作系统如[win32]段,添加:

    locale = default, us_english, cp936

    就可以了,在数据传输过程中sybase会自动进行cp936和utf8之间的转换。一点小问题:我在linux下用sqsh连接服务器,不管-J参数怎么设置,select @@client_csname都是NULL,不过中文好像也能够正常使用(linux为Ubuntu,字符集为en_US.utf8)

    其它关于字符集的参考资料:

    自定义cfg文件

    内存
    max memory = 1048576

    2k的页大小,设置2G的内存,XE版中设置超过这个值的话,反而会被ASE拒绝,使用默认值49152。

    cpu
    max online engines = 1

    其实这一项使用DEFAULT即可,因为XE的限制,设置多了也不会起作用。

    其他参数
    number of user connections = 300
    number of locks = 10000 (ASE 15默认值就是这个)
    lock scheme = datarows
    identity burning set factor

    这个是用来自动分配identity列的值的,sybase采用预分配区间的方式,所以重启或rollback事务会产生断带,这个参数就是用来控制断带的大小的,公式为:

    identity burning set factor(F) = N * power(10, 7 - M)

    其中N是每次分配的种子数量,M为identity列的长度。反过来,想知道每次会分配多少种子数,公式就是:

    N = F * power(10, M - 7)

    在我这里,identity列长度为8/numeric(8,0),identity burning set factor设置为10,每次的种子分配就是100个,最大的断带也就是100。

    其它文档中提到,但是不需要运行的

    • installmaster
    • installcommit 两阶段提交或分布式事务(two-phase commit or distributed transactions)
    • installsecurity (Sybase auditing feature)
    • instmsgs.ebf (brings your Adaptive Server messages up to the level of this EBF)
    • installjsdb (Job Scheduler feature enabled)and(upgrade the Job Scheduler Templates)
    • installmontables (update the Monitoring Tables' definitions)

    文档中都有详细说明,用isql执行相应sql文件即可,我没有装。

    创建init.d脚本

    我的安装并没有自动在/etc/init.d/下创建控制服务的脚本,所以只能自己按照SQL Relay 上的例子创建一个了(有一点点改动):

    #!/bin/sh

    export SYBASE=/opt/sybase
    export PATH=$PATH:$SYBASE/ASE-15_0/bin:$SYBASE/ASE-15_0/install
    export LD_POINTER_GUARD=0
    #echo 268435456 > /proc/sys/kernel/shmmax
    case "$1" in
    start)
    for i in `ls $SYBASE/ASE-15_0/install/RUN_*`
    do
    su -c "$SYBASE/ASE-15_0/install/startserver -f $i" > /dev/null 2>&1;
    #su -c "$SYBASE/ASE-15_0/install/startserver -f $i"
    done
    ;;
    stop)
    kill `ps -efa | grep sybase | grep -v grep | awk '{print $2}'`
    ;;
    *)
    echo $"Usage: $0 {start|stop}"
    exit 1
    esac

    exit 0

    这里还有一个更好的脚本,主要是关闭使用的不是kill,而是数据库自身的shutdown功能),针对我的平台,我有略微改动,建议大家使用这个或参照修改:

    #!/bin/bash
    # Author: MichaelBibby
    # Date: 2007.06.19
    # description: Normal RC script for SYBASE.

    SYBASE_USERNAME="sa"
    SYBASE_PASSWORD=""

    export LD_POINTER_GUARD=0
    export SYBASE=/opt/sybase
    export SYBASE_HOME='/opt/sybase'
    export SYBASE_OCS='OCS-15_0'
    export SYBASE_ASE='ASE-15_0'
    # ************************************************
    # Warnning: Modify the RUN_xxx to fit your need.
    # Your startup script will be such as:
    # ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER}
    # ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER_BACKUP}
    export SERVER='SVR6'
    export SERVER_BACKUP='SVR6_BS'
    # For multi-server
    # export SERVER='server1 server2'
    # export SERVER_BACKUP='server1_backup server2_backup'
    # ************************************************

    export LIB="${SYBASE_HOME}/${SYBASE_OCS}/lib"
    export PATH=$PATH:"${SYBASE_HOME}/${SYBASE_ASE}/bin:${SYBASE_HOME}/${SYBASE_ASE}/install:${SYBASE_HOME}/${SYBASE_OCS}/bin"

    start_db()
    {
    su -p sybase -c "${SYBASE_HOME}/${SYBASE_ASE}/install/startserver
    -f ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER}"

    su -p sybase -c "${SYBASE_HOME}/${SYBASE_ASE}/install/startserver
    -f ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER_BACKUP}"
    }

    stop_db()
    {
    # Error: Site 'SVR6_BS' not found in sysservers/ User default back_srv name.
    ${SYBASE_HOME}/${SYBASE_OCS}/bin/isql
    -U${SYBASE_USERNAME}
    -P${SYBASE_PASSWORD}
    -S${SERVER} </dev/null
    if [ X"$?" == X"0" ]; then
    stop_db
    else
    exit 0
    fi
    ;;
    status) status_db ;;
    *) echo "USAGE: $0 [start|stop|status|restart]" ;;
    esac

    把这个脚本ln为/etc/init.d/sybase就可以用来控制服务了。

    开机后自动启动

    把刚才创建的/etc/init.d/sybase这个文件ln到各个rc目录下就可以了:

    cd /etc/rc0.d/
    ln -s ../init.d/sybase K90sybase
    cd /etc/rc1.d/
    ln -s ../init.d/sybase K90sybase
    cd /etc/rc2.d/
    ln -s ../init.d/sybase S90sybase
    cd /etc/rc3.d/
    ln -s ../init.d/sybase K90sybase
    cd /etc/rc4.d/
    ln -s ../init.d/sybase K90sybase
    cd /etc/rc5.d/
    ln -s ../init.d/sybase K90sybase
    cd /etc/rc6.d/
    ln -s ../init.d/sybase K90sybase
    cd /etc/rcS.d/
    ln -s ../init.d/sybase S90sybase

    绑定两个ip地址

    默认情况下,sybase只在一个ip地址上监听,如果在interfaces文件中强行添加其他的ip,或者是其他的端口,比如这样:

    SVR6
    master tcp ether svr6 5000
    query tcp ether svr6 5000
    master tcp ether svr6 4000
    query tcp ether svr6 4000
    master tcp ether 192.168.0.106 5008
    query tcp ether 192.168.0.106 5008

    都用svr6这个名字,5000和4000端口都可以监听成功,但第二个106的地址监听不成功:

    00:00000:00008:2007/09/18 13:43:49.84 kernel  network name svr6, interface IPv4, address 0.0.0.0, type tcp, port 5000, filter NONE 
    00:00000:00008:2007/09/18 13:43:49.84 kernel network name svr6, interface IPv4, address 0.0.0.0, type tcp, port 4000, filter NONE
    00:00000:00008:2007/09/18 13:43:55.17 kernel ninit: cannot find host 192.168.0.106 00:00000:00008:2007/09/18 13:43:55.17 kernel Cannot allocate resources for listener with protocol tcp, host 192.168.0.106 , port 5008, engine 0.

    所以变通的办法无外乎两种,一种是用防火墙把另外一个ip地址的端口作dnat转发过来,另外一种就是修改hosts文件,把svr6的地址指定为0.0.0.0,个人认为第二种方式较好一些,并且试验成功。

    创建数据库

    设定以后的用户数据库不要默认创建在master设备上

    1> sp_diskdefault master, defaultoff
    2> go

    更改tempdb的大小(建议使用下面ram设备的方式)

    先查看tempdb的状态:sp_helpdb tempdb,默认是创建在master设备上,大小为4M,而将临时数据库放在单独的设备上更好,现在就来调整:

    > disk init     # 初始化设备
    > name="tempdb_dev", # 设备名称,遵守sybase标识符规则
    > physname="/opt/sybase/tempdb.dat", #设备物理地址,最好用绝对地址
    > vdevno=13, # 设备编号(需要唯一,我刚装上的系统,master是0,sysprocsdev是1,systemdbdev是2,再新建就该用3了)
    > dsync=false, # 关闭I/O缓存,提升性能
    > size=15360 # 设备大小,默认是以块为单位(一般512字节或者2k),不过建议使用尺寸,比如"200M"或者"1g",这样更容易掌握一些)
    > go

    将临时数据库扩展到该一个设备上,注意这里的单位是M

    > alter database tempdb on tempdb_dev=30
    > go

    打开tempdb数据库,从段上删除master设备

    > use tempdb
    > go
    > sp_dropsegment default, tempdb, master
    > go
    > sp_dropsegment logsegment, tempdb, master
    > go
    > sp_dropsegment system, tempdb, master
    > go

    设置tempdb为第一个recover的库(好像没必要)

    -- make the second tempdb the first user db to be recovered.
    > sp_dbrecovery_order tempdb_report, 1
    > go

    参考:disk init手册

    把tempdb创建在ram设备上

    首先创建虚拟的ram设备,挂载上(默认的大小单位好像是1k,但建议适当多划分一点空间留给文件系统和容纳计算误差,比如我想用30M的tempdb,就划了33000),创建设备文件,并更改文件权限:

    mkdir /home/sybase/tempdb
    mke2fs -q -m0 /dev/ram0 33000
    mount -t ext2 /dev/ram0 /home/sybase/tempdb
    ?? touch /home/sybase/tempdb/tempdb.dat (第一次创建的时候不建文件,加在启动脚本里再用touch?)
    chown -R sybase:sybase /home/sybase/tempdb

    然后在这个设备文件上创建sybase数据库设备,并把tempdb转移过来,首先创建设备:

    > disk init name="tempdb_dev", phyname="/home/sybase/tempdb/tempdb.dat", vdevno=3,dsync=false,size="30M"
    > go

    在新设备上分配空间:

    > use master
    > alter database tempdb on tempdb_dev=30
    > go
    Extending database by 15360 pages (30.0 megabytes) on disk tempdb_dev

    从旧设备(master)上删除段:

    > use tempdb
    > go
    > sp_dropsegment "default", tempdb, master
    > go
    > sp_dropsegment logsegment, tempdb, master
    > go
    > sp_dropsegment system, tempdb, master
    > go

    回收旧设备上的空间,还是直接修改系统表最简单,不过最好先查询一下,对照sysusages表的内容进行适应性调整:

    > sp_configure "allow update", 1
    > go
    > begin tran
    > delete from sysusages where dbid=2 and segmap=0
    > go
    > update sysusages set lstart=0 where dbid=2
    > go
    > commit
    > go
    > sp_configure "allow update", 0
    > go

    还有一种用临时表,写日志然后截断日志的方式,可以参考同一设备数据库如何分离日志与数据,不过我作的时候没有成功,还因为日志堵塞动弹不得(我循环了50万次都没事,然后全部 delete from就出事了 :);另外一次是在执行sql insert into t select id from t时,第一次执行没事,5万条数据出来了,第二次再执行。。。死掉了)。可以用sp_helpdb tempdb查设备和段分配情况,

    为了在重启的时候也能正常创建ram盘,还要在上面说过的服务控制脚本中添加创建并使用ram盘的内容,即在start_db的开始部分加上:

    start_db()
    {
    echo "Mounting ramdisk for tempdb ..."
    mke2fs -q -m0 /dev/ram0 33000
    mount -t ext2 /dev/ram0 /home/sybase/tempdb
    touch /home/sybase/tempdb/tempdb.dat
    chown -R sybase:sybase /home/sybase/tempdb
    ......

    在stop_db()的结尾部分加上:

        ......
    echo "Dismounting ramdisk of tempdb ..."
    umount /home/sybase/tempdb

    if [ X"$?" == X"0" ]; then
    exit 0
    else
    exit 1
    fi
    } // end of func stop_db

    两个疑惑的地方及我看到的结果:

    • mke2fs创建的ram盘占用实际的内存么?好像不占,分配到文件上才占。
    • sybase重启后,tempdb会重用大小和以前不同的同名设备文件么?会的,tempdb的机制和其他用户库不一样。

    参考:

    搞定收工,可以正式建库配置应用数据库了,再推荐几个sybase的资料:

    Source: http://www.fwolf.com/blog/post/357