Gih's Blog

只言片语
Posts tagged as freebsd

This is my desktop... 5 years ago.

2014-08-15 by gihnius, tagged as freebsd, linux

Can you guess which OS?

Emacs, Firefox, Xterm, Rxvt, Fcitx...

and FreeBSD!

FreeBSD多路由表的应用

2011-06-24 by gihnius, tagged as freebsd

从FreeBSD 7.1开始,系统支持 multi route tables. 不过还不是默认,需要编译内核才支持. 其实有很多人都希望这个应作为系统默认的功能. 希望在即将到来的FreeBSD 9中出现. 这样可以轻松实现策略路由. 本人在工作中也需要这种功能,所以写个经验总结跟大家分享一下. 错漏之处还请多多指教.

加入内核支持,这个是必需的,希望以后成为默认:

option ROUTETABLES=16
这个值有个范围: 1 - 16, 选最大的吧. 添加进内核后, 可以通过 net.fib=N来修改,比如:
## in /boot/loader.conf
net.fib=4 
还可以通过sysctl 查看当前设置值.
$ sysctl net. | grep fib
net.my_fibnum: 0
net.add_addr_allfibs: 1
net.fibs: 16 
编译内核,参考文档吧:
cd /usr/src; make -j4 kernel KERNCONF=MRT
应用:客户端应用,以我的为例, 上班时我要用wifi上网,又要上维护内网服务器.wifi的路由是 192.168.1.1 192.168.1.0/24, 接口是 wlan0内网服务器的路由是 132.96.20.8 132.96.20.0/26, 接口是 re0先配置ip, wlan0是动态的,常规方法配置即可. re0是静态的:
ifconfig re0 up
ifconfig re0 inet 132.96.20.24 netmask 255.255.255.192
setfib -F 1 route add default 132.96.20.8 
re0的路由表配置在 fib 1 上, wlan0之前已经设置,它会默认使用 fib 0.可以看看路由表:
 netstat -nr
Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            192.168.1.1        UGS        20     9905  wlan0
127.0.0.1          link#13            UH          0     4092    lo0
132.96.20.0/26     link#6             U           0        0    re0
132.96.20.24       link#6             UHS         0        0    lo0
192.168.1.0/24     link#15            U           0       43  wlan0
192.168.1.9        link#15            UHS         0        0    lo0
... 
上面是 wlan0的配置,跟 setfib -F 0是一致的:
 setfib -F 0 netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            192.168.1.1        UGS        11    10008  wlan0
127.0.0.1          link#13            UH          0     4098    lo0
132.96.20.0/26     link#6             U           0        0    re0
132.96.20.24       link#6             UHS         0        0    lo0
192.168.1.0/24     link#15            U           0       43  wlan0
192.168.1.9        link#15            UHS         0        0    lo0
... 
re0上的配置:
 setfib -F 1 netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            132.96.20.8        UGS       112     3518    re0
127.0.0.1          link#13            UH          0       75    lo0
132.96.20.0/26     link#6             U           0        0    re0
192.168.1.0/24     link#15            U           0        0  wlan0
... 
路由器应用:接口1 re0, 接外网internet, 通过专用 ISP. fib=2接口2 re1, 接城域网 172.16.1.0/24 fib=1接口3 re2, 接内部局域网 192.168.1.0/24 fib=0fib跟随配置网络的顺序增加.可以在路由器上用setfib启动一个shell,这个shell就处于对应的网络环境下:
setfib -F 1 $SHELL -l
之后就可以接入城域网.具体配置跟上面的差不多,无非是再作一个路由器,就不详细介绍了,因为涉及具体的方案,而且需求不同也可以灵活配置,还可以结合 pf一起使用,功能就不是一般的强大了.

How to delay start a daemon ?

2011-06-22 by gihnius, tagged as freebsd

默认情况下很多系统服务都是在开机过程完成启动的, 但有时我希望一些服务在开机后过一段时间再启动. 在FreeBSD, AIX, Linux都可以通过简单的脚本实现, 不过要注意,有些服务会提供全局的环境变量或者成为其它服务进程的依赖时不能这么做!

以我的笔记本为例, 因为经常会在不同的地方上网, 所以我取消了系统开机自动配置网络,在开机后自己再执行相应的脚本连网. 有些服务比如 ntp(时间同步), pf(防火墙), stunnel, privoxy等等, 我都 delay start了. 方法是在/etc/rc.local里添加:

## rc.local
(sleep 600; service ntpdate onestart) &
(sleep 660; service ntpd onestart) &
(sleep 120; /path/to/other_scripts) &
... 
像ntpdate, 如果在开机时运行, 没有网络就不能校正时间了.我觉得这样还是有好处的, 还可以缩短开机时间.

FreeBSD系统通过devd/devfs自动挂载USB存储

2011-06-21 by gihnius, tagged as freebsd

因为自己不用KDE/GNOME等桌面系统,也不喜欢Hald提供的挂载方式, 所以写了一个脚本, 实现FreeBSD系统使用devd/devfs自动挂载U盘. 想了解 devd/devfs 就参考man文档吧! 设计脚本的功能大致如下:

插入usb disk后, 创建挂载目录, 检测文件系统类型, 然后使用适当的命令挂载, 把挂载信息记录到syslog里. 支持多个U盘,多分区,多文件系统类型挂载. 默认使用当前桌面用户id进行挂载.脚本的缺点:不能提示用户已经挂载, 不能通过图形界面卸载. 如果你觉得这个脚本有用,就给些建议帮忙改进吧!配置:设置系统运行普通用户挂载设备:在/etc/sysctl.conf加入:

Read more »

FreeBSD LCD屏幕亮度控制

2011-06-09 by gihnius, tagged as freebsd

在我的笔记本上,可以通过acpi_video.ko来控制屏幕亮度. 写了一个脚本lcd.sh,通过参数"lcd_up","lcd_down"来调节亮度,并用 osd_cat显示百分比信息.

## sysctl MIB of acpi_video
hw.acpi.reset_video: 1
hw.acpi.video.ext0.active: 0
hw.acpi.video.crt0.active: 0
hw.acpi.video.lcd0.active: 0
hw.acpi.video.lcd0.brightness: 70
hw.acpi.video.lcd0.fullpower: 100
hw.acpi.video.lcd0.economy: 90
hw.acpi.video.lcd0.levels: 100 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20
dev.acpi_video.0.%desc: ACPI video extension
dev.acpi_video.0.%driver: acpi_video
dev.acpi_video.0.%parent: vgapci0 

配置sudo,允许wheel组用户通过执行/etc/lcd.sh,调节屏幕亮度.

%wheel     ALL=NOPASSWD:   /etc/lcd.sh

我的FreeBSD LCD屏幕亮度控制脚本: 可能你需要修改脚本的获取和设置lcd信息的 MIB.

#!/bin/sh

action=$1
DISPLAY=:0.0

xosd_bar_font="-adobe-helvetica-bold-*-*-*-34-*-*-*-*-*-*-*"

lcd_down () {
    levels=$(sysctl -n hw.acpi.video.lcd0.levels)
    top=$(echo $levels | sed "s/\(^[0-9]\{2,3\}\).*/\1/")
    bot=$(echo $levels | sed "s/.* \([0-9]\{2,3\}\)$/\1/")
    curr=$(sysctl -n hw.acpi.video.lcd0.brightness)
    down=$curr

    if [ "$curr" -le "$top" ] && [ "$curr" -gt "$bot" ] ; then
        if [ "$down" -ne "$bot" ] ; then
            down=$(echo $levels | sed "s/.*$curr \([0-9]\{2,3\}\).*/\1/")
        fi
    fi

    sysctl hw.acpi.video.lcd0.brightness=$down
    killall osd_cat >/dev/null 2>&1
    osd_cat -p middle -A center -f $xosd_bar_font -c green -O 3 -d 1 -b percentage -P $down -T "LCD: $down %" &
}

lcd_up () {
    levels=$(sysctl -n hw.acpi.video.lcd0.levels)
    top=$(echo $levels | sed "s/\(^[0-9]\{2,3\}\).*/\1/")
    bot=$(echo $levels | sed "s/.* \([0-9]\{2,3\}\)$/\1/")
    curr=$(sysctl -n hw.acpi.video.lcd0.brightness)
    up=$curr

    if [ "$curr" -lt "$top" ] && [ "$curr" -ge "$bot" ] ; then
        up=$(echo $levels | sed "s/^\([0-9]\{2,3\}\) $curr.*/\1/" | sed "s/.*\($curr\).*/\1/")
        if [ "$up" -ne "$top" ] ; then
            up=$(echo $levels | sed "s/.*\([0-9]\{2,3\}\) $curr.*/\1/")
        fi
    fi

    sysctl hw.acpi.video.lcd0.brightness=$up
    killall osd_cat >/dev/null 2>&1
    osd_cat -p middle -A center -f $xosd_bar_font -c green -O 3 -d 1 -b percentage -P $up -T "LCD: $up %" &
}


## do
{
case $action in
    lcd_up)
        lcd_up
        ;;
    lcd_down)
        lcd_down
        ;;
    *)
        ;;
esac
} > /dev/null 

把脚本绑定到快捷键上, 我的fvwm配置:

Key XF86Forward A   A       Exec sudo /etc/lcd.sh lcd_up
Key XF86Back    A   A       Exec sudo /etc/lcd.sh lcd_down 

获取FreeBSD源代码的方式(svn and csup)

2011-06-02 by gihnius, tagged as freebsd

默认FreeBSD系统使用cvsup更新源代码. 运行cvsup需要一个supfile配置文件.

使用时一般只需修改supfile里的

*default host=cvsup.freebsd.org
*default release=cvs tag=RELENG_8
其中 tag=RELENG_8 指定源代码的版本.如果是 stable版本,一般写为 tag=RELENG_X(X即为版本号).如果是 release版本,一般是 tag=RELENG_X_R (如7.4release: RELENG_7_4)如果是 currnt版本, tag=. (.表示当前最新版本号)设置好后执行以下命令进行更新:
cvsup -g -L 2 /usr/share/example/cvsup/stable-supfile
另外:使用cvsup需要安装额外的 cvsup-without-gui包,如不安装也可使用系统自带的 csup命令. csup是 cvsup的C语言版本.以上可以满足大多数人的需求.接着介绍用 subversion 操作的方法和过程.为什么推荐用 subversion ? 个人认为, 保留一个 svn repo到本地,更方便代码更新,修改,打补丁,进而发现和报告bug.FreeBSD的开发已经采用 subversion管理代码,你还可以看到代码的具体版本和修改记录及注释.FreeBSD svn Web服务地址: http://svn.freebsd.org查看源代码列表:
svn list svn://svn.freebsd.org/base
svn list svn://svn.freebsd.org/base/head
svn list svn://svn.freebsd.org/base/stable
以上命令分别查看 base tree, current tree, stable tree的源代码根目录文件列表.下载更新源代码:
## 下载 current版本源代码到 /usr/current
svn checkout svn://svn.freebsd.org/base/head /usr/current
## 下载 stable版本
svn checkout svn://svn.freebsd.org/base/stable/8 /usr/src
## 下载 release版本
svn checkout svn://svn.freebsd.org/base/release/8.2.0 /usr/release
## 还有一个 releng 版本
这个用得不多,它只是release发行前的准备版本.

## 下载你想要的任意一部分(比如 ath 驱动)
svn checkout svn://svn.freebsd.org/base/stable/8/sys/dev/ath  ~/test/8-stable-ath
## 更新
cd /usr/src; svn up
不过, 使用svn方式要比cvsup的多占用空间.

在硬盘上安装多个FreeBSD系统

2011-06-02 by gihnius, tagged as freebsd

经过测试,可以在硬盘上安装多个FreeBSD系统.这样测试系统时就不用在一个系统内换来换去根分区和不同版本的kernel了.

以硬盘ada0为例,在其上划分多个Slices,目前FreeBSD支持在一快盘上划最多4个slice.计划分三个slice, ada0s1, ada0s2, ada0s3.

ada0s1 安装常用的 stable版,并启用BootMgr引导管理器.

ada0s2 安装测试的 current版.

ada0s3 用来备份.

在stable系统上看,分区大概是这样:

ls /dev/ada0s?
/dev/ada0s1 /dev/ada0s2 /dev/ada0s3
ls /dev/ada0s1*
/dev/ada0s1  /dev/ada0s1b /dev/ada0s1e /dev/ada0s1g
/dev/ada0s1a /dev/ada0s1d /dev/ada0s1f 

之所以用一个独立的slice备份,因为安装系统那个slice有可能因崩溃而损坏,所有的数据都放在一个slice里面没保障.

当然,一个硬盘也不保障!管理保护硬盘数据的左右手:冗余-备份是必须的.

FreeBSD 8 的无线设置

2011-06-01 by gihnius, tagged as freebsd

觉得FreeBSD 8 对无线配置的支持还是不够友好.整个ports里面只有一个叫 wifimgr 的工具管理无线,而且功能非常有限,比 wpa_gui 好不出哪! 所以我一直都是手工上无线. 因为经常要在不同的地点连接不同的无线网络(AP). 我只要事先把常用到的无线帐号都写到  /etc/wpa_supplicant.conf 里,并设置各个网络为disable.如:

network={
    ssid="CHINANET"
    psk="chinanet"
    disabled=1
}

network={
    ssid="linksys"
    key_mgmt=NONE
    disabled=1
}

network={
    ssid="linksys88"
    key_mgmt=NONE
    disabled=1
}

network={
    ssid="CMCC"
    key_mgmt=NONE
    disabled=1
}

network={
    ssid="TP_LINK"
    scan_ssid=1
    key_mgmt=WPA-PSK
    proto=WPA
    pairwise=CCMP
    group=CCMP
    psk="passwordtest"
    disabled=1
}

...... 

这样,当启动wpa_supplicant daemon时就不会试图连接哪个! 取消 /etc/rc.conf 里的设置:

# wlans_ath0="wlan0"
# ifconfig_wlan0="WPA DHCP"
# 

我取消开机自动配置wifi, 开机后执行以下脚本:

ifconfig wlan0 create wlandev ath0
ifconfig wlan0 up
/etc/rc.d/wpa_supplicant start wlan0
wpa_cli list ## 选择当前环境的网络
wpa_cli enable_network <network id> ## 输入要连接的网络 id
wpa_cli reconnect
sleep 2
dhclient -b wlan0
sleep 2
...... 

上面黄色那两行,你可以手动把 /etc/wpa_supplicant.conf 里对应的 network 段的 "disabled=1" 注释掉来代替. 整成脚本就是:

#!/bin/sh
## wifi.sh
ifconfig wlan0 create wlandev ath0
ifconfig wlan0 up
/etc/rc.d/wpa_supplicant start wlan0
sleep 2
wpa_cli list
echo "Please enter the network id: (number)"
read network_id
wpa_cli enable_network $network_id
wpa_cli reconnect
sleep 1
dhclient -b wlan0 
#!/bin/sh
## wifi_stop.sh
ifconfig wlan0 down
wpa_cli disconnect
wpa_cli terminate
/etc/rc.d/dhclient stop wlan0
ifconfig wlan0 destroy
echo "wifi interface destroy!" 

这样你不论在家里,上班,出差,星巴克,都可以通过这个脚本连接 wifi 了.