2010年12月6日 星期一
人生三態(轉貼)
人生有三態,悲觀、樂觀與達觀。
悲觀的人在山腳看世界,看到幽冥小徑;
樂觀的人在山腰看世界,看到柳暗花明;
達觀的人在山頂看世界,看到天廣地清。
悲觀的人說:人生像一杯苦酒,清濁均苦澀。
樂觀的人說:人生像一杯美酒,點滴皆芬芳。
達觀的人說:人生像一杯清泉,冷暖都清涼。
悲觀的人看到花謝的悲傷;
樂觀的人看到花開的燦爛;
達觀的人看到花果的希望。
悲觀的人見到人生的生老病死;
樂觀的人見到人生的甘甜喜樂;
達觀的人見到人生的春夏秋冬。
悲觀的人嘆人生步步走向死亡;
樂觀的人讚人生步步邁上尖端;
達觀的人悟人生步步回歸自然。
悲觀的人趨向陰暗一角;
樂觀的人迎向光明一面;
達觀的人橫跨陰陽二界。
悲觀的人埋怨風向;
樂觀的人等待風向;
達觀的人調整風帆。
悲觀的人用加法生活,平添勞苦;
樂觀的人用減法生活,減少憂傷;
達觀的人用除法生活,分享喜樂。
2010年12月5日 星期日
git筆記
先把用過的指令List出來
git init
Create an empty git repository or reinitialize an existing one
git add
Add file contents to the index
git commit
Record changes to the repository
git log
Show commit logs.
git config
Get and set repository or global options.
git branch
List, create, or delete branches.
git checkout
Checkout a branch or paths to the working tree.
git clone
Clone a repository into a new directory.
建立Local Repository並且加入新檔
brook@vista:~/git_test$ git init Initialized empty Git repository in /home/brook/git_test/.git/ brook@vista:~/git_test$ echo 1 > a.txt brook@vista:~/git_test$ git add . brook@vista:~/git_test$ git commit -a -m "init version" [master (root-commit) 3f4bf46] init version 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 a.txt brook@vista:~/git_test$ git log --stat commit 3f4bf46a188e676104bd8bb929a8ba85e85bb536 Author: Brook <rene3210@> Date: Sat Dec 4 22:21:16 2010 +0800 init version a.txt | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
透過ssh複製遠端的Repository
brook@vista:~/git_test2$ git clone ssh://brook@127.0.0.1/home/brook/git_test/ . Initialized empty Git repository in /home/brook/git_test2/git_test/.git/ brook@127.0.0.1's password: remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) Receiving objects: 100% (3/3), done. brook@vista:~/git_test2$ ls a.txt
建立branch/複製遠端的branch
brook@vista:~/git_test$ git branch 顯示目前的branch * master brook@vista:~/git_test$ git branch new_branch建立一個名為new_branch的branch brook@vista:~/git_test$ git branch * master new_branch brook@vista:~/git_test$ git checkout new_branch 切換到new_branch Switched to branch 'new_branch' brook@vista:~/git_test$ git branch master * new_branch 複製遠端的branch brook@vista:~/git_test2$ git checkout --track origin/new_branch Branch new_branch set up to track remote branch new_branch from origin. Switched to a new branch 'new_branch' brook@vista:~/git_test2$ git branch master * new_branch
利用pull(下載)/push(上傳)更新資料
利用pull更新資料 brook@vista:~/test$ mkdir git1 brook@vista:~/test$ mkdir git2 brook@vista:~/test$ cd git1/ brook@vista:~/test/git1$ git init Initialized empty Git repository in /home/brook/test/git1/.git/ brook@vista:~/test/git1$ echo "01" > 01.txt brook@vista:~/test/git1$ git add 01.txt brook@vista:~/test/git1$ git commit -a -m "v1" [master (root-commit) 6d3302a] v1 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 01.txt brook@vista:~/test/git1$ cd ../git2 brook@vista:~/test/git2$ git clone ../git1 . Initialized empty Git repository in /home/brook/test/git2/.git/ brook@vista:~/test/git2$ ls 01.txt brook@vista:~/test/git2$ cd ../git1 brook@vista:~/test/git1$ echo "012" > 01.txt brook@vista:~/test/git1$ git commit -a -m "v2" [master 9824999] v2 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/test/git1$ cd ../git2/ brook@vista:~/test/git2$ git pull remote: Counting objects: 5, done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From /home/brook/test/git2/../git1 6d3302a..9824999 master -> origin/master Updating 6d3302a..9824999 Fast-forward 01.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/test/git2$ cat 01.txt 012 利用push(上傳)更新資料 brook@vista:~/test/git2$ echo "0123" > 01.txt brook@vista:~/test/git2$ git commit -a -m "v3" [master 3dd46af] v3 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/test/git2$ git push Counting objects: 5, done. Writing objects: 100% (3/3), 231 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. remote: error: refusing to update checked out branch: refs/heads/master remote: error: By default, updating the current branch in a non-bare repository remote: error: is denied, because it will make the index and work tree inconsist ent remote: error: with what you pushed, and will require 'git reset --hard' to matc h remote: error: the work tree to HEAD. remote: error: remote: error: You can set 'receive.denyCurrentBranch' configuration variable t remote: error: 'ignore' or 'warn' in the remote repository to allow pushing int remote: error: its current branch; however, this is not recommended unless you remote: error: arranged to update its work tree to match what you pushed in som remote: error: other way. remote: error: remote: error: To squelch this message and still keep the default behaviour, se remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'. To /home/brook/test/git2/../git1 ! [remote rejected] master -> master (branch is currently checked out) error: failed to push some refs to '/home/brook/test/git2/../git1' brook@vista:~/test/git2$ vim ../git1/.git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [receive] denyCurrentBranch = false brook@vista:~/test/git2$ git push Counting objects: 5, done. Writing objects: 100% (3/3), 231 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To /home/brook/test/git2/../git1 9824999..3dd46af master -> master brook@vista:~/test/git2$ cd ../git1 brook@vista:~/test/git1$ git log -1 commit 3dd46af43524c4e81597f392f58899c78faf087b Author: Brook <rene3210@> Date: Wed Dec 15 22:37:39 2010 +0800 v3
merge預設會將每一個change重作一次
rook@vista:~/git$ git init Initialized empty Git repository in /home/brook/git/.git/ brook@vista:~/git$ echo "01" > 01.txt brook@vista:~/git$ git add 01.txt brook@vista:~/git$ git commit -a -m "v1" [master (root-commit) 0b7b5ea] v1 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 01.txt brook@vista:~/git$ git branch my_branch brook@vista:~/git$ git checkout my_branch Switched to branch 'my_branch' brook@vista:~/git$ git branch master * my_branch brook@vista:~/git$ echo "012" > 01.txt brook@vista:~/git$ git commit -a -m "v2" [my_branch de5e153] v2 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ echo "0123" > 01.txt brook@vista:~/git$ git commit -a -m "v3" [my_branch a8d702d] v3 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ echo "01234" > 01.txt brook@vista:~/git$ git commit -a -m "v4" [my_branch 8bae340] v4 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ git log commit 8bae34004943242020b4e1b54726ae1bb77bb991 Author: Brook <rene3210@> Date: Wed Dec 15 22:50:43 2010 +0800 v4 commit a8d702da300bbf643c5b7a7f3be60d7133658b5f Author: Brook <rene3210@> Date: Wed Dec 15 22:50:26 2010 +0800 v3 commit de5e153e8f3414ede60891c21686811b2cf704a6 Author: Brook <rene3210@> Date: Wed Dec 15 22:50:16 2010 +0800 v2 commit 0b7b5ead8e486ba7dc3f1dc75498f27ebd008805 Author: Brook <rene3210@> Date: Wed Dec 15 22:49:11 2010 +0800 v1 brook@vista:~/git$ git checkout master Switched to branch 'master' brook@vista:~/git$ git merge my_branch Updating 0b7b5ea..8bae340 Fast-forward 01.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ cat 01.txt 01234 brook@vista:~/git$ git log commit 8bae34004943242020b4e1b54726ae1bb77bb991 Author: Brook <rene3210@> Date: Wed Dec 15 22:50:43 2010 +0800 v4 commit a8d702da300bbf643c5b7a7f3be60d7133658b5f Author: Brook <rene3210@> Date: Wed Dec 15 22:50:26 2010 +0800 v3 commit de5e153e8f3414ede60891c21686811b2cf704a6 Author: Brook <rene3210@> Date: Wed Dec 15 22:50:16 2010 +0800 v2 commit 0b7b5ead8e486ba7dc3f1dc75498f27ebd008805 Author: Brook <rene3210@> Date: Wed Dec 15 22:49:11 2010 +0800 v1
subversion方式的merge(squash)
brook@vista:~/git$ git init Initialized empty Git repository in /home/brook/git/.git/ brook@vista:~/git$ echo "01" > 01.txt brook@vista:~/git$ git add . brook@vista:~/git$ git commit -a -m "v1" [master (root-commit) fbf643a] v1 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 01.txt brook@vista:~/git$ git branch my_branch brook@vista:~/git$ git checkout my_branch Switched to branch 'my_branch' brook@vista:~/git$ echo "012" > 01.txt brook@vista:~/git$ git commit -a -m "v2" [my_branch 51c6575] v2 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ echo "0123" > 01.txt brook@vista:~/git$ git commit -a -m "v3" [my_branch 67873cb] v3 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ git log commit 67873cb645636a0ab70309cfa65b678ed49eb2b9 Author: Brook <rene3210@> Date: Wed Dec 15 22:58:42 2010 +0800 v3 commit 51c6575ba88dcfb8a3cfd19b2b4d36ae85fd5ac1 Author: Brook <rene3210@> Date: Wed Dec 15 22:58:37 2010 +0800 v2 commit fbf643a72076d43c16a089c2fe330c357bba004e Author: Brook <rene3210@> Date: Wed Dec 15 22:58:12 2010 +0800 v1 brook@vista:~/git$ git checkout master Switched to branch 'master' brook@vista:~/git$ git merge --squash my_branch Updating fbf643a..67873cb Fast-forward Squash commit -- not updating HEAD 01.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ git commit -a -m "merge with squash" [master eefb013] merge with squash 1 files changed, 1 insertions(+), 1 deletions(-) brook@vista:~/git$ git log commit eefb0132ae0c1eaa40b746bca7b5440c54e63cb2 Author: Brook <rene3210@> Date: Wed Dec 15 23:00:49 2010 +0800 merge with squash commit fbf643a72076d43c16a089c2fe330c357bba004e Author: Brook <rene3210@> Date: Wed Dec 15 22:58:12 2010 +0800 v1
標籤:
tools - devel
2010年11月27日 星期六
Linux Kernel(12.1)- netfilter機制之初探
延續Linux Modules(12)- netfilter我們由nf_register_hooks()來看看netfilter這個framework是如何運作的。
struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; int nf_register_hook(struct nf_hook_ops *reg) { struct nf_hook_ops *elem; int err; err = mutex_lock_interruptible(&nf_hook_mutex); if (err < 0) return err; list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) { if (reg->priority < elem->priority) break; } list_add_rcu(®->list, elem->list.prev); mutex_unlock(&nf_hook_mutex); return 0; } void nf_unregister_hook(struct nf_hook_ops *reg) { mutex_lock(&nf_hook_mutex); list_del_rcu(®->list); mutex_unlock(&nf_hook_mutex); synchronize_net(); }nf_hook_register_hook()其實就是在將要註冊的callback function依照所屬的protocol family以及hooknum插入struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS],並且會依照priority由小到大,而nf_unregister_hook()就是很簡單的reg由nf_hooks中移除。
接著我們再來看看nf_iterate(),程式碼中以//為註解方式,且為粗體字型就是我的註解。
unsigned int nf_iterate(struct list_head *head, struct sk_buff *skb, unsigned int hook, const struct net_device *indev, const struct net_device *outdev, struct list_head **i, int (*okfn)(struct sk_buff *), int hook_thresh) { unsigned int verdict; /* * The caller must not block between calls to this * function because of risk of continuing from deleted element. */ list_for_each_continue_rcu(*i, head) { struct nf_hook_ops *elem = (struct nf_hook_ops *)*i; // 註冊的priority必須小於等於hook_thresh才會被執行 if (hook_thresh > elem->priority) continue; /* Optimization: we don't need to hold module reference here, since function can't sleep. --RR */ //丟進註冊的hook function執行 verdict = elem->hook(hook, skb, indev, outdev, okfn); if (verdict != NF_ACCEPT) { #ifdef CONFIG_NETFILTER_DEBUG if (unlikely((verdict & NF_VERDICT_MASK) > NF_MAX_VERDICT)) { NFDEBUG("Evil return from %p(%u).\n", elem->hook, hook); continue; } #endif //如果不是NF_ACCEPT而且也不是NF_REPEAT就回傳verdict // (NF_DROP/NF_STOLEN/NF_QUEUE) if (verdict != NF_REPEAT) return verdict; //會執行到這邊就是NF_REPEAT啦 *i = (*i)->prev; } // 如果verdict是NF_ACCEPT就會繼續往下一個hook function執行 } //如果沒有任何的hook function或者所有的hook function都是NF_ACCEPT return NF_ACCEPT; }
/* Returns 1 if okfn() needs to be executed by the caller, * -EPERM for NF_DROP, 0 otherwise. */ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *), int hook_thresh) { struct list_head *elem; unsigned int verdict; int ret = 0; /* We may already have this, but read-locks nest anyway */ rcu_read_lock(); elem = &nf_hooks[pf][hook]; next_hook: // 將nf_hooks[pf][hook]這個linked list丟進nf_iterate()中執行 verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev, outdev, &elem, okfn, hook_thresh); if (verdict == NF_ACCEPT || verdict == NF_STOP) { // 如果是NF_ACCEPT或NF_STOP就回傳1, 到時候NF_HOOK()/NF_HOOK_COND() // 等macro就會執行okfn, 前面的註解也有說明 ret = 1; } else if (verdict == NF_DROP) { // 如果是NF_DROP就會free resource並且回傳!1, 就是不會呼叫okfn()了 kfree_skb(skb); ret = -EPERM; } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { // 如果是QUEUE就會將他nf_queue()將資訊暫時存起來, 等候處理 if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn, verdict >> NF_VERDICT_BITS)) goto next_hook; } rcu_read_unlock(); // 執行到這邊有可能是NF_STOLEN, 但ret = 0, 所以不會執行okfn, // NF_STOLEN會改變packet原本要走的路徑 return ret; }
#iddef CONFIG_NETFILTER int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *), int thresh); /** * nf_hook_thresh - call a netfilter hook * * Returns 1 if the hook has allowed the packet to pass. The function * okfn must be invoked by the caller in this case. Any other return * value indicates the packet has been consumed by the hook. */ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *), int thresh) { #ifndef CONFIG_NETFILTER_DEBUG if (list_empty(&nf_hooks[pf][hook])) return 1; #endif return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh); } static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *)) { return nf_hook_thresh(pf, hook, skb, indev, outdev, okfn, INT_MIN); } /* Activate hook; either okfn or kfree_skb called, unless a hook returns NF_STOLEN (in which case, it's up to the hook to deal with the consequences). Returns -ERRNO if packet dropped. Zero means queued, stolen or accepted. */ /* RR: > I don't want nf_hook to return anything because people might forget > about async and trust the return value to mean "packet was ok". AK: Just document it clearly, then you can expect some sense from kernel coders :) */ static inline int NF_HOOK_THRESH(uint8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *), int thresh) { int ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, thresh); if (ret == 1) ret = okfn(skb); return ret; } static inline int NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *), bool cond) { int ret; if (!cond || (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1)) ret = okfn(skb); return ret; } static inline int NF_HOOK(uint8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { return NF_HOOK_THRESH(pf, hook, skb, in, out, okfn, INT_MIN); } #else /* !CONFIG_NETFILTER */ #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb) static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *), int thresh) { return okfn(skb); } static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *)) { return 1; } #endif /*CONFIG_NETFILTER*/如果沒有defined CONFIG_NETFILTER,NF_HOOK()其實就是直接呼叫okfn了。到這邊對於netfilter的運作就有基本的認識了,有機會hack其他關於netfilter的心得再和大家分享。
Kernel version:2.6.36
標籤:
Linux - kernel
訂閱:
文章 (Atom)
熱門文章
-
轉自 http://www.wretch.cc/blog/redsonoma/14021073 基本概念: 1> tty(終端設備的統稱): tty一詞源於Teletypes,或者teletypewriters,原來指的是電傳打字機,是通過串行線用打印機鍵盤通過閱...
-
Work queue提供一個interface,讓使用者輕易的建立kernel thread並且將work綁在這個kernel thread上面,如下圖[1]所示。 由於work queue是建立一個kernel thread來執行,所以是在process context...
-
(V)將介紹file operations中的ioctl。ioctl的prototype為: int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); ...
-
這兩天電腦的word忽然都不能存檔,即便是另存新檔也不行,最後都只能放棄修改檔案,即便重新安裝過或者更新成2007也都不能存檔,最後就乖乖的google一下,原來是暫存的資料夾不存在,按照以下方式就可以解決了。 資料來源: word 2003不能存檔問題 編輯機碼的(reg...
-
System Call在HW和user space提供一層抽象層,主要目的有: 為user space提供硬體抽象層。比如,讀取檔案時,不用管檔案所在的媒體類型與檔案儲存類型。 System call能確保系統的安全與穩定。避免user space的無意或惡意的破壞。 ...
-
在kernel中建立thread可以使用kthread_create(),建立一個task,然後在調用wake_up_process(task)讓task真正的運行,如果要kill一個kthread可以使用kthread_stop()。 在kernel中,將kthread_cr...
-
Linux module練習手札I紀錄如何撰寫一個簡單的module,並且編輯它,以及load和unload一個module。 write a module #include <linux/init.h> #include <linux/module.h...
-
幾乎任何使用 TCP,UDP或UNIX-domain socket的動作都可以用nc來達成,常見的功能如。 simple TCP proxies shell-script based HTTP clients and servers network daemon testi...
-
很多人心中都有過一個問題 What is the difference between Platform driver and normal device driver? ,簡單的來說Platform devices就non-discoverable,也就是device本身沒辦法...
-
組成元件 要能正確顯示資料,必須包含資料倉儲(Store),資料欄位的定義(ColumnModel)。 首先我們先定義資料欄位: var cm = new Ext.grid.ColumnModel({ {header: 'Name', dataIndex...