cross compile bash for openWRT on Rasp Pi 3

refer https://openwrt.org/docs/guide-developer/crosscompile

openWRT source 編譯的時候可以順便編譯出cross compile tool chain

  1. git clone https://git.lede-project.org/source.git
  2. cd source
  3. make menuconfig
  4. enter target system, select BCM27xx
  5. enter subtarget, select BCM2710
  6. check and enter Advanced configuration options (for developers)
    1. check Target Options
    2. check Toolchain Options
    3. keep default in above 2 options
  7. make -j8

以上編譯完成之後會出現 staging_dir/ 這個資料夾

staging_dir/ 資料夾裡面會有四個資料夾

host
packages
target-arm_cortex-a53+neon-vfpv4_musl-1.1.16_eabi
toolchain-arm_cortex-a53+neon-vfpv4_gcc-5.4.0_musl-1.1.16_eabi

toolchain 就是第四個資料夾了

接著寫個script (~/crosscompile/env.sh)方便設定cross compile 環境變數

export STAGING_DIR=/data2/owenwen/crosscompile/source/staging_dir
export TOOLCHAIN_DIR=$STAGING_DIR/toolchain-arm_cortex-a53+neon-vfpv4_gcc-5.4.0_musl-1.1.16_eabi
export LDCFLAGS=$TOOLCHAIN_DIR/usr/lib
export LD_LIBRARY_PATH=$TOOLCHAIN_DIR/usr/lib
export PATH=$TOOLCHAIN_DIR/bin:$PATH

然後下載 bash source , configure 的部份

  1. wget https://ftp.gnu.org/gnu/bash/bash-4.4.tar.gz
  2. tar zxf bash-4.4.tar.gz
  3. cd bash-4.4
  4. source ~/crosscompile/env.sh
  5. ./configure –build=i686-linux –host=armv7-linux CC=$TOOLCHAIN_DIR/bin/arm-openwrt-linux-gcc CXX=$TOOLCHAIN_DIR/bin/arm-openwrt-linux-g++ –without-bash-malloc
  6. make -j8

build pass 之後就會有一個可以在 openWRT on Rasp PI 3 上面運行的bash 囉!

在沒有加 –without-bash-malloc 之前,運行bash 會看到下面這個錯誤訊息

locale.c:81: cannot allocate 18 bytes

咕狗之後看到docker bash 也有一樣的錯誤訊息並且說明是musl 沒有實做 brk/sbrk 的關係

https://github.com/tianon/docker-bash/blob/master/4.4/Dockerfile

# musl does not implement brk/sbrk (they simply return -ENOMEM)
# bash: xmalloc: locale.c:81: cannot allocate 18 bytes (0 bytes allocated)

 

我也把一份已經編譯好的上傳在google drive bash

refer http://worldend.logdown.com/posts/276005-cross-compile-for-openwrt

How CVE-2014-6271 works

透過下面這篇看懂了~ycombinator除了創業竟然還可以順便解惑…
https://news.ycombinator.com/item?id=8361574

先透過下面這個方式設定一個環境變數
$ export badvar='() { :;}; echo vulnerable’
然後再呼叫bash執行某指令,例如
$ bash -c “pwd"
然後就可以發現原本設定在環境變數裡面分號後面的指令竟然就被執行了…
$ bash -c “pwd"
vulnerable
/home/owen

原因應該是呼叫 bash 的時候,實際上的行為就是 fork 出一個 bash process
並且會設定一次目前現有的環境變數給 fork 出來的子程序
然後在設定環境變數的過程中執行到了badvar=() { :;}; echo vulnerable
然後就順便執行了後面的 echo 指令
不過這好像沒有辦法作到權限提昇,傷害應該有限

php 下載 youtube 的影片,並且取出 mp3 or ogg 音源

如何從 youtube 下載影片並且自動轉出 mp3 or ogg 檔案


解析出來的網址如下:


array(10) {
  [0]=>
  string(422) "url=http://o-o.preferred.ascc-tpe1.v24.lscache3.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Cratebypass%2Ccp&fexp=912302%2C906429%2C913105&itag=46&ip=140.0.0.0&signature=3CA6BBF9474841CF105653580E29EB74BB9148FC.325416BE1EBD7407467F642EEFBECCFEBCD5951D&sver=3&ratebypass=yes&source=youtube&expire=1330387565&key=yt1&ipbits=8&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [1]=>
  string(421) "url=http://o-o.preferred.ascc-tpe1.v6.lscache1.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Cratebypass%2Ccp&fexp=912302%2C906429%2C913105&itag=37&ip=140.0.0.0&signature=3DD8E663008956A26A1DABFADFC0BD852D0C8CF5.CD9C6458FAB292D8144FA8284ED55479B8065734&sver=3&ratebypass=yes&source=youtube&expire=1330387565&key=yt1&ipbits=8&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [2]=>
  string(422) "url=http://o-o.preferred.ascc-tpe1.v14.lscache3.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Cratebypass%2Ccp&fexp=912302%2C906429%2C913105&itag=45&ip=140.0.0.0&signature=5E6D3DBAEA96C7937278BD88FA520F7FAF287A6D.196CA2DBD1F58D5B0C63370FC0CE2097321F53A2&sver=3&ratebypass=yes&source=youtube&expire=1330387565&key=yt1&ipbits=8&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [3]=>
  string(421) "url=http://o-o.preferred.ascc-tpe1.v7.lscache1.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Cratebypass%2Ccp&fexp=912302%2C906429%2C913105&itag=22&ip=140.0.0.0&signature=9521DF5BF21112B0C5AC95D4135057DE6EDF6EAD.0DBD9897B1442F30F2436D61459281F266B0E171&sver=3&ratebypass=yes&source=youtube&expire=1330387565&key=yt1&ipbits=8&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [4]=>
  string(422) "url=http://o-o.preferred.ascc-tpe1.v16.lscache4.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Cratebypass%2Ccp&fexp=912302%2C906429%2C913105&itag=44&ip=140.0.0.0&signature=708BC1DE44BF36D838A7A343343D448D13070901.B6D3417B3410D1CA4AE590DFD1A2444859711B61&sver=3&ratebypass=yes&source=youtube&expire=1330387565&key=yt1&ipbits=8&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [5]=>
  string(470) "url=http://o-o.preferred.ascc-tpe1.v19.lscache3.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Calgorithm%2Cburst%2Cfactor%2Ccp&fexp=912302%2C906429%2C913105&algorithm=throttle-factor&itag=35&ip=140.0.0.0&burst=40&sver=3&signature=5FBC0A0F53CA3B475D3F50404F0A9CCD30CDD972.7C8E3CA2F856B4A907608B862206CE9C6BFC9D63&source=youtube&expire=1330387565&key=yt1&ipbits=8&factor=1.25&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [6]=>
  string(421) "url=http://o-o.preferred.ascc-tpe1.v9.lscache2.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Cratebypass%2Ccp&fexp=912302%2C906429%2C913105&itag=43&ip=140.0.0.0&signature=B9811AF3C187D1C938A3B7762CB563895A7179ED.7F50E525FCF19E50EC72C7BFA42F71F08F94D9E6&sver=3&ratebypass=yes&source=youtube&expire=1330387565&key=yt1&ipbits=8&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [7]=>
  string(470) "url=http://o-o.preferred.ascc-tpe1.v22.lscache7.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Calgorithm%2Cburst%2Cfactor%2Ccp&fexp=912302%2C906429%2C913105&algorithm=throttle-factor&itag=34&ip=140.0.0.0&burst=40&sver=3&signature=C73DA387F4955ACAAE339AAE67677A62B631EC73.A066F4F997AA4C6D1C90BE3FAE005EF2DE18A753&source=youtube&expire=1330387565&key=yt1&ipbits=8&factor=1.25&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [8]=>
  string(421) "url=http://o-o.preferred.ascc-tpe1.v9.lscache7.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Cratebypass%2Ccp&fexp=912302%2C906429%2C913105&itag=18&ip=140.0.0.0&signature=4C1A34563C1B2A42B1C023A2C620C070AC7DEAB7.0CF6081EA6930AA4EC68FD025F6F98B00F902A11&sver=3&ratebypass=yes&source=youtube&expire=1330387565&key=yt1&ipbits=8&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
  [9]=>
  string(469) "url=http://o-o.preferred.ascc-tpe1.v12.lscache5.c.youtube.com/videoplayback?sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Csource%2Calgorithm%2Cburst%2Cfactor%2Ccp&fexp=912302%2C906429%2C913105&algorithm=throttle-factor&itag=5&ip=140.0.0.0&burst=40&sver=3&signature=D4AB3700B913D6FA884D91AB5A27B7C219DE9912.CF9CB67707CAD08979DF1CFBED4724BC39C78E92&source=youtube&expire=1330387565&key=yt1&ipbits=8&factor=1.25&cp=U0hSRVNTVV9LT0NOMl9LTVlGOmhZR1cwOUZseVVa&id=e7bceb9ff3396c4f"
}

裡面有 ip 這個參數,基本上我試了一下,在 A 這個電腦產生的網址真的沒有辦法在 B 電腦下載(兩邊 IP 不同)

產生出來的連結裡面有個 expire 參數,帶的是 unix time 時間

網址後面帶有 itag 這個參數,這個數值可以提供影片的格式和畫素資訊,請直接看 wiki 的整理:
http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs

$ ffmpeg -i input_name -y -vn -f ogg output_name
$ ./youtube-dl.py --extract-audio --audio-format mp3 http://www.youtube.com/watch?v=57zrn_M5bE8
-y 輸出檔名相同的話直接覆蓋
-vn 只取出音源
-f 輸出格式

另外,上面的 php 程式碼部份,可以選擇取出目前 youtube 上面的影片 webm 格式

ffmpeg 我安裝 0.10 版本才有 webm 的 vp8 格式支援(Ubuntu10.04 server LTS)

sudo apt-get install libfaac-dev libmp3lame-dev

./configuration –enable-pthreads –enable-gpl –enable-libfaac –enable-libmp3lame –enable-nonfree

http://ffmpeg.org/releases/ffmpeg-0.10.tar.gz

試跑的過程中有時候成功有時候失敗,原因不明。
而且學網很慢= =a

<?php
//產生出來的連結不一定第一次點擊就可以使用
//所以網路上的下載方式有些會要求使用者貼上 info 資訊
//目的應該就是先產生第一次點擊
//保證使用者要下載的時候該連結一定可以生效
$file_contents = file_get_contents("http://www.youtube.com/get_video_info?video_id=57zrn_M5bE8");
$file_contents = urldecode(urldecode($file_contents));//至此,產生出來的 http link 可以使用了
preg_match_all('/url=(.+?)id=w{16}/', $file_contents, $p);//$p[0]:包含id ,$p[1]:不含id
$i = 0;
//echo '

preview image

'; foreach( $p[0] as $url ){ $itag = strstr($url, 'itag='); $url = substr($url, strlen("url=")) ; $itag = strstr($itag, '&', true); $itag = strstr($itag, '='); $itag = substr($itag, strlen("=")); $info[$i]["url"] = $url; $info[$i]["itag"] = $itag; $i++; } $max = $info[0]; foreach( $info as $i ){ if( $i["itag"] > $max["itag"] ){ $max = $i; } } //echo $max["itag"]."
n"; //echo $max["url"]."
n"; switch($max["itag"]){ case "46": echo '1080p WebM'; exec('curl "http://www.youtube.com/get_video_info?video_id=57zrn_M5bE8" > /tmp/youtube.tmp'); exec('curl "'.$max["url"].'" > a.webm'); break; case "45": echo '720p WebM'; break; case "44": echo '480p WebM'; break; case "43": echo '360p WebM'; break; case "38": echo '2304p MP4'; break; case "37": echo '1080p MP4'; break; case "22": echo '720p MP4'; break; case "18": echo '360p MP4'; break; case "102": echo '720p WebM 3D'; break; case "101": echo '480p WebM 3D'; break; case "100": echo '360p WebM 3D'; break; case "84": echo '720p MP4 3D'; break; case "85": echo '520p MP4 3D'; break; case "82": echo '360p MP4 3D'; break; case "83": echo '240p MP4 3D'; break; case "35": echo '480p FLV'; break; case "34": echo '360p FLV'; break; case "6": echo '270p FLV'; break; case "5": echo '224p FVL'; break; case "17": echo '3GP'; break; case "13": echo '3GP'; break; default: echo "未知的格式n"; break; } ?>

如何用 ps 找出 fork 的 PID

原文網址:http://www.thegeekstuff.com/2011/04/ps-command-examples/

在 Unix-like 系統裡面,跑伺服器,或者寫任何7×24全年無休的程式,關心我們的程式記憶體使用量以及使用者使用的時候程式的 fork 或者 thread 情況非常重要,也很有趣。

在 fork 或者 thread 設計的好,加上好的記憶體管理方式,可以非常準確的使用機器資源,達到非常好的服務效率。

1.最普遍的用法 ps -ef

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 11:00 ?        00:00:01 /sbin/init
root         2     0  0 11:00 ?        00:00:00 [kthreadd]
root         3     2  0 11:00 ?        00:00:00 [migration/0]
root         4     2  0 11:00 ?        00:00:00 [ksoftirqd/0]
root         5     2  0 11:00 ?        00:00:00 [watchdog/0]
root         6     2  0 11:00 ?        00:00:00 [migration/1]
root         7     2  0 11:00 ?        00:00:00 [ksoftirqd/1]
root         8     2  0 11:00 ?        00:00:00 [watchdog/1]
...

e:列出所有程式
f:列出詳細資訊

原文文章在這邊還有提到 ps -aux ,說這是 BSD 底下的用法,我在 linux 上面打了 ps aux 也可以運作,還會額外顯示記憶體的資訊。這時候沒有 – 號。

2.根據使用者名稱或者指令名稱列出 ps -U, ps -C

owen@desktop:~$ ps -C chrome
  PID TTY          TIME CMD
 1704 ?        00:04:04 chrome
 1708 ?        00:00:22 chrome
 1710 ?        00:00:00 chrome
 1774 ?        00:00:30 chrome
 1877 ?        00:00:00 chrome
 1892 ?        00:05:19 chrome
 1919 ?        00:00:02 chrome
 2096 ?        00:10:01 chrome
 2666 ?        00:00:22 chrome
 2688 ?        00:00:34 chrome
 2932 ?        00:00:36 chrome
owen@desktop:~$ ps -U owen
  PID TTY          TIME CMD
 1229 ?        00:00:00 gnome-session
 1319 ?        00:00:13 ibus-daemon
 1332 ?        00:00:00 ssh-agent
 1335 ?        00:00:00 dbus-launch
 1338 ?        00:00:00 ibus-gconf
 1340 ?        00:00:19 python
 1342 ?        00:00:00 ibus-x11
 1380 ?        00:00:00 dbus-daemon

其實我還是覺得 ps -ef 之後使出 grep 處理比較符合需求…我怎麼可能每次都打出落落長的指令名稱呢,用 grep 只要指令的關鍵字出現就行了…例如:ps -ef | grep chro

3.列出 PID 或者 PPID 程序。ps -f -p, ps -f –ppid

magicallove@iwhiori:~$ ps -f --ppid 17877
UID        PID  PPID  C STIME TTY          TIME CMD
1000     17891 17877 16 Jan26 ?        3-18:01:12 /usr/lib/virtualbox/VirtualBox
1000     18101 17877  3 Jan26 ?        21:44:35 /usr/lib/virtualbox/VirtualBox
1000     28689 17877 25 Feb17 ?        06:43:27 /usr/lib/virtualbox/VirtualBox

上面演示了列出所有 ppid 為 17877 的程序 ,在本例中是 VM 呼叫出來的

magicallove@iwhiori:~$ ps -f -p 30491
UID        PID  PPID  C STIME TTY          TIME CMD
1000     30491     1 26 09:02 pts/1    01:38:26 filezilla

這個比較沒什麼用,就列出指定的 pid 的資訊。

4.樹狀圖顯示 process 之間的呼叫關係 ps -e –forest

 1688 ?        00:00:00 sshd
 1704 ?        00:04:10 chrome
 1708 ?        00:00:22  _ chrome
 2096 ?        00:10:10  _ chrome
 1710 ?        00:00:00 chrome
 1712 ?        00:00:00  _ nacl_helper_boo
 1774 ?        00:00:31  _ chrome
 1877 ?        00:00:00  _ chrome
 1892 ?        00:05:22  _ chrome
 1919 ?        00:00:02  _ chrome
 2666 ?        00:00:24  _ chrome
 2688 ?        00:00:34  _ chrome
 2932 ?        00:00:49  _ chrome
 1718 ?        00:01:06 firefox
 2012 ?        00:05:58  _ plugin-containe
 1731 ?        00:00:50 chromium-browse
 1743 ?        00:00:02  _ chromium-browse
 2007 ?        00:01:42  _ chromium-browse
 1745 ?        00:00:00 chromium-browse
 1808 ?        00:00:02  _ chromium-browse
 1813 ?        00:00:00  _ chromium-browse
 1832 ?        00:00:01  _ chromium-browse
 1837 ?        00:00:00  _ chromium-browse
 1842 ?        00:00:01  _ chromium-browse
 1847 ?        00:00:08  _ chromium-browse
 1852 ?        00:00:01  _ chromium-browse
 1857 ?        00:00:05  _ chromium-browse
 1862 ?        00:00:02  _ chromium-browse
 1867 ?        00:00:01  _ chromium-browse
 1872 ?        00:00:02  _ chromium-browse

列出程序之間呼叫的相對應關係,原本 ps -ef 看到很多 chromium-browse ,在這個參數作用下就可以看到父程序和子程序分別是誰了。
道理和 pstree 差不多。
演示中剛好也告訴了我們 咕狗瀏覽器吃資源不是假的,你看看這麼多 process ,難怪它快,火狐也不慢但是只有一個 process ,這樣應該撰寫代碼比較複雜吧!
奇妙的是,為什麼 chrome chromium-browse 都分別有兩個看似多餘的父程序,其底下又都掛了兩個子程序,其中奧妙不得而知。

5.這個指令巧了!可列出程序執行了多久!ps -p -o etime

owen@desktop:~$ ps -p2054 -o etime
    ELAPSED
   04:28:58

這時候,知道 -o (output) 後面可以接什麼參數非常重要,我從 man page 裡面翻出來的是:

STANDARD FORMAT SPECIFIERS
       Here are the different keywords that may be used to control the output format (e.g. with option -o) or to sort the selected
       processes with the GNU-style --sort option.

       For example:  ps -eo pid,user,args --sort user

       This version of ps tries to recognize most of the keywords used in other implementations of ps.

       The following user-defined format specifiers may contain spaces: args, cmd, comm, command, fname, ucmd, ucomm, lstart, bsdstart,
       start.

       Some keywords may not be available for sorting.


       CODE      HEADER DESCRIPTION

       %cpu      %CPU   cpu utilization of the process in "##.#" format. Currently, it is the CPU time used divided by the time the process
                        has been running (cputime/realtime ratio), expressed as a percentage. It will not add up to 100% unless you are lucky.
                        (alias pcpu).

       %mem      %MEM   ratio of the process's resident set size  to the physical memory on the machine, expressed as a percentage.
                        (alias pmem).

       args      COMMANDcommand with all its arguments as a string. Modifications to the arguments may be shown. The output in this column may
                        contain spaces. A process marked  is partly dead, waiting to be fully destroyed by its parent. Sometimes the
                        process args will be unavailable; when this happens, ps will instead print the executable name in brackets.
                        (alias cmd, command). See also the comm format keyword, the -f option, and the c option.
                        When specified last, this column will extend to the edge of the display. If ps can not determine display width, as
                        when output is redirected (piped) into a file or another command, the output width is undefined. (it may be 80,
                        unlimited, determined by the TERM variable, and so on) The COLUMNS environment variable or --cols option may be used
                        to exactly determine the width in this case. The w or -w option may be also be used to adjust width.

       blocked   BLOCKEDmask of the blocked signals, see signal(7). According to the width of the field, a 32-bit or 64-bit mask in
                        hexadecimal format is displayed. (alias sig_block, sigmask).

       bsdstart  START  time the command started. If the process was started less than 24 hours ago, the output format is " HH:MM", else it is
                        "mmm dd" (where mmm is the three letters of the month). See also lstart, start, start_time, and stime.

       bsdtime   TIME   accumulated cpu time, user + system. The display format is usually "MMM:SS", but can be shifted to the right if the
                        process used more than 999 minutes of cpu time.

       c         C      processor utilization. Currently, this is the integer value of the percent usage over the lifetime of the process.
                        (see %cpu).

       caught    CAUGHT mask of the caught signals, see signal(7). According to the width of the field, a 32 or 64 bits mask in hexadecimal
                        format is displayed. (alias sig_catch, sigcatch).

       class     CLS    scheduling class of the process. (alias policy, cls). Field's possible values are:
                        -   not reported
                        TS  SCHED_OTHER
                        FF  SCHED_FIFO
                        RR  SCHED_RR
                        B   SCHED_BATCH
                        ISO SCHED_ISO
                        IDL SCHED_IDLE
                        ?   unknown value

       cls       CLS    scheduling class of the process. (alias policy, class). Field's possible values are:
                        -   not reported
                        TS  SCHED_OTHER
                        FF  SCHED_FIFO
                        RR  SCHED_RR
                        B   SCHED_BATCH
                        ISO SCHED_ISO
                        IDL SCHED_IDLE
                        ?   unknown value

       cmd       CMD    see args. (alias args, command).

       comm      COMMANDcommand name (only the executable name). Modifications to the command name will not be shown. A process marked
                         is partly dead, waiting to be fully destroyed by its parent. The output in this column may contain spaces.
                        (alias ucmd, ucomm). See also the args format keyword, the -f option, and the c option.
                        When specified last, this column will extend to the edge of the display. If ps can not determine display width, as
                        when output is redirected (piped) into a file or another command, the output width is undefined. (it may be 80,
                        unlimited, determined by the TERM variable, and so on) The COLUMNS environment variable or --cols option may be used
                        to exactly determine the width in this case. The w or -w option may be also be used to adjust width.

       command   COMMANDsee args. (alias args, cmd).


       cp        CP     per-mill (tenths of a percent) CPU usage. (see %cpu).

       cputime   TIME   cumulative CPU time, "[dd-]hh:mm:ss" format. (alias time).

       egid      EGID   effective group ID number of the process as a decimal integer. (alias gid).

       egroup    EGROUP effective group ID of the process. This will be the textual group ID, if it can be obtained and the field width
                        permits, or a decimal representation otherwise. (alias group).

       eip       EIP    instruction pointer.

       esp       ESP    stack pointer.

       etime     ELAPSEDelapsed time since the process was started, in the form [[dd-]hh:]mm:ss.

       euid      EUID   effective user ID. (alias uid).

       euser     EUSER  effective user name. This will be the textual user ID, if it can be obtained and the field width permits, or a decimal
                        representation otherwise. The n option can be used to force the decimal representation. (alias uname, user).

       f         F      flags associated with the process, see the PROCESS FLAGS section. (alias flag, flags).

       fgid      FGID   filesystem access group ID. (alias fsgid).

       fgroup    FGROUP filesystem access group ID. This will be the textual user ID, if it can be obtained and the field width permits,
                        or a decimal representation otherwise. (alias fsgroup).

       flag      F      see f. (alias f, flags).

       flags     F      see f. (alias f, flag).

       fname     COMMANDfirst 8 bytes of the base name of the process's executable file. The output in this column may contain spaces.

       fuid      FUID   filesystem access user ID. (alias fsuid).

       fuser     FUSER  filesystem access user ID. This will be the textual user ID, if it can be obtained and the field width permits,
                        or a decimal representation otherwise.

       gid       GID    see egid. (alias egid).

       group     GROUP  see egroup. (alias egroup).

       ignored   IGNOREDmask of the ignored signals, see signal(7). According to the width of the field, a 32-bit or 64-bit mask in
                        hexadecimal format is displayed. (alias sig_ignore, sigignore).

       label     LABEL  security label, most commonly used for SE Linux context data. This is for the Mandatory Access Control ("MAC") found
                        on high-security systems.

       lstart    STARTEDtime the command started. See also bsdstart, start, start_time, and stime.

       lwp       LWP    lwp (light weight process, or thread) ID of the lwp being reported. (alias spid, tid).

       ni        NI     nice value. This ranges from 19 (nicest) to -20 (not nice to others), see nice(1). (alias nice).

       nice      NI     see ni. (alias ni).

       nlwp      NLWP   number of lwps (threads) in the process. (alias thcount).

       nwchan    WCHAN  address of the kernel function where the process is sleeping (use wchan if you want the kernel function name). Running
                        tasks will display a dash ('-') in this column.

       pcpu      %CPU   see %cpu. (alias %cpu).

       pending   PENDINGmask of the pending signals. See signal(7). Signals pending on the process are distinct from signals pending on
                        individual threads. Use the m option or the -m option to see both. According to the width of the field, a 32-bit or
                        64-bit mask in hexadecimal format is displayed. (alias sig).


       pgid      PGID   process group ID or, equivalently, the process ID of the process group leader. (alias pgrp).

       pgrp      PGRP   see pgid. (alias pgid).

       pid       PID    process ID number of the process.

       pmem      %MEM   see %mem. (alias %mem).

       policy    POL    scheduling class of the process. (alias class, cls). Possible values are:
                        -   not reported
                        TS  SCHED_OTHER
                        FF  SCHED_FIFO
                        RR  SCHED_RR
                        B   SCHED_BATCH
                        ISO SCHED_ISO
                        IDL SCHED_IDLE
                        ?   unknown value

       ppid      PPID   parent process ID.

       pri       PRI    priority of the process. Higher number means lower priority

       psr       PSR    processor that process is currently assigned to.

       rgid      RGID   real group ID.

       rgroup    RGROUP real group name. This will be the textual group ID, if it can be obtained and the field width permits, or a decimal
                        representation otherwise.

       rss       RSS    resident set size, the non-swapped physical memory that a task has used (in kiloBytes). (alias rssize, rsz).

       rssize    RSS    see rss. (alias rss, rsz).

       rsz       RSZ    see rss. (alias rss, rssize).

       rtprio    RTPRIO realtime priority.

       ruid      RUID   real user ID.

       ruser     RUSER  real user ID. This will be the textual user ID, if it can be obtained and the field width permits, or a decimal
                        representation otherwise.

       s         S      minimal state display (one character). See section PROCESS STATE CODES for the different values. See also stat if you
                        want additional information displayed. (alias state).

       sched     SCH    scheduling policy of the process. The policies SCHED_OTHER (SCHED_NORMAL), SCHED_FIFO, SCHED_RR, SCHED_BATCH,
                        SCHED_ISO, and SCHED_IDLE are respectively displayed as 0, 1, 2, 3, 4, and 5.

       sess      SESS   session ID or, equivalently, the process ID of the session leader. (alias session, sid).

       sgi_p     P      processor that the process is currently executing on. Displays "*" if the process is not currently running or
                        runnable.

       sgid      SGID   saved group ID. (alias svgid).

       sgroup    SGROUP saved group name. This will be the textual group ID, if it can be obtained and the field width permits, or a decimal
                        representation otherwise.

       sid       SID    see sess. (alias sess, session).

       sig       PENDINGsee pending. (alias pending, sig_pend).

       sigcatch  CAUGHT see caught. (alias caught, sig_catch).

       sigignore IGNOREDsee ignored. (alias ignored, sig_ignore).

       sigmask   BLOCKEDsee blocked. (alias blocked, sig_block).


       size      SZ     approximate amount of swap space that would be required if the process were to dirty all writable pages and then be
                        swapped out. This number is very rough!

       spid      SPID   see lwp. (alias lwp, tid).

       stackp    STACKP address of the bottom (start) of stack for the process.

       start     STARTEDtime the command started. If the process was started less than 24 hours ago, the output format is "HH:MM:SS", else it
                        is "  mmm dd" (where mmm is a three-letter month name). See also lstart, bsdstart, start_time, and stime.

       start_timeSTART  starting time or date of the process. Only the year will be displayed if the process was not started the same year ps
                        was invoked, or "mmmdd" if it was not started the same day, or "HH:MM" otherwise. See also bsdstart, start, lstart,
                        and stime.

       stat      STAT   multi-character process state. See section PROCESS STATE CODES for the different values meaning. See also s and state
                        if you just want the first character displayed.

       state     S      see s. (alias s).

       suid      SUID   saved user ID. (alias svuid).

       suser     SUSER  saved user name. This will be the textual user ID, if it can be obtained and the field width permits, or a decimal
                        representation otherwise. (alias svuser).

       svgid     SVGID  see sgid. (alias sgid).

       svuid     SVUID  see suid. (alias suid).

       sz        SZ     size in physical pages of the core image of the process. This includes text, data, and stack space. Device mappings
                        are currently excluded; this is subject to change. See vsz and rss.

       thcount   THCNT  see nlwp. (alias nlwp). number of kernel threads owned by the process.

       tid       TID    see lwp. (alias lwp).

       time      TIME   cumulative CPU time, "[dd-]hh:mm:ss" format. (alias cputime).

       tname     TTY    controlling tty (terminal). (alias tt, tty).

       tpgid     TPGID  ID of the foreground process group on the tty (terminal) that the process is connected to, or -1 if the process is not
                        connected to a tty.

       tt        TT     controlling tty (terminal). (alias tname, tty).

       tty       TT     controlling tty (terminal). (alias tname, tt).

       ucmd      CMD    see comm. (alias comm, ucomm).

       ucomm     COMMANDsee comm. (alias comm, ucmd).

       uid       UID    see euid. (alias euid).

       uname     USER   see euser. (alias euser, user).

       user      USER   see euser. (alias euser, uname).

       vsize     VSZ    see vsz. (alias vsz).

       vsz       VSZ    virtual memory size of the process in KiB (1024-byte units). Device mappings are currently excluded; this is subject
                        to change. (alias vsize).

       wchan     WCHAN  name of the kernel function in which the process is sleeping, a "-" if the process is running, or a "*" if the process
                        is multi-threaded and ps is not displaying threads.


%mem, etime, cmd 這幾個參數不錯。
我還蠻想要把 forest 和 -o etime 搭配起來看程序之間呼叫的狀況和執行時間
不過沒找到方法。

6.列出 thread ps -L

owen@desktop:~$ ps -f -L -C chromium-browser
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
owen      1731     1  1731  0   17 11:01 ?        00:00:33 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1752  0   17 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1753  0   17 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1754  0   17 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1755  0   17 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1756  0   17 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1757  0   17 11:01 ?        00:00:02 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1758  0   17 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1760  0   17 11:01 ?        00:00:18 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1817  0   17 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  1942  0   17 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  3466  0   17 15:12 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  3622  0   17 15:17 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  3623  0   17 15:17 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  3624  0   17 15:17 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  3625  0   17 15:17 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1731     1  3626  0   17 15:17 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser
owen      1743  1731  1743  0    1 11:01 ?        00:00:02 /usr/lib/chromium-browser/chromium-browser
owen      1745     1  1745  0    1 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=zygote
owen      1808  1745  1808  0    2 11:01 ?        00:00:02 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1808  1745  1810  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1813  1745  1813  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1813  1745  1815  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1832  1745  1832  0    2 11:01 ?        00:00:01 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1832  1745  1834  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1837  1745  1837  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1837  1745  1839  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1842  1745  1842  0    2 11:01 ?        00:00:01 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1842  1745  1844  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1847  1745  1847  0    2 11:01 ?        00:00:08 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1847  1745  1849  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1852  1745  1852  0    2 11:01 ?        00:00:01 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1852  1745  1854  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1857  1745  1857  0    2 11:01 ?        00:00:15 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1857  1745  1859  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1862  1745  1862  0    2 11:01 ?        00:00:02 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1862  1745  1864  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1867  1745  1867  0    2 11:01 ?        00:00:01 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1867  1745  1869  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1872  1745  1872  0    2 11:01 ?        00:00:02 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      1872  1745  1874  0    2 11:01 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=renderer --lang=en-US --force-fie
owen      2007  1731  2007  0   11 11:02 ?        00:01:56 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2008  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2025  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2027  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2028  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2030  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2032  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2035  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2037  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2039  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado
owen      2007  1731  2057  0   11 11:02 ?        00:00:00 /usr/lib/chromium-browser/chromium-browser --type=plugin --plugin-path=/usr/lib/ado

上面演示 chromium-browser 了在我的桌電上 fork 的情況和 thread 的情況,在使用者名稱後面三個欄位分別是pid, ppid, tid,tid 指的是 thread id,我曉得 pid, ppid,但是 tid 今天倒是第一次聽到。

7.針對使用記憶體做排序 ps -ef –sort %mem


這,我在我的桌電上面沒有成功排序過…查了 man page 也找不到原因
QQ
等我成功了再來更新文章

我認為所謂的 fork thread 設計的好,大概用這些概念下去評估。平常等待做 listen 的時候 fork 出來的數量,如何在伺服器負載高峰期做變化,不要佔去無謂的資源。

又如果 fork 出來的 child process 在結束或者在執行過程中會呼叫其他程式,要如何保證 child process 能夠正確呼叫,萬一 child process 遇到不可預期的錯誤掛了,parent process 如何繼續 child process 未完成的資料處理。

在 IO 上面, process 之間有沒有設計到可以互相分配一下佔用資源。因為硬碟很慢阿!如果 process 有個動作要佔用大量硬碟 IO,例如 tar 打包資料,那大家一起來就會變成大家都要很久才能完成…雖然不至於造成執行上的錯誤,但是很慢…就會被時代淘汰!

improve android build time with distcc

原文網址:http://goo.gl/P2LcN
下面當作備份。
我用四台機器下去作分散
過程遇到非常多像這樣的錯誤

cp: cannot stat `out/host/linux-x86/obj/STATIC_LIBRARIES/libcutils_intermediates/tztime.d': No such file or directory

而且編譯過程中使用的 cc 位址除了
/google/prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin 之外
還有
/google/prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/libexec/gcc/arm-linux-androideabi/4.4.3

我覺得問題出在 build/core/combo/TARGET_linux-arm.mk 中的 TARGET_TOOLS_PREFIX 值
這個值原本是
prebuilt/$(HOST_PREBUILT_TAG)/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-
下面文章說要改成
/usr/lib/distcc/arm-eabi-
這邊好像怪怪的

distcc简介

distcc

distcc源起于著名开源项目samba,是一款有着较长历史的跨平台开源分布式编译解决方案。

对于大多数c语言及其衍生语言来说,编译过程主要分为三个步骤:

  1. 预编译
  2. 编译
  3. 链接

distcc的作用就是将第二步的编译(3.0版本后通过pump支持部分第一步)过程采用网格计算的模式,将编译任务分配至其它主机,并在编译结束后回传,以供第三步链接使用。并由此降低了发起编译的机器的负载,并提升了编译效率。

distcc本身事实上并不参与任何编译过程,而只是一个编译器(gcc等)的前端。为编译器加入分布式特性,并参与部分管理和简单的负载均衡的功能。根据官方说法,其性能提升的极限阈值是3倍速度,即根据编译池的扩大,无限接近但无法达到原始编译速度的三分之一。

截至目前为止,distcc仅支持c语言及其衍生的c++,Objective-c等的编译。无法支持Java的分布式编译。

pump

自distcc版本3.0开始,加入了基于python的新工具pump。其功能是将头文件也随同源码一起发送至编译服务器。将部分预编译工作也进行分布式处理。从而进一步的提升了编译效率。官方给出的数字是对于文件传输、编译过程有10倍的效率提升。

但pump模式的局限之处在于:在整个编译过程中,源代码(尤其是头文件)不能进行改动,否则会造成错误的编译结果。

ccache

ccache同样产生于samba项目,其作用是将编译过程中的中间文件根据预编译结果,通过hash表索引进行缓存。Ccache具有以下特性:

 

  1. 在命中/缺失上是静态的
  2. 自动的缓存大小管理
  3. 可以缓存产生的编译警告
  4. 容易安装
  5. 很低的开销
  6. 可以使用硬联接来避免复制与distcc不同,ccache是android官方直接支持的编译加速方案。

dmucs

dmucs是为distcc服务的分布式负载均衡解决方案。原始的distcc仅根据服务器指定的顺序来分配编译任务,无法根据编译池中服务器的负载情况进行动态的编译任务分配。而dmucs则会将编译池中主机的负载情况通知到dmucs服务主机。并由其根据负载及编译机承担能力,动态的对编译任务进行分配。

 

基准测试结果及分析

构建结果分析

图1展示了不同编译条件下的编译时间。其中,单机的编译参数使用了-j8, 而双机、三机的编译参数则分别为: -j12,-j15

基准测试结果

 

由此图,大致可以总结出以下结论:

  1. distcc对android系统编译起到显著的加速作用,编译时间随着编译池中编译机器数目的增加而基本呈线性下降趋势。因为暂时无法获得更多的主机进行测试。故无法获知边界情况。
  2. 分布式编译的效果在android 4.0的编译过程中体现相对于 2.3更为明显。
  3. pump工具在编译过程中起到的速度提升作用并不明显。估计是因为android的预编译过程牵涉了大量的头文件和依赖关系,分布式得到的速度提升被文件传输过程所抵消。
  4. ccache的加入极大的改善了编译时间。对ccache的使用命中率,针对2.3.7平台,统计结果如下:cache hit 12127
    cache miss 16
    called for link 691
    not a C/C++ file 307
    unsupported compiler option 48
    files in cache 23020
    cache size 1.0 Gbytes
    max cache size 20.0 Gbytesccache 二次编译 2.3.7 统计结果

    cache hit 878
    cache miss 11494
    called for link 691
    not a C/C++ file 307
    unsupported compiler option 48
    files in cache 22988
    cache size 1.0 Gbytes
    max cache size 20.0 Gbytes
    ccache 初次编译 2.3.7 统计结果

    由此可见,在第二次编译时(代码未改动),cache的命中率超过了90%。而速度也因此得到大幅度的提升,基本接近初始速度的三倍。对android 4.0版本的速度提升尤为显著。但此数据对平时开发过程中代码有变化的情况仅能起到参考作用。

  5. 在测试过程中,dmucs的加入并未在时间上有效的缩短单编译请求的时间。原因是因为java/c的混合编译,无法根据distcc的推荐方法增加编译job的数量,也就无法充分体现分布式编译均衡的优势。但根据编译时观察,dmucs确实能有效的控制编译池中编译机器的负载,并根据编译能力进行平均分配。
  6. 此外,在图表中未能体现的一个结果为:发起编译的客户机平均负载在采用了分布式编译之后,在c类语言编译阶段,均有较为可观的降低。

 

图2展示了在三机分布式条件下编译android 4.0代码,job数目与编译时间的大致关系。

分布式条件下增加Job数目对编译时间的影响

由此可知,单纯增加job数目并不能获取更好的编译时间。具体原因如下述。

存在的问题及后续解决方案的方向

由于android系统的编译过程中同时存在java的编译和c的编译,而distcc又仅支持c类语言的分布式编译。故对于android的分布式编译获得的效果不如普通纯c类语言项目明显。随着jobs数目的增加,仅能在本机处理的java编译过程反而由于机器硬件机能的限制而拖慢了整体的编译速度,甚至抵消了由distcc分布式编译获取的益处。

为了解决这个问题,可从以下几个方面入手,进行进一步的改造:

  1. 分割c类语言的编译过程:将整体android编译过程划分为c语言为主和java为主的两个过程,其中c语言的编译过程采用distcc编译,而java语言的编译则因循原来的编译方式。 此方法涉及android编译脚本的修改,实现较为简单。
  2. 修改make的实现,根据调用java/c编译器的不同,动态的调整作业数目。此改动可能涉及编译脚本修改甚至make源代码修改,实现稍微复杂。
  3. 将java编译过程同样进行分布式处理。可能的方式是在不同的主机上对不同的java项目进行编译。但需要物理的共享存储以及编译脚本修改。实现更为复杂。但仍在可行的范围内。

分布式负载均衡编译环境部署i

为支持分布式编译,单一编译主机需要进行以下部署步骤:

  1. 安装支持包: 编译主机需要安装distcc、distcc-pump、dmucs包
    apt-get install distcc distcc-pump dumcs
  2. 部署交叉编译工具链至特定位置:
    将android源码自带的prebuilt目录复制到固定地点,比如:/opt/。
  3. 修改distcc的配置文件:
    修改/etc/default/distcc,将
    STARTDISTCC设置为true;
    ALLOWEDNETS为连接的客户端范围,按需设置;
    LISTENER为侦听地址,设置为本机ip地址;
    JOB为同时可承担的编译任务数目,一般设置为CPU个数+2。
    修改/etc/init.d/distcc,将
    PATH参数加入步骤2的交叉编译工具链编译器位置,以使distcc在接到编译任务时,能找到对应的编译器。
  4. 启动distcc服务: sudo service distcc start

 

发出编译请求的客户端还需要进行如下部署步骤:

 

  1. 创建交叉编译工具至distcc的链接:
    将交叉编译工具全部链接至distcc:
    cd /usr/lib/distcc
    ln -s ../../bin/distcc arm-eabi-addr2line
    ln -s ../../bin/distcc arm-eabi-ar
    ln -s ../../bin/distcc arm-eabi-as
    ln -s ../../bin/distcc arm-eabi-c++
    ln -s ../../bin/distcc arm-eabi-c++filt
    ln -s ../../bin/distcc arm-eabi-cpp
    ……
  2. 修改android编译脚本,使其支持distcc编译:
    将build/core/combo/TARGET_linux-arm.mk中的TARGET_TOOLS_PREFIX变量改为/usr/lib/distcc/arm-eabi-
  3. 修改环境变量:
    修改PATH,将distcc编译器路径加入PATH的第一个,并加入交叉编译器路径:
    export PATH=/usr/lib/distcc:<上述第二步交叉编译工具链位置>:$PATH
    此命令可写入profile。
    修改DISTCC_HOSTS,指明支持分布式编译的主机地址:
    export DISTCC_HOSTS=’localhost … … ‘
  4. 发起编译过程:
    make -j8 CC=distcc 根据编译池主机数和本机资源情况调整job数目,以获取最佳性能。

与ccache配合使用

因android官方已经在构建环境中加入了ccache支持,故可以很简单的打开ccache功能以提高编译效率。具体方法为:

$ export USE_CCACHE=1

$ export CCACHE_DIR=/<path_of_your_choice>/.ccache

$ prebuilt/linux-x86/ccache/ccache -M 20G

其中,20G为推荐值,事实上可以根据编译机器的具体情况进行调整。

在编译期或编译结束后,可以用“ccache -s”命令查看缓存命中情况。

用dmucs实现负载均衡

选中某台主机作为dmucs服务器。进行配置:

  1. 修改/etc/default/dmucs,启用dmucs
    将SERVER改为yes
  2. 修改/etc/dmucs.conf 文件,配置编译池:
    根据文件原有说明格式,加入编译池中的主机。
  3. 启动dmucs服务:
    service start dmucs
  4. 在每个编译主机上执行负载发布客户端:
    loadavg -s 主机地址 &

此时,即可以在发起编译时使用

make -j8 CC=gethost distcc

来启用支持负载均衡的分布式编译过程了。

rsync 與 lftp 鏡像備份的比較。rsync mirro versus lftp mirror

lftp ftp://xxx:162938@xxx.xxx.xxx.xxx
lftp owen@xxx.xxx.xxx.xxx:~> mirror --reverse --delete prebuilt
Total: 1907 directories, 15044 files, 8338 symlinks
New: 15044 files, 0 symlinks
2025750448 bytes transferred in 325 seconds (5.94M/s)
lftp owen@owen1.twbbs.org:~>

time lftp -c "open ftp://xxx:162938@xxx.xxx.xxx.xxx;mirror --reverse --delete prebuilt"
real	1m26.084s
user	0m42.390s
sys	0m1.710s

sent 2027701117 bytes  received 318489 bytes  11555667.27 bytes/sec
total size is 2026376344  speedup is 1.00

real	2m55.261s
user	1m7.540s
sys	0m14.040s

time rsync -av -e ssh prebuilt/ xxx@xxx.xxx.xxx.xxx:/home/xxx/prebuilt/
sending incremental file list

sent 1037166 bytes  received 1918 bytes  692722.67 bytes/sec
total size is 2026376344  speedup is 1950.16

real	0m0.753s
user	0m0.120s
sys	0m0.100s

結果相差非常懸殊

要傳輸的資料夾大小 2G

lftp mirror 傳輸整個資料夾 325 秒,再傳輸一次做相同比對的測試 86 秒

rsync 走 ssh 傳輸只個資料夾 175 秒,再傳輸一次做相同比對的測試 0.75 秒

這比對的速度也太快了= =a