Bind-9_6_0-P1源代码分析之一@整体架构.doc_第1页
Bind-9_6_0-P1源代码分析之一@整体架构.doc_第2页
Bind-9_6_0-P1源代码分析之一@整体架构.doc_第3页
Bind-9_6_0-P1源代码分析之一@整体架构.doc_第4页
Bind-9_6_0-P1源代码分析之一@整体架构.doc_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Bind-9.6.0-P1源代码分析之一:整体架构(初稿)一、 说明参考/lxr/http/source/bin/named/main.c这是bind解析程序的入口事件bind程序也事件驱动型,以任务作为主要的执行。当一个解析请求到来时,就会通过事件的产生来触发任务dispatch处理。这样的处理有相应if (event-ev_action != NULL) 861 UNLOCK(&task-lock);862 (event-ev_action)(task,event);863 LOCK(&task-lock);这里 action就是执行函数本文主要关注整体的运行结构,主要参考文件是main.c二、 启动入口870 int871 main(int argc, char *argv) 命令行参数传入以上为设置错误消息895 isc_assertion_setcallback(assertion_failed);896 isc_error_setfatal(library_fatal_error);897 isc_error_setunexpected(library_unexpected_error);898初始化系统日志,权限等899 ns_os_init(program_name);900初始化工作901 dns_result_register();902 dst_result_register();903 isccc_result_register();904 命令行参数分析,如-g将日志输出到front-end905 parse_command_line(argc, argv);注意以下的内存机制,isc_mem可见/lxr/http/source/lib/isc/mem.c#L113定义注意以/lxr/http/source/lib/isc/mem.c#L725用到了锁机制830 LOCK(&lock);831 ISC_LIST_INITANDAPPEND(contexts, ctx, link);832 UNLOCK(&lock);833 内存生成采用标准的系统调用 malloc和free,但考虑到多线程下的竞争情况,对内存块访问需要锁机制。Ns_g_mctx是信号量,要求ns_g_mctx!=NULL&*ns_g_mctx=NULL919 result = isc_mem_create(0, 0, &ns_g_mctx);920 if (result != ISC_R_SUCCESS)921 ns_main_earlyfatal(isc_mem_create() failed: %s,922 isc_result_totext(result);对设置923 isc_mem_setname(ns_g_mctx, main, NULL);924 /setup是重要的一部分,见分析三925 setup();接下来就是解析主体程序了,是通过循环来做的,直到错误或者接收到退出信号。递/*928 * Start things running and then wait for a shutdown request929 * or reload.930 */931 do 932 result = isc_app_run();是重要部分,见分析四933 934 if (result = ISC_R_RELOAD) /通过我们会做这种操作,当配置了一个新的zone文件时935 ns_server_reloadwanted(ns_g_server);936 else if (result != ISC_R_SUCCESS) 937 UNEXPECTED_ERROR(_FILE_, _LINE_,938 isc_app_run(): %s,939 isc_result_totext(result);940 /*941 * Force exit.942 */943 result = ISC_R_SUCCESS;944 945 while (result != ISC_R_SUCCESS);946 947 #ifdef HAVE_LIBSCF948 if (ns_smf_want_disable = 1) 949 result = ns_smf_get_instance(&instance, 1, ns_g_mctx);950 if (result = ISC_R_SUCCESS & instance != NULL) 951 if (smf_disable_instance(instance, 0) != 0)952 UNEXPECTED_ERROR(_FILE_, _LINE_,953 smf_disable_instance() 954 failed for %s : %s,955 instance,956 scf_strerror(scf_error();957 958 if (instance != NULL)959 isc_mem_free(ns_g_mctx, instance);960 961 #endif /* HAVE_LIBSCF */962 963 cleanup();964 965 if (want_stats) 966 isc_mem_stats(ns_g_mctx, stdout);967 isc_mutex_stats(stdout);968 969 970 if (ns_g_memstatistics & memstats != NULL) 971 FILE *fp = NULL;972 result = isc_stdio_open(memstats, w, &fp);973 if (result = ISC_R_SUCCESS) 974 isc_mem_stats(ns_g_mctx, fp);975 isc_mutex_stats(fp);976 isc_stdio_close(fp);977 978 979 isc_mem_destroy(&ns_g_mctx);980 isc_mem_checkdestroyed(stderr);981 982 ns_main_setmemstats(NULL);983 984 isc_app_finish();985 986 ns_os_closedevnull();987 988 ns_os_shutdown();989 990 return (0);991 三、 初始设置setup595 ns_os_tzset(); 初始化时区596 597 ns_os_opendevnull(); 打开空设备以便消息转向599 #ifdef HAVE_LIBSCF 是否solaris的smf管理机制600 /* Check if named is under smf control, before chroot. */601 result = ns_smf_get_instance(&instance, 0, ns_g_mctx);602 /* We dont care about instance, just check if we got one. */603 if (result = ISC_R_SUCCESS)604 ns_smf_got_instance = 1;605 else606 ns_smf_got_instance = 0;607 if (instance != NULL)608 isc_mem_free(ns_g_mctx, instance);609 #endif /* HAVE_LIBSCF */如果是chroot运行方式化,初始化可用资源。Chroot是以普通用户运行超级资源,是unix系统的一种机制611 #ifdef PATH_RANDOMDEV612 /*613 * Initialize systems random device as fallback entropy source614 * if running chrooted.615 */616 if (ns_g_chrootdir != NULL) 617 result = isc_entropy_create(ns_g_mctx, &ns_g_fallbackentropy);618 if (result != ISC_R_SUCCESS)619 ns_main_earlyfatal(isc_entropy_create() failed: %s,620 isc_result_totext(result);621 622 result = isc_entropy_createfilesource(ns_g_fallbackentropy,623 PATH_RANDOMDEV);624 if (result != ISC_R_SUCCESS) 625 ns_main_earlywarning(could not open pre-chroot 626 entropy source %s: %s,627 PATH_RANDOMDEV,628 isc_result_totext(result);629 isc_entropy_detach(&ns_g_fallbackentropy);630 631 632 #endif看cpu数目634 #ifdef ISC_PLATFORM_USETHREADS635 /*636 * Check for the number of cpus before ns_os_chroot().637 */638 ns_g_cpus_detected = isc_os_ncpus();639 #endif以下说明了最小权限运行机制,读config文件需要有root机制,通过unix的sid置位实现,即setsid()/*644 * For operating systems which have a capability mechanism, now645 * is the time to switch to minimal privs and change our user id.646 * On traditional UNIX systems, this call will be a no-op, and we647 * will change the user ID after reading the config file the first648 * time. (We need to read the config file to know which possibly649 * privileged ports to bind() to.)650 */651 ns_os_minprivs();652 日志初始化653 result = ns_log_init(ISC_TF(ns_g_username != NULL);654 if (result != ISC_R_SUCCESS)655 ns_main_earlyfatal(ns_log_init() failed: %s,656 isc_result_totext(result);pid = fork();产生新的子进程,如果是直接named而不是named g的话,因此,需要派生子进程,并关闭父的一些输入输出句柄,参见fork例程if (!ns_g_foreground)666 ns_os_daemonize();/*669 * We call isc_app_start() here as some versions of FreeBSDs fork()670 * destroys all the signal handling it sets up.671 */Isc_app_start主要是处理fork的信号机制的恢复672 result = isc_app_start();673 if (result != ISC_R_SUCCESS)674 ns_main_earlyfatal(isc_app_start() failed: %s,675 isc_result_totext(result);676 写日志文件,开始启动677 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,678 ISC_LOG_NOTICE, starting BIND %s%s, ns_g_version,679 saved_command_line);680 681 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,682 ISC_LOG_NOTICE, built with %s, ns_g_configargs);683 接下来是资源限制部分,可用#ulimit a来理解 /*729 * Record the servers startup time.730 */731 result = isc_time_now(&ns_g_boottime);732 if (result != ISC_R_SUCCESS)733 ns_main_earlyfatal(isc_time_now() failed: %s,734 isc_result_totext(result);735 生成管理器,如任务、超时、entropy、hash,socket等管理器736 result = create_managers();737 if (result != ISC_R_SUCCESS)738 ns_main_earlyfatal(create_managers() failed: %s,739 isc_result_totext(result);740 741 ns_builtin_init();742 743 /*744 * Add calls to register sdb drivers here.745 */746 /* xxdb_init(); */747 748 #ifdef DLZ749 /*750 * Registyer any DLZ drivers.751 */752 result = dlz_drivers_init();753 if (result != ISC_R_SUCCESS)754 ns_main_earlyfatal(dlz_drivers_init() failed: %s,755 isc_result_totext(result);756 #endif757 生成服务,重要部分,见分析六758 ns_server_create(ns_g_mctx, &ns_g_server);759 760 四、 运行主体程序文件/lxr/http/source/lib/isc/unix/app.c#L431430 isc_result_t431 isc_app_run(void) 432 int result;433 isc_event_t *event, *next_event;434 isc_task_t *task;435 #ifdef ISC_PLATFORM_USETHREADS436 sigset_t sset;437 char strbufISC_STRERRORSIZE;438 #ifdef HAVE_SIGWAIT439 int sig;440 #endif441 #endif /* ISC_PLATFORM_USETHREADS */442 443 #ifdef HAVE_LINUXTHREADS 如果启用了多线程编译,目前我们编译的是单线程,可用ps em|grep named查看线程数444 REQUIRE(main_thread = pthread_self();445 #endif446 加锁,事件队列是关键区,race condition447 LOCK(&lock);448 449 if (!running) 450 running = ISC_TRUE;451 事件结构有sender,type,action,arguments,而采用队列ev_link实现,事件FIFO依序处理。452 /*453 * Post any on-run events (in FIFO order).454 */主循环455 for (event = ISC_LIST_HEAD(on_run);456 event != NULL;457 event = next_event) 458 next_event = ISC_LIST_NEXT(event, ev_link);459 ISC_LIST_UNLINK(on_run, event, ev_link);460 task = event-ev_sender;461 event-ev_sender = NULL;事件任务机制,见分析五462 isc_task_sendanddetach(&task, &event);463 464 465 466 467 UNLOCK(&lock);468 以下主要为信号捕获处理机制,特别注意shutdown退出时的处理。信号catch处理机制能够使应用更安全退出。469 #ifndef HAVE_SIGWAIT470 /*471 * Catch SIGHUP.472 *473 * We do this here to ensure that the signal handler is installed474 * (i.e. that it wasnt a one-shot handler).475 */476 result = handle_signal(SIGHUP, reload_action);477 if (result != ISC_R_SUCCESS)478 return (ISC_R_SUCCESS);479 #endif480 481 #ifdef ISC_PLATFORM_USETHREADS482 /*483 * There is no danger if isc_app_shutdown() is called before we wait484 * for signals. Signals are blocked, so any such signal will simply485 * be made pending and we will get it when we call sigwait().486 */487 488 while (!want_shutdown) 489 #ifdef HAVE_SIGWAIT490 /*491 * Wait for SIGHUP, SIGINT, or SIGTERM.492 */493 if (sigemptyset(&sset) != 0 |494 sigaddset(&sset, SIGHUP) != 0 |495 sigaddset(&sset, SIGINT) != 0 |496 sigaddset(&sset, SIGTERM) != 0) 497 isc_strerror(errno, strbuf, sizeof(strbuf);498 UNEXPECTED_ERROR(_FILE_, _LINE_,499 isc_app_run() sigsetops: %s, strbuf);500 return (ISC_R_UNEXPECTED);501 502 503 #ifndef HAVE_UNIXWARE_SIGWAIT504 result = sigwait(&sset, &sig);505 if (result = 0) 506 if (sig = SIGINT |507 sig = SIGTERM)508 want_shutdown = ISC_TRUE;509 else if (sig = SIGHUP)510 want_reload = ISC_TRUE;511 512 513 #else /* Using UnixWare sigwait semantics. */514 sig = sigwait(&sset);515 if (sig = 0) 516 if (sig = SIGINT |517 sig = SIGTERM)518 want_shutdown = ISC_TRUE;519 else if (sig = SIGHUP)520 want_reload = ISC_TRUE;521 522 523 #endif /* HAVE_UNIXWARE_SIGWAIT */524 #else /* Dont have sigwait(). */525 /*526 * Listen for all signals.527 */528 if (sigemptyset(&sset) != 0) 529 isc_strerror(errno, strbuf, sizeof(strbuf);530 UNEXPECTED_ERROR(_FILE_, _LINE_,531 isc_app_run() sigsetops: %s, strbuf);532 return (ISC_R_UNEXPECTED);533 534 result = sigsuspend(&sset);535 #endif /* HAVE_SIGWAIT */536 537 if (want_reload) 538 want_reload = ISC_FALSE;539 return (ISC_R_RELOAD);540 541 542 if (want_shutdown & blocked)543 exit(1);544 545 546 #else /* ISC_PLATFORM_USETHREADS */547 548 (void)isc_taskmgr_dispatch();549 550 result = evloop();551 if (result != ISC_R_SUCCESS)552 return (result);553 554 #endif /* ISC_PLATFORM_USETHREADS */555 556 return (ISC_R_SUCCESS);557 正常关闭时,需要将相关线程也中止558 559 isc_result_t560 isc_app_shutdown(void) 561 isc_boolean_t want_kill = ISC_TRUE;562 char strbufISC_STRERRORSIZE;563 564 LOCK(&lock);565 566 REQUIRE(running);567 568 if (shutdown_requested)569 want_kill = ISC_FALSE;570 else571 shutdown_requested = ISC_TRUE;572 573 UNLOCK(&lock);574 575 if (want_kill) 576 #ifdef HAVE_LINUXTHREADS577 int result;578 579 result = pthread_kill(main_thread, SIGTERM);580 if (result != 0) 581 isc_strerror(result, strbuf, sizeof(strbuf);582 UNEXPECTED_ERROR(_FILE_, _LINE_,583 isc_app_shutdown() pthread_kill: %s,584 strbuf);585 return (ISC_R_UNEXPECTED);586 587 #else588 if (kill(getpid(), SIGTERM) ev_sender;event-ev_sender = NULL;isc_task_sendanddetach(&task, &event);void430 isc_task_sendanddetach(isc_task_t *taskp, isc_event_t *eventp) 431 isc_boolean_t idle1, idle2;432 isc_task_t *task;433 434 /*435 * Send *event to *taskp and then detach *taskp from its436 * task.437 */438 439 REQUIRE(taskp != NULL);440 task = *taskp;441 REQUIRE(VALID_TASK(task);442 443 XTRACE(isc_task_sendanddetach);444 445 LOCK(&task-lock);446 idle1 = task_send(task, eventp);447 idle2 = task_detach(task);448 UNLOCK(&task-lock);449 450 /*451 * If idle1, then idle2 shouldnt be true as well since were holding452 * the task lock, and thus the task cannot switch from ready back to453 * idle.454 */455 INSIST(!(idle1 & idle2);456 457 if (idle1 | idle2)458 task_ready(task);459 460 *taskp = NULL;461 462 463 #define PURGE_OK(event) (event)-ev_attributes & ISC_EVENTATTR_NOPURGE) = 0)464 六 服务任务生成(主要与rndc的channel通信)3826 void3827 ns_server_create(isc_mem_t *mctx, ns_server_t *serverp) 3828 isc_result_t result;3829 3830 ns_server_t *server = isc_mem_get(mctx, sizeof(*server);3831 if (server = NULL)3832 fatal(allocating server object, ISC_R_NOMEMORY);3833 3834 server-mctx = mctx;3835 server-task = NULL;3836 3837 /* Initialize configuration data with default values. */3838 3839 result = isc_quota_init(&server-xfroutquota, 10);3840 RUNTIME_CHECK(result = ISC_R_SUCCESS);3841 result = isc_quota_init(&server-tcpquota, 10);3842 RUNTIME_CHECK(result = ISC_R_SUCCESS);3843 result = isc_quota_init(&server-recursionquota, 100);3844 RUNTIME_CHECK(result = ISC_R_SUCCESS);3845 3846 result = dns_aclenv_init(mctx, &server-ac

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论