Android交叉编译curl

操作系统:ubuntu 14.04
一.安装需要工具

sudo apt-get install autoconf libtool libsysfs-dev

二.制作交叉编译工具链
1.下载NDK,并配置NDK环境变量为NDK的安装路径
2.根据NDK里docs文档里的standalone-toolchain.html来抽取交叉编译的环境。
3.配置SYSROOT环境变量:

SYSROOT=$NDK/platforms/android-19/arch-arm //android-19是你的android开发版本所定

4.然后运行命令:

$NDK/build/tools/make-standalone-toolchain.sh --platform=android-19 --install-dir=/tmp/my-android-toolchain

/tmp/my-android-toolchain是你交叉编译环境的复制路径。最好别放在tmp目录里,因为重启机子就立即消失了。这个新生成的文件 夹即是你的交叉编译环境
5.配置PAHT和CC环境变量:

export PATH=/tmp/my-android-toolchain/bin:$PATH
export CC=arm-linux-androideabi-gcc

三.下载curl并编译

git clone https://github.com/curl/curl.git
cd curl
mkdir build
autoreconf -i
./configure --host=arm-linux --enable-cross-compile --enable-threaded-resolver --disable-shared --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-manual --enable-proxy --enable-ipv6 --enable-cookies --enable-symbol-hiding --disable-versioned-symbols --disable-soname-bump --disable-sspi --disable-ntlm-wb --prefix=`pwd`/build
make 
make install

Linux下让指定程序走代理

1.proxychains-ng安装

git clone https://github.com/rofl0r/proxychains-ng.git
cd proxychains-ng/
./configure --prefix=/usr/local/proxychains --sysconfdir=/etc
sudo make 
sudo make install
sudo make install-config

2.proxychains-ng配置

sudo vim /etc/proxychains.conf
#将socks4 127.0.0.1 9095改为自己的代理端口
socks5  127.0.0.1 1080  //1080改为你自己的端口
sudo cp /usr/local/proxychains/bin/proxychains4 /usr/local/bin/proxy

3.proxychains-ng使用

proxy wget http://www.baidu.com

GRADLE多渠道打包

示例脚本

apply plugin: 'com.android.application'

def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

android {
    compileSdkVersion 21
    buildToolsVersion '21.1.2'

    defaultConfig {
        applicationId "com.boohee.*"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"

        // dex突破65535的限制
        multiDexEnabled true
        // 默认是umeng的渠道
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "umeng"]
    }

    lintOptions {
        abortOnError false
    }

    signingConfigs {
        debug {
            // No debug config
        }

        release {
            storeFile file("../yourapp.keystore")
            storePassword "your password"
            keyAlias "your alias"
            keyPassword "your password"
        }
    }

    buildTypes {
        debug {
            // 显示Log
            buildConfigField "boolean", "LOG_DEBUG", "true"

            versionNameSuffix "-debug"
            minifyEnabled false
            zipAlignEnabled false
            shrinkResources false
            signingConfig signingConfigs.debug
        }

        release {
            // 不显示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"

            minifyEnabled true
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release

            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        // 输出apk名称为boohee_v1.0_2015-01-15_wandoujia.apk
                        def fileName = "boohee_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk"
                        output.outputFile = new File(outputFile.parent, fileName)
                    }
                }
            }
        }
    }

    // 友盟多渠道打包
    productFlavors {
        wandoujia {}
        _360 {}
        baidu {}
        xiaomi {}
        tencent {}
        taobao {}
        ...
    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:21.0.3'
    compile 'com.jakewharton:butterknife:6.0.0'
    ...
}

如何用gradle生成javadoc

在模块的build.gradle中填入以下内容

task javadoc(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

javadoc {
    options {
        encoding "UTF-8"
        charSet 'UTF-8'
        author true
        version true
        splitIndex true
        noDeprecated true
        setMemberLevel(JavadocMemberLevel.PUBLIC)
        links "http://docs.oracle.com/javase/8/docs/api"
    }
}

下面还有一个可能更好使

android.libraryVariants.all { variant ->
    task("generate${variant.name}Javadoc", type: Javadoc) {
        title = "$name $version API"
        source = variant.javaCompile.source
        ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
        classpath = files(variant.javaCompile.classpath.files, ext.androidJar)
        options {
            links("http://docs.oracle.com/javase/8/docs/api/");
            linksOffline("http://d.android.com/reference", "${android.sdkDirectory}/docs/reference");
            encoding "UTF-8"
            charSet 'UTF-8'
            author true
            version true
            splitIndex true
            noDeprecated true
            setMemberLevel(JavadocMemberLevel.PUBLIC)
        }
        failOnError false
        exclude '**/BuildConfig.java'
        exclude '**/R.java'
    }
}

搭建ldap服务器并认证登陆linux系统

1.搭建ldap服务器

在终端输入下面的命令:

sunny@server1:~$ sudo apt-get install slapd ldap-utils

填入相应的信息。如果相重新填写执行sudo dpkg-reconfigure slapd

安装管理工具:

sunny@server1:~$ sudo apt-get install phpldapadmin

修改配置文件

sunny@server1:~$ sudo vim /etc/phpldapadmin/config.php

$servers->setValue('server','base',array('dc=example,dc=com'));以及$servers->setValue('login','bind_id','cn=admin,dc=example,dc=com');位置将dc=example,dc=com修改为上面配置slapd时填入的域名。

登入管理页面http://localhost/phpldapadmin

创建People和group对象,并建立群组和用户实例。

2.ldap认证登陆

sunny@server2:~$ sudo apt-get install ldap-auth-client nscd
LDAP server Uniform Resource Identifier: ldap://LDAP-server-IP-Address
将默认的"ldapi:///"修改为"ldap://"
Distinguished name of the search base:填入上面"dc=example,dc=com"部分
LDAP version to use: 3
Make local root Database admin: No
Does the LDAP database require login? No
LDAP account for root:填入上面"cn=admin,dc=example,dc=com"部分
LDAP root account password: 你的ldap管理密码

如果想重新配置执行sunny@server2:~$ sudo dpkg-reconfigure ldap-auth-config

编辑文件nsswitch.conf

sudo vim /etc/nsswitch.conf
passwd: files ldap
group: files ldap
shadow: files ldap

上面三部分需要包含ldap

编辑文件

sunny@server2:~$ sudo vim /etc/pam.d/common-session

在行尾填入如下内容:

session required    pam_mkhomedir.so skel=/etc/skel umask=0022

重启服务:

sudo /etc/init.d/nscd restart

这样这台服务器就可以通过server1的ldap中配置的用户登陆了。

怎样搭建本地AOSP Gerrit服务器

怎样搭建本地AOSP Gerrit服务器

在这个教程里,我会介绍怎样搭建一个本地Android源码Gerrit服务器。

完成这个教程后,你会拥有一个完全可运行的AOSP镜像和本地Gerrit服务器。

首先我们需要一个Linux服务器。这里用Ubuntu 14.04

Gerrit 需求:

1.Java JDK > 1.7

2.Git

3.SSH server

4.DB

我选择mysql作为数据库服务,当然你也可以用其他的数据库软件。可以参考Gerrit文档

这里有一句命令可以让你得到你所需要的一切。

$ sudo apt-get install git openjdk-8-jdk openssh-server mysql-server gitweb

下载并安装Android repo

$ sudo curl https://storage.googleapis.com/git-repo-downloads/repo > /usr/bin/repo
$ sudo chmod a+x /usr/bin

现在我们需要设置一个本地Android镜像,这需要一段时间,你可以先去喝杯咖啡。

$ mkdir -p /usr/local/aosp/mirror
$ cd /usr/local/aosp/mirror
$ repo init -u https://android.googlesource.com/mirror/manifest --mirror
$ repo sync

下载Gerrit

创建一个Gerrit用户

$ sudo adduser --system --shell /bin/bash --gecos 'Gerrit Code Review User' --group --disabled-password --home /home/gerrit2 gerrit2

Gerrit需要一个数据库来工作,这里用的是mysql。打开终端输入以下命令:

$ mysql -u root -p
CREATE USER 'gerrit2'@'localhost' IDENTIFIED BY 'secret';
CREATE DATABASE reviewdb;
ALTER DATABASE reviewdb charset=latin1;
GRANT ALL ON reviewdb.* TO 'gerrit2'@'localhost';
FLUSH PRIVILEGES;
quit

上面这个命令在mysql中创建了一个gerrit用户,一个数据库和gerrit用户需要的权限集合。

用新的系统用户登陆:

$ sudo su gerrit2

复制上面下载的文件gerrit-2.13.5.war到gerrit2的home下,然后执行下面的命令:

$ java -jar ./gerrit-2.11.war init -d review_site
Using secure store: com.google.gerrit.server.securestore.DefaultSecureStore

*** Gerrit Code Review 2.11
***

Create ‘/home/gerrit2/review_site’ [Y/n]?

*** Git Repositories
***

Location of Git repositories [git]:

*** SQL Database
***

Database server type [h2]: MySQL

Gerrit Code Review is not shipped with MySQL Connector/J 5.1.21
** This library is required for your configuration. **
Download and install it now [Y/n]?
Downloading http://repo2.maven.org/maven2/mysql/mysql-connector-java/5.1.21/mysql-connector-java-5.1.21.jar … OK
Checksum mysql-connector-java-5.1.21.jar OK
Server hostname [localhost]:
Server port [(mysql default)]:
Database name [reviewdb]:
Database username [gerrit2]: gerrit2
gerrit’s password :
confirm password :

*** Index
***

Type [LUCENE/?]:

*** User Authentication
***

Authentication method [OPENID/?]:

*** Review Labels
***

Install Verified label [y/N]?

*** Email Delivery
***

SMTP server hostname [localhost]:
SMTP server port [(default)]:
SMTP encryption [NONE/?]:
SMTP username :

*** Container Process
***

Run as [gerrit2]:
Java runtime [/usr/lib/jvm/java-8-openjdk-amd64/jre]:
Copy gerrit-2.11.war to /home/gerrit2/review_site/bin/gerrit.war [Y/n]?
Copying gerrit-2.11.war to /home/gerrit2/review_site/bin/gerrit.war
*** SSH Daemon
***

Listen on address [*]:
Listen on port [29418]:

Gerrit Code Review is not shipped with Bouncy Castle Crypto SSL v151
If available, Gerrit can take advantage of features
in the library, but will also function without it.
Download and install it now [Y/n]?
Downloading http://www.bouncycastle.org/download/bcpkix-jdk15on-151.jar … OK
Checksum bcpkix-jdk15on-151.jar OK
Generating SSH host key … rsa… dsa… done

*** HTTP Daemon
***

Behind reverse proxy [y/N]?
Use SSL (https://) [y/N]?
Listen on address [*]:
Listen on port [8080]:
Canonical URL [http://ubuntu:8080/]: http://10.0.0.9:8080

*** Plugins
***

Installing plugins.
Install plugin download-commands version v2.11 [y/N]?
Install plugin reviewnotes version v2.11 [y/N]?
Install plugin singleusergroup version v2.11 [y/N]?
Install plugin replication version v2.11 [y/N]?
Install plugin commit-message-length-validator version v2.11 [y/N]?
Initializing plugins.
No plugins found with init steps.

Initialized /home/gerrit2/review_site
Executing /home/gerrit2/review_site/bin/gerrit.sh start
Starting Gerrit Code Review: OK
Waiting for server on ubuntu:8080 … OK
Opening http://10.0.0.9:8080/#/admin/projects/ …FAILED
Open Gerrit with a JavaScript capable browser:
http://10.0.0.9:8080/#/admin/projects/

现在Gerrit已经开始运行了。

需要注意的是,第一个登陆到gerrit的用户将会成为管理员。

Gerrit能通过多种认证方式登陆。上面选择的OpenID。

现在让我们打开浏览器并打开Gerrit网站。

注册并登陆后需要设置SSH keys,这样我们就能够在命令行下工作。

下面我们在Ubuntu系统的另一个用户下执行以下命令:

$ ssh-keygen <ENTER>
Generating public/private rsa key pair.
Enter file in which to save the key (/home/serveradmin/.ssh/id_rsa):  <ENTER>
Enter passphrase (empty for no passphrase): <ENTER>
Enter same passphrase again: <ENTER>
Your identification has been saved in /home/serveradmin/.ssh/id_rsa.
Your public key has been saved in /home/serveradmin/.ssh/id_rsa.pub.
The key fingerprint is:
d5:7b:51:d8:22:0e:95:63:f9:0e:a2:22:1c:97:76:40 serveradmin@ubuntu
The key's randomart image is:
+---[RSA 2048]----+
| .E ..o o.|
| . ..* o..|
| o .+.+.. |
| . + ... o... |
| . + .S. ..o. |
| o . . .. |
| . . |
| |
| |
+-----------------+

$ cat ~/.ssh/id_rsa.pub  <ENTER>
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDobCUbb8ExP9ci48ZCzCUE3P+IjoH6zrv/l88+4NOTf9FJWDAl4SHCXI+mrZoFEeZo9
uieKTuvHqUFQNpnVA9vfNY6bhaTucAAt0fX9Q1M1ZtNj2IxaQd7u9PnxjSGEig0BUtjqDEu4CMhMShXGWsGAwL7ju/qu7G7RF
iK/Wtcye6wUSjziXseCusb1DUZZ6dsOpxrPYEM3kwXpItQtAq1oEIQWsxEgj2nrOqRXm1UWdqIQU1X45XHQtg5iqi44PfLVNU
3alu453MeWn5PrpSS5dFw/7AkBW4KMPwrOvVnu8gb9xLA0TWtPf+sQ9ROEQC5SBeO+4Q9XRNf5YaswpLj 

在网站的右上角点击你的用户名然后点击Settings,在左侧的菜单中选择“SSH Public Keys”,复制上面的内容到里面,然后点Add。

下面让我们测试一下通过SSH访问Gerrit:

ssh -p 29418 admin@localhost <ENTER> <Change "admin" to your username in gerrit>

**** Welcome to Gerrit Code Review ****

Hi Administrator, you have successfully connected over SSH.

Unfortunately, interactive shells are disabled.
To clone a hosted Git repository, use:

git clone ssh://ramon@10.0.0.9:29418/REPOSITORY_NAME.git
Connection to localhost closed.

出现以上信息说明登陆成功,下面创建两个group:“android-admin” and “android”

前者用来管理,包含review,merge,delete等权限,后者只有view和change-set的权限。

在网页中点击People -> Create New Group,输入名称“android-admin”。执行同样的操作创建“android”。

现在我们为AOSP代码树创建一个父项目。所有为这个项目的设置都会继承到子项目。如果跳过这步,AOSP项目会继承“All-Projects”项目,而这个项目太通用了。

在网站中点击Project -> Create New Project,填入以下内容:

Project Name: Android
Rights Inherit From: All-Projects

勾选 “Only Serve As Parent For Other Projects”,然后点击“Create Project”按钮。

项目已经创建完,下面来为这个项目设置权限控制:

点击Projects -> List,然后选择“Android”项目,点击“Access”然后点击“Edit”,修改成如下图。图中还包含了其他的群组,可自行设置。

Gerrit权限配置

现在我们可以把所有的Android项目推送到Gerrit了。

第一条命令会在Gerrit上创建所有的Android项目;第二条命令会将刚刚创建的项目的父项目修改为“Android”;第三条命令会将代码推送到Gerrit,时间会比较长。

进入下载Android镜像的目录执行以下命令:

$ repo forall -c 'echo $REPO_PATH; ssh -p 29418 admin@localhost gerrit create-project --name android/$REPO_PATH --owner android;'

accessories/manifest
device/asus/deb
device/asus/flo
device/asus/flo-kernel
device/asus/fugu
device/asus/fugu-kernel
…

$ repo forall -c 'echo $REPO_PATH; ssh -p 29418 admin@localhost gerrit set-project-parent --parent Android android/$REPO_PATH;'

accessories/manifest
device/asus/deb
device/asus/flo
device/asus/flo-kernel
…

$ repo forall -c 'echo $REPO_PATH; git push ssh://ramon@localhost:29418/android/$REPO_PATH +refs/heads/* +refs/tags/*;'

大功告成!

创建Gerrit服务自启:

$ sudo echo "GERRIT_SITE=/opt/gerrit-review" >> /etc/default/gerritcodereview
$ sudo ln -snf /opt/gerrit-review/bin/gerrit.sh /etc/init.d/gerrit
$ sudo update-rc.d gerrit defaults

下面贴一个gerrit配置文件(postgre数据库,ldap认证,提交信息增加jira链接)

[gerrit]
    basePath = git
    canonicalWebUrl = http://localhost:8080/
[database]
    type = postgresql
    hostname = localhost
    database = reviewdb
    username = gerrit2
[index]
    type = LUCENE
[auth]
    type = LDAP
[ldap]
    server = ldap://localhost:389
    username = cn=admin,dc=darkerthanblack,dc=org
    accountBase = ou=People,dc=darkerthanblack,dc=org
    groupBase = ou=group,dc=darkerthanblack,dc=org
[receive]
    enableSignedPush = false
[sendemail]
    smtpServer = smtp.exmail.qq.com
    smtpServerPort = 465
    smtpEncryption = SSL
    smtpUser = example@example.com
        smtpPass = your_password
        from = example@example.com
[container]
    user = gerrit2
    javaHome = /usr/lib/jvm/java-8-openjdk-amd64/jre
[sshd]
    listenAddress = *:29418
    maxConnectionsPerUser = 0
[httpd]
    listenUrl = http://*:8080/
[cache]
    directory = cache
[gitweb]
    cgi = /usr/lib/cgi-bin/gitweb.cgi
[commentlink "jira"]
    match = ([A-Z]+-[0-9]+)
    link = http://localhost:8081/browse/$1

参考:
http://openwares.net/linux/gerrit2_setup.html
https://nativeguru.wordpress.com/2015/08/18/how-to-set-local-aosp-gerrit-server-part-1

KVM

一、安装kvm

  1. $ sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
  2. $ sudo adduser `id -un` libvirtd
  3. 验证安装:
    $ virsh -c qemu:///system list
    没有错误信息就表明安装成功!
    确认如下两个文件的权限正确:
    $ sudo ls -la /var/run/libvirt/libvirt-sock
    srwxrwx--- 1 root libvirtd 0 2010-08-24 14:54 /var/run/libvirt/libvirt-sock
    $ ls -l /dev/kvm
    crw-rw----+ 1 root kvm 10, 232 Jul 8 22:04 /dev/kvm
  4. 安装完毕后,会自动生成虚拟网卡 virbr0,可以通过 ifconfig 查看确认一下
  5. 创建网卡桥接
    $ sudo vi /etc/network/interfaces
    增加如下内容:

    auto br0
    iface br0 inet static
    address 192.168.0.222
    netmask 255.255.255.0
    gateway 192.168.0.1
    bridge_ports eth0

    保存,重启网卡设置,ifconfig 再查看网卡的设置,这个时候 eth0 已经没有具体的IP地址,IP地址出在了 br0 的虚拟网上面。
    安装后,默认的目录为:/etc/libvirt/qemu/

二、kvm 虚拟机的日常管理


virsh list --all > 查看虚拟机状态
virsh start [name] > 开机
virsh shutdown [name] > 关机
virsh destroy [name] > 强制关闭电源
virsh reboot[name] > 关机
virsh suspend [name] > 挂起服务器
virsh resume [name] > 恢复服务器
virsh autostart [name] > 配置开机自启动虚拟机 (/etc/libvirt/qemu/autostart/)
virsh undefine [name] > 删除虚拟机 (只删除配置文件,并不删除虚拟磁盘文件)
virsh create /etc/libvirt/qemu/[name].xml > 通过配置文件启动虚拟机
virsh dumpxml [name] > /etc/libvirt/qemu/[name].xml > 导出KVM虚拟机配置文件(可通过这种方式进行备份)
virsh edit [name] > 编辑虚拟机配置文件(/etc/libvirt/qemu/[name].xml,不建议直接通过vi编辑)
virsh --version > 查看虚拟工具版本
virt-install --version > 查看虚拟工具版本
qemu-kvm -version > 查看虚拟工具版本

注:virsh 命令丰富,可以执行各种维护任务。

三、安装 Win2003SP2 虚拟机

  1. 上传系统 iso 文件到 /file/tools/win/win2003/WIN_2003_SP2.iso
  2. 开始安装

    $ virt-install --name=win2003sp2 \
    --hvm \
    --ram 1024 \
    --vcpus=1 \
    --os-type=windows \
    --os-variant=win2k3 \
    --arch=x86_64 \
    --disk path=/file/kvm/win2003sp2/win2003sp2.img,size=20 \
    --network bridge=br0 \
    --accelerate \
    --graphics vnc,listen=0.0.0.0,port=5911 \
    --cdrom /file/tools/win/win2003/WIN_2003_SP2.iso \
    --boot cdrom

    参数说明:

    --name 指定虚拟机名称
    --hvm 使用全虚拟化(与--paravirt相对)
    --ram 分配内存大小,单位为 MB
    --vcpus 分配CPU核心数,最大与实体机CPU核心数相同
    --disk 指定虚拟机使用的磁盘,path 指定路径,size 指定大小,单位为G
    --network 网络设置,使用默认配置时可设为 "--network network:default"
    --accelerate 加速
    --graphics vnc,listen=0.0.0.0,port=5911 指定VNC监控端口、绑定IP,默认端口为5900,端口不能重复;IP 默认绑定127.0.0.1,这里改为 0.0.0.0
    --cdrom 指定安装镜像iso设置光驱获取虚拟光驱文件的路径
    --os-type=windows
    --os-variant=win2k3
    --arch=x86_64
    --boot cdrom 指定从 cdrom 启动,从硬盘启动时设为 hd
    --autostart 指定主机启动时自动启动此虚拟机

  3. 将虚拟机的启动方式改为从磁盘启动
    $ virsh edit win2003sp3
    <boot dev='cdrom'/>改为 <boot dev='hd'/>
    然后重新启动虚拟机:
    $virsh destroy win2003sp3
    $virsh start win2003sp3
    之后就可以重新使用 vnc 连接,继续安装过程。

  4. 安装完毕后按需要设置IP地址、远程连接等即可

四、KVM 克隆

复制已经安装好的虚拟机为另一个全新的虚拟机。如要将上面的 win2003sp2 复制为 win2003sp2-2:
1. 关闭 win2003sp2
$virsh shutdown win2003sp2
2. 克隆 win2003sp2-2
$virt-clone -o win2003sp2 -n win2003sp2-2 -f /file/kvm/win2003sp2/win2003sp2-2.img
如果虚拟机文件比较大,复制的时间就会比较长。
3. 修改 win2003sp2-2.xml 文件
修改 vnc 端口避免与 win2003sp2 重复。
$virsh edit win2003sp2-2
<graphics type='vnc' port='5912' autoport='no' listen='0.0.0.0'>
4. 启动 win2003sp2-2
$virsh start win2003sp2-2
最后利用 vnc 登录到 win2003sp2-2 之后,修改网络设置,避免 IP 冲突。

五、KVM 快照

对虚拟机做快照,防止损坏了可以正常恢复。kvm 快照分两种:
第1种:lvm 快照,如果分区是 lvm,可以利用 lvm 进行 kvm 的快照备份
第2种:由于 raw 格式不支持镜像,所以需要将格式转换为 qcow2 才可以创建快照。
第2种具体操作如下:
kvm 虚拟机默认使用 raw 格式的镜像格式,性能最好,速度最快,它的缺点就是不支持一些新的功能,如镜像、zlib 磁盘压缩、AES加密等。
要使用镜像功能,磁盘格式必须为 qcow2。
下面开始 kvm 虚拟机快照备份的过程:
1. 查看磁盘格式
$qemu-img info win2003sp2.img
2. 关闭 win2003sp2
$virsh shutdown win2003sp2
3. 转换磁盘格式
$qemu-img convert -f raw -O qcow2 win2003sp2.img win2003sp2.img.qcow2
-f 源镜像的格式
-O 目标镜像的格式
4. 修改虚拟机配置文件,指向新的磁盘格式文件
$virsh edit win2003sp2
<devices>
...
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/>
<source file='/file/kvm/win2003sp2/win2003sp2.img.qcow2'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
...
</devices>

注:我发现转换后镜像文件占用的空间大大减少了,而且日后为动态自动增加,而不是固定占用开始设置时占用的大小。
5. 创建快照
$virsh snapshot-create-as win2003sp2 clean
6. 查看虚拟机镜像快照的版本
$virsh snapshot-list win2003sp2
7. 看当前最新的快照版本
$virsh snapshot-current win2003sp2
8. 恢复虚拟机快照
恢复虚拟机快照前必须先关闭虚拟机!
$virsh snapshot-revert win2003sp2 clean
9. 删除虚拟机快照
$virsh snapshot-delete win2003sp2 clean