Linux下的 Ghost---G4L

Posted in 未分类 on 08月 14th, 2007

    新硬盘到手,西数160G。

很早就计划让WINDOWS文件系统在我硬盘中消失了,此时不待,更待何时?Debian 4.0的安装也十分顺利,只是在安装Nvidia显示卡驱动碰到了点困难,最终还是解决了(在Debian 3中的kernel-headers在Debian 4中变为linux-haders)。

按以前的习惯,在配置好了DEBIAN后,一般都习惯用GHOST进行备份,GHOST能够备份ext3的文件系统,但是用来备份的目标文件系统格式却不识别ext3,以前的硬盘中有fat32分区,所以不存在什么问题,把备份文件放在fat32分区就可以了。

但是现在,系统中没有FAT32分区了,GHOST就行不通了(也没深究)。于是决定寻找一个专门用于LINUX系统的GHOST,结果就是------G4L!!!

下载地址:http://sourceforge.net/projects/g4l

下载下来的文件是ISO文件,可刻成盘使用。但60多兆的ISO刻录成盘怎么着都觉得亏了,于是搜到了重硬盘应到G4L的方法:

1.在G4L的ISO文件中提取出 bzImage20.1和ramdisk.gz放在你认为合适的位置,例如/boot下。

2.修改GRUB配置文件/boot/grub/menu.lst,指向上述文件,如下:

title G4L
root        (hd0,0)
kernel /boot/bzImage20.1 ramdisk_size=65536 root=/dev/ram0
initrd /boot/ramdisk.gz

3.重启电脑,此时在GRUB菜单中就可以选G4L了。

OK,进入后按提示一步一步来吧!

安装 win 2003造成Grub丢失无法启动Debian的补救方法

Posted in 操作系统 on 12月 8th, 2006

一时无聊装了个2003,本来打算装Ghost 版的,省得要重建Grub,无奈寻觅未果,只好找了个安装版的2003。

可是用Rescuse重建Grub后无法启动Debian,提示找不到根分区。原来2003不但把我的分区表给改了,原来在hda3的Debian分区现在变为了hda2.但在/boot/grub/menu.lst和/etc/fstab中依然时hda3.

解决方法:

在Grub提示符下指定boot分区,进入系统后修改menu.lst和fstab

grub>root (hd0,*) /*你的root分区所在的分区号,如果分区只分了/,那么就是 /的分区号*/

grub>kernel /vmlinuz-* ro root=/dev/hda* /* vmlinuz是你的系统内核文件,可以 用tab键来自动补

齐,root=/dev/hda*是/分区的分区号,注意 hd0,*的方式和hda*的方式稍有不同,hd0,0对应hda1,其

余类 推。ro是read only的意思,以只读的方式加载内核 */ grub>initrd /initrd-* /*根目录镜像文件,用

于加载不是ext2格式的根分区,如果你的 /是ext3或其他类型,那么最好写上。同样可以用tab补齐*/

grub>boot

Macbook or Thinkpad?

Posted in 未分类 on 10月 2nd, 2006

原来一直认为如果我有点钱能买本本,首选肯定是apple,可是今天陪仪逛了下笔记本市场后,发现多了个竞争对手了——-IBM ThinkPad.可以说是两种截然不同的风格,一个流线型,一个正正规的方块,一个精致无比,一个粗况而有质感。IBM的东西(虽然现在归联想)看起来的确是男性气息十足,一摸就有种心里时分踏实的感觉.但两者也据有让然不爽的共同点:贵!时分贵!也不知道毕业后要攒多久的钱啊。

唉,还得慢慢意淫那。。。

DEBIAN下安装Oracle 10g备忘

Posted in 服务器架设 on 09月 25th, 2006

今天终于绝定了在DEBIAN下装个ORACLE玩玩,还算顺利,在这留个底。

Oracle 10g下载地址:

Oracle 10g

选取合式的版本

Oracle 对系统的基本要求是至少512MB内存,1G交换分区。我的机子内存只有256MB,

也凑或着装了上1去,当然,交换分区势必是要增加一点了

第一步:增加交换分区

有两种方法,1.重新从硬盘分一部分交换分区出来; 2.指定一个文件为SWAP

选择后者会好一点,因为风险几乎为0

$ grep SwapTotal /proc/meminfo //查看目前交换分区的大小

$ dd if=/dev/zero of=/mnt/swapfile bs=1024 count=1048576 //创建一个

1G的swap 文件在/mnt目录

$ mkswap /mnt/swapfile

$ swapon /mnt/swapfile

第二步:安装所需的依赖包

要安装ORACLE先确定系统安装了以下软件包

gcc make binutils libmotif3 lesstif2 rpm libaio1

可以通过apt-get 来安装

apt-get install gcc make binutils libmotif3 lesstif2 rpm libaio1

注意:如果你的DEBIAN用的是stable版,通过APT-GET可能无法安装libaio1,你需要

到debian的网站下载unstable版libaio1的deb包到本机安装

下载地址:http://packages.debian.org/unstable/libs/libaio1

$dpkg -i libaio1_0.3.106-2_i386.deb

第三步:配置系统基本参数

由于Oracle 10g在LINUX下的版本没有面向DEBIAN的 ,好像只有面向redhat as 和

SUSE的。所以我们需要配置DEBIAN的参数使它看起来象red hat(当让你也可以选择

 oracle xe,它有DE的版本)

$ ln -s /usr/bin/awk /bin/awk

$ ln -s /usr/bin/rpm /bin/rpm

$ ln -s /usr/bin/basename /bin/basename

$ ln -s /etc /etc/rc.d

新建/etc/redhat-release 添加如下内容

Red Hat Linux release 4.1

第四步:新建ORACLE用户组

使用下面的命令新建Oracle的组和用户

$ /usr/sbin/groupadd oinstall

$ /usr/sbin/groupadd dba

$ /usr/sbin/groupadd nobody

$ /usr/sbin/useradd -c “Oracle software owner” -g oinstall -G dba -d /opt/oracle oracle

$password oracle

输入oracle密码

$ /usr/sbin/useradd -g nobody nobody

新建Oracle安装目录并设置权限,假设为/opt/oracle
$ mkdir /opt/oracle

$ chown -R oralce.oinstall /opt/oracle

$ chmod -R 775 /opt/oracle

第五步:配置系统内核参数

打开/etc/sysctl.conf ,增加如下部分

kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000

执行/sbin/sysctl -p使修改生效

在/etc/security/limits.conf 中增加如下内容

 soft    nproc   2047
 hard    nproc   16384
 soft    nofile  1024
 hard    nofile  65536

在/etc/profile 中增加如下内容

if [ $USER = "oracle" ];
then       if [ $SHELL = "/bin/ksh" ];
then             ulimit -p 16384             ulimit -n 65536
else             ulimit -u 16384 -n 65536
fi
fi

切换到oracle用户

$ su oracle

将下面这行加入~/.bash_profile 中

umask 022

设置环境变量

ORACLE_BASE=/u01/app/oracle
ORACLE_SID=test export
ORACLE_BASE ORACLE_SID
unset ORACLE_HOME
unset TNS_ADMIN

第六步:开始安装Oracle

以ROOT身份解压ORACLE压缩包后执行

$ xhost + $ su oracle

进入解压目录,执行安装程序

$ ./runInstaller
如过不出什么意外的话,就能看到图形安装界面了

如果图形界面出不来,提示x DISPLAY错误

则在安装前先执行

$export DISPLAY=”:0.0″

安装完成后,就可以进入bin目录执行dbca进行数据库的一些基本配置了

附录 (来自http://www.oracle.com)

 

使用 SQL*Plus 访问数据库

以 oracle 身份登录到 Linux。设置环境。

设置 Oracle 环境变量:

$ export ORACLE_BASE=/u01/app/oracle
$ export ORACLE_SID=demo1
$ export ORACLE_HOME=$ORACLE_BASE/product/10.1.0/db_1
$ export PATH=$PATH:$ORACLE_HOME/bin

运行 SQL*Plus:

$ sqlplus  使用 Oracle Enterprise Manager 10g 数据库控制

在 Web 浏览器中,连接到安装过程中提供的 URL。

例如:
http://ds1.orademo.org:5500/em(如果服务器不在 DNS 中,则必须使用 IP

地址代替主机名。)

用户名:SYS
口令:
连接为:SYSDBA
单击

图 6

欢迎走入 Oracle Enterprise Manager 10g 数据库控制的精彩世界!

启动和停止 Oracle Enterprise Manager 数据库控制:

$ emctl start dbconsole $ emctl stop dbconsole

使用 iSQL*Plus 访问数据库

iSQL*Plus 是历史悠久的 SQL*Plus 交互式工具的基于 Web 的版本,用于访问数据库。

要使用 iSQL*Plus,请单击 OEM 控制台 Related Links 部分中的 iSQL*Plus 链接,或

将浏览器指向安装过程中提供的 iSQL*Plus URL。

例如:
http://ds1.orademo.org:5560/isqlplus(如果数据库服务器不在 DNS 中,则必须使用

IP 地址代替主机名。)

用户名:SYSTEM
口令:

单击 。

在 Workspace 框中输入 SQL 命令,然后单击 Execute

图 7

启动和停止 iSQL*Plus:

$ isqlplusctl start $ isqlplusctl stop

启动和停止监听器:

监听器接受客户端的连接请求,并在验证证书后创建数据库连接。要使用 OEM 或 iSQL*Plus,必须先启动监听器。

$ lsnrctl start $ lsnrctl stop

启动和停止数据库:

启动和停止数据库的最简单方法是从 OEM 控制台启动和停止。要从命令行执行此操作,请在以 oracle 身份登录后使用 SQL*Plus,如下所示:

启动:

$ sqlplus  Shutdown:
$ sqlplus  SQL*Plus:
列出 Oracle 进程:
$ ps a€“fuoracle

 

WordPress多用户版,选择WordPress mu还是lyceum?

Posted in 服务器架设 on 06月 27th, 2006

两个都 装了一下,配置起来都很快.相对而言lyceum可能会麻烦一点,但只要仔细按照其中的安装说明来做,都不会有什么大问题.

WPMU是Wordpress的官方多用户版本,与wordpress的插件兼容性肯定是相对要好很多的,它采用每个用户都使用自己表结构的方式,某种意义上可以说隔离了不同的用户的数据库(不过看一些E文网站好象说LYCEUM对插件的支持更好).经管在整体上是一个多用户版本,但实际上可以说是每个用户拥有了一个独立的数据库.而且,既然是官方版本,以后的升级和兼容肯定是有保障的.

Lyceum的数据库结构刚好相反,采用共用表结构的方式,这种方式其实才是比较符合多用户BLOG系统的常规思路的.虽然Lyceum是基于wordpress的,但要实现这样的结构必然要对wordpress的数据库语句进行修改.对于一些需要用到数据库操作的插件估计就要面临兼容性的整合了.而且Lyceum现在好象就是一个人在开发,会不会某天就停止开发真是说不定.系统的升级可能也会面令问题,还好最新的Lyecum提供升级了.

可是,我最终还是选择了Lyceum,就是因为它的数据库结构.由于它的表结构很简捷和固定,对于我们这样玩友是最方便的.

而WPMU为每一位用户都提供一套表.先看看下面的这个只有三个用户的WPMU表和生成的文件

如果以后有新用户增加,数据表和文件还将以9的步长增加!

如果有5000个用户,那就会有近50000张表和文件!

再比较下Lyceum的表和文件.

Lyceum的表和文件的个数是故定的,虽然大小会变化,但个数不会变化.

既然是多用户BLOG,最终要的当然就是当用户达到一定数量时的系统性能问题,两者都采用WordPress的缓存技术,其实比较的关键就是在于数据库的性能了.Lyceum由于采用的是用户共用表的结构,那么当用户数量很多的时候,单个表的数据量是很大的,单表查询的耗时肯定也会很大.而WordPress虽然采用的是每个用户使用独立的表,降低了表内查询的时间,但代价是表的个数大幅度增加,却又大幅增加了文件系统的寻表时间!两者性能究竟谁更好,不做时间的抗压测试还真是不好判断.

我觉得 WordPress的设计师采用这样的数据库构架是有他的原因的.当面对海量的用户访问时,服务器的硬件将成为很大的问题.通常的做法就是负载均衡,比如对数据库的访问.当一台数据库服务器无法满足要求时候,通常采用多台数据库服务器,里面的数据操作采用同步操作,每台机子都是对等的,网站对数据库的访问采用轮循的方式.但是,对数据库群里的单独一台机子而言,同样还是存在瓶颈.因为负载均衡虽然能够减低对每台机子的访问次数,但是却不能减少当访问某一台机子时的操作时间.因为每台机子里数据库的庞大数据项还是在那里的,例如假设Lyceum中有5000000篇文章,它们全都放在一张表里.而由于WPMU采用得是分离表结构,那么就可以很轻易得分配用户的表(资料和文章)到不同的机器上去,每台机子上可能只分配50000篇文章.对每台机器而言,数据库的操作速度就上来了.

这些东西就涉及到服务器的集群技术了,对于没有强大的技术支持和硬件支持的玩友,还是推荐Lyceum.毕竟 简单的表结构更便于自己掌握!

单点登录(SSO)的实现—通行证的基本原理

Posted in 编程知识 on 05月 26th, 2006

问题起源:想做一个面向校园的网站,因为势单力薄。部分模块采用整合其它开源系统的方案,比如BBS系统和BLOG系统。首先面临的就是用户身份认证的方式。由于这些不是自己开发的系统,都分别有自己的用户系统,于是面临统一身份认证的过程。

以前看过企业级的Web service方案,主要是通过XML,SOAP,WSDL和UDDI来实现。将应用服务都注册到UDDI服务器中,通过SOAP协议使用XML传递信息(当然需经过加密)。由于涉及到很多服务部署的问题,用JAVA来做这样的项目肯定是再好不过的了。我的目的只是几个WEB系统的整合,肯定是要排除这么伟大的方案了。关于Web service有兴趣的朋友可以参考机械工业出版社出版的《Web Servides原理与研发实践》,里面有详细的介绍。

那么对于这样的 小WEB系统的整合该怎么来实现?我们假设这是个从零开始的项目,除了自己开发的系统外,还要用到一些其它组织开发的开源系统:比如BLOG,CMS,BBS。这些系统都有各自的用户系统。要把他们整合到一块有个原则,就是尽量不要破坏或者修改这些系统。那么要实现统一身份认证,我们必须要有一个用户信息库,然后吧这个数据库的信息映射到那些子系统的数据库中,在大型项目中,一般都会独立出一台单独的用户信息服务器,大部分高校采用LDAP来存放用户信息,因为采用的是树状结构,对经常读取但很少修改的数据而言,它的性能是很高的。

LDAP用户库和 各子系统用户库的映射有很多种方法,我这里只用最简单的直接映射,也就是帐号和密码都是相同的。

假设我的域名部署如下

http://news.domain.com 这是CMS系统的域名

http://bbs.domain.com 这是论坛的域名

http://blog.domain.com 这是博客域名

http://reg.domain.com 这是统一注册和登录页面的域名
首先是注册,我们让所有子系统注册页面都转向到一个注册页面上来(各种脚本语言都有转向函数),比如说当用户希望在http://blog.domain.com/reg.php注册是,reg.php把这个请求转向到http://reg.domain.com/reg.php.

在实现注册时,由于刚开始时候子系统并不多,注册时把用户注册信息写入主用户数据库的同时写入各子系统的用户库。以后若有新的子系统加入进来时可以通过帐号激活的方式来实现新系统的帐号激活。

用户登录的过程,可以参考如下来自IBM的图片

流程描述如下:(仅描述正常流程)

1. 用户使用在统一认证服务注册的用户名和密码(也可能是其他的授权信息,比如数字签名等)登陆统一认证服务;

2. 统一认证服务创建了一个会话,同时将与该会话关联的访问认证令牌返回给用户;

3. 用户使用这个访问认证令牌访问某个支持统一身份认证服务的应用系统;

4. 该应用系统将访问认证令牌传入统一身份认证服务,认证访问认证令牌的有效性;

5. 统一身份认证服务确认认证令牌的有效性;

6. 应用系统接收访问,并返回访问结果,如果需要提高访问效率的话,应用系统可选择返回其自身的认证令牌已使得用户之后可以使用这个私有令牌持续访问。

上面所说的令牌我在WEB引用中可以用COOKIE或者SEESION来实现。

例如通过COOKIE来实现

1.用户在统一登录页登陆,通过查询主用户数据库判断用户是否合法,若是,则注册该用户的唯一COOKIE标识(可以通过加密用户名和密码得到,网上有很多算法)。

2.用户进入某子系统时,先判断COOKIE是否注册,若注册了 ,则解密该COOKIE得到用户名和帐号,并判断合法性。

3.如果合法,则立刻在该子系统中注册(可在原子系统的登录脚本种抽出登录的部分做成一个函数)

使用COOKIE的优点就是简单,只要设置一下就可以实现COOKIE的跨子域传递

例如

setcookie(NC_USER_COOKIE, 用户名, 失效时间, 作用路径, ‘.domain.com’);

就能实现在所有.domain.com子域下的传递。

但COOKIE也有他的缺点,首先就是安全级别不高,要提防COOKIE劫持的威胁,其次就是它只能跨子域传递,而不能跨完全不同的域。比如说domain.com和fuck.com之间就不能传递。

然后再说下SESSION的方式,由于SESSION是存储在服务器端的,所以安全级别肯定要比COOKIE的级别高。但是由于SEESION存储的位置不同,造成了无法跨域传递 。可以通过把SEESION村入数据库来解决这个问题。

由于PHP的SESSION需要用到标识SESSION的COOKIE,所以需要设置下COOKIE的作用域

ini_set(’session.cookie_domain’, ‘.domian.com’);

然后重写PHP的SESSION操作函数。

PHP 提供了session_set_save_handle() 函数来自定义 SESSION 的处理过程,先将 session.save_handler 改成 user

session_module_name(‘user’);

然后几可以重写SESSION的操作了,下面是PHP牛人NIO写的SESSION操作

define(‘MY_SESS_TIME’, 3600);   //SESSION 生存时长
//类定义
class My_Sess
{
    function init()
    {
        $domain = ‘.infor96.com’;
        //不使用 GET/POST 变量方式
        ini_set(’session.use_trans_sid’,    0);
        //设置垃圾回收最大生存时间
        ini_set(’session.gc_maxlifetime’,   MY_SESS_TIME);

        //使用 COOKIE 保存 SESSION ID 的方式
        ini_set(’session.use_cookies’,      1);
        ini_set(’session.cookie_path’,      ‘/’);
        //多主机共享保存 SESSION ID 的 COOKIE
        ini_set(’session.cookie_domain’,    $domain);

        //将 session.save_handler 设置为 user,而不是默认的 files
        session_module_name(‘user’);
        //定义 SESSION 各项操作所对应的方法名:
        session_set_save_handler(
            array(‘My_Sess’, ‘open’),   //对应于静态方法 My_Sess::open(),下同。
            array(‘My_Sess’, ‘close’),
            array(‘My_Sess’, ‘read’),
            array(‘My_Sess’, ‘write’),
            array(‘My_Sess’, ‘destroy’),
            array(‘My_Sess’, ‘gc’)
        );
    }   //end function

    function open($save_path, $session_name) {
        return true;
    }   //end function

    function close() {
        global $MY_SESS_CONN;

        if ($MY_SESS_CONN) {    //关闭数据库连接
            $MY_SESS_CONN->Close();
        }
        return true;
    }   //end function

    function read($sesskey) {
        global $MY_SESS_CONN;

        $sql = ‘SELECT data FROM sess WHERE sesskey=’ . $MY_SESS_CONN->qstr($sesskey) . ‘ AND expiry>=’ . time();
        $rs =& $MY_SESS_CONN->Execute($sql);
        if ($rs) {
            if ($rs->EOF) {
                return ‘’;
            } else {    //读取到对应于 SESSION ID 的 SESSION 数据
                $v = $rs->fields[0];
                $rs->Close();
                return $v;
            }   //end if
        }   //end if
        return ‘’;
    }   //end function

    function write($sesskey, $data) {
        global $MY_SESS_CONN;
        
        $qkey = $MY_SESS_CONN->qstr($sesskey);
        $expiry = time() + My_SESS_TIME;    //设置过期时间
        
        //写入 SESSION
        $arr = array(
            ’sesskey’ => $qkey,
            ‘expiry’  => $expiry,
            ‘data’    => $data);
        $MY_SESS_CONN->Replace(’sess’, $arr, ’sesskey’, $autoQuote = true);
        return true;
    }   //end function

    function destroy($sesskey) {
        global $MY_SESS_CONN;

        $sql = ‘DELETE FROM sess WHERE sesskey=’ . $MY_SESS_CONN->qstr($sesskey);
        $rs =& $MY_SESS_CONN->Execute($sql);
        return true;
    }   //end function

    function gc($maxlifetime = null) {
        global $MY_SESS_CONN;

        $sql = ‘DELETE FROM sess WHERE expiry. time();
        $MY_SESS_CONN->Execute($sql);
        //由于经常性的对表 sess 做删除操作,容易产生碎片,
        //所以在垃圾回收中对该表进行优化操作。
        $sql = ‘OPTIMIZE TABLE sess’;
        $MY_SESS_CONN->Execute($sql);
        return true;
    }   //end function
}   ///:~

//使用 ADOdb 作为数据库抽象层。
require_once(‘adodb/adodb.inc.php’);
//数据库配置项,可放入配置文件中(如:config.inc.php)。
$db_type = ‘mysql’;
$db_host = ‘192.168.212.1′;
$db_user = ’sess_user’;
$db_pass = ’sess_pass’;
$db_name = ’sess_db’;
//创建数据库连接,这是一个全局变量。
$GLOBALS[‘MY_SESS_CONN’] =& ADONewConnection($db_type);
$GLOBALS[‘MY_SESS_CONN’]->Connect( $db_host, $db_user, $db_pass, $db_name);
//初始化 SESSION 设置,必须在 session_start() 之前运行!!
My_Sess::init();

基本的原理差不多就这样,细节方面就看还有很多需要琢磨的地方..