Revision | b4dc0c921ee782d841bc476470f28605529c03c2 (tree) |
---|---|
Zeit | 2014-12-24 16:07:22 |
Autor | Hiroaki Nakano <nakano.hiroaki@nttc...> |
Commiter | Hiroaki Nakano |
2014/12/24 edit
Signed-off-by: Hiroaki Nakano <nakano.hiroaki@nttcom.co.jp>
@@ -50,6 +50,7 @@ struct l7vs_dest; | ||
50 | 50 | extern int l7vs_lsock_init(); |
51 | 51 | extern void l7vs_lsock_fini(); |
52 | 52 | extern struct l7vs_lsock* l7vs_lsock_get( struct sockaddr_in*, uint8_t, int ); |
53 | +extern struct l7vs_lsock* l7vs_lsock_get_dummy( struct sockaddr_in*, uint8_t, int ); | |
53 | 54 | extern void l7vs_lsock_put( struct l7vs_lsock* ); |
54 | 55 | extern struct l7vs_lsock* l7vs_lsock_table_lookup( struct sockaddr_in*, uint8_t ); |
55 | 56 | extern void l7vs_lsock_add_service( struct l7vs_lsock*, struct l7vs_service* ); |
@@ -261,6 +261,92 @@ l7vs_lsock_get(struct sockaddr_in *sin, uint8_t proto, int backlog) | ||
261 | 261 | } |
262 | 262 | |
263 | 263 | /*! |
264 | + * look up infomation for socket | |
265 | + * return lsock structure without socket and iomux. | |
266 | + * | |
267 | + * @param[in] sin socket address struct( if ipv6 may be change this struct ) | |
268 | + * @param[in] proto TCS/UDP select. | |
269 | + * @param[in] backlog | |
270 | + */ | |
271 | +struct l7vs_lsock * | |
272 | +l7vs_lsock_get_dummy(struct sockaddr_in *sin, uint8_t proto, int backlog) | |
273 | +{ | |
274 | + struct l7vs_lsock *lsock; | |
275 | + int stype; | |
276 | + int ret; | |
277 | + int on = 1; | |
278 | + | |
279 | + if (logger_get_log_level(LOG_CAT_L7VSD_SYSTEM_SOCKET) == LOG_LV_DEBUG) { | |
280 | + LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_SYSTEM_SOCKET,20, | |
281 | + "in_fuction: struct l7vs_lsock * l7vs_lsock_get_dummy(struct sockaddr_in *sin, uint8_t proto, int backlog)" | |
282 | + "*sin =%p :proto = %d :backlog = %d :", | |
283 | + sin,proto,backlog); | |
284 | + } | |
285 | + | |
286 | + if (sin == NULL) { | |
287 | + return NULL; | |
288 | + } | |
289 | + | |
290 | + lsock = l7vs_lsock_table_lookup(sin, proto); | |
291 | + if (lsock != NULL) { | |
292 | + lsock->refcnt++; | |
293 | + if (logger_get_log_level(LOG_CAT_L7VSD_SYSTEM_SOCKET) == LOG_LV_DEBUG) { | |
294 | + char lsock_str[DEBUG_STR_LEN] = {0}; | |
295 | + l7vs_lsock_c_str(lsock_str, lsock); | |
296 | + LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_SYSTEM_SOCKET,21, | |
297 | + "table look up: lsock=%s", lsock_str); | |
298 | + } | |
299 | + return lsock; | |
300 | + } | |
301 | + | |
302 | + switch (proto) { | |
303 | + case IPPROTO_TCP: | |
304 | + stype = SOCK_STREAM; | |
305 | + break; | |
306 | + case IPPROTO_UDP: | |
307 | + stype = SOCK_DGRAM; | |
308 | + break; | |
309 | + default: | |
310 | + LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_SOCKET,21, | |
311 | + "Protocol number should be TCP or UDP (%d)", proto); | |
312 | + return NULL; | |
313 | + } | |
314 | + | |
315 | + lsock = (struct l7vs_lsock *)calloc(1, sizeof(*lsock)); | |
316 | + if (lsock == NULL) { | |
317 | + LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_SYSTEM_MEMORY,14, "Could not allocate lsock"); | |
318 | + return lsock; | |
319 | + } | |
320 | + if (logger_get_log_level(LOG_CAT_L7VSD_SYSTEM_MEMORY) == LOG_LV_DEBUG) { | |
321 | + LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_SYSTEM_MEMORY,6, | |
322 | + "in function l7vs_lsock_get: allocate memory" | |
323 | + " : size=%zu ,pointer=%p", sizeof(*lsock),lsock); | |
324 | + } | |
325 | + | |
326 | + if (logger_get_log_level(LOG_CAT_L7VSD_SYSTEM_SOCKET) == LOG_LV_DEBUG) { | |
327 | + LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_SYSTEM_SOCKET,22, "creating lsock %p", lsock); | |
328 | + } | |
329 | + lsock->proto = proto; | |
330 | + | |
331 | + lsock->addr = *sin; | |
332 | + | |
333 | + lsock->refcnt = 1; | |
334 | + lsock->fast_schedule = 1; | |
335 | + | |
336 | + l7vs_lsock_table_add(lsock); //Add socket in the list. It may be used for maintaining session (Am not sure) | |
337 | +// l7vs_iomux_add(&lsock->iom, L7VS_IOMUX_READ); | |
338 | + | |
339 | + if (logger_get_log_level(LOG_CAT_L7VSD_SYSTEM_SOCKET) == LOG_LV_DEBUG) { | |
340 | + char lsock_str[DEBUG_STR_LEN] = {0}; | |
341 | + l7vs_lsock_c_str(lsock_str, lsock); | |
342 | + LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_SYSTEM_SOCKET,23, | |
343 | + "creat: lsock=%s", lsock_str); | |
344 | + } | |
345 | + | |
346 | + return lsock; | |
347 | +} | |
348 | + | |
349 | +/*! | |
264 | 350 | * lisning socket remove list and iomuxlist. |
265 | 351 | * @param[in] lsock removing lisning socket |
266 | 352 | * @return void |
@@ -625,19 +625,23 @@ l7vs_service_list_dest_arg(struct l7vs_service *srv, | ||
625 | 625 | * @return int number currently created / -1 failure |
626 | 626 | */ |
627 | 627 | static l7vs_service * |
628 | -make_l7vs_service_data( l7vs_service_arg_multi *arg, int *err) | |
628 | +make_l7vs_service_data( l7vs_service_arg_multi *arg, int *err, pid_t pid) | |
629 | 629 | { |
630 | 630 | int ret; |
631 | 631 | |
632 | - struct l7vs_protomod *pmod; | |
633 | - struct l7vs_scheduler *sched; | |
634 | - struct l7vs_service *srv; | |
635 | - struct l7vs_lsock *lsock; | |
636 | - struct l7vs_dest *sorry_dest; //! sorry-server destination | |
632 | + struct l7vs_protomod *pmod; | |
633 | + struct l7vs_scheduler *sched; | |
634 | + struct l7vs_service *srv; | |
635 | + struct l7vs_lsock *lsock; | |
636 | + struct l7vs_dest *sorry_dest; //! sorry-server destination | |
637 | 637 | // struct l7vs_service_repdata * service_replicationdata; |
638 | 638 | |
639 | 639 | /* ソケット作成 */ |
640 | - lsock = l7vs_lsock_get(&arg->srv_arg.addr, arg->srv_arg.proto, arg->srv_arg.backlog); | |
640 | + if(pid == 0) | |
641 | + lsock = l7vs_lsock_get(&arg->srv_arg.addr, arg->srv_arg.proto, arg->srv_arg.backlog); | |
642 | + else | |
643 | + lsock = l7vs_lsock_get_dummy(&arg->srv_arg.addr, arg->srv_arg.proto, arg->srv_arg.backlog); | |
644 | + | |
641 | 645 | if(lsock == NULL) { |
642 | 646 | LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,1, "Could not create listen socket" ); |
643 | 647 | *err = L7VS_CONFIG_ERR_NOSOCK; |
@@ -654,7 +658,7 @@ make_l7vs_service_data( l7vs_service_arg_multi *arg, int *err) | ||
654 | 658 | /* プロトコルモジュールロード */ |
655 | 659 | pmod = l7vs_protomod_get(arg->srv_arg.protomod); |
656 | 660 | if (pmod == NULL) { |
657 | - l7vs_lsock_put(lsock); | |
661 | + if(pid==0) l7vs_lsock_put(lsock); | |
658 | 662 | *err = L7VS_CONFIG_ERR_NOMEM; |
659 | 663 | //debug output |
660 | 664 | if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){ |
@@ -670,7 +674,7 @@ make_l7vs_service_data( l7vs_service_arg_multi *arg, int *err) | ||
670 | 674 | sched = l7vs_sched_get(arg->srv_arg.schedmod); |
671 | 675 | if (sched == NULL) { |
672 | 676 | l7vs_protomod_put(pmod); |
673 | - l7vs_lsock_put(lsock); | |
677 | + if(pid==0) l7vs_lsock_put(lsock); | |
674 | 678 | *err = L7VS_CONFIG_ERR_NOSCHED; |
675 | 679 | //debug output |
676 | 680 | if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){ |
@@ -688,7 +692,7 @@ make_l7vs_service_data( l7vs_service_arg_multi *arg, int *err) | ||
688 | 692 | if (sorry_dest == NULL) { |
689 | 693 | l7vs_sched_put(sched); |
690 | 694 | l7vs_protomod_put(pmod); |
691 | - l7vs_lsock_put(lsock); | |
695 | + if(pid==0) l7vs_lsock_put(lsock); | |
692 | 696 | *err = L7VS_CONFIG_ERR_NOMEM; |
693 | 697 | //debug output |
694 | 698 | if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){ |
@@ -706,7 +710,7 @@ make_l7vs_service_data( l7vs_service_arg_multi *arg, int *err) | ||
706 | 710 | l7vs_dest_destroy(sorry_dest); |
707 | 711 | l7vs_sched_put(sched); |
708 | 712 | l7vs_protomod_put(pmod); |
709 | - l7vs_lsock_put(lsock); | |
713 | + if(pid==0) l7vs_lsock_put(lsock); | |
710 | 714 | *err = L7VS_CONFIG_ERR_NOMEM; |
711 | 715 | LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_SYSTEM_MEMORY,5, "l7vs_service memory allocate error" ); |
712 | 716 | return NULL; |
@@ -736,7 +740,7 @@ make_l7vs_service_data( l7vs_service_arg_multi *arg, int *err) | ||
736 | 740 | l7vs_dest_destroy(sorry_dest); |
737 | 741 | l7vs_sched_put(sched); |
738 | 742 | l7vs_protomod_put(pmod); |
739 | - l7vs_lsock_put(lsock); | |
743 | + if(pid==0) l7vs_lsock_put(lsock); | |
740 | 744 | *err = L7VS_CONFIG_ERR_NOMEM; |
741 | 745 | //debug output |
742 | 746 | if( LOG_LV_DEBUG == logger_get_log_level( LOG_CAT_L7VSD_VIRTUAL_SERVICE ) ){ |
@@ -974,7 +978,7 @@ l7vs_notify_proto_of_child(gpointer pid,struct l7vs_service_arg_multi *arg) | ||
974 | 978 | /*! |
975 | 979 | * check child process when create service. and send information for adding service. |
976 | 980 | * @param[in] *arg l7vs_service_arg_multi |
977 | - * @return 0: nothing IP+port, 1: exist IP+port | |
981 | + * @return 0: nothing IP+port, 1: exist IP+port, -1: error | |
978 | 982 | */ |
979 | 983 | int |
980 | 984 | l7vs_child_process_check(struct l7vs_service_arg_multi *arg) |
@@ -1000,12 +1004,14 @@ l7vs_child_process_check(struct l7vs_service_arg_multi *arg) | ||
1000 | 1004 | if(ret){ |
1001 | 1005 | /* あったのでサービス重複エラー */ |
1002 | 1006 | LOGGER_PUT_LOG_ERROR( LOG_CAT_L7VSD_VIRTUAL_SERVICE,2, "Virtual service already exists" ); |
1007 | + srv_sock_check_flg = -1; | |
1003 | 1008 | }else{ |
1004 | 1009 | /* 親持ちのリストl7vs_child_proto_grpにプロトコル追加 */ |
1005 | 1010 | l7vs_child_proto_add_proto(cpgrp,arg->srv_arg.protomod); |
1006 | 1011 | |
1007 | 1012 | /* 既存子プロセス持ちのリストにprotocol追加通知 */ |
1008 | 1013 | g_slist_foreach(cpgrp->child_pid,(GFunc)l7vs_notify_proto_of_child,arg); |
1014 | + | |
1009 | 1015 | } |
1010 | 1016 | } |
1011 | 1017 |
@@ -1018,7 +1024,7 @@ l7vs_child_process_check(struct l7vs_service_arg_multi *arg) | ||
1018 | 1024 | * @return OK=0, NG=-1 |
1019 | 1025 | */ |
1020 | 1026 | int |
1021 | -l7vs_receive_add_protocol_info(int fd) | |
1027 | +l7vs_receive_add_protocol_info(int fd, pid_t pid) | |
1022 | 1028 | { |
1023 | 1029 | l7vs_service_arg_multi *arg; |
1024 | 1030 | void *buffer; |
@@ -1026,6 +1032,8 @@ l7vs_receive_add_protocol_info(int fd) | ||
1026 | 1032 | |
1027 | 1033 | int err; |
1028 | 1034 | |
1035 | + /* 子プロセスでl7vs_service_arg_multiを作る関数 */ | |
1036 | + | |
1029 | 1037 | // buffer確保 |
1030 | 1038 | buffer = malloc(sizeof(struct l7vs_service_arg_multi)); |
1031 | 1039 | if(buffer == NULL){ |
@@ -1042,7 +1050,7 @@ l7vs_receive_add_protocol_info(int fd) | ||
1042 | 1050 | arg = (l7vs_service_arg_multi *)buffer; |
1043 | 1051 | |
1044 | 1052 | // l7vs_service作成 |
1045 | - srv = make_l7vs_service_data(arg,&err); | |
1053 | + srv = make_l7vs_service_data(arg,&err,pid); | |
1046 | 1054 | if(srv == NULL){ |
1047 | 1055 | free(buffer); |
1048 | 1056 | return -1; |
@@ -1060,7 +1068,7 @@ l7vs_receive_add_protocol_info(int fd) | ||
1060 | 1068 | * @return int OK=0, NG<0 |
1061 | 1069 | */ |
1062 | 1070 | static int |
1063 | -l7vs_cfifo_callback(struct l7vs_iomux *iom ) | |
1071 | +l7vs_cfifo_callback(struct l7vs_iomux *iom) | |
1064 | 1072 | { |
1065 | 1073 | int ret; |
1066 | 1074 |
@@ -1089,8 +1097,8 @@ l7vs_cfifo_callback(struct l7vs_iomux *iom ) | ||
1089 | 1097 | "in_fuction: int l7vs_cfifo_callback (struct l7vs_iomux *iom) iom = %p",iom); |
1090 | 1098 | } |
1091 | 1099 | |
1092 | - | |
1093 | - ret = l7vs_receive_add_protocol_info(iom->fd); | |
1100 | + /* 必ず子で起動するはずなので、pidは0固定 */ | |
1101 | + ret = l7vs_receive_add_protocol_info(iom->fd,0); | |
1094 | 1102 | if(ret==-1){ |
1095 | 1103 | return -1; |
1096 | 1104 | } |
@@ -1323,6 +1331,7 @@ l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) | ||
1323 | 1331 | /* 子プロセスを生成したら親プロセスでIP,portとPIDの対応リストを作る */ |
1324 | 1332 | |
1325 | 1333 | /* 親プロセスから引き継いだUNIXドメインソケットを閉じる */ |
1334 | + /* 現在、閉じると親プロセスが死ぬ */ | |
1326 | 1335 | //l7vs_config_close(); |
1327 | 1336 | |
1328 | 1337 | /* 親プロセス用PIPEを閉じる */ |
@@ -1332,7 +1341,7 @@ l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) | ||
1332 | 1341 | if( pid == 0 ){ |
1333 | 1342 | /* ソケット作成 */ |
1334 | 1343 | /* 以前はmake_l7vs_service_dataがまるごと入っていた */ |
1335 | - srv = make_l7vs_service_data(arg,err); | |
1344 | + srv = make_l7vs_service_data(arg,err,pid); | |
1336 | 1345 | if( srv == NULL) return NULL; |
1337 | 1346 | |
1338 | 1347 | /* 名前付きパイプ作成 */ |
@@ -1404,7 +1413,7 @@ l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) | ||
1404 | 1413 | l7vs_cfifo_iomux->data = NULL; |
1405 | 1414 | l7vs_cfifo_iomux->callback = l7vs_cfifo_callback; |
1406 | 1415 | l7vs_cfifo_iomux->status = iomux_cfifo_read_waiting; |
1407 | - l7vs_iomux_add( l7vs_cfifo_iomux, iom_read ); | |
1416 | + l7vs_iomux_add( l7vs_cfifo_iomux, iom_read); | |
1408 | 1417 | |
1409 | 1418 | /* 親PIPEを開いてPIDとIP,portを親に通知 */ |
1410 | 1419 | /* リトライするかどうか・・・sleepいれる? */ |
@@ -1445,12 +1454,17 @@ l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) | ||
1445 | 1454 | |
1446 | 1455 | }else if( pid > 0 ){ |
1447 | 1456 | /* 親プロセス処理 */ |
1457 | + // 子プロセス作成ループに入れると、子プロセス個数分親処理が走ってしまう | |
1458 | + | |
1459 | + /* VS情報作成 */ | |
1460 | + srv = make_l7vs_service_data(arg,err,pid); | |
1461 | + if( srv == NULL) return NULL; | |
1448 | 1462 | |
1449 | 1463 | /* l7vs_child_proto_grpを初期化作成してリスト登録←複数回を考慮 */ |
1450 | 1464 | grp = l7vs_child_proto_grp_init(arg->srv_arg.addr.sin_addr.s_addr, |
1451 | 1465 | arg->srv_arg.addr.sin_port, |
1452 | 1466 | arg->srv_arg.protomod ); |
1453 | - | |
1467 | + return srv; | |
1454 | 1468 | }else if( pid < 0 ){ |
1455 | 1469 | /* 子プロセス作成失敗 */ |
1456 | 1470 | //DEBUG output |
@@ -1461,6 +1475,17 @@ l7vs_service_create(struct l7vs_service_arg_multi *arg, int *err) | ||
1461 | 1475 | return NULL; |
1462 | 1476 | } |
1463 | 1477 | } |
1478 | + }else if(srv_sock_check_flg == 1){ | |
1479 | + /* 子プロセス追加なし、VSのみ追加 */ | |
1480 | + /* 子プロセスは追加しないけど、親側VS情報は追加 */ | |
1481 | + // pidは0以外ならOK | |
1482 | + srv = make_l7vs_service_data(arg,err,1); | |
1483 | + if( srv == NULL) return NULL; | |
1484 | + | |
1485 | + return srv; | |
1486 | + }else{ | |
1487 | + /* VS重複エラー */ | |
1488 | + return NULL; | |
1464 | 1489 | } |
1465 | 1490 | } |
1466 | 1491 |