ZFS Pool 里增加硬盘做镜像

ZFS 第一次出现在 OpenSolaris 上是在2005年11月发布的 build 27 版本,因为稳定性、可靠性等原因直到最近 VPSee 才有考虑把它用在生产环境里,现在 VPSee 所有的 Solaris 服务器还是在用很古老的 UFS,UFS 仍是 Solaris 10 的默认文件系统。昨天简单玩了一下 ZFS,用6个文件模拟6个硬盘在 ZFS 上进行了一系列添加、删除、镜像的操作,立刻体会到了 ZFS 的强大,但这与实际操作物理硬盘还是有点差别。VPSee 当时安装 OpenSolaris 的时候只用了一块 250GB 的硬盘,现在可以增加一块 250GB 的硬盘做镜像,试验一下 ZFS 强大的 mirror,相当于做 RAID1.

检查 pool

要在服务器上增加一块实际硬盘,先要看看系统原来的 pool 有什么:

# zpool status
  pool: rpool
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          c8t0d0s0  ONLINE       0     0     0

errors: No known data errors

上面显示 c8t0d0s0 是里面唯一的一块硬盘。现在插上一块新硬盘后(必要时需要重启)运行 format 工具:

# format
Searching for disks...

The device does not support mode page 3 or page 4,
or the reported geometry info is invalid.
WARNING: Disk geometry is based on capacity data.

The current rpm value 0 is invalid, adjusting it to 3600
done

c8t1d0: configured with capacity of 232.87GB


AVAILABLE DISK SELECTIONS:
       0. c8t0d0 
          /pci@0,0/pci108e,534c@5/disk@0,0
       1. c8t1d0 
          /pci@0,0/pci108e,534c@5/disk@1,0
Specify disk (enter its number):

按 “Ctrl + C” 退出。c8t0d0 是原来的硬盘,c8t1d0 是后来加上去的新硬盘。

分区和 label

现在用 -e 参数再次运行 format,然后选择 partition,创建一个 Solaris 分区后打印出分区表看看,只有 s0, s2, s8 有内容。完成分区后退到 format 菜单,接着选择 label,因为大多数的 PC BIOS 都不支持 EFI labels,所以要选择 SMI:

# format -e c8t1d0

format> partition
SELECT ONE OF THE FOLLOWING:
   1. Create a partition
...

partition> print
Current partition table (original):
Total disk cylinders available: 30398 + 2 (reserved cylinders)

Part      Tag    Flag     Cylinders         Size            Blocks
  0       root    wm       1 - 30396      232.85GB    (30396/0/0) 488311740
  1 unassigned    wu       0                0         (0/0/0)             0
  2     backup    wu       0 - 30396      232.85GB    (30397/0/0) 488327805
  3 unassigned    wu       0                0         (0/0/0)             0
  4 unassigned    wu       0                0         (0/0/0)             0
  5 unassigned    wu       0                0         (0/0/0)             0
  6 unassigned    wu       0                0         (0/0/0)             0
  7 unassigned    wu       0                0         (0/0/0)             0
  8       boot    wu       0 -     0        7.84MB    (1/0/0)         16065
  9 unassigned    wu       0                0         (0/0/0)             0
partition>quit

format> label
[0] SMI Label
[1] EFI Label
Specify Label type[0]: 0
Ready to label disk, continue? y

做镜像

退出 format,在 rpool 里增加新硬盘作为第1一块硬盘 mirror,会出现以下报错:

# zpool attach -f rpool c8t0d0 c8t1d0
cannot label 'c8t1d0': EFI labeled devices are not supported on root pools.

我们必须把 VTOC 从第1块硬盘拷贝到第2块硬盘,注意这里 s2 是 slice(分区),c8t0d0s2 是 c8t0d0 的 s2 分区,注意上面打印的分区显示 s2 代表整个硬盘,看 Blocks 发现 s2 = s0 + s8,s0 是 root 分区,s8 是 boot 分区:

# prtvtoc /dev/rdsk/c8t0d0s2 | fmthard -s - /dev/rdsk/c8t1d0s2 
fmthard: Partition 2 specifies the full disk and is not equal
full size of disk.  The full disk capacity is 488343870 sectors.
fmthard:  New volume table of contents now in place.

新硬盘的 c8t1d0s0 分区做成 c8t0d0s0 的镜像,注意上面打印的分区显示 s0 是 root 分区,有 232.85GB 空间,也是我们想 mirror 的分区:

# zpool attach -f rpool c8t0d0s0 c8t1d0s0
Please be sure to invoke installgrub(1M) to make 'c8t1d0s0' bootable.

安装 grub

这一步非常重要,需要把 grub 安装在第二块硬盘上:

# installgrub -m /boot/grub/stage1 /boot/grub/stage2 /dev/rdsk/c8t1d0s0 
Updating master boot sector destroys existing boot managers (if any).
continue (y/n)?y

校验 pool

校验 pool 后查看校验后状态:

# zpool scrub rpool

# zpool status
  pool: rpool
 state: ONLINE
 scrub: scrub in progress for 0h0m, 0.95% done, 0h26m to go
config:

        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          c8t0d0s0  ONLINE       0     0     0
          c8t1d0s0  ONLINE       0     0     0

errors: No known data errors

ZFS 的简单使用

ZFS 被 Sun 称为史上最后一个文件系统,说得一点都不夸张,在 VPSee 看来 ZFS 至少要比现有的其他文件系统领先五年。开发一个全新的文件系统非常耗时,ext4 从2006开始到现在都三年了而且还是在前人的基础上(ext3)开发的,最近 RedHat 发布的 RHEL 5.4 还只是把 ext4 列入 technical preview 的状态,默认的安装文件系统还是 ext3,可见要开发一个可靠的文件系统多么困难,ext4 仍然不够稳定,在系统崩溃时某些条件下可能会造成数据丢失现象。虽然 ZFS 是开放源代码的,由于版权是 CDDL 与 Linux kernel 的 GPL2 冲突,导致 ZFS 不能移植到 Linux 上,FreeBSD 上的 ZFS 移植不完整而且不是很稳定,如果想用 ZFS 的话,建议安装和使用 OpenSolaris,以下操作在 OpenSolaris 2009.06 上执行。

准备工作

先创建6个普通文件充当6个硬盘,来看看 ZFS 是如何方便的添加、删除、镜像硬盘的:

# cd /var/tmp
# mkfile 100m c0d0 c0d1 c0d2 c1d0 c1d1 c1d2

创建 pool

使用第1块硬盘(c0d0)创建一个 pool:

# zpool create mypool /var/tmp/c0d0 
# zpool status
  pool: mypool
 state: ONLINE
 scrub: none requested
config:

        NAME             STATE     READ WRITE CKSUM
        mypool           ONLINE       0     0     0
          /var/tmp/c0d0  ONLINE       0     0     0

errors: No known data errors

创建镜像

在 pool 里添加第2块硬盘(c0d1),并且做成第1块硬盘(c0d0)的镜像:

# zpool attach mypool /var/tmp/c0d0 /var/tmp/c0d1
# zpool status
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Sun Nov  1 15:08:42 2009
config:

        NAME               STATE     READ WRITE CKSUM
        mypool             ONLINE       0     0     0
          mirror           ONLINE       0     0     0
            /var/tmp/c0d0  ONLINE       0     0     0
            /var/tmp/c0d1  ONLINE       0     0     0  73K resilvered

errors: No known data errors

替换硬盘

假设上面第2块硬盘(c0d1)坏了,想用另一块硬盘(c1d0)替换:

# zpool replace mypool /var/tmp/c0d1 /var/tmp/c1d0 
# zpool status
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Sun Nov  1 15:11:33 2009
config:

        NAME               STATE     READ WRITE CKSUM
        mypool             ONLINE       0     0     0
          mirror           ONLINE       0     0     0
            /var/tmp/c0d0  ONLINE       0     0     0
            /var/tmp/c1d0  ONLINE       0     0     0  83.5K resilvered

errors: No known data errors

增加硬盘

如果发现上面两块硬盘不够用了,想在 pool 里增加第3块硬盘(c0d1)只需要简单的 zpool add,这时候需要用到 -f 强制选项,因为 pool 里硬盘类型是 mirror 的,而想要增加的硬盘是 file 的,类型不同所以报错,需要强制执行:

# zpool add mypool /var/tmp/c0d1
invalid vdev specification
use '-f' to override the following errors:
mismatched replication level: pool uses mirror and new vdev is file

# zpool add -f mypool /var/tmp/c0d1
# zpool status
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Sun Nov  1 15:11:33 2009
config:

        NAME               STATE     READ WRITE CKSUM
        mypool             ONLINE       0     0     0
          mirror           ONLINE       0     0     0
            /var/tmp/c0d0  ONLINE       0     0     0
            /var/tmp/c1d0  ONLINE       0     0     0  83.5K resilvered
          /var/tmp/c0d1    ONLINE       0     0     0

errors: No known data errors

现在用第4块硬盘(c1d1)对第3块硬盘(c0d1)做一个镜像;然后加上第5块硬盘(c0d2)和第6块硬盘(c1d0),其中第6块是第5块的镜像:

# zpool attach mypool /var/tmp/c0d1 /var/tmp/c1d1
# zpool add mypool mirror /var/tmp/c0d2 /var/tmp/c1d2 

完成上面的操作以后就会得到类似下面这样的结构,很清晰易懂,c0d0 和 c1d0 是镜像,c0d1 和 c1d1 是镜像,c0d2 和 c1d2 是镜像:

# zpool status
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Sun Nov  1 15:24:51 2009
config:

        NAME               STATE     READ WRITE CKSUM
        mypool             ONLINE       0     0     0
          mirror           ONLINE       0     0     0
            /var/tmp/c0d0  ONLINE       0     0     0
            /var/tmp/c1d0  ONLINE       0     0     0
          mirror           ONLINE       0     0     0
            /var/tmp/c0d1  ONLINE       0     0     0
            /var/tmp/c1d1  ONLINE       0     0     0  14.5K resilvered
          mirror           ONLINE       0     0     0
            /var/tmp/c0d2  ONLINE       0     0     0
            /var/tmp/c1d2  ONLINE       0     0     0

errors: No known data errors

是不是要比 RAID + LVM + EXT3 简单多了?

校验 pool

最好经常时不时的用 zpool scrub 检查一下 pool 和 checksums:

# zpool scrub mypool

删除 pool

# zpool destroy mypool
# rm /var/tmp/c[01]d[012]

最小化安装 OpenSolaris 2009.06

opensolaris

OpenSolaris 有一些令其他系统羡慕的创新技术,比如:ZFS, DTrace, Containers, Crossbow 等。因为版权原因有些技术还不能直接移植到 Linux 上,Mac 已经在其新发行的 Mac OS X Snow Leopard 中应用了 DTrace,但是最近 Apple 突然关闭了 ZFS 项目并停止了对 ZFS 的支持,据外界猜测和 NetApp 的版权有关。OpenSolaris 的这些很酷的技术只有在服务器端才能发挥最大价值,但是感觉 OpenSolaris 面向的是桌面用户,我们在桌面已经有了 Mac OS X/Ubuntu/Windows 7,OpenSolaris 要想进入桌面市场难度很大,VPSee 一直认为 Sun 和 OpenSolaris 社区应该好好利用 Solaris 的强大技术优势把 OpenSolaris 的发展重点放在服务器端,特别是高端服务器。OpenSolaris 在安装过程中没有提供最小化安装选择,可定义的选项也很少,这里提供一种最小化安装 OpenSolaris 的方法,可供服务器安装。

安装系统

OpenSoaris 的安装很傻瓜,甚至比多数 Linux 版本还简单,只需按几下鼠标就可完成。

最小化

默认安装完的 OpenSolaris 是一个拥有丰富功能的全桌面系统,对于服务器来说太过庞大,很多服务、软件包、图形界面,Office 套件等都不需要,既占 CPU/RAM 资源又霸占硬盘。这里用一个 Immutable Service Container 项目提供的脚本来自动删除不必要的软件包和服务。首先下载这个脚本然后运行:

$ hg clone https://kenai.com/hg/isc~source isc

$ pfexec svcadm disable gdm
$ pfexec isc/opt/samples/minimization.ksh

运行脚本后会删除237个软件包停止11个服务,OpenSolaris 占据的硬盘空间由 2.92GB 减少到 1.28GB.

Troubleshooting

那个脚本可能删除了一些软件包关联和配置文件,导致系统会可能会出现一点小问题:1)DHCP 不停的得到 IP 释放 IP;2)DNS client 不能正确工作,可以 ping IP 但是不能 ping 域名。根据具体情况修改下面一些 OpenSolaris 网络设置。

使用静态 IP 地址:

$ pfexec vi /etc/nwam/llp
pcn0    172.16.38.10

$ pfexec svcadm restart nwam

检查 DNS 设置:

$ pfexec cp /etc/nsswitch.dns /etc/nsswitch.conf 
$ svcs -a | grep dns 

$ pfexec vi /etc/resolv.conf

检查 Routing:

$ pfexec vi /etc/defaultrouter
172.16.38.1

$pfexec svcadm restart network/routing-setup

Linux 下的推荐分区方案

调查了 Sun Ray 服务器的硬件配置要求以后,VPSee 开始着手安装一台新服务器,从别的项目组扒了一台 SUN Fire X2200,4核的 Quad-Core AMD Opteron Processor 2218 2.6GHz,8GB DDR2-667 ECC 内存,250GB SATA 2 的硬盘,没多余的硬盘做不了 RAID 10,先用1个硬盘凑合。这台机器只做 Sun Ray Server 不做别的,所以分区简单没有用更灵活的 LVM,服务器分区如下:

/boot (100MB)
boot 分区用来存放 Linux 内核,100MB 足够了。

/ (5GB)
root 分区用来存放系统主要文件、程序等。CentOS/RHEL 5 最小安装需要 3GB,全安装(安装所有包)需要 5GB,所以给 5GB 应该够了。

/var (5GB)
var 分区通常包括一些日志、临时文件、运行时目录等,推荐 3GB 以上,5GB 应该够了。

/home
home 分区包含所有用户的数据,需要最多的硬盘空间,剩下的空间都分给它。

swap
上个世纪的时候,VPSee 看过的几乎所有 Linux 系统管理的书上都推荐设置交换分区大小为内存的2倍。这些建议到了现在就是那么适用了,现在的服务器动不动就是 16GB/32GB 内存,难道相应的交换分区也要扩大到 32GB/64GB?根据 OpenBSD 的安装建议

Many people follow an old rule of thumb that your swap partition should be twice the size of your main system RAM. This rule is nonsense. On a modern system, that’s a LOT of swap, most people prefer that their systems never swap. You don’t want your system to ever run out of RAM+swap, but you usually would rather have enough RAM in the system so it doesn’t need to swap. If you are using a flash device for disk, you probably want no swap partition at all. Use what is appropriate for your needs.

再看看 RHEL 5 推荐的 swap 分区大小

Swap should equal 2x physical RAM for up to 2 GB of physical RAM, and then an additional 1x physical RAM for any amount above 2 GB, but never less than 32 MB. For systems with really large amounts of RAM (more than 32 GB) you can likely get away with a smaller swap partition (around 1x, or less, of physical RAM).

上面说的是一般情况,在安装系统的时候很难决定多大的交换空间,往往需要根据服务器实际负载、运行情况、以及未来可能应用来综合考虑 swap 分区的大小,所以这里参考推荐最小 swap 大小更实际一些:

  • 4GB 或 4GB 以下内存的系统,最小需要 2GB 交换空间;
  • 大于 4GB 而小于 16GB 内存的系统,最小需要 4GB 交换空间;
  • 大于 16GB 而小于 64GB 内存的系统,最小需要 8GB 交换空间;
  • 大于 64GB 而小于 256GB 内存的系统,最小需要 16GB 交换空间。

Linux 下给图片批量加水印

一个非盈利组织的项目负责人突发奇想想给他们网站上的每张照片加上水印,说实话那些照片都是平时活动、party 的生活照片用不着用水印那么夸张,第一次听说给生活照加水印的。没办法,谁让我们和他们有合作项目呢。还好他们服务器用的是 Linux,在 Linux 下给图片批量加水印简单多了,用 imagemagick + 一个小脚本搞定。

在 CentOS 下安装:

# yum install ImageMagick

在 Ubuntu 下安装:

$ sudo apt-get install imagemagick

先用画图工具制作好一个水印图片 watermark.jpg,然后执行 composite 命令把这个 watermark.jpg 水印加到图片 vpsee.jpg 上,-dissolve 15 是指 watermark.jpg 使用15%的透明附在原图上:

$ composite -gravity northeast -dissolve 15 watermark.jpg vpsee.jpg vpsee.jpg

要事先做个 watermark.jpg 好麻烦,有没有不用 watermark.jpg 直接加水印的方法?有,不过这种方法需要 Linux 系统上已经安装 True 字体(一般来说服务器都没有安装,不建议为了一个水印安装一个硕大的字体),以下命令把 vpsee.com 字符串加到 image.jpg 图片上:

$ mogrify -font /usr/share/fonts/truetype/thai/Purisa.ttf -pointsize 15 \
-verbose -draw "fill black text 5,23 'vpsee.com' \
fill orange text 6,24 'vpsee.com' " image.jpg

可以用下面的 shell script 对某个目录的所有图片加水印,需要注意的是处理带空白字符的文件名很麻烦,所以下面的脚本先处理空白字符,把包含空白字符的文件名用 “_” 字符替代,比如:image 1.jpg 替换成 image_1.jpg:

#!/bin/bash

echo "Image watermarking Script"
echo "http://www.vpsee.com"
echo ""

if [ $# -ne 2 ]
then
    echo "usage: ./watermark watermark.jpg picture_directory"
    echo ""
        exit
fi

MARK=$1
PICDIR=$2
for each in $PICDIR/*{.jpg,.jpeg,.png,.JPG,.JPEG,PNG}
do
    mv "$each" `echo $each | tr ' ' '_'`;
    composite -gravity northeast -dissolve 15.3 $MARK $each $each 2> /dev/null
    echo "$each: done!"
done
exit 0

imagemagick 的功能很强大,把上面脚本中的 composite 一行换成下面这行就成了批量给图片改大小了:

$ convert -resize 400 old_image.jpg new_image.jpg

如果想直接把原图改小,用新图片覆盖原图片的话:

$ convert -resize 400 image.jpg image.jpg

如何查看进程 IO 读写情况?

Linux Kernel 2.6.20 以上的内核支持进程 IO 统计,可以用类似 iotop 这样的工具来监测每个进程对 IO 操作的情况,就像用 top 来实时查看进程内存、CPU 等占用情况那样。但是对于 2.6.20 以下的 Linux 内核版本就没那么幸运了,根据 Stack Overflow 的这篇回帖 给出的方法,VPSee 写了一个简单的 Python 脚本用来在 linux kernel < 2.6.20 下打印进程 IO 状况。

Kernel < 2.6.20

这个脚本的想法很简单,把 dmesg 的结果重定向到一个文件后再解析出来,每隔1秒钟打印一次进程 IO 读写的统计信息,执行这个脚本需要 root:

#!/usr/bin/python
# Monitoring per-process disk I/O activity
# written by http://www.vpsee.com 

import sys, os, time, signal, re

class DiskIO:
    def __init__(self, pname=None, pid=None, reads=0, writes=0):
        self.pname = pname 
        self.pid = pid
        self.reads = 0
        self.writes = 0

def main():
    argc = len(sys.argv)
    if argc != 1:
        print "usage: ./iotop"
        sys.exit(0)

    if os.getuid() != 0:
        print "must be run as root"
        sys.exit(0)

    signal.signal(signal.SIGINT, signal_handler)
    os.system('echo 1 > /proc/sys/vm/block_dump')
    print "TASK              PID       READ      WRITE"
    while True:
        os.system('dmesg -c > /tmp/diskio.log')
        l = []  
        f = open('/tmp/diskio.log', 'r')
        line = f.readline()
        while line:
            m = re.match(\
                '^(\S+)\((\d+)\): (READ|WRITE) block (\d+) on (\S+)', line)
            if m != None:
                if not l:       
                    l.append(DiskIO(m.group(1), m.group(2)))
                    line = f.readline() 
                    continue            
                found = False   
                for item in l:  
                    if item.pid == m.group(2):
                        found = True            
                        if m.group(3) == "READ":
                            item.reads = item.reads + 1 
                        elif m.group(3) == "WRITE":
                            item.writes = item.writes + 1
                if not found:   
                    l.append(DiskIO(m.group(1), m.group(2)))
            line = f.readline()
        time.sleep(1)
        for item in l:
            print "%-10s %10s %10d %10d" % \
                (item.pname, item.pid, item.reads, item.writes)

def signal_handler(signal, frame):
    os.system('echo 0 > /proc/sys/vm/block_dump')
    sys.exit(0)

if __name__=="__main__":
    main()


继续阅读 »

CentOS 5 上配置 Trac 和 Git

git

VPSee 一直使用 Subversion 来管理自己和其他人的项目,甚至文档和资料也是通过 Subversion 来管理的。最近大家对 Subversion 抱怨变多,主要是因为慢,特别是 merge 速度很慢,checkout 也很慢,从本地局域网 checkout 有时候不到 20K 每秒,一直想找个机会换掉 Subversion。版本控制软件可选的不多,有名的就这么几个:CVS、Subversion、Arch、Bazaar、BitKeeper、Git。Git 是 Linus Torvalds 开发的一套版本控制系统,其初衷是用来替代 BitKeeper。经过一段时间的沉淀,现在 Git 终于开始步入主流,在开源项目里很受欢迎,Linux Kernel、Perl、Gnome、Ruby on Rails、Android、Fedora、Debian、X.org 等都是用 Git 来做版本控制的,Digg 最近也在考虑从 Subversion 移到 Git。Git 是分布式版本控制,与 Subversion 集中式控制不同,刚开始接触 Git 可能有点不适应,一旦熟悉以后就会发现 Git 特别方便,简单实用,而且速度超快。Trac 和 Subversion 组合起来很强大,通过 Git Plugin for Trac 插件 也可以把 Trac 和 Git 组合起来,而且还不需要额外的类似 Apache + mod_svn 的支持。

安装和使用 Git

安装过程很简单:

# yum install git

增加 Git 用户:

$ git config --global user.name "vpsee"
$ git config --global user.email "[email protected]"

创建一个项目目录,把所有想被版本控制的文件、目录拷贝进来:

$ mkdir myproject
$ cd myproject/


继续阅读 »

在 IBM TP600E 上运行 FreeBSD 7.1

如果非要挑个非 Mac 的话,那就只能是 Thinkpad 了,手上这台 IBM Thinkpad 600E 差不多陪了本人十年,历尽沧桑,最惨的时候可能就是拿它来垫桌子吃火锅了:),笔记本的质量能做成这样,已经服了~。新 Mac 被 LP 抢走后,少了台看信息的机器。昨天把这台不抱希望的本本拿出来点亮,居然还可以显示,光驱、硬盘可以用,除了电池以外其他基本正常,上面还跑着我 n 年前装的 FreeBSD 4.7,密码忘了进不去,重装 FreeBSD 7.1 算了。我打算做个架子把这台机器挂在办公桌旁边的墙上,当作监控用。这样抬头就可以看到各种信息,服务器断了、异常了、过载了就发警报提示。发张照片纪念一下 VPSee 的第一个10年本本:

ibm tp600e

FreeBSD 的安装过程这里就不提了,现在操作系统的安装程序都做得很傻瓜,没有什么问题。不过遇到几个硬件驱动问题需要编译内核解决。

配置内核

拷贝一个内核配置文件出来,然后在上面修改,除去不必要的 USB、不用的网卡、各类不需要的驱动,优化内核配置,最后加上 PCMCIA 网卡(3Com 3C589D)和声卡驱动:

# cp /usr/src/sys/i386/conf/GENERIC /usr/src/sys/i386/conf/TP600E
# vi /usr/src/sys/i386/conf/TP600E

# Display card support
device          agp             # support several AGP chipsets
options VESA
options SC_PIXEL_MODE
options SC_NORM_ATTR=(FG_GREEN|BG_BLACK)
options SC_NORM_REV_ATTR=(FG_YELLOW|BG_GREEN)
options SC_KERNEL_CONS_ATTR=(FG_RED|BG_BLACK)
options SC_KERNEL_CONS_REV_ATTR=(FG_BLACK|BG_RED)
device dpms # DPMS suspend & resume via VESA BIOS

# Sound card support
device          sound
device          snd_mss

# PCCARD (PCMCIA) support
# PCMCIA and cardbus bridge support
device          cbb             # cardbus (yenta) bridge
device          pccard          # PC Card (16-bit) bus
device          cardbus         # CardBus (32-bit) bus

# PCI Ethernet NICs that use the common MII bus controller code.
# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
device          miibus          # MII bus support

# ISA Ethernet NICs.  pccard NICs included.
device          ep              # Etherlink III based cards

编译、安装内核

编译和安装内核:

# cd /usr/src

# make buildkernel KERNCONF=TP600E
# make installkernel KERNCONF=TP600E

修改 /etc/rc.conf,加入下面几行后重启系统:

# vi /etc/rc.conf

allscreens_flags="-MODE_278"
pccard_enable="YES"
ifconfig_ep0="DHCP"
hald_enable="YES"
dbus_enable="YES"

# shutdown -r now

重启后,插入 PCMCIA 网卡报错,提示:

pccard0: Card has no functions

估计是不能正确映射内存的原因,加入下面一行就应该可以了:

# vi /boot/loader.conf:

hw.cbb.start_memory="0x20000000" 

# shutdown -r now

如果重启后 dhcp 没有得到 IP 地址,手动运行:

# dhclient

启动 X

startx 启动 X 失败,看日志发现没有找到 neomagic 模块,需要安装 neomagic 驱动(机器在防火墙后面,需要先设代理,然后换个支持 http 下载的 port location,FreeBSD 默认是 ftp 的 port,如果不想每次登录都设 proxy 就把它加到 .cshrc 里面去):

# setenv HTTP_PROXY http://squid.vpsee.com:3128/

# setenv PACKAGESITE http://ftp2.de.freebsd.org/pub/FreeBSD/ports/i386/
packages-7.1-release/

# cd /usr/ports/
# pkg_add -r -v x11-drivers/xf86-video-neomagic-1.2.2_1

安装一个小巧的 X 窗口管理器 Fluxbox:

# cd /usr/ports/
# pkg_add -r -v x11-wm/fluxbox-1.1.0.1_5

# vi ~/.xinitrc
exec xterm &
exec fluxbox

升级系统

下载和安装二进制 FreeBSD base:

# freebsd-update fetch
# freebsd-update install

下载和升级 FreeBSD ports:

# portsnap fetch
# portsnap extract

用 Cacti 监视 Linux 服务器

给每年的 hacker 大会提供网络支持是件很有挑战的事情,弄不好就会有 hacker 当场黑掉网络这种尴尬事情出现。看看刚刚过去的 Defcon 大会技术人员是怎么架设网络的,使用了哪些有趣的硬件和软件,这里有 图片报道:2009 Defcon 的网络图片报道:2008年 Defcon 的网络。Defcon 技术人员用 OpenBSD 做 Firewall 跑在 Xeon 服务器上,用 Cacti 监测流量。VPSee 一直都用 Nagios 来监测自己的多台服务器,对 Cacti 很好奇,今天刚好有时间安装试试看。

安装 Cacti

安装必要的软件包:

# yum install net-snmp-utils php-snmp net-snmp-libs
# yum install perl-rrdtool rrdtool

Cacti 官方网站下载 cacti-0.8.7e.tar.gz:

# tar zxvf cacti-0.8.7e.tar.gz
# mv cacti-0.8.7e /var/www/cacti

给 cacti 打补丁:

# wget http://www.cacti.net/downloads/patches/0.8.7e/cli_add_graph.patch
# wget http://www.cacti.net/downloads/patches/0.8.7e/snmp_invalid_response.patch
# wget http://www.cacti.net/downloads/patches/0.8.7e/template_duplication.patch
# wget http://www.cacti.net/downloads/patches/0.8.7e/fix_icmp_on_windows_iis_servers.patch
# wget http://www.cacti.net/downloads/patches/0.8.7e/cross_site_fix.patch
# patch -p1 -N < cli_add_graph.patch
# patch -p1 -N < cross_site_fix.patch
# patch -p1 -N < fix_icmp_on_windows_iis_servers.patch
# patch -p1 -N < snmp_invalid_response.patch
# patch -p1 -N < template_duplication.patch

配置 Cacti

创建 Cacti 需要的数据库:

# mysql -u root -p
mysql> CREATE DATABASE cacti;
mysql> GRANT ALL ON cacti.* TO vpsee@localhost IDENTIFIED BY 'password';
mysql> FLUSH privileges;

初始化 Cacti 数据库表:

# mysql -u vpsee -p cacti < /var/www/cacti/cacti.sql

修改 Cacti 配置文件以连接到上面的数据库:

继续阅读 »

Kill 某个用户的所有进程

在一台100多人使用的 SUN 服务器上经常发现有人滥用资源,平时用用就算了,到了交作业的时候100多号人同时登录使用,服务器明显迟缓,特别是实验室用的是瘦客户机,没硬盘,SUN 客户端需要从服务器装载系统镜像,而且编译、运行程序都要在服务器上完成。如果发现某个用户运行很多进程,并且进程还有子进程,怎么能方便的找出全部进程并 kill 掉呢?

ps -ef | grep ^username | cut -c 10-15 | xargs kill -9

把全部进程打印出来根据用户名过滤后找出全部进程号,然后逐行 kill 掉。xargs 就是用来把 cut 后的输出逐个以空白符分割后输给 kill。注意上面的 grep ^username 不能缺 ^,^username 表示从一行开始匹配 username,比如就可以避免匹配到 sshd: username@pts/0。不过尽管加了 ^,上面的代码仍然有个小 bug,如果恰好有个进程名和用户名完全一样怎么办?可以用 ps -u 找出所有与 username 相关的进程,然后 grep -v 过滤掉 PID 只剩下进程信息,然后逐行 kill 掉,如下:

ps -u username | grep -v PID | cut -c 0-5 | xargs kill -9

不过上面的命令还有个小问题就是如果 cut 的时候不小心 cut 多了或者 cut 少了怎么办?可以用 awk 过滤一列信息出来:

ps -u username | grep -v PID | awk '{print$1}'| xargs kill -9

上面的命令也可以在 Linux 上运行,不过在 Linux 下可以用更简单的 killall,Solaris 上没有 killall:

killall -u username

一个小小的命令行反反复复改了多次,更别说上百万行的代码了,写代码太容易引入 bug 了,这就是为什么测试这么重要的原因,我觉得程序员应该用50%的时间写代码,50%的时间测代码;测试员也应该用50%的时间测代码,50%的时间写工具来自动测试代码。