blktap(1)

来源:互联网 发布:java base64解码utf8 编辑:程序博客网 时间:2024/06/14 00:13

blktap(1)


tapdisk2.c
main()函数:
c = getopt(argc, argv, “s:Dh”)
int getopt(int argc, char * const argv[], const char *optstring);参考
这里表示有s,D,h三种选项,s的后面跟一个参数。
s:memshr_set_domid(atoi(optarg))
optarg这时指向参数,把vhd_info的domid设置为这个参数。

 27 typedef struct { 28     int     enabled; 29     domid_t domid; 30     xc_interface *xc_handle; 31 } memshr_vbd_info_t; 32  33 memshr_vbd_info_t vbd_info = {0, DOMID_INVALID};  46 void memshr_set_domid(int domid) 47 { 48     vbd_info.domid = domid; 49 }

d:nodaemon=1
h:usage(argv[0],0)

42 static void 43 usage(const char *app, int err) 44 { 45         fprintf(stderr, "usage: %s [-D] <-u uuid> <-c control socket>\n", app)    ; 46         exit(err); 47 }

输出错误提示,目的?
tapdisk_server_init()

280 int281 tapdisk_server_init(void)282 {283         memset(&server, 0, sizeof(server));284         INIT_LIST_HEAD(&server.vbds);285 286         scheduler_initialize(&server.scheduler);287 288         return 0;289 }
 60 typedef struct tapdisk_server { 61         int                          run; 62         struct list_head             vbds; 63         scheduler_t                  scheduler; 64         struct tqueue                aio_queue; 65 } tapdisk_server_t; 66 
253 void254 scheduler_initialize(scheduler_t *s)255 {256         memset(s, 0, sizeof(scheduler_t));257 258         s->uuid = 1;259 260         FD_ZERO(&s->read_fds);261         FD_ZERO(&s->write_fds);262         FD_ZERO(&s->except_fds);263 264         INIT_LIST_HEAD(&s->events);265 }
 43 typedef struct scheduler { 44         fd_set                       read_fds; 45         fd_set                       write_fds; 46         fd_set                       except_fds; 47  48         struct list_head             events; 49  50         int                          uuid; 51         int                          max_fd; 52         int                          timeout; 53         int                          restart; 54         int                          max_timeout; 55 } scheduler_t;

初始化server:初始化scheduler和vbds
继续main

 96         if (!nodaemon) { 97                 err = daemon(0, 1); 98                 if (err) { 99                         DPRINTF("failed to daemonize: %d\n", errno);100                         goto out;101                 }102         }

如果nodaemon为0,则daemon。所以如果有选项D则代表不要daemon.
在Linux中专门提供了一个函数来完成这个daemon化的过程,这个函数的原型如下

int daemon (int __nochdir, int __noclose);

如果__nochdir的值为0,则将切换工作目录为根目录;如果__noclose为0,则将标准输入,输出和标准错误都重定向到/dev /null。参考

104         err = tapdisk_control_open(&control);
829 int830 tapdisk_control_open(char **path)831 {832         int err;833     //初始化socket,event_id为-1    //signal(SIGPIPE, SIG_IGN);    //ignore SIGPIPE834         tapdisk_control_initialize();835 836         return tapdisk_control_create_socket(path);837 }
 51 struct tapdisk_control { 52         char              *path; 53         int                socket; 54         int                event_id; 55 }; 62 static struct tapdisk_control td_control;
758 static int759 tapdisk_control_create_socket(char **socket_path)760 {761         int err, flags;762         struct sockaddr_un saddr;763 // 47 #define BLKTAP2_CONTROL_NAME           "blktap-control" //48 #define BLKTAP2_CONTROL_DIR            "/var/run/"BLKTAP2_CONTROL_NAME764         err = tapdisk_control_mkdir(BLKTAP2_CONTROL_DIR);785         td_control.socket = socket(AF_UNIX, SOCK_STREAM, 0);792         memset(&saddr, 0, sizeof(saddr));793         strncpy(saddr.sun_path, td_control.path, sizeof(saddr.sun_path));794         saddr.sun_family = AF_UNIX;795 796         err = bind(td_control.socket,797                    (const struct sockaddr *)&saddr, sizeof(saddr));804         err = listen(td_control.socket, 10);811         err = tapdisk_server_register_event(SCHEDULER_POLL_READ_FD,812                                             td_control.socket, 0,813                                             tapdisk_control_accept, NULL);819         td_control.event_id = err;820         *socket_path = td_control.path;821 

初始化tapdisk_control,其中tapdisk_control_create_socket创建了socket赋值给tapdisk_control的socket,把path返回到返回到参数path,并且赋值给tapdisk_control的path。在main里面,path就是control
这里的细节先不看了。

接下来,如果是有daemon的,把/dev/null的东西复制到STDIN_FILENO等地方,为什么??先跳过

113         if (!nodaemon) {114                 int fd;115 116                 fd = open("/dev/null", O_RDWR);117                 if (fd != -1) {118                         dup2(fd, STDIN_FILENO);119                         dup2(fd, STDOUT_FILENO);120                         dup2(fd, STDERR_FILENO);121                         if (fd > 2)122                                 close(fd);123                 }124         }
126         err = tapdisk_server_complete();
291 int292 tapdisk_server_complete(void)293 {294         int err;295 296         err = tapdisk_server_init_aio();297         if (err)298                 goto fail;299     //run置1300         server.run = 1;301 302         return 0;303 304 fail:305         tapdisk_server_close_aio();306         return err;307 }
208 static int209 tapdisk_server_init_aio(void)210 {211         return tapdisk_init_queue(&server.aio_queue, TAPDISK_TIOCBS,212                                   TIO_DRV_LIO, NULL);213 }
 56 struct tqueue { 57         int                   size; 58  59         const struct tio     *tio; 60         void                 *tio_data; 61  62         struct opioctx        opioctx; 63  64         int                   queued; 65         struct iocb         **iocbs; 66  67         /* number of iocbs pending in the aio layer */ 68         int                   iocbs_pending; 69  70         /* number of tiocbs pending in the queue --  71          * this is likely to be larger than iocbs_pending  72          * due to request coalescing */ 73         int                   tiocbs_pending; 74  75         /* iocbs may be deferred if the aio ring is full. 76          * tapdisk_queue_complete will ensure deferred 77          * iocbs are queued as slots become available. */ 78         struct tlist          deferred; 79         int                   tiocbs_deferred; 80  81         /* optional tapdisk filter */ 82         struct tfilter       *filter; 83  84         uint64_t              deferrals; 85 };
607 int608 tapdisk_init_queue(struct tqueue *queue, int size,609                    int drv, struct tfilter *filter)610 {611         int i, err;612 613         memset(queue, 0, sizeof(struct tqueue));614 615         queue->size   = size;616         queue->filter = filter;617 618         if (!size)619                 return 0;620 621         err = tapdisk_queue_init_io(queue, drv);622         if (err)623                 goto fail;624 625         queue->iocbs = calloc(size, sizeof(struct iocb *));626         if (!queue->iocbs) {627                 err = -errno;628                 goto fail;629         }630 631         err = opio_init(&queue->opioctx, size);632         if (err)633                 goto fail;634 635         return 0;

看到这里,可以猜测tapdisk_server_complete初始化server:将run置1;初始化aoiqueue。这个aoiqueue是干嘛的,以后再看。

132         err = tapdisk_server_run();
Created with Raphaël 2.1.0main()tapdisk_server_init()nodaemon == 0?daemon(0,1)tapdisk_control_open(&control)tapdisk_server_complete()tapdisk_server_run()endyesno
Created with Raphaël 2.1.0main()main()tapdisk_control_open(&control)tapdisk_control_open(&control)tapdisk_control_initialize()tapdisk_control_initialize()tapdisk_control_create_socket(path)tapdisk_control_create_socket(path)open control,control = path
0 0
原创粉丝点击