Mac OS 升到Yosemite后, 打开 Android Studio报
1 2 |
Symbol not found: _CGContextSetAllowsAcceleration Referenced from: /Library/Java/JavaVirtualMachines/1.6.0_35-b10-428.jdk/Contents/Libraries/libawt.jnilib |
最近发现网站总是被电信恶意添加了广告,导致链接总是各种异常,因此打算开启HTTPS来规避这种情况。本来以为很简单的,结果发现网上的各种不靠谱。
1.启用Apache自带的SSL模块
1 |
sudo a2enmod ssl |
2.激活Apache对于HTTPS的支持
1 |
sudo a2ensite default-ssl |
这一步骤其实就是把/etc/apache2/sites-available/default-ssl拷贝到了 /etc/apache2/sites-enabled/default-ssl,并且更改了一下文件权限
如果要取消对于HTTPS的支持 可以执行
1 |
sudo a2dissite default-ssl |
或者
1 |
sudo rm -rf /etc/apache2/sites-enabled/default-ssl |
3.强制Apache2 刷新配置
1 |
sudo service apache2 reload |
或者
1 |
sudo service apache2 restart |
这样便开启了Apache2 的HTTPS支持,此时输入https://www.mobibrw.com/就可以正常访问了。
但是此时使用的证书是在 /etc/apache2/sites-enabled/default-ssl中配置的默认的证书文件,内容如下:
1 2 3 4 5 6 7 8 |
# A self-signed (snakeoil) certificate can be created by installing # the ssl-cert package. See # /usr/share/doc/apache2.2-common/README.Debian.gz for more info. # If both key and certificate are stored in the same file, only the # SSLCertificateFile directive is needed. SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key |
如果要替换成自己的证书文件,只要修改 SSLCertificateFile
跟SSLCertificateKeyFile
就可以了。
上面使用的例子的证书格式是.pem
格式的,如果是.csr
格式的只要是Base64
编码格式的(记事本打开之后,首行是"-----BEGIN CERTIFICATE-----
"),跟上面的例子相同,直接设置就可以了。以申请到的沃通的免费证书为例子:
申请完成后的证书ZIP文件中有一个for Apache.zip的压缩包,解压缩之后,上传到服务器,然后直接如下设置就可以了:
1 2 3 4 5 6 7 8 |
# A self-signed (snakeoil) certificate can be created by installing # the ssl-cert package. See # /usr/share/doc/apache2.2-common/README.Debian.gz for more info. # If both key and certificate are stored in the same file, only the # SSLCertificateFile directive is needed. SSLCertificateFile /etc/apache2/certs/wosign.csr SSLCertificateKeyFile /etc/apache2/certs/wosign.key |
至于其他的配置,跟/etc/apache2/sites-enabled/000-default中的一致就可以了。
安装 Ubuntu 等 Linux 发行版之后,开机后会出现 Grub 启动菜单用于选择需要进入的操作系统。如果我们需要对 Grub 启动菜单进行修改,除了传统的修改文本配置文件的方法之外,还可以使用图形设置工具 Grub Customizer 进行设置。
Grub Customizer 可以通过 PPA 安装,启动终端依次输入以下命令即可:
1 2 3 |
sudo add-apt-repository ppa:danielrichter2007/grub-customizer sudo apt-get update sudo apt-get install grub-customizer |
启动 Grub Customizer,主界面如下图所示:
在 Grub Customizer 的主界面中,我们可以调整启动项的位置(使用工具栏的向上向下箭头按钮),还可以通过启动项前的复选框控制该启动项是否可见,我们可以通过这种方法隐藏多 余的 Linux 内核选项。如果去除某一类别中“新条目”的复选框,还可以“冻结”该类别,自动探测的新条目将不会被添加到这一类别。
点击工具栏的“首选项”按钮,在此我们可以对 Grub 启动菜单进行进一步定制。
首先是常规标签页,在此我们可以设置 Grub 启动菜单的默认启动项、是否显示菜单、等待时间等等。
然后是外观标签页,在此对 Grub 启动菜单的外观进行定制,如调整分辨率、设置背景等等。
最后是高级标签页,如果你不了解这些选项的意义,请不要随便修改。
设置完成之后记得点击工具栏的“保存”按钮保存设置。
WD MyCloud中,有时候我们需要某些服务随着开机而启动,而且,我们不希望我们手工添加进去的服务如果不能正常启动,导致系统启动异常。因此,我们把这个放到系统服务启动的最后一句最好了,在WD MyCloud中,应该如下修改
1 |
$ vim /etc/init.d/wdInitFinalize |
我们可以看到,文件最后附近,有如下语句
1 2 3 4 5 6 7 8 9 |
log_action_msg "NAS Init Completed==================" if [ -f ${MINIMAL_TRIGGER} ]; then changeRunLevel.pl --level=minimal & else ## switch to App run-level by default changeRunLevel.pl --level=app & fi exit 0 |
把系统的启动服务,放到这些的后面,exit语句的前面。
以启动subversion为例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
log_action_msg "NAS Init Completed==================" if [ -f ${MINIMAL_TRIGGER} ]; then changeRunLevel.pl --level=minimal & else ## switch to App run-level by default changeRunLevel.pl --level=app & fi #如果SVN的项目路径中存在中文,则需要如下的export设置 #svn: E210005: No repository found export LC_ALL="zh_CN.utf8" svnserve -d -r /nfs/MyCloud/.Repositories/ exit 0 |
最近小米2 总是报告系统空间不足,一般的应用的安装,升级都搞不定了,网上搜索了一下,找到了无损分区的调整办法,本文对于步骤进行了精简,原文有些过于繁琐了。
1.下载Mi2 Repartition 解压到“C:\Mi2 Repartition”下(D盘也可以)。其中含Android命令行工具、WinHex十六进制编辑软件、userdata分区挂载可使用空间调整工具resize_data,以及处理过程中的backup备份文件夹。(精简了DiskGenius,因为实际上是用不到的,原文过于折腾了)
2.下载高通 Qualcomm HS-USB QDLoader设备驱动 Qualcomm_HS-USB_QDLoader_Driver 之所以不用小米的 MiFlash ,原因在于驱动里面的qcCoInstaller.dll 经常莫名奇妙的丢失,导致驱动安装不上,一直报错。(注意目前这个驱动已经可以通过Windows Update正常获得,因此不再需要)
3.下载支持Linux Ext4格式无损调整分区(前移后挪双向均支持)的软件:Paragon Hard Disk Manager 14 Pro (原作者的百度网盘分享),如果不能正常下载可以使用本站下载
4.如果是64位系统,则重启机器,启动时候按住 F8,选择“禁用驱动程序签名强制”(注意目前这个驱动已经可以通过Windows Update正常获得,因此不再需要禁用驱动签名,更新一下驱动即可正常使用了)
5.确保手机电池电量充足,最好是满电状态。
1.正常开机状态下,在“设置-其他高级设置-开发者选项”中打开“USB调试”。电脑端按键盘Win+R(限Windows系统。Mac OS请出门左转),输入cmd回车,打开命令行窗口,输入cd C:\Mi2 Repartition回车。然后按顺序运行下图中的三条命令。注意运行命令时手机屏幕上是否提示操作权限,请给予允许:
#注释:运行命令时手机必须已获得完整root权限。开发版自带完整 root权限,如运行命令时手机屏幕上提示有程序被禁用root权限,进入“安全中心-权限管理-ROOT权限管理”中允许给予root权限再重新运行命 令。稳定版需自行处理获得完整root权限。稳定版系统如何获取完整root权限的方法请论坛自学
1 2 3 4 5 |
$ adb shell su -c "dd if=/dev/block/mmcblk0p9 of=/sdcard/aboot.img bs=4096" $ adb pull /sdcard/aboot.img .\backup $ adb push resize_data /sdcard/ |
2.关机,按住音量-键,再短按开机键,进入fastboot启动环境。然后运行以下命令:
1 |
$ fastboot erase aboot |
#注释:本命令在fastboot状态下擦除手机aboot逻辑区块中的数据
#注释:去掉aboot模块后,重开机才能已Qualcomm MMC Storage模式在PC上加载手机内部存储器</span
然后长按开机键约10秒,听到USB设备断开并重新加载的声音后松开电源键。此时会安装并加载Qualcomm HS-USB QDLoader设备驱动,让设备进入MMC Storage内部存储模式
#注释:需安装小米手机驱动(MiFlash线刷工具软件中集成),否则无法安装Qualcomm HS-USB QDLoader设备驱动
#注释:如安装Qualcomm HS-USB QDLoader驱动后,在Windows设备管理器中发现此设备前有黄色感叹号无法启动的情况,需在设备管理器中禁用此设备,断开并重新连接USB后, 在设备管理器中启用此设备,即可正常加载。此问题是PC系统驱动环境引起。
3.打开Paragon Hard Disk Manager 14,首次运行出现如下画面,选择箭头指向的按钮点击即可。
为了规避出现软件报告调整分区时发现cross-link files而拒绝操作报失败的情况,请按下图所示操作,强制让软件忽略文件系统完整性检查,即可顺利调整分区大小(图为HDM 15版本,与教程中使用的14版操作上无区别)
开始调整分区,划出用来合并到系统分区的空闲分区
然后执行合并系统分区的操作(下图是网络图片,跟上图有些差别,分区信息仅仅作为示意图)
同样点击 "Apply"之后等待合并空闲分区完成。
4.打开WinHex,在软件主界面按Ctrl-D打开硬盘克隆功能,严格按下图操作,然后确认写入操作。写入完毕后aboot分区数据即已恢复,可长按电源键约10秒正常开机进入系统了
#注释:“357410”是aboot分区在MMC存储器中的起始扇区号。这个aboot分区起始扇区号357410可在DiskGenius软件中选中aboot分区,在分区参数中看到,可自行验证。2和2S所有型号都相同,都填这个数
5.将之前放进sdcard中的resize_data文件移动到根目录/system/bin/中,试验中发现,/system 是只读的,无法拷贝进入,此时可以拷贝到 /目录下面也可以,两者分区相同,因此理论上面调整起来应该是一样的。(注意,目前尝试的小米2的特殊版本,到Android 5.0之后,已经不需要这个程序,系统启动后会自动调整分区)
1 2 3 4 5 6 7 |
$ adb shell su -c "cp /sdcard/resize_data /system/bin/resize_data" $ adb shell su -c "chmod 777 /system/bin/resize_data" $ adb shell su -c "resize_data doit" $ adb shell su -c "rm /system/bin/resize_data" |
平常Linux管理方面最重要的任务之一就是,检查文件系统的完整性。Linux文件系统有可能在各种各样的情况下受到损坏,比如系统崩溃、突然断电、磁盘断开,或者文件节点(i-node)不小心被覆盖等等。因此,定期检查文件系统的完整性是个好主意,以便尽量减小文件系统受到损坏的风险。而说到检查和修复Linux文件系统,fsck是一款实用的工具。
我在本教程中将介绍如何借助fsck工具,实现文件系统的自动检查。
系统一启动,就触发文件系统自动检查机制
如果你希望系统一启动,就自动触发fsck,那么有一些方法可以设置在启动过程中实现无人值守的fschk,这些方法具体取决于特定的Linux发行版。
在Debian、Ubuntu或Linux Mint上,编辑/etc/default/rcS,如下所示。
1 |
$ sudo vi /etc/default/rcS |
# 启动过程中,自动修复出现不一致性的文件系统
1 |
FSCKFIX=yes |
在CentOS上,使用下列内容,编辑/etc/sysconfig/autofsck(要是它没有,就创建)。
1 2 |
$ sudo vi /etc/sysconfig/autofsck AUTOFSCK_DEF_CHECK=yes |
强制定期检查文件系统
如果文件系统很庞大,你可以强制定期检查文件系统,而不是每次系统启动时检查文件系统。为了实现这个操作,先要借助tune2fs命令,找到文件系统配置。下面这个命令行显示了文件系统相关参数的当前值。请注意:/dev/sda1是文件系统超级块所在的分区。
1 |
$ sudo tune2fs -l /dev/sda1 |
从tune2fs的输出结果中,我们不仅可以看到文件系统的状态(干净与否),还可以看到与文件系统检查有关的一些参数。"Maximum mount count"(最大挂载次数)这个参数是指文件系统检查被触发后的挂载次数。"Check interval"(检查时间间隔)这个参数显示了两次文件系统检查之间的最长时间。在大多数Linux发行版上,这些参数并不是默认情况下被设置的,这意味着并不进行任何定期的文件系统检查。
如果想强制每隔30次挂载就检查文件系统,请运行下面这个命令。
1 |
$ sudo tune2fs -c 30 /dev/sda1 |
如果想强制每隔3个月就检查文件系统,请使用下面这个命令。
1 |
$ sudo tune2fs -i 3m /dev/sda1 |
现在确认刚添加上去的文件系统检查条件已正确设置。
1 2 3 4 5 6 7 8 9 |
$ sudo tune2fs -l /dev/sda1 . . . Last mount time: n/a Last write time: Fri Mar 14 22:29:24 2014 Mount count: 20 Maximum mount count: 30 Last checked: Mon Mar 3 20:55:08 2014 Check interval: 7776000 (3 months) Next check after: Sun Jun 1 21:55:08 2014 |
强制下一次系统重启时,进行一次性的文件系统检查
如果你想在下一次系统重启时触发一次性的文件系统检查,可以使用这个命令。
1 |
$ sudo touch /forcefsck |
一旦你在类似上面的顶层目录(/)中创建了一个名为forcefsck的空文件,它就会在你下一次重启时,强制进行文件系统检查。系统成功启动后,/forcefsck则会自动被清除。
最近接到用户的投诉,在Windows 7 32位的机器上,UMDF驱动频繁崩溃,关键是SetUnhandledExceptionFilter 设置的异常过滤竟然一丁点用都没有,查询了半天,才注意到UMDF框架把UnhandledException接管了,你完全是无力反抗。
然后去MSDN上查询,根据Determining Why the Reflector Terminated the Host Process微软文档,WER会在“%windir%\system32\LogFiles\WUDF”目录下面生成DUMP文件,测试之后发现,是否生成完全依赖WER的心情,捣鼓到后来,干脆完全不生成DUMP文件了,另外他偶尔生成的也都是MiniDump ,作用有限。“Users\All Users\Microsoft\Windows\WER\ReportQueue”目录下面的报告数据,也是时有时无,阴晴不定。
继续Google,微软文档 Collecting User-Mode Dumps 设置如下的注册表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps] "DumpType"=dword:00000001 "DumpCount"=dword:0000000A "DumpFolder"="D:\\Temp" [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\Windows Error Reporting\LocalDumps] "DumpType"=dword:00000001 "DumpCount"=dword:0000000A "DumpFolder"="D:\\Temp" [HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps] "DumpType"=dword:00000001 "DumpCount"=dword:0000000A "DumpFolder"="D:\\Temp" |
这样设置之后,正常的应用都可以在D:\Temp 下面生成崩溃记录,但是WUDFHost.exe 就是不能生成崩溃DUMP,貌似是WUDFHost.exe 用其他低权限用户账户运行,导致没办法生成转储文件。
继续Google,ProcDump进入视野,着实是个好的工具软件,非常好用。于是写了个批处理文件来跟踪WUDFHost.exe的异常。
1 |
procdump -ma -e WUDFHost.exe |
应用崩溃的时候,会在当前目录下面生产对应的.dmp文件。
下面为简单的用法例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
Using ProcDump usage: procdump [-a] [[-c|-cl CPU usage] [-u] [-s seconds]] [-n exceeds] [-e [1 [-b]] [-f <filter,...>] [-g] [-h] [-l] [-m|-ml commit usage] [-ma | -mp] [-o] [-p|-pl counter threshold] [-r] [-t] [-d <callback DLL>] [-64] <[-w] <process name or service name or PID> [dump file] | -i <dump file> | -u | -x <dump file> <image file> [arguments] >] [-? [ -e] -a Avoid outage. Requires -r. If the trigger will cause the target to suspend for a prolonged time due to an exceeded concurrent dump limit, the trigger will be skipped. -b Treat debug breakpoints as exceptions (otherwise ignore them). -c CPU threshold at which to create a dump of the process. -cl CPU threshold below which to create a dump of the process. -d Invoke the minidump callback routine named MiniDumpCallbackRoutine of the specified DLL. -e Write a dump when the process encounters an unhandled exception. Include the 1 to create dump on first chance exceptions. -f Filter the first chance exceptions. Wildcards (*) are supported. To just display the names without dumping, use a blank ("") filter. -g Run as a native debugger in a managed process (no interop). -h Write dump if process has a hung window (does not respond to window messages for at least 5 seconds). -i Install ProcDump as the AeDebug postmortem debugger. Only -ma, -mp, -d and -r are supported as additional options. -l Display the debug logging of the process. -m Memory commit threshold in MB at which to create a dump. -ma Write a dump file with all process memory. The default dump format only includes thread and handle information. -ml Trigger when memory commit drops below specified MB value. -mp Write a dump file with thread and handle information, and all read/write process memory. To minimize dump size, memory areas larger than 512MB are searched for, and if found, the largest area is excluded. A memory area is the collection of same sized memory allocation areas. The removal of this (cache) memory reduces Exchange and SQL Server dumps by over 90%. -n Number of dumps to write before exiting. -o Overwrite an existing dump file. -p Trigger on the specified performance counter when the threshold is exceeded. Note: to specify a process counter when there are multiple instances of the process running, use the process ID with the following syntax: "\Process(<name>_<pid>)\counter" -pl Trigger when performance counter falls below the specified value. -r Dump using a clone. Concurrent limit is optional (default 1, max 5). CAUTION: a high concurrency value may impact system performance. Windows 7 : Uses Reflection. OS doesn't support -e. Windows 8.0 : Uses Reflection. OS doesn't support -e. Windows 8.1+: Uses PSS. All trigger types are supported. -s Consecutive seconds before dump is written (default is 10). -t Write a dump when the process terminates. -u Treat CPU usage relative to a single core (used with -c). As the only option, Uninstalls ProcDump as the postmortem debugger. -w Wait for the specified process to launch if it's not running. -x Launch the specified image with optional arguments. If it is a Store Application or Package, ProcDump will start on the next activation (only). -64 By default ProcDump will capture a 32-bit dump of a 32-bit process when running on 64-bit Windows. This option overrides to create a 64-bit dump. Only use for WOW64 subsystem debugging. -? Use -? -e to see example command lines. If you omit the dump file name, it defaults to <processname>_<datetime>.dmp. Use the -accepteula command line option to automatically accept the Sysinternals license agreement. Examples Write a mini dump of a process named 'notepad' (only one match can exist): C:\>procdump notepad Write a full dump of a process with PID '4572': C:\>procdump -ma 4572 Write 3 mini dumps 5 seconds apart of a process named 'notepad': C:\>procdump -s 5 -n 3 notepad Write up to 3 mini dumps of a process named 'consume' when it exceeds 20% CPU usage for five seconds: C:\>procdump -c 20 -s 5 -n 3 consume Write a mini dump for a process named 'hang.exe' when one of it's Windows is unresponsive for more than 5 seconds: C:\>procdump -h hang.exe hungwindow.dmp Write a mini dump of a process named 'outlook' when total system CPU usage exceeds 20% for 10 seconds: C:\>procdump outlook -p "\Processor(_Total)\% Processor Time" 20 Write a full dump of a process named 'outlook' when Outlook's handle count exceeds 10,000: C:\>procdump -ma outlook -p "\Process(Outlook)\Handle Count" 10000 Write a MiniPlus dump of the Microsoft Exchange Information Store when it has an unhandled exception: C:\>procdump -mp -e store.exe Display without writing a dump, the exception codes/names of w3wp.exe: C:\>procdump -e 1 -f "" w3wp.exe Write a mini dump of w3wp.exe if an exception's code/name contains 'NotFound': C:\>procdump -e 1 -f NotFound w3wp.exe Launch a process and then monitor it for exceptions: C:\>procdump -e 1 -f "" -x c:\dumps consume.exe Register for launch, and attempt to activate, a modern 'application'. A new ProcDump instance will start when it activated to monitor for exceptions: C:\>procdump -e 1 -f "" -x c:\dumps Microsoft.BingMaps_8wekyb3d8bbwe!AppexMaps Register for launch of a modern 'package'. A new ProcDump instance will start when it is (manually) activated to monitor for exceptions: C:\>procdump -e 1 -f "" -x c:\dumps Microsoft.BingMaps_1.2.0.136_x64__8wekyb3d8bbwe Register as the Just-in-Time (AeDebug) debugger. Makes full dumps in c:\dumps. C:\>procdump -ma -i c:\dumps See a list of example command lines (the examples are listed above): C:\>procdump -? -e |
有些软件可能要求系统的 Glibc 高于某个版本才可以正常运行。如果您的 Glibc 低于要求的版本,为了运行这些软件,您就不得不升级您的 Glibc 了 。您可以寻找已经编译好的 rpm 包或者使用源代码的方式升级 Glibc。
使用源代码方式升级 Glibc 是需要小心考虑的事情,因为整个系统几乎所有应用程序都依赖于原有的动态库,升级的时候,执行"make install"命令会打断旧的动态库链接,改为指向新的库文件。在这个过程中,不同的链接指向新旧不同版本的库文件,很容易导致系统崩溃,崩溃后,一般是无法重新启动的。
笔者使用的Linux发行版本是Mandriva Linux release 2006.0,其Glibc版本是2.3.5,内核版本是2.6.12-12mdk。由于某些需要,笔者必须升级原来的Glibc到更高的版本。经过实 践,成功使用源代码的方式安全地把Glibc从2.3.5升级到2.6。使用相同的方法,也能成功升级到Glibc2.4或Glibc2.5。成功升级 后,还可以在新旧不同版本的Glibc之间自由切换。
如果您需要阅读有关升级Glibc的文档,可以阅读Glibc 2 HOWTO文档,该文论述了如何从libc5升级到libc6,但是现在的Linux发行版的Glibc都已经使用libc6,更多的需要是在libc6 的范围内,从低版本升级到更高的版本。另外您可以阅读Linux From Scratch项目有关如何安装Glibc的文档。笔者认为最有必要阅读的是Glibc源程序目录树下的INSTALL和FAQ文档,INSTALL详细 描述了有关各编译选项的具体作用,FAQ回答了很多具体的问题。
为了安全升级Glibc,在升级前必须做好详细的部署和备份,即使是升级失败,系统也要能够还原为原来的状态。升级Glibc失败后,一般是无法重新启动系统的,必须使用另外一个可以启动计算机的Linux系统启动,挂载升级失败的根文件系统,恢复系统的Glibc为原来的状态。因此,准备另外一个可以启动 的Linux系统,是必需的。
准备好另外一个可以启动的Linux系统后,接下来的工作是编译Glibc。编译前要执行"configure"命令,用户可以根据自己的需要,加入不同的编译选项,编译选项在INSTLL文件里有详细的说明。如果是升级当前的Glibc, 必须使用--prefix=/usr选项,该选项指定当前即将编译的Glibc作为系统的标准动态库,安装的时候,Glibc会修改/lib,/usr等 目录下的文件和链接。如果--prefix不是指向/usr,譬如--prefix=/glibc, 安装的时候,Glibc只会在/glibc目录下生成目录,文件以及链接,安装后的Glibc不会成为系统的标准动态库。如果不指定 --prefix,Glibc缺省认为--prefix=/usr/local,安装后的Glibc也不会成为系统的标准动态库。编译Glibc的时候需 要使用Linux内核的头文件,如果内核的头文件太旧,执行"make"的时候,可能会失败,这时可以在configure的时候,使用--with- headers选项指定新内核的头文件的所在目录。笔者的Mandriva Linux release 2006.0的内核头文件就不能令Glibc2.6成功编译,但是却能令Glibc2.4和Glibc2.5成功编译,使用--with-headers 指向新内核的头文件后,Glibc2.6也能成功编译,下文将会有详细叙述。
Glibc安装的时候,会直接修改/lib,/usr/lib等目录下的文件和链接,为了在升级失败的情况下能够恢复系统的Glibc为原来状态,在安装新版本的Glibc之前必须对一些重要目录进行备份,至于哪些目录需要做备份,下文将会有叙述。
备份好重要目录后就可以安装Glibc了,必须由root用户执行make install命令,不同的Linux发行版,可能会有不同的结果。笔者使用的Mandriva Linux release 2006.0在这个过程中会出现错误,并且输入任何命令都无效,重新启动也无法再次进入Linux系统。出现的这样的错误是由于Coreutils的命令 都是依赖于/usr/tls/目录下的链接文件,这些链接文件都指向原来的Glibc动态库文件,而/lib/ld-linux.so.2已经被改为指向 新版本的Glibc动态库文件了,这些重要链接分别指向新旧不同版本的库文件,导致了执行Coreutils的命令无效。这个时候,就要用另外一个 Linux系统启动,把/usr/tls/目录下的链接修改为指向新版本的Glibc的库文件。
经过上述修改,重新启动计算机,如果能重新 进入原Linux系统,表明到目前为止升级过程都是正确的。这个时候,要再执行一次"make install"重新安装Glibc,正常情况下,这次不会出现任何错误,安装结束的时候,Glibc会给出安装成功的消息。如果修改/lib/tls /下的链接后重新启动计算机仍然不能进入原Linux系统,表明这次升级失败,只能再次使用另外一个Linux系统启动,挂载升级失败的根文件系统,把先前备份好的重要目录恢复为原来的名字,经过这样的恢复,一般是可以重新启动升级失败的Linux系统的。
升级的最后一步是执行"make localedata/install-locales"命令安装时区和地区数据库。
本文介绍的方法在升级过程中会出现一次链接错误,系统无法输入命令,重新启动也无法进入Linux,必须使用另外一个Linux系统启动,并挂载原根文件系 统,修正在升级过程中产生的错误链接,然后才能继续升级。因此在升级之前,一定要先确保拥有另外一个可启动的Linux系统。此外,还要备份下文将会论述 的一些重要目录,如果最终升级失败,需要用另外一个Linux系统启动,恢复原Linux系统的Glibc为原来的版本。
建议在升级之前,详细阅读Glibc源代码包内的INSTALL和FAQ文件。
本文假设进行编译的用户名字是xyz,用户目录是/home/xyz/,所有源代码都在/home/xyz/build/目录下编译。所有源代码压缩包都已 经拷贝到/home/xyz/build/目录下。升级Glibc的Linux系统的根文件系统使用hda5分区,其文件系统格式为xfs。
准备另外一个可启动的Linux系统的方法有很多,可以在硬盘上安装另外一个Linux发行版,可以在DOS环境下使用loadlin.exe启动一个 Linux系统,最简单的方式是使用Live CD,从光驱启动。无论使用什么形式,它都必须能挂载需要升级Glibc的根文件系统。
如果选择Live CD启动,Knoppix是一个很好的选择。您可以从Knoppix的网站下载iso文件,烧制成启动CD,也可以把Knoppix的系统文件拷贝到硬盘 上,在DOS环境下,执行loadlin.exe启动。笔者使用了Knoppix 5.0.1,制作成Live CD启动。参考资料有介绍如何使用 Knoppix 进行系统恢复。
Glibc的编译安装与一般的软件很类似,都是要经过configure,make和make install三个阶段。Glibc不能在源代码目录下编译,必须在一个空目录下编译。
编译Glibc是需要内核头文件的,笔者的Mandriva Linux release 2006.0的内核版本是2.6.12-12mdk,可以直接使用该版本内核的头文件升级到Glibc2.4 和Glibc2.5。如果升级到Glibc2.6,在make过程中,会出现以下错误:
1 2 3 |
libc_pic.os: In function `sync_file_range': : undefined reference to `.Lpseudo_end' collect2: ld returned 1 exit status |
这是由于2.6.12-12mdk的内核头文件太旧,为了顺利编译Glibc2.6,必须使用新的内核头文件。
2.1 编译Glibc2.4或Glibc2.5
如果要升级Glibc到2.4或2.5,configure的时候只需要--prefix=/usr一个选项,意思是该Glibc将会作为系统的标准动态库。
以升级到Glibc2.5为例,执行以下命令进行编译:
1 2 3 4 5 6 |
$ cd ~/build $ tar xjf glibc-2.5.tar.bz2 $ mkdir glibc-2.5-build $ cd glibc-2.5-build $ ../glibc-2.5/configure --prefix=/usr $ make |
glibc-2.5.tar.bz2是Glibc2.5的源代码压缩包,执行"tar xjf glibc-2.5.tar.bz2"命令后,在~/build/目录下产生了glibc-2.5目录树,Glibc2.5的源代码就在这个目录里面。 Glibc不能在源代码目录下编译,因此执行了"mkdir glibc-2.5-build"命令,生成glibc-2.5-build目录,编译Glibc2.5时产生的文件,保存在这个目录下。如果顺利,将会成功编译,不会出现错误信息。
2.2 编译Glibc2.6
如果您打算升级到 Glibc2.6,使用版本为2.6.12-12mdk的内核头文件是不能成功编译的,必须使用新的内核头文件。configure的时候使用 --with-headers选项指向新的内核头文件的目录。Glibc的FAQ文档明确指出最好使用最新版本的内核头文件,而且编译时需要的内核头文件 的版本不需要与当前正在运行的内核版本一致。笔者试验了版本为linux-2.6.20.7和linux-2.6.18两个版本的内核头文件,编译时系统 运行的内核版本是2.6.12-12mdk,都可以成功编译Glibc2.6。
为了使用新版本的内核头文件,解开新版本的内核压缩包后,在源代码目录下执行"make menuconfig",这将会进入内核的设置页面,不需要作任何处理,直接退出并保存。然后执行"make",不需要等待make完毕,一开始看到
1 |
SYMLINK include/asm -> include/asm-i386 |
就可以按下ctrl+c停止编译内核。执行"make"的目的是在内核源代码目录树内生成一些重要的文件和软链接,其中在include/目录下产生一个名为asm的软链接指向asm-i386目录,没有这个链接,Glibc2.6是无法编译的。
假设使用linux-2.6.20.7的内核头文件,执行以下命令:
1 2 3 4 5 |
$ cd ~/build $ tar xjf linux-2.6.20.7.tar.bz2 $ cd linux-2.6.20.7 $ make menuconfig $ make |
linux-2.6.20.7.tar.bz2是2.6.20.7版本的Linux内核源代码压缩包,执 行"tar xjf linux-2.6.20.7.tar.bz2"命令后,将会产生linux-2.6.20.7目录,Linux内核的源代码都在这个目录下,其中内核头 文件在linux-2.6.20.7/include/下。确保linux-2.6.20.7/include/asm已经产生后,就可以停止内核的编 译,然后进行Glibc2.6的编译:
1 2 3 4 5 6 |
$ cd ~/build $ tar xjf glibc-2.6.tar.bz2 $ mkdir glibc-2.6-build $ cd glibc-2.6-build $ ../glibc-2.6/configure --prefix=/usr --with-headers=~/build/linux-2.6.20.7/include $ make |
glibc-2.6.tar.bz2是Glibc2.6的源代码压缩包,执行"tar xjf glibc-2.6.tar.bz2"命令后,在~/build/目录下产生了glibc-2.6目录树。
如果您的系统当前运行的内核已经升级到比较新的版本,例如2.6.20.7,configure的时候,就不需要--with-headers选项了,与 Glibc2.4或Glibc2.5的configure命令一样,只需要--prefix=/usr选项就可以了,但是前提条件是/lib /modules/uname -r
/source指向内核的源程序目录,您可以用以下命令查看它指向哪里:
1 |
$ ls -l /lib/modules/`uname -r`/ |
3.1 哪些目录需要备份?
安装Glibc前必须备份好原来的系统动态库,一旦安装失败,使用另外一个Linux系统启动,挂载升级失败的根文件系统,还原Glibc为原来的状态。可是哪些目录需要备份?Glibc在安装的时候,将会修改哪个目录下的文件?
Glibc 在安装时可以指定install_root选项,命令Glibc把该选项指向的目录作为根,文件都安装到这个目录下,通过观察Glibc在这个目录里生成了什么目录和文件,我们就可以知道Glibc在安装的时候到底会修改哪些目录了。假设安装到~/build/system_fake_root上:
1 2 3 |
$ cd ~/build $ cd glibc-2.6-build $ make install install_root=~/build/system_fake_root |
安装后:
1 2 |
$ ls ~/build/system_fake_root etc/ lib/ sbin/ usr/ |
可以看出,Glibc的make install命令会修改/etc,/lib,/sbin和/usr目录下的文件。这里最重要的是/lib和/usr。一般来说/usr目录下有很多文件,占用硬盘空间很大,实际也不需要对整个/usr目录备份,使用以下命令查看Glibc会修改/usr/下的哪些目录:
1 2 |
$ ls ~/build/system_fake_root/usr bin/ include/ info/ lib/ libexec/ sbin/ share/ |
经分析,笔者选择了备份/lib,/usr/lib,/usr/include,/usr/sbin和/usr/bin。您当然可以备份更多的目录,不过笔者发现备份上述5个目录已经可以恢复系统的Glibc为原来的版本了。
3.2 备份目录
使用su命令切换为root。执行:
1 2 3 4 5 6 |
# cp -a /lib /lib.2.3.5 # cd /usr # cp -a lib lib.2.3.5 # cp -a bin bin.2.3.5 # cp -a sbin sbin.2.3.5 # cp -a include include.2.3.5 |
经过以上步骤,就备份了以后还原用的目录。备份的目录名字使用原目录名后加上.2.3.5后缀,目的是区分不同的Glibc版本目录。
3.3 如何还原系统的Glibc
如果升级最终失败,导致系统无法启动,就必须使用另外一个Linux系统启动,还原上述备份的目录为原来的名字。以笔者的系统为例,升级失败的根文件系统使用hda5分区,其文件系统格式为xfs,将被挂载到/mnt/m1目录。使用Knoppix 5.0.1 Live CD启动后,打开一个控制台,执行"su"命令切换为root用户,执行以下命令
1 2 3 4 5 6 7 8 9 10 11 12 |
# cd /mnt # mkdir m1 # mount -t xfs /dev/hda5 /mnt/m1 # cd /mnt/m1 # rm -fr lib # mv lib.2.3.5 lib # cd usr # rm -fr lib bin sbin include # mv lib.2.3.5 lib # mv bin.2.3.5 bin # mv sbin.2.3.5 sbin # mv include.2.3.5 include |
执行上述命令后,Glibc已经被恢复为原来的版本,系统应该可以正常启动。
3.4 如何知道当前的Glibc版本
Mandriva Linux release 2006.0的动态库是Glibc2.3.5。执行"/lib/libc.so.6"可以知道当前的Glibc是什么版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ /lib/libc.so.6 GNU C Library stable release version 2.3.5, by Roland McGrath et al. Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled by GNU CC version 4.0.1 (4.0.1-2mdk for Mandriva Linux release 2006.0). Compiled on a Linux 2.6.12 system on 2005-08-30. Available extensions: GNU libio by Per Bothner crypt add-on version 2.1 by Michael Glad and others linuxthreads-0.10 by Xavier Leroy BIND-8.2.3-T5B NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk Glibc-2.0 compatibility add-on by Cristian Gafton libthread_db work sponsored by Alpha Processor Inc Thread-local storage support included. For bug reporting instructions, please see: <http://www.gnu.org/software/libc/bugs.html>. |
从以上输出可以看到,当前系统的Glibc版本是2.3.5,使用Gcc4.0.1编译,编译时运行的Linux内核版本是2.6.12。
Glibc的FAQ文档给出以下程序用于查看当前的Glibc的版本:
1 2 3 |
#include <stdio.h> #include <gnu/libc-version.h> int main (void) { puts (gnu_get_libc_version ()); return 0; } |
把上述程序写到chk_lib_v.c文件,执行以下命令编译:
1 |
gcc -o chk_lib_v chk_lib_v.c |
执行chk_lib_v后有以下输出:
1 2 |
$ ./chk_lib_v 2.3.5 |
3.5 注意Coreutils依赖的动态库情况
Mandriva Linux release 2006.0系统的/lib/目录下有个tls目录。该目录下的文件是能否成功升级Glibc到2.6的关键。使用ldd命令查看Coreutils的应用程序依赖的动态库情况可以发现:
1 2 3 4 5 6 7 8 9 |
$ ldd /bin/ls linux-gate.so.1 => (0xffffe000) librt.so.1 => /lib/tls/librt.so.1 (0xb7f60000) libtermcap.so.2 => /lib/libtermcap.so.2 (0xb7f5b000) libacl.so.1 => /lib/libacl.so.1 (0xb7f54000) libc.so.6 => /lib/tls/libc.so.6 (0xb7e26000) libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7e14000) /lib/ld-linux.so.2 (0xb7f89000) libattr.so.1 => /lib/libattr.so.1 (0xb7e10000) |
请注意上述的librt.so.1,libc.so.6和libpthread.so.0,它们都是位于/lib/tls/,而不是/lib/。换言之,ls的执行,依赖于/lib/tls目录下的某些动态链接库文件。tls是thread-local storage,当不同的线程使用同一个全局变量的时候,各线程将会在本地保留该变量的备份,查阅参考资料可以了解更多有关tls的信息。 Glibc2.4,Glibc2.5和Glibc2.6都支持tls。
/lib/tls/下有以下文件:
1 2 3 4 5 6 7 8 9 10 11 12 |
$ ls -l /lib/tls 总用量 1488 -rw-r--r-- 1 root root 1229976 8月 30 2005 libc-2.3.5.so lrwxrwxrwx 1 root root 13 5月 12 21:25 libc.so.6 -> libc-2.3.5.so -rw-r--r-- 1 root root 145176 8月 30 2005 libm-2.3.5.so lrwxrwxrwx 1 root root 13 5月 12 21:25 libm.so.6 -> libm-2.3.5.so -rw-r--r-- 1 root root 84987 8月 30 2005 libpthread-0.10.so lrwxrwxrwx 1 root root 18 5月 12 21:25 libpthread.so.0 -> libpthread-0.10.so -rw-r--r-- 1 root root 30620 8月 30 2005 librt-2.3.5.so lrwxrwxrwx 1 root root 14 5月 12 21:25 librt.so.1 -> librt-2.3.5.so -rw-r--r-- 1 root root 22108 8月 30 2005 libthread_db-1.0.so lrwxrwxrwx 1 root root 19 5月 12 21:25 libthread_db.so.1 -> libthread_db-1.0.so |
/lib/tls目录下的文件是一些很重要的动态库及软连接,其中包括libc.so.6,它们都是指向2.3.5版本的动态库文件。
4.1 第一次make install
切换到root用户,执行make install就开始安装Glibc了:
1 2 3 4 |
$ cd ~/build $ cd glibc-2.6-build $ su # make install |
在安装过程中,将会出现如下错误:
1 2 3 4 5 6 7 8 |
/home/xyz/build/glibc-2.6-build/elf/sln /home/xyz/build/glibc-2.6-build/elf/symlink.list rm -f /home/xyz/build/glibc-2.6-build/elf/symlink.list rm: relocation error: /lib/tls/libc.so.6: symbol _dl_out_of_memory, \ version GLIBC_PRIVATE not defined in file ld-linux.so.2 with link time reference make[1]: *** [install-symbolic-link] Error 127 make[1]: Leaving directory `/home/xyz/build/glibc-2.6' make: *** [install] Error 2 |
安装失败后,输入任何命令都是无效的,系统只会重 复"relocation error: /lib/tls/libc.so.6: symbol _dl_out_of_memory, version GLIBC_PRIVATE not defined in file ld-linux.so.2 with link time reference"的错误信息,重新启动计算机在启动中就会失败,根本无法进入原Linux系统。
出现这样的错误的原因是 Coreutils的应用程序都依赖于/lib/tls/下的动态库,在make install的时候,/lib/ld-linux.so.2从原来指向ld-2.3.5.so被改为指向ld-2.6.so,但这个时候/lib /tls/libc.so.6指向的仍然是/lib/tls/libc-2.3.5.so。/lib/ld-linux.so.2和/lib/tls /libc.so.6各自指向不同版本的库文件导致了Coreutils的命令执行失败,从而make install也失败。
这个时候, 就要用另外一个Linux系统启动,挂载升级失败的根文件系统,把原根文件系统的/lib/tls/下的链接全部改为指向2.6版本的库文件,具体就是 /lib/tls/libc.so.6,/lib/tls/libm.so.6, /lib/tls/libpthread.so.0和/lib/tls/librt.so.1这4个软链接分别指向libc-2.6.so, libm-2.6.so,libpthread-2.6.so和librt-2.6.so。libthread_db.so.1仍然是指向 libthread_db-1.0.so,但这个时候/lib/libthread_db-1.0.so已经是Glibc2.6版本的了,原/lib /tls/libthread_db-1.0.so必须被替换为Glibc2.6版本的libthread_db-1.0.so。
笔者使用Knoppix 5.0.1 Live CD启动计算机,启动后,打开一个控制台,执行"su"命令切换为root,执行以下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# cd /mnt # mkdir m1 # mount -t xfs /dev/hda5 /mnt/m1 # cd /mnt/m1/lib/tls # cp -f ../libthread_db-1.0.so . # cp ../libc-2.6.so . # cp ../libm-2.6.so . # cp ../libpthread-2.6.so . # cp ../librt-2.6.so . # ln -sf libc-2.6.so libc.so.6 # ln -sf libm-2.6.so libm.so.6 # ln -sf libpthread-2.6.so libpthread.so.0 # ln -sf librt-2.6.so librt.so.1 |
上述命令就是把原根文件系统/lib/下的libc- 2.6.so, libm-2.6.so,libpthread-2.6.so和librt-2.6.so拷贝到/lib/tls/下,并把/lib/tls /libc.so.6,/lib/tls/libm.so.6,/lib/tls/libpthread.so.0和/lib/tls /librt.so.1这4个软链接从原来指向2.3.5版本的库文件改为指向最新的2.6版本的库文件。原/lib/tls /libthread_db-1.0.so下的文件被/lib/libthread_db-1.0.so替换。
4.2 第二次make install
修改了/lib/tls/下的链接和文件后,就可以重新启动计算机,进入原Linux系统,这次将会正常启动,登陆后,执行Coreutils的命令,例如 ls,已经不会出现"relocation error: /lib/tls/libc.so.6: symbol _dl_out_of_memory, version GLIBC_PRIVATE not defined in file ld-linux.so.2 with link time reference"的错误信息。由于Glibc2.6没有彻底安装完毕,我们还要重新执行一次make install:
1 2 3 4 |
$ cd ~/build $ cd glibc-2.6-build $ su # make install |
这次make install将不会出现错误,如果安装成功,到最后会有以下信息提示:
1 2 |
Your new glibc installation seems to be ok. make[1]: Leaving directory `/home/xyz/build/glibc-2.6' |
执行/lib/libc.so.6查看Glibc的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ /lib/libc.so.6 GNU C Library stable release version 2.6, by Roland McGrath et al. Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled by GNU CC version 4.0.1 (4.0.1-5mdk for Mandriva Linux release 2006.0). Compiled on a Linux >>2.6.12-12mdk<< system on 2007-05-26. Available extensions: crypt add-on version 2.1 by Michael Glad and others Native POSIX Threads Library by Ulrich Drepper et al BIND-8.2.3-T5B For bug reporting instructions, please see: <http://www.gnu.org/software/libc/bugs.html>. 执行chk_lib_v: $ ./chk_lib_v 2.6 |
这都表明当前系统的动态库已经使用了Glibc2.6。
如果把/lib/tls/下的链接改为指向2.6版本的库文件后,重新启动计算机仍然无法进入原Linux系统,就说明升级Glibc失败,只能再次使用另外一个Linux系统启动,恢复原系统的Glibc为原来的版本,请参考3.3节。
4.3 安装时区和地区数据库
虽然现在系统已经使用Glibc2.6,但是在X Window下,使用fcitx中文输入法的用户会发现按下ctrl+space不会弹出中文输入框。这是因为新的Glibc2.6还没安装时区和地区数据库。执行以下命令:
1 2 3 4 |
$ cd ~/build $ cd glibc-2.6-build $ su # make localedata/install-locales |
上述命令将会在/usr/lib/locale/下生成一个名为"locale-archive"的文件。重新启动X Window, 按下ctrl+space就可以调出中文输入框并输入中文了。
至此,升级Glibc完毕。笔者在升级到了Glibc2.6的Linux系统上使用了 VMware,Openoffice,Mplayer,Skype,Firefox,Thunderbird,Vim,Fcitx等一系列软件一段时间, 未发现由于升级了Glibc而导致的错误出现。
回到Glibc2.3.5 成功升级后,想在Glibc2.6和原来的Glibc2.3.5之间切换是很容易的。因为安装前对Glibc2.3.5的重要目录进行了备份,只需使用另 外一个Linux启动,挂载原Linux的根文件系统,把升级前备份好的/lib.2.3.5等目录的名字改为/lib等原来的名字即可。
使用Knoppix 5.0.1 Live CD启动,打开一个控制台,执行"su"命令切换为root,执行以下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# cd /mnt # mkdir m1 # mount -t xfs /dev/hda5 /mnt/m1 # cd /mnt/m1 # mv lib lib.2.6 # mv lib.2.3.5 lib # cd usr # mv lib lib.2.6 # mv bin bin.2.6 # mv sbin sbin.2.6 # mv include include.2.6 # mv lib.2.3.5 lib # mv bin.2.3.5 bin # mv sbin.2.3.5 sbin # mv include.2.3.5 include |
重新启动,系统将会使用原来的Glibc2.3.5,Glibc2.6的目录备份为原目录名后加.2.6后缀。
总结
使用源代码升级Glibc,做好升级前的准备是最重要的。首先要准备好另外一个可以启动的,能挂载原根文件系统的Linux系统。其次是对/lib, /usr/lib,/usr/include,/usr/sbin,/usr/bin等目录进行备份。成功升级后,可以在高低两个版本的Glibc之间自 由切换。
升级前只要做好上述两个准备,升级系统的Glibc是安全的。
由于不同的Linux发行版的系统环境不一样,因此使用源代码升级Glibc的过程可能会有差异,为了成功升级,读者必须在升级过程中根据自己的系统的实际情况作相应的调整。
链接地址