挖掘互联网的潜力,开发特别的系统
2009/09/17 18:47
91d2成立至今已经有3年有余,马上即将迎来中国60周年的大庆。
在这样的节日里,我仅代表管理层,来接受大家的意见。
活动名称:我给91把把脉
活动时间:9月8日-9月31日
活动内容:根据自己玩暗黑到现在的经验,结合91d2的实际情况,表达自己的意见、建议。对管理、服务器、论坛、网站版面进行深入的评价,指出自己道听途说或者亲身感受的事情,并提出您宝贵的意见。
参与办法:玩家只需要把自己的意见打出来,发送到maxwell@91d2.cn即可。
Maxwell静候您的意见!
在这样的节日里,我仅代表管理层,来接受大家的意见。
活动名称:我给91把把脉
活动时间:9月8日-9月31日
活动内容:根据自己玩暗黑到现在的经验,结合91d2的实际情况,表达自己的意见、建议。对管理、服务器、论坛、网站版面进行深入的评价,指出自己道听途说或者亲身感受的事情,并提出您宝贵的意见。
参与办法:玩家只需要把自己的意见打出来,发送到maxwell@91d2.cn即可。
Maxwell静候您的意见!
2009/07/23 16:12
单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。正是由于这个特点,单例对象通常作为程序中的存放配置信息的载体,因为它能保证其他对象读到一致的信息。例如在某个服务器程序中,该服务器的配置信息可能存放在数据库或文件中,这些配置数据由某个单例对象统一读取,服务进程中的其他对象如果要获取这些配置信息,只需访问该单例对象即可。这种方式极大地简化了在复杂环境下,尤其是多线程环境下的配置管理,但是随着应用场景的不同,也可能带来一些同步问题。
本文将探讨一下在多线程环境下,使用单例对象作配置信息管理时可能会带来的几个同步问题,并针对每个问题给出可选的解决办法。
问题描述
在多线程环境下,单例对象的同步问题主要体现在两个方面,单例对象的初始化和单例对象的属性更新。
本文描述的方法有如下假设:
1. 单例对象的属性(或成员变量)的获取,是通过单例对象的初始化实现的。也就是说,在单例对象初始化时,会从文件或数据库中读取最新的配置信息。
2. 其他对象不能直接改变单例对象的属性,单例对象属性的变化来源于配置文件或配置数据库数据的变化。
1.1 单例对象的初始化
首先,讨论一下单例对象的初始化同步。单例模式的通常处理方式是,在对象中有一个静态成员变量,其类型就是单例类型本身;如果该变量为null,则创建该单例类型的对象,并将该变量指向这个对象;如果该变量不为null,则直接使用该变量。
其过程如下面代码所示:
public class GlobalConfig {
private static GlobalConfig instance = null;
private Vector properties = null;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
public static GlobalConfig getInstance() {
if (instance == null) {
instance = new GlobalConfig();
}
return instance;
}
public Vector getProperties() {
return properties;
}
}
这种处理方式在单线程的模式下可以很好的运行;但是在多线程模式下,可能产生问题。如果第一个线程发现成员变量为null,准备创建对象;这是第二个线程同时也发现成员变量为null,也会创建新对象。这就会造成在一个JVM中有多个单例类型的实例。如果这个单例类型的成员变量在运行过程中变化,会造成多个单例类型实例的不一致,产生一些很奇怪的现象。例如,某服务进程通过检查单例对象的某个属性来停止多个线程服务,如果存在多个单例对象的实例,就会造成部分线程服务停止,部分线程服务不能停止的情况。
1.2 单例对象的属性更新
通常,为了实现配置信息的实时更新,会有一个线程不停检测配置文件或配置数据库的内容,一旦发现变化,就更新到单例对象的属性中。在更新这些信息的时候,很可能还会有其他线程正在读取这些信息,造成意想不到的后果。还是以通过单例对象属性停止线程服务为例,如果更新属性时读写不同步,可能访问该属性时这个属性正好为空(null),程序就会抛出异常。
解决方法
2.1 单例对象的初始化同步
对于初始化的同步,可以通过如下代码所采用的方式解决。
public class GlobalConfig {
private static GlobalConfig instance = null;
private Vector properties = null;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
private static synchronized void syncInit() {
if (instance == null) {
instance = new GlobalConfig();
}
}
public static GlobalConfig getInstance() {
if (instance == null) {
syncInit();
}
return instance;
}
public Vector getProperties() {
return properties;
}
}
这种处理方式虽然引入了同步代码,但是因为这段同步代码只会在最开始的时候执行一次或多次,所以对整个系统的性能不会有影响。
2.2 单例对象的属性更新同步
为了解决第2个问题,有两种方法:
1,参照读者/写者的处理方式
设置一个读计数器,每次读取配置信息前,将计数器加1,读完后将计数器减1.只有在读计数器为0时,才能更新数据,同时要阻塞所有读属性的调用。代码如下。
public class GlobalConfig {
private static GlobalConfig instance;
private Vector properties = null;
private boolean isUpdating = false;
private int readCount = 0;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
private static synchronized void syncInit() {
if (instance == null) {
instance = new GlobalConfig();
}
}
public static GlobalConfig getInstance() {
if (instance==null) {
syncInit();
}
return instance;
}
public synchronized void update(String p_data) {
syncUpdateIn();
//Update properties
}
private synchronized void syncUpdateIn() {
while (readCount > 0) {
try {
wait();
} catch (Exception e) {
}
}
}
private synchronized void syncReadIn() {
readCount++;
}
private synchronized void syncReadOut() {
readCount--;
notifyAll();
}
public Vector getProperties() {
syncReadIn();
//Process data
syncReadOut();
return properties;
}
}
2,采用"影子实例"的办法
具体说,就是在更新属性时,直接生成另一个单例对象实例,这个新生成的单例对象实例将从数据库或文件中读取最新的配置信息;然后将这些配置信息直接赋值给旧单例对象的属性。如下面代码所示。
public class GlobalConfig {
private static GlobalConfig instance = null;
private Vector properties = null;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
private static synchronized void syncInit() {
if (instance = null) {
instance = new GlobalConfig();
}
}
public static GlobalConfig getInstance() {
if (instance = null) {
syncInit();
}
return instance;
}
public Vector getProperties() {
return properties;
}
public void updateProperties() {
//Load updated configuration information by new a GlobalConfig object
GlobalConfig shadow = new GlobalConfig();
properties = shadow.getProperties();
}
}
注意:在更新方法中,通过生成新的GlobalConfig的实例,从文件或数据库中得到最新配置信息,并存放到properties属性中。
上面两个方法比较起来,第二个方法更好,首先,编程更简单;其次,没有那么多的同步操作,对性能的影响也不大。
本文将探讨一下在多线程环境下,使用单例对象作配置信息管理时可能会带来的几个同步问题,并针对每个问题给出可选的解决办法。
问题描述
在多线程环境下,单例对象的同步问题主要体现在两个方面,单例对象的初始化和单例对象的属性更新。
本文描述的方法有如下假设:
1. 单例对象的属性(或成员变量)的获取,是通过单例对象的初始化实现的。也就是说,在单例对象初始化时,会从文件或数据库中读取最新的配置信息。
2. 其他对象不能直接改变单例对象的属性,单例对象属性的变化来源于配置文件或配置数据库数据的变化。
1.1 单例对象的初始化
首先,讨论一下单例对象的初始化同步。单例模式的通常处理方式是,在对象中有一个静态成员变量,其类型就是单例类型本身;如果该变量为null,则创建该单例类型的对象,并将该变量指向这个对象;如果该变量不为null,则直接使用该变量。
其过程如下面代码所示:
public class GlobalConfig {
private static GlobalConfig instance = null;
private Vector properties = null;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
public static GlobalConfig getInstance() {
if (instance == null) {
instance = new GlobalConfig();
}
return instance;
}
public Vector getProperties() {
return properties;
}
}
这种处理方式在单线程的模式下可以很好的运行;但是在多线程模式下,可能产生问题。如果第一个线程发现成员变量为null,准备创建对象;这是第二个线程同时也发现成员变量为null,也会创建新对象。这就会造成在一个JVM中有多个单例类型的实例。如果这个单例类型的成员变量在运行过程中变化,会造成多个单例类型实例的不一致,产生一些很奇怪的现象。例如,某服务进程通过检查单例对象的某个属性来停止多个线程服务,如果存在多个单例对象的实例,就会造成部分线程服务停止,部分线程服务不能停止的情况。
1.2 单例对象的属性更新
通常,为了实现配置信息的实时更新,会有一个线程不停检测配置文件或配置数据库的内容,一旦发现变化,就更新到单例对象的属性中。在更新这些信息的时候,很可能还会有其他线程正在读取这些信息,造成意想不到的后果。还是以通过单例对象属性停止线程服务为例,如果更新属性时读写不同步,可能访问该属性时这个属性正好为空(null),程序就会抛出异常。
解决方法
2.1 单例对象的初始化同步
对于初始化的同步,可以通过如下代码所采用的方式解决。
public class GlobalConfig {
private static GlobalConfig instance = null;
private Vector properties = null;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
private static synchronized void syncInit() {
if (instance == null) {
instance = new GlobalConfig();
}
}
public static GlobalConfig getInstance() {
if (instance == null) {
syncInit();
}
return instance;
}
public Vector getProperties() {
return properties;
}
}
这种处理方式虽然引入了同步代码,但是因为这段同步代码只会在最开始的时候执行一次或多次,所以对整个系统的性能不会有影响。
2.2 单例对象的属性更新同步
为了解决第2个问题,有两种方法:
1,参照读者/写者的处理方式
设置一个读计数器,每次读取配置信息前,将计数器加1,读完后将计数器减1.只有在读计数器为0时,才能更新数据,同时要阻塞所有读属性的调用。代码如下。
public class GlobalConfig {
private static GlobalConfig instance;
private Vector properties = null;
private boolean isUpdating = false;
private int readCount = 0;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
private static synchronized void syncInit() {
if (instance == null) {
instance = new GlobalConfig();
}
}
public static GlobalConfig getInstance() {
if (instance==null) {
syncInit();
}
return instance;
}
public synchronized void update(String p_data) {
syncUpdateIn();
//Update properties
}
private synchronized void syncUpdateIn() {
while (readCount > 0) {
try {
wait();
} catch (Exception e) {
}
}
}
private synchronized void syncReadIn() {
readCount++;
}
private synchronized void syncReadOut() {
readCount--;
notifyAll();
}
public Vector getProperties() {
syncReadIn();
//Process data
syncReadOut();
return properties;
}
}
2,采用"影子实例"的办法
具体说,就是在更新属性时,直接生成另一个单例对象实例,这个新生成的单例对象实例将从数据库或文件中读取最新的配置信息;然后将这些配置信息直接赋值给旧单例对象的属性。如下面代码所示。
public class GlobalConfig {
private static GlobalConfig instance = null;
private Vector properties = null;
private GlobalConfig() {
//Load configuration information from DB or file
//Set values for properties
}
private static synchronized void syncInit() {
if (instance = null) {
instance = new GlobalConfig();
}
}
public static GlobalConfig getInstance() {
if (instance = null) {
syncInit();
}
return instance;
}
public Vector getProperties() {
return properties;
}
public void updateProperties() {
//Load updated configuration information by new a GlobalConfig object
GlobalConfig shadow = new GlobalConfig();
properties = shadow.getProperties();
}
}
注意:在更新方法中,通过生成新的GlobalConfig的实例,从文件或数据库中得到最新配置信息,并存放到properties属性中。
上面两个方法比较起来,第二个方法更好,首先,编程更简单;其次,没有那么多的同步操作,对性能的影响也不大。
2009/07/23 16:10
一台服务器 几乎所有网站打开网页 甚至HTML网页 都出现了
这种样式的代码 有的在头部 有的在尾部 部分杀毒软件打开会报毒
打开HTML或ASP PHP页面 在源码中怎么也找不到这段代码
分析原因
首先怀疑ARP挂马,用防ARP的工具又没有发现有arp欺骗
而且arp欺骗一般不会每次都被插入代码,而是时有时无
而且使用http://127.0.0.1 或者http://localhost 访问的时候也可以找到这段代码
arp欺骗的可能排除。
然后就想到可能是JS被篡改,或者是其它的包含文件,查找后没有发现被改的页面 连新建的HTML页面浏览的时候也会被插入这段代码,那就只能是通过IIS挂上去的了。
备份iis数据然后重装iis,代码消失,将备份的iis恢复,问题又来了。
仔细寻找,问题应该出在IIS的配置文件上,打开配置文件,没有发现那段代码。
那很有可能是调用了某个文件,这个怎么查啊,忽然想起了大名鼎鼎的Filemon
本地载了一个上传到服务器上,打开Filemon,数据太多了,过滤掉一些没有用的
只留下iis的进程,数据还是很多,看来服务器上的站点还是挺多人在访问的。
关掉所有站点,建了一个测试站点anky 目录为D:\www\ 在下面建了一个空白页面test.htm
访问一下这个页面代码被插进来了,再看一下Filemon 奇怪怎么读取C:\Inetpub\wwwroot\iisstart.htm
打开C:\Inetpub\wwwroot\iisstart.htm一看,里面就躺着
把代码删除了留空,访问test.htm 正常了,把C:\Inetpub\wwwroot\iisstart.htm删除了再访问
test.htm 出现 “读取数据页脚文件出错”问题就出这里了,看来是调用了
这个文件。
把C:\Inetpub\wwwroot\iisstart.htm清空就正常了,这样怎么行,解决问题当然要连根拔掉。
continue
有没有可能是扩展造成的,到扩展中检查了一遍全部都是正常的
当然 通过ISAPI 挂马的也是存在的
左想右想最后还是觉得配置文件有问题
打开配置文件,配置文件在%windir%\system32\inetsrv\MetaBase.xml
用记事本打开,查找iisstart.htm 找到一行,开始以为是默认站点,后来一想不对啊
默认站点都删除了,再仔细一看这句代码为
DefaultDocFooter="FILE:C:\Inetpub\wwwroot\iisstart.htm"
删除掉这一行,问题彻底解决了
这种样式的代码 有的在头部 有的在尾部 部分杀毒软件打开会报毒
打开HTML或ASP PHP页面 在源码中怎么也找不到这段代码
分析原因
首先怀疑ARP挂马,用防ARP的工具又没有发现有arp欺骗
而且arp欺骗一般不会每次都被插入代码,而是时有时无
而且使用http://127.0.0.1 或者http://localhost 访问的时候也可以找到这段代码
arp欺骗的可能排除。
然后就想到可能是JS被篡改,或者是其它的包含文件,查找后没有发现被改的页面 连新建的HTML页面浏览的时候也会被插入这段代码,那就只能是通过IIS挂上去的了。
备份iis数据然后重装iis,代码消失,将备份的iis恢复,问题又来了。
仔细寻找,问题应该出在IIS的配置文件上,打开配置文件,没有发现那段代码。
那很有可能是调用了某个文件,这个怎么查啊,忽然想起了大名鼎鼎的Filemon
本地载了一个上传到服务器上,打开Filemon,数据太多了,过滤掉一些没有用的
只留下iis的进程,数据还是很多,看来服务器上的站点还是挺多人在访问的。
关掉所有站点,建了一个测试站点anky 目录为D:\www\ 在下面建了一个空白页面test.htm
访问一下这个页面代码被插进来了,再看一下Filemon 奇怪怎么读取C:\Inetpub\wwwroot\iisstart.htm
打开C:\Inetpub\wwwroot\iisstart.htm一看,里面就躺着
把代码删除了留空,访问test.htm 正常了,把C:\Inetpub\wwwroot\iisstart.htm删除了再访问
test.htm 出现 “读取数据页脚文件出错”问题就出这里了,看来是调用了
这个文件。
把C:\Inetpub\wwwroot\iisstart.htm清空就正常了,这样怎么行,解决问题当然要连根拔掉。
continue
有没有可能是扩展造成的,到扩展中检查了一遍全部都是正常的
当然 通过ISAPI 挂马的也是存在的
左想右想最后还是觉得配置文件有问题
打开配置文件,配置文件在%windir%\system32\inetsrv\MetaBase.xml
用记事本打开,查找iisstart.htm 找到一行,开始以为是默认站点,后来一想不对啊
默认站点都删除了,再仔细一看这句代码为
DefaultDocFooter="FILE:C:\Inetpub\wwwroot\iisstart.htm"
删除掉这一行,问题彻底解决了
2009/07/14 20:29
介绍
XCache是一种新兴的php缓存器,经过本人测试,在Windows下效果比同类软件强很多。
实际测试效果如下(非科学方法):
原网页平均执行时间: 0.13 秒
加速后网页平均执行时间: 0.03秒
原CPU占用率: 15% - 60%
加速后CPU占用率: 3% - 30%
可以看出,使用这个加速器可以很大程度的降低CPU占用(但会造成更多的内存占用),并使网页执行时间缩短。具体原理不介绍了,网上有很多。
由于其他同类软件对Windows的支持不够好,所以选用XCache。
网上很多说明都不够详细,所以给大家写一篇。
安装与配置
首先下载XCache,网址为:
http://xcache.lighttpd.net...
需要下载跟你php版本匹配的binaries for Windows(怎么跟我名字一样……)。
下载后解压,把php_xcache.dll放在php.ini中指定extension_dir中。
下面开始配置,打开php.ini。
添加
zend_extension_ts = "($extension_dir)\php_xcache.dll"
(为什么不用extension,一会再说)
添加
[xcache.admin]
xcache.admin.enable_auth = Off
xcache.admin.user = "binarie"
xcache.admin.pass = "1234"
[xcache]
xcache.shm_scheme = "mmap"
xcache.size = 64M
xcache.count = 4
xcache.slots = 64K
xcache.ttl = 1800
xcache.gc_interval = 1800
xcache.var_size = 8M
xcache.var_count = 4
xcache.var_slots = 64K
xcache.var_ttl = 0
xcache.var_maxttl = 0
xcache.var_gc_interval = 300
xcache.test = Off
xcache.readonly_protection = Off
xcache.mmap_path = "xcache"
xcache.coredump_directory = ""
xcache.cacher = On
xcache.stat = Off
xcache.optimizer = Off
[xcache.coverager]
xcache.coverager = Off
xcache.coveragedump_directory = ""
需要修改的值已经用蓝色标出,说明如下:
xcache.admin.enable_auth XCache后台是否需要验证(这个后台在刚才下载的XCache的admin目录中,可以自由处理)
xcache.admin.user XCache后台登陆用户名
xcache.admin.pass XCache后台登陆密码
xcache.size XCache的内存缓存大小,普通网站建议设置为64MB,如果是IDC服务器,可以设置成256MB
xcache.count 设置为CPU的数量(双核算2个,比如我的是两个双核Xeon 3.0,就设置为4)
xcache.var_size
xcache.var_count 跟上两条一样
xcache.mmap_path 共享内存标识名,尽量用xcache,避免跟其它软件冲突
xcache.optimizer 优化器,如果没安装Zend可以开启。
至此配置完毕,重新启动IIS即可。
至于为什么不用extension,而用zend_extension_ts,
因为这个发行版的xcache的接口是ZEND_API,直接用extension无法初始化。
疑难解答
1、phpinfo()中显示没有加载php_xcache.dll
检查php_xcache.dll的NTFS权限是否正确,需要给网站用户(或者可以用Guests)只读权限。
2、出现php内存错误
使用了extension调用php_xcache.dll,请尝试使用zend_extension_ts。
3、打开网页没有响应,出现错误 Fatal error: [Zend Optimizer] Zend Optimizer *** is incompatible with XCache 1.2.2
这是因为安装了Zend导致,解决方法很简单,把调用php_xcache.dll的zend_extension_ts提到调用zend的前面。如:
zend_extension_manager.optimizer_ts="C:\Program Files\Zend\ZendOptimizer-3.3.0\lib\Optimizer-3.3.0"
zend_extension_ts="C:\php\ext\php_xcache.dll"
zend_extension_ts="C:\Program Files\Zend\ZendOptimizer-3.3.0\lib\ZendExtensionManager.dll"
XCache是一种新兴的php缓存器,经过本人测试,在Windows下效果比同类软件强很多。
实际测试效果如下(非科学方法):
原网页平均执行时间: 0.13 秒
加速后网页平均执行时间: 0.03秒
原CPU占用率: 15% - 60%
加速后CPU占用率: 3% - 30%
可以看出,使用这个加速器可以很大程度的降低CPU占用(但会造成更多的内存占用),并使网页执行时间缩短。具体原理不介绍了,网上有很多。
由于其他同类软件对Windows的支持不够好,所以选用XCache。
网上很多说明都不够详细,所以给大家写一篇。
安装与配置
首先下载XCache,网址为:
http://xcache.lighttpd.net...
需要下载跟你php版本匹配的binaries for Windows(怎么跟我名字一样……)。
下载后解压,把php_xcache.dll放在php.ini中指定extension_dir中。
下面开始配置,打开php.ini。
添加
zend_extension_ts = "($extension_dir)\php_xcache.dll"
(为什么不用extension,一会再说)
添加
[xcache.admin]
xcache.admin.enable_auth = Off
xcache.admin.user = "binarie"
xcache.admin.pass = "1234"
[xcache]
xcache.shm_scheme = "mmap"
xcache.size = 64M
xcache.count = 4
xcache.slots = 64K
xcache.ttl = 1800
xcache.gc_interval = 1800
xcache.var_size = 8M
xcache.var_count = 4
xcache.var_slots = 64K
xcache.var_ttl = 0
xcache.var_maxttl = 0
xcache.var_gc_interval = 300
xcache.test = Off
xcache.readonly_protection = Off
xcache.mmap_path = "xcache"
xcache.coredump_directory = ""
xcache.cacher = On
xcache.stat = Off
xcache.optimizer = Off
[xcache.coverager]
xcache.coverager = Off
xcache.coveragedump_directory = ""
需要修改的值已经用蓝色标出,说明如下:
xcache.admin.enable_auth XCache后台是否需要验证(这个后台在刚才下载的XCache的admin目录中,可以自由处理)
xcache.admin.user XCache后台登陆用户名
xcache.admin.pass XCache后台登陆密码
xcache.size XCache的内存缓存大小,普通网站建议设置为64MB,如果是IDC服务器,可以设置成256MB
xcache.count 设置为CPU的数量(双核算2个,比如我的是两个双核Xeon 3.0,就设置为4)
xcache.var_size
xcache.var_count 跟上两条一样
xcache.mmap_path 共享内存标识名,尽量用xcache,避免跟其它软件冲突
xcache.optimizer 优化器,如果没安装Zend可以开启。
至此配置完毕,重新启动IIS即可。
至于为什么不用extension,而用zend_extension_ts,
因为这个发行版的xcache的接口是ZEND_API,直接用extension无法初始化。
疑难解答
1、phpinfo()中显示没有加载php_xcache.dll
检查php_xcache.dll的NTFS权限是否正确,需要给网站用户(或者可以用Guests)只读权限。
2、出现php内存错误
使用了extension调用php_xcache.dll,请尝试使用zend_extension_ts。
3、打开网页没有响应,出现错误 Fatal error: [Zend Optimizer] Zend Optimizer *** is incompatible with XCache 1.2.2
这是因为安装了Zend导致,解决方法很简单,把调用php_xcache.dll的zend_extension_ts提到调用zend的前面。如:
zend_extension_manager.optimizer_ts="C:\Program Files\Zend\ZendOptimizer-3.3.0\lib\Optimizer-3.3.0"
zend_extension_ts="C:\php\ext\php_xcache.dll"
zend_extension_ts="C:\Program Files\Zend\ZendOptimizer-3.3.0\lib\ZendExtensionManager.dll"
2009/04/29 11:50
linux中,所有的设备都被表示为一个文件,
dd这个命令的作用是进行文件流的拷贝和转换,所以自然可以用来进行硬盘克隆。
方法如下:
将源盘与目标盘一同接到电脑上,启动linux,
确定源盘和目标盘的设备文件名(/dev/sd*或/dev/hd*),
执行命令:dd if=源盘 of=目标盘 conv=noerror,sync
完成后即可。
conv中参数的作用:
noerror
拷贝时遇到错误,则跳过,并继续执行
sync
拷贝时遇到错误,跳过此块可能导致后面的数据整体位置改变,加此参数可以用空数据填充目标文件中与错误块位置相同的部分,保证文件系统结构稳定。
dd这个命令的作用是进行文件流的拷贝和转换,所以自然可以用来进行硬盘克隆。
方法如下:
将源盘与目标盘一同接到电脑上,启动linux,
确定源盘和目标盘的设备文件名(/dev/sd*或/dev/hd*),
执行命令:dd if=源盘 of=目标盘 conv=noerror,sync
完成后即可。
conv中参数的作用:
noerror
拷贝时遇到错误,则跳过,并继续执行
sync
拷贝时遇到错误,跳过此块可能导致后面的数据整体位置改变,加此参数可以用空数据填充目标文件中与错误块位置相同的部分,保证文件系统结构稳定。
2009/04/20 20:18
团队项目:AzureDawn
AzureDawn是91D2暗黑战网的Web管理平台系统,整合了帐号注册、密码找回、卡号智能调节等功能。AzureDawn提供了一个Web2.0的用户界面,广泛应用Ajax技术。
此项目为目前处于测试阶段。
预览:http://app.91d2.cn/
AzureDawn是91D2暗黑战网的Web管理平台系统,整合了帐号注册、密码找回、卡号智能调节等功能。AzureDawn提供了一个Web2.0的用户界面,广泛应用Ajax技术。
此项目为目前处于测试阶段。
预览:http://app.91d2.cn/
2009/04/20 20:05





