顯示具有 linux 標籤的文章。 顯示所有文章
顯示具有 linux 標籤的文章。 顯示所有文章

2013/05/21

解開 fd_set size limitation

寫 socket programming 時會用 select 搭配 fd_set 來偵測 file descriptor 是否可讀寫
但 Linux 系統預設的 fd_set size 只有 1024,若同時間處理的 fd 超過 1024 就會出問題


修改下面這兩個檔案,重新 build application 時就會引用到新的 define 值

/usr/include/bits/typesizes.h:
#define    __FD_SETSIZE        1024

/usr/include/linux/posix_types.h:
#define    __FD_SETSIZE        1024

2013/02/22

快速架設 DNS - dnsmasq

在 debug 時偶爾會有一種需求,就是要假造 DNS resolve 的結果,讓一些設備能夠暫時導向我指定的 ip 去,而 bind 這一套的設定對我來說太過複雜了 ><
於是同事推薦了我這個:Dnsmasq
Dnsmasq is a lightweight, easy to configure DNS forwarder and DHCP server.
酷!一次滿足兩個願望


安裝
$ yum install dnsmasq

設定上層 DNS server
$ vim /etc/dnsmasq.resolv.conf
nameserver 8.8.8.8

自定 dns record
$ vim /etc/hosts
10.0.0.1  anything.com.tw

啟動 dnsmasq
$ /etc/init.d/dnsmasq start

搞定啦!

更多設定在 /etc/dnsmasq.conf

2012/08/04

工欲善其事,必先利其器:GDB 基本教學

最基本的編譯時要加"-g",把 debugging information 編譯進去,否則印不出什麼資訊來。再來就是不要做 optimize,不然程式碼行數會對不上。
$ gcc -g -o hello hello.c

啟動 GDB
$ gdb ./hello

必要時加入"-d (dirctory)"的參數,指定 source code 的位置
$ gdb -d /home/brian/test ./hello 

若程式已經在執行了,可以先查詢 pid,然後用 attach 的方式。記得 binary 的要跟正在 run 的 program 一致
$ gdb ./hello 12238

進入GDB後執行程式
(GDB) run
若要帶參數的話
run (init parameter)
Ex:
(GDB) run -h localhost -p 8080

Breakpoint
設定中斷點
b (filename):(line num)
Ex:
(GDB) b hello.c:5

列出目前的中斷點
(GDB) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040049c in main at hello.c:5

移除中斷點
d (breakpoint id)
Ex:
(GDB) d 1

列出當下的狀況
列出 function stack (Back trace)
(GDB) bt
#0  hello () at hello.c:9
#1  0x00000000004004cf in main () at hello.c:14

列出更詳細的資訊,包含 variable 的值
(GDB) bt full
#0  hello () at hello.c:9
        i = 0
#1  0x00000000004004cf in main () at hello.c:14
No locals.

列印變數
p (variable)
Ex:
(GDB) p iValue
(GDB) p *stEmployee

切換 frame。要列印區域變數時,必須要切換到正確的 frame
f (frame num)
EX:
(GDB) f 3

流程控制
Step over (不會進 function)
(GDB) n
Step into (會跳入 function)
(GDB) s
Continue
(GDB) c

Signal Handle
handle (signal) (operation)
Operation 預設為 stop print noignore,也就是遇到 signal 時,GDB 會先攔截,並中斷程式,必要時可以改為 nostop noprint,讓程式本身去處理 signal。若下達 ignore 則是讓程式忽略此 signal。
(GDB) handle SIGUSR nostop noprint

列出目前 signal 設定的狀態
(GDB) i handle
Signal        Stop      Print   Pass to program Description

SIGHUP        Yes       Yes     Yes             Hangup
SIGINT        Yes       Yes     No              Interrupt
SIGQUIT       Yes       Yes     Yes             Quit
SIGILL        Yes       Yes     Yes             Illegal instruction
SIGTRAP       Yes       Yes     No              Trace/breakpoint trap
有關 signal 的部分可以參考 http://sourceware.org/gdb

Thread
查看目前在哪個 thread
(GDB) thread

切換 thread
(GDB) thread 3

列出所有 thread 的 function stack
(GDB) thread apply all bt
(GDB) thread apply all bt full

Ref:
Examining the Symbol Table

2012/04/21

sudo: no valid sudoers sources found, quitting

犯了一個天大的錯誤,就是編輯 sudoers 的時候,忘記把權限改回來,於是就失去了 sudo 的權限了...
sudo: /etc/sudoers is mode 0640, should be 0440
sudo: no valid sudoers sources found, quitting

如果你的機器就在旁邊的話,可以進入 recovery mode 或用 liveCD 把權限改回來。

如果是在 AWS呢?找到一篇教學:
Fixing Files on the Root EBS Volume of an EC2 Instance - Alestic.com

步驟
1. 把 Server A 的 EBS Volume detach,然後 attach 到另外一台 Sever B
2. 進入 Server B 把 device node mount,開始修復檔案
3. 最後再 attach 回原本的 Server A


後來才知道,要用 visudo 這個指令去修改才對...

2011/09/06

Forward Proxy 的選擇 - Squid

Forward proxy 與 Reverse proxy 是什麼可以參考聯成電腦這篇的說明

用途方面簡單舉幾個例子

  • Forward proxy
    • 用戶套用Hinet的proxy,抓國外的東西會比較快,因為proxy上面已經cache一份。
    • 公司或宿舍網路禁止對外存取facebook或上msn,proxy上有強大的parser可以check/replace特定字眼。
  • Reverse proxy
    • 在多台web server前架一台proxy做分流可以大大提高capacity與安全性,推薦Nginx。
    • 搭配virtual host,可將不同domain name的request導向不同的server。



最近剛好有使用forward proxy的需求,也就是用戶透過proxy連到public網路,如果遇到連接對向很慢或不存在的時候,此時proxy的connection就會被占住,直到timeout為止。剛開始是使用apache,apache prefork或worker模式下,其connection的數量是有限的(再設定檔內指定),若遇到上述的狀況,整體服務狀況就會變得很差。

Proxy的選擇
  • Apache + module proxy: 很吃記憶體,polling的做法不合用
  • Tinyproxy: 較apache省記憶體,但運作方式也是一個thread一個connection,response time比apache還差
  • Lighttpd: 不支援forward proxy,底層為epoll
  • Nginx: 不支援forward proxy,底層為epoll
  • Squid: 支援forward proxy,底層採用epoll (最後的選擇)

Squid的filter真的很強大,過濾ip, port, mac都沒有問題。
效能方面,我讓他hang了20,000條connection,new request上去反應並沒有被影響。

設定方面可以參考

2011/08/08

Oprofile - program performance analysis

一套 profiling 工具,透過分析結果可以得知程式運作這段期間,哪個 function 花費最多時間,哪一行程式碼被執行最多次。

下載

使用步驟
Initial and setup
$ opcontrol --init
$ opcontrol --reset 
$ opcontrol --setup --no-vmlinux --separate=library
$ opcontrol --start
--separate=none: 只想看程式本身的 function
--separate=lib: 想連程式使用到的library都一起看到
適度調整取樣率

啟動想分析的 program
$ ./app

Stop
$ opcontrol --dump
$ opcontrol --stop
$ opcontrol -h

Analysis
$ opreport -l ./app

CPU: CPU with timer interrupt, speed 1999.97 MHz (estimated)
Profiling through timer interrupt
samples  %        image name               symbol name
7251     30.3186  libx264.so.128           x264_cavlc_init
6247     26.1206  libx264.so.128           x264_coeff_level_run16
3018     12.6192  libx264.so.128           x264_analyse_init_costs   encoder/analyse.c:292
1496      6.2552  libavcodec.so.52.72.2    /opt/ffmpeg-0.6.5/lib/libavcodec.so.52.72.2
1426      5.9625  libc-2.12.so             __strcmp_sse42
1120      4.6831  libm-2.12.so             __ieee754_log2f
384       1.6056  libavformat.so.52.64.2   /opt/ffmpeg-0.6.5/lib/libavformat.so.52.64.2
329       1.3756  libc-2.12.so             memcpy
239       0.9993  libc-2.12.so             _int_malloc
213       0.8906  libm-2.12.so             __ieee754_pow
180       0.7526  libx264.so.128           x264_cqm_init

$ opannotate --source ./app

... (執行次數) (花費比例)

               :static uint64_t pop_buffer_value(struct transient * trans)
 11510  1.9661 :{ /* pop_buffer_value total:  89901 15.3566 */
               :        uint64_t val;
               :
 10227  1.7469 :        if (!trans->remaining) {
               :                fprintf(stderr, "BUG: popping empty buffer !\n");
               :                exit(EXIT_FAILURE);
               :        }
               :
               :        val = get_buffer_value(trans->buffer, 0);
  2281  0.3896 :        trans->remaining--;
  2296  0.3922 :        trans->buffer += kernel_pointer_size;
               :        return val;
 10454  1.7857 :}
...



在 AWS EC2 上使用 oprofile
opcontrol --deinit 
modprobe oprofile timer=1
opcontrol --reset 
opcontrol --no-vmlinux --separate=library
opcontrol --start


參考資料

2011/06/16

C socket client in Linux - sample code

Sample code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define LOCAL_IP                        "127.0.0.1"
#define LOCAL_PORT                      5678
#define SVR_IP                          "127.0.0.1"
#define SVR_PORT                        8080
#define BUF_SIZE                        1024
#define MESSAGE                         "hello"

int main (int argc, char **argv) {
    struct sockaddr_in  local_addr, server_addr;
    socklen_t           len;
    int                 sock_fd;
    char                buff[BUF_SIZE];
    int                 recv_len;
    
    len = sizeof(struct sockaddr_in);
    
    /* Set local address (In general, we don't care local address) */
    memset(&local_addr, 0, sizeof(local_addr));
    local_addr.sin_family = AF_INET;
    local_addr.sin_addr.s_addr = inet_addr(LOCAL_IP);
    local_addr.sin_port = htons(LOCAL_PORT);
    
    /* Set server address */
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SVR_IP);
    server_addr.sin_port = htons(SVR_PORT);

    /* Create endpoint */
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket()");
        return -1;
    } else {
        printf("sock_fd=[%d]\n", sock_fd);
    }

    /* Bind */
    if (bind(sock_fd, (struct sockaddr *)&local_addr, sizeof(local_addr)) == -1) {
        perror("bind()");
        return -1;
    } else {
        printf("bind [%s:%u] success\n",
            inet_ntoa(local_addr.sin_addr), ntohs(local_addr.sin_port));
    }

    /* Connect */
    if (connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("connect()");
        return -1;
    } else {
        printf("connect to [%s:%u] success\n",
            inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));
    }
    
    /* Send */
    send(sock_fd, MESSAGE, strlen(MESSAGE), 0);

    /* Receive */
    memset(buff, 0, sizeof(buff));
    recv_len = recv(sock_fd, buff, sizeof(buff), 0);
    if (recv_len == -1) {
        perror("recv()");
        return -1;
    } else if (recv_len == 0) {
        printf("Client disconnect\n");
    } else {
        printf("Receive: len=[%d] msg=[%s]\n", recv_len, buff);
    }
    
    return 0;
}

2011/06/15

C socket server in Linux - sample code

長期用libevent來implement socket program,都快忘了一般select的用法了,寫了一個echo server
供各位參考。

不過有一點我還是不太懂,為何fd_set要copy一份起來,是因為fd_set 經過select function後就無效了嗎?我試過只用一個fd_set,果真只能接收到第一個request,除非每次select前重新把所有的fd做FD_SET()。

Select的用法可以參考:石頭閒語:select() - I/O Multiplexer

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SVR_IP                          "127.0.0.1"
#define SVR_PORT                        8080
#define BUF_SIZE                        1024

int main (int argc, char **argv) {
    struct sockaddr_in  server_addr;
    socklen_t           len;
    fd_set              active_fd_set;
    int                 sock_fd;
    int                 max_fd;
    int                 flag = 1;
    char                buff[BUF_SIZE];
    
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SVR_IP);
    server_addr.sin_port = htons(SVR_PORT);
    len = sizeof(struct sockaddr_in);

    /* Create endpoint */
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket()");
        return -1;
    } else {
        printf("sock_fd=[%d]\n", sock_fd);
    }

    /* Set socket option */
    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int)) < 0) {
        perror("setsockopt()");
        return -1;
    }

    /* Bind */
    if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("bind()");
        return -1;
    } else {
        printf("bind [%s:%u] success\n",
            inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));
    }

    /* Listen */
    if (listen(sock_fd, 128) == -1) {
        perror("listen()");
        return -1;
    }

    FD_ZERO(&active_fd_set);
    FD_SET(sock_fd, &active_fd_set);
    max_fd = sock_fd;

    while (1) {
        int             ret;
        struct timeval  tv;
        fd_set          read_fds;

        /* Set timeout */
        tv.tv_sec = 2;
        tv.tv_usec = 0;

        /* Copy fd set */
        read_fds = active_fd_set;
        ret = select(max_fd + 1, &read_fds, NULL, NULL, &tv);
        if (ret == -1) {
            perror("select()");
            return -1;
        } else if (ret == 0) {
            printf("select timeout\n");
            continue;
        } else {
            int i;

            /* Service all sockets */
            for (i = 0; i < FD_SETSIZE; i++) {
                if (FD_ISSET(i, &read_fds)) {
                    if (i == sock_fd) {
                        /* Connection request on original socket. */
                        struct sockaddr_in  client_addr;
                        int                 new_fd;

                        /* Accept */
                        new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &len);
                        if (new_fd == -1) {
                            perror("accept()");
                            return -1;
                        } else {
                            printf("Accpet client come from [%s:%u] by fd [%d]\n",
                                inet_ntoa(client_addr.sin_addr),
                                ntohs(client_addr.sin_port), new_fd);

                            /* Add to fd set */
                            FD_SET(new_fd, &active_fd_set);
                            if (new_fd > max_fd)
                                max_fd = new_fd;
                        }
                    } else {
                        /* Data arriving on an already-connected socket */
                        int recv_len;

                        /* Receive */
                        memset(buff, 0, sizeof(buff));
                        recv_len = recv(i, buff, sizeof(buff), 0);
                        if (recv_len == -1) {
                            perror("recv()");
                            return -1;
                        } else if (recv_len == 0) {
                            printf("Client disconnect\n");
                        } else {
                            printf("Receive: len=[%d] msg=[%s]\n", recv_len, buff);

                            /* Send (In fact we should determine when it can be written)*/
                            send(i, buff, recv_len, 0);
                        }

                        /* Clean up */
                        close(i);
                        FD_CLR(i, &active_fd_set);
                    }

                } // end of if
            } //end of for
        } // end of if
    } // end of while
    
    return 0;
}

2011/06/08

Get IPv4 address from sockaddr or socket

(sock_fd is a socket)
sockaddr_in  addr_in;
int          len = sizeof(sockaddr_in);

/* Get sockaddr_in structure information from socket */
getsockname(sock_fd, (sockaddr *)&addr_in, (socklen_t *)&len);

/* Get address from sockaddr_in */
printf("IP=[%s] port=[%d]\n", inet_ntoa(addr_in.sin_addr), addr_in.sin_port);

2011/06/02

netcat

Top 100 Network Security Tools 排行第四名的軟體,也是我在寫socket program時最常用到的工具,不管是當server/client,tcp/udp都沒問題!


在wiki中已經講述了大部份的使用方法:

  • raw connection
  • http server
  • file server
  • proxy server
  • port scanning
  • port forwarding

下載:
The GNU Netcat -- Official homepage -- Downloads

Support SSL的版本
netcat SSL

這一套感覺更強大,可以support UDP和SSL!
SSL Capable NetCat

2011/05/17

mtrace - 檢查memory leak

Memory leak中文叫內存洩漏,也是我在開發程式中一個很難搞的問題。拜一些tool所賜,讓工程師可以更容易發現問題所在。

mtrace是glibc內提供的工具,其實它的原理很簡單,就是把你程式中malloc()與free()的位址全部下來,最後兩兩配對,殘留下來沒有配對到的就是leak。

1. 安裝glibc-utils

2. 在程式中include header file並在程式最前面call mtrace()
e.g. test.c
#include 
#include 

int main(void) {
    char *p;

    mtrace();
    p = malloc(5);  // 要一塊記憶體,但沒有釋放

    return 0;
}

3. compile
$ gcc -g -o test test.c
一定要加-g

4. run program
$ MALLOC_TRACE=output.log ./test
MALLOC_TRACE指向output file

5. 抓leak
$ mtrace ./test ./output.log
結果:
Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000c2d460      0x5  at /tmp/test.c:8
很清楚看到test.c第8行allocate 5 byte未釋放

--

不過mtrace算是很陽春的工具,如果是間接allocte記憶體,如call object_new()這種init function,那mtrace就沒辦法表示得那麼清楚了。
e.g. test2.c
#include 
#include 
#include 

int main(void) {
    GHashTable *ht;

    mtrace();
    ht = g_hash_table_new(NULL, NULL);

    return 0;
}

執行mtrace結果:
Memory not freed:
-----------------
           Address     Size     Caller
0x0000000012a24460     0xfc  at 0x2b267c24f3b1
0x0000000012a24570    0x1f8  at 0x2b267c24f3b1
0x0000000012a24770    0x1f8  at 0x2b267c24f3b1
0x0000000012a24970    0x7f0  at 0x2b267c24f3b1
0x0000000012a25170     0xc0  at 0x2b267c24f3b1
0x0000000012a25400    0x3f0  at 0x2b267c262ce1
0x0000000012a25800    0x3f0  at 0x2b267c262ce1

這樣的訊息對我們來說沒什麼幫助,這時候可以借助更強大的工具valgrind或heap checker。

2011/05/16

pstack - 列印出process stack trace

有時候遇到process hang住了,我們想知道各thread目前function call stack為何就可以利用pstack。使用前提是binary還保有symbol(還未strip)

用法︰
$  pstack pid

e.g.
$ pstack `pgrep syslog-ng`

Backtrace for pid 21374
A syntax error in expression, near `'.
#0  0x00000034bb6cb14f in poll () from /lib64/libc.so.6
#1  0x0000000000402957 in main_context_poll (ufds=0x9b1920, nfsd=22,
    timeout_=14303) at main.c:134
#2  0x00002b3ba086a90f in g_main_context_poll (context=0x966400, block=1,
    dispatch=1, self=) at gmain.c:3093
#3  g_main_context_iterate (context=0x966400, block=1, dispatch=1,
    self=) at gmain.c:2775
#4  0x00002b3ba086af0b in g_main_context_iteration (context=0x966400,
    may_block=1) at gmain.c:2843
#5  0x0000000000402421 in main_loop_run (cfg=0x7ffff43c6040) at main.c:170
#6  0x00000000004028d9 in main (argc=1, argv=0x7ffff43c6138) at main.c:448
這個訊息跟在gdb下thread apply all bt是一樣的。

下載︰
我只找到Oracol Project: GDB pstack

一些常用的 Linux 指令

1. 查看某個網路service的連線狀態
$ netstat -an | grep 127.0.0.1:5432 | awk '{print $6}' | sort | uniq -c
結果:
10 CLOSE_WAIT
36 ESTABLISHED
 1 LISTEN
33 TIME_WAIT


2. 在top中查看特定的process
$ top -p `pgrep sshd | sed -e :x -e '$!N;s/\n/,/;tx'`
# sed 的作用是把換行字元取代成","
結果︰
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
2198 root      16   0 90128 3308 2580 S  0.0  0.0   0:02.97 sshd
2212 test      15   0 90228 1880 1104 S  0.0  0.0   0:20.82 sshd
2224 root      16   0 90128 3308 2580 S  0.0  0.0   0:00.03 sshd


3. 監看某一daemon的fd數量
$ watch -n 1 'ls /proc/`pgrep daemon`/fd | wc -l'
結果︰
Every 1.0s: ls /proc/`pgrep daemon`/fd | wc -l            Mon May 16 21:01:04 2011

50


4. sed取代換行字元
$ sed -e :x -e '$!N;s/\n/,/;tx'
或
$ sed '/^.*$/N;s/,/\n/g'


5. 列出server上的服務
$ netstat -ntulp
結果:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      2304/httpd
tcp        0      0 10.32.1.10:22               0.0.0.0:*                   LISTEN      2110/sshd
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      2136/sendmail: acce
tcp        0      0 0.0.0.0:443                 0.0.0.0:*                   LISTEN      2304/httpd
udp        0      0 127.0.0.1:514               0.0.0.0:*                               10575/syslog-ng
udp        0      0 0.0.0.0:34224               0.0.0.0:*                               10614/collectd


6. 查看Linux distribution
$ lsb_release -a
or
$ cat /etc/issue
or
$ cat /proc/version

crontab 自動排程

安排例行性工作需要用到: backup, log rotate, clean tmp...

1. 編輯crontab
$ crontab -e
或
$ vim /etc/crontab

2. 設定執行時間
3  4  *  *  *    root      sh /home/backup.sh
分 時 日 月 週   身份      指令
上述指令為每天半夜4:03備份資料


參考資料︰
鳥哥的 Linux 私房菜 -- 例行性工作排程 (crontab)

2011/05/15

SSH免密碼登入

使用ssh登入遠端server時會要求輸入密碼,有些時候想要略過此步驟(如執行auto script時),建立免密碼登入就可以派上用場。

1. 在local端建立public key與private key
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/test/.ssh/id_rsa):     (按enter)
Enter passphrase (empty for no passphrase):                       (按enter)
Enter same passphrase again:                                      (按enter)
Your identification has been saved in /home/test/.ssh/id_rsa.     (按enter)
Your public key has been saved in /home/test/.ssh/id_rsa.pub.     (按enter)
The key fingerprint is:
fe:3f:63:3d:7d:34:06:53:a3:53:22:73:c3:c4:a3:f3 test@test-desktop.local
andomart image is:
+--[ RSA 2048]----+
|           o+  . |
|          .  +.E+|
|         .   ..=.|
|   . o  ..= . oo.|
|  . + = So.=. o. |
|   . . o  ...+   |
|           .     |
|                 |
|                 |
+-----------------+
在~/.ssh目錄下產生了id_rsa與id_rsa.pub

2. 將public key放到server端
$ cd ~/.ssh
$ scp id_rsa.pub username@server_host_name:~/.ssh

3. 進到server端~/.ssh目錄,將public key加到authorized_keys的結尾(authorized_keys可以放置多組),並修改權限為600
$ cd ~/.ssh
$ cat id_rsa.pub >> authorized_keys
$ chmod 600 authorized_keys

下次登入server時就不需要輸入密碼了。

Rsync - 聰明的資料備份

之前在linux都用scp來備份檔案到其他地方,scp(secure copy)簡單來說就是透過ssh來copy檔案,不過在複製的過程中沒有辨認檔案新舊或是否修改過,有點浪費頻寬。所以rsync就是更好的選擇摟!

例如我想把local端的/home/brian/program備份到遠端的/home/brian/backup
$ rsync -avz --delete -e ssh /home/brian/program brian@10.10.0.1:/home/brian/backup
參數說明:
--delete: 刪除遠端多餘的檔案,也就是說今天你把local的某個檔案刪除,rsync的時候遠端的檔案也會被刪除。所以在使用這個參數時請確認您的來源是對的,否則會誤刪遠端的檔案
-z: 傳輸過程壓縮,可以節省頻寬,但相對的壓縮也是需要時間的

思考:
這邊所介紹的只是單方向的備份,例如從local備份到remote,如果想從remote復原到local,只要把source跟destination交關即可。基本上remote端的資料不會手動去修改的,如果我想做像dropbox的樣子,local或remote修改時都會自動sync到對方,應該也是可以達到吧?

2011/05/13

解决 ip_conntrack: table full, dropping packet

當linux系統連線來源ip過多時, /var/log/message 會出現 ip_conntrack: table full, dropping packet

解決方式:
加大tracking table, 下面三種方式都可以
$ echo 6553600 >/proc/sys/net/ipv4/netfilter/ip_conntrack_max

$ sysctl -w net.ipv4.ip_conntrack_max=6553600

$ vim /etc/sysctl.conf
  修改 netfilter/ip_conntrack_max 這一行