/* Add the various callbacks. Right now the transport layer is present
* but not initialized. Also note we need to be careful as the stream
* int is not initialized yet.
*/
conn_prepare(s->si[0].conn, &sess_conn_cb, l->proto, l->xprt, s);
fdtab[cfd].owner = s->si[0].conn; /*fd 对应的 owner 为 connection 结构*/
fdtab[cfd].iocb = conn_fd_handler;
conn_data_want_recv(s->si[0].conn);
if (conn_xprt_init(s->si[0].conn) < 0)
goto out_free_task;
...
si_takeover_conn(&s->si[0], l->proto, l->xprt);
...
t->process = l->handler;
...
if (p->accept && (ret = p->accept(s)) <= 0) {
/* Either we had an unrecoverable error (<0) or work is
* finished (=0, eg: monitoring), in both situations,
* we can release everything and close.
*/
goto out_free_rep_buf;
}
...
task_wakeup(t, TASK_WOKEN_INIT);
int conn_fd_handler(int fd)
{
struct connection *conn = fdtab[fd].owner;
...
if ((fdtab[fd].ev & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR)) &&
conn->xprt &&
!(conn->flags & (CO_FL_WAIT_RD|CO_FL_WAIT_ROOM|CO_FL_ERROR|CO_FL_HANDSHAKE))) {
/* force detection of a flag change : it's impossible to have both
* CONNECTED and WAIT_CONN so we're certain to trigger a change.
*/
flags = CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED;
conn->data->recv(conn);
}
...
}
/* The acl will be linked to from the proxy where it is declared */
struct acl {
struct list list; /* chaining */
char *name; /* acl name */
struct list expr; /* list of acl_exprs */
int cache_idx; /* ACL index in cache */
unsigned int requires; /* or'ed bit mask of all acl_expr's ACL_USE_* */
};
rule 应该是 action + condition 组成
有些动作自身可能也需要记录一些信息。不同的 rule 对应动作的信息可能不同,比如 reqirep 等
block rules 的动作比较单一, condition 满足之后处理结果均相同
condition,完成 rule 检测的判断条件 对应数据结构: struct acl_cond
struct acl_cond {
struct list list; /* Some specific tests may use multiple conditions */
struct list suites; /* list of acl_term_suites */
int pol; /* polarity: ACL_COND_IF / ACL_COND_UNLESS */
unsigned int requires; /* or'ed bit mask of all acl's ACL_USE_* */
const char *file; /* config file where the condition is declared */
int line; /* line in the config file where the condition is declared */
};
condition 包含多个 ACL 组。组的分割逻辑是逻辑或(|| 或者 or),即 struct list suites 的成员,组的数据结构 struct acl_term_suite
struct acl_term_suite {
struct list list; /* chaining of term suites */
struct list terms; /* list of acl_terms */
};
该数据结构可以包含多个 ACL,以及每个 ACL 可能的一个取反标识 '!'
所有表达式中相邻的 ACL 且其逻辑关系为逻辑与(&&) 的构成一个 ACL 组
比如 if acl1 !acl2 or acl3 acl4,则构成两个 acl_term_suite,分别是 acl1 !acl2 和 acl3 acl4
每个 ACL 及其可能的取反标记对应的数据结构: struct acl_term
struct acl_term {
struct list list; /* chaining */
struct acl *acl; /* acl pointed to by this term */
int neg; /* 1 if the ACL result must be negated */
};
一个 ACL 包含多个 expr
3. rule 的执行
概括起来很简单,执行判断条件。符合条件,然后执行对应动作。
下面是 rspadd 的示例代码:
123456789101112131415
/* add response headers from the rule sets in the same order */
list_for_each_entry(wl, &rule_set->rsp_add, list) {
if (txn->status < 200)
break;
if (wl->cond) {
int ret = acl_exec_cond(wl->cond, px, t, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
ret = acl_pass(ret);
if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
ret = !ret;
if (!ret)
continue;
}
if (unlikely(http_header_add_tail(&txn->rsp, &txn->hdr_idx, wl->s) < 0))
goto return_bad_resp;
}
[root@jay-linux qemu-kvm.git]# ./configure --help
Usage: configure [options]
Options: [defaults in brackets after descriptions]
Standard options:
--help print this message
--prefix=PREFIX install in PREFIX [/usr/local]
--interp-prefix=PREFIX where to find shared libraries, etc.
use %M for cpu name [/usr/gnemul/qemu-%M]
--target-list=LIST set target list (default: build everything)
Available targets: i386-softmmu x86_64-softmmu
<!- 此处省略百余行帮助信息的输出 ->
--disable-guest-agent disable building of the QEMU Guest Agent
--enable-guest-agent enable building of the QEMU Guest Agent
--with-coroutine=BACKEND coroutine backend. Supported options:
gthread, ucontext, sigaltstack, windows
NOTE: The object files are built at the place where configure is launched
执行configure文件进行配置的过程如下:
1234567891011121314151617181920212223
[root@jay-linux qemu-kvm.git]# ./configure
Install prefix /usr/local
BIOS directory /usr/local/share/qemu
binary directory /usr/local/bin
library directory /usr/local/lib
include directory /usr/local/include
config directory /usr/local/etc
Manual directory /usr/local/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path /root/kvm_demo/qemu-kvm.git
C compiler gcc
Host C compiler gcc
<!– 此处省略数十行 –>
VNC support yes #通常需要通过VNC连接到客户机中
<!– 此处省略十余行 –>
KVM support yes #这是对KVM的支持
TCG interpreter no
KVM device assig. yes #这是对KVM中VT-d功能的支持
<!– 此处省略十余行 –>
OpenGL support yes
libiscsi support no
build guest agent yes
coroutine backend ucontext
[root@jay-linux qemu-kvm.git]# make -j 20
GEN config-host.h
GEN trace.h
GEN qemu-options.def
GEN qmp-commands.h
GEN qapi-types.h
GEN qapi-visit.h
GEN tests/test-qapi-types.h
GEN tests/test-qapi-visit.h
GEN tests/test-qmp-commands.h
CC libcacard/cac.o
CC libcacard/event.o
<!– 此处省略数百行的编译时输出信息 –>
CC x86_64-softmmu/target-i386/cpu.o
CC x86_64-softmmu/target-i386/machine.o
CC x86_64-softmmu/target-i386/arch_memory_mapping.o
CC x86_64-softmmu/target-i386/arch_dump.o
CC x86_64-softmmu/target-i386/kvm.o
CC x86_64-softmmu/target-i386/hyperv.o
LINK x86_64-softmmu/qemu-system-x86_64