Changeset 3081
- Timestamp:
- 09/18/10 01:37:45 (14 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/globals.h
r3069 r3081 860 860 int saveinithistory; 861 861 int reader_restart_seconds; //schlocke: reader restart auf x seconds, disable = 0 862 int reader_auto_loadbalance; //schlocke: reader loadbalancing disable = 0 enable = 1 863 int reader_auto_loadbalance_save; //schlocke: load/save statistics to file, save every x ecms 862 863 //Loadbalancer-Config: 864 int lb_mode; //schlocke: reader loadbalancing mode 865 int lb_save; //schlocke: load/save statistics to file, save every x ecms 866 int lb_nbest_readers; // count of best readers 867 int lb_nfb_readers; // count of fallback readers 868 int lb_min_ecmcount; // minimal ecm count to evaluate lbvalues 869 int lb_max_ecmcount; // maximum ecm count before reseting lbvalues 870 int lb_reopen_seconds; //time between retrying failed readers/caids/prov/srv 871 864 872 int resolve_gethostbyname; 865 873 874 #ifdef CS_WITH_DOUBLECHECK 875 int double_check; //schlocke: Double checks each ecm+dcw from two (or more) readers 876 #endif 877 866 878 #ifdef CS_WITH_GBOX 867 879 uchar gbox_pwd[8]; … … 930 942 int btun; // mark er as betatunneled 931 943 944 #ifdef CS_WITH_DOUBLECHECK 945 int checked; 946 uchar cw_checked[16]; 947 int origin_reader; 948 #endif 949 932 950 #ifdef CS_WITH_GBOX 933 951 ushort gbxCWFrom; … … 948 966 #define LB_LOWEST_USAGELEVEL 3 949 967 950 #define MAX_STAT_TIME 20951 #define MIN_ECM_COUNT 5952 #define MAX_ECM_COUNT 500953 954 955 968 typedef struct add_reader_stat_t 956 969 { … … 963 976 ushort srvid; 964 977 } GCC_PACK ADD_READER_STAT; 978 979 #define MAX_STAT_TIME 20 965 980 966 981 typedef struct reader_stat_t -
trunk/module-stat.c
r3056 r3081 3 3 #define UNDEF_AVG_TIME 80000 4 4 #define MAX_ECM_SEND_CACHE 8 5 #define REOPEN_SECONDS 900 5 6 #define DEFAULT_REOPEN_SECONDS 900 7 #define DEFAULT_MIN_ECM_COUNT 5 8 #define DEFAULT_MAX_ECM_COUNT 500 9 #define DEFAULT_NBEST 1 10 #define DEFAULT_NFB 1 6 11 7 12 // … … 26 31 memset(ecm_send_cache, 0, sizeof(ECM_SEND_CACHE)*MAX_ECM_SEND_CACHE); 27 32 cs_ftime(&nulltime); 33 34 //checking config 35 if (cfg->lb_nbest_readers < 2) 36 cfg->lb_nbest_readers = DEFAULT_NBEST; 37 if (cfg->lb_nfb_readers < 2) 38 cfg->lb_nfb_readers = DEFAULT_NFB; 39 if (cfg->lb_min_ecmcount < 1) 40 cfg->lb_min_ecmcount = DEFAULT_MIN_ECM_COUNT; 41 if (cfg->lb_max_ecmcount < 2) 42 cfg->lb_max_ecmcount = DEFAULT_MAX_ECM_COUNT; 43 if (cfg->lb_reopen_seconds < 10) 44 cfg->lb_reopen_seconds = DEFAULT_REOPEN_SECONDS; 28 45 } 29 46 … … 90 107 if (!reader_stat[ridx]) { 91 108 reader_stat[ridx] = llist_create(); 92 if (cfg-> reader_auto_loadbalance_save)109 if (cfg->lb_save) 93 110 load_stat_from_file(ridx); 94 111 } … … 245 262 //USAGELEVEL: 246 263 int ule = reader[ridx].lb_usagelevel_ecmcount; 247 if (ule > 0 && ((ule / MIN_ECM_COUNT) > 0)) //update every MIN_ECM_COUNT usagelevel:264 if (ule > 0 && ((ule / cfg->lb_min_ecmcount) > 0)) //update every MIN_ECM_COUNT usagelevel: 248 265 { 249 266 time_t t = (time(NULL)-reader[ridx].lb_usagelevel_time); … … 265 282 266 283 //debug only: 267 if (cfg-> reader_auto_loadbalance_save) {284 if (cfg->lb_save) { 268 285 stat_load_save++; 269 if (stat_load_save > cfg-> reader_auto_loadbalance_save) {286 if (stat_load_save > cfg->lb_save) { 270 287 stat_load_save = 0; 271 288 save_all_stat_to_file(); … … 301 318 /** 302 319 * Gets best reader for caid/prid/srvid. 303 * Best reader is evaluated by lowest avg time but only if ecm_count > MIN_ECM_COUNT(5)320 * Best reader is evaluated by lowest avg time but only if ecm_count > cfg->lb_min_ecmcount (5) 304 321 * Also the reader is asked if he is "available" 305 322 * returns ridx when found or -1 when not found … … 321 338 } 322 339 340 int re[CS_MAXREADER]; 341 323 342 //resulting readers: 324 343 memset(result, 0, sizeof(int)*CS_MAXREADER); 344 //resulting values: 345 memset(re, 0, sizeof(re)); 325 346 326 347 struct timeb new_nulltime; … … 328 349 time_t current_time = time(NULL); 329 350 330 int best_ridx = -1, best_ridx2 = -1;331 int best = 0, best2 = 0;332 351 int current = -1; 333 int secondbest_ridx = -1;334 int secondbest_ridx2 = -1;335 352 336 353 READER_STAT *stat = NULL; … … 346 363 } 347 364 348 if (stat->ecm_count < 0||(stat->ecm_count > MAX_ECM_COUNT&& stat->time_avg > (int)cfg->ftimeout)) {349 cs_debug_mask(D_TRACE, "loadbalancer: max ecms (%d) reached by reader %s, resetting statistics", MAX_ECM_COUNT, reader[i].label);365 if (stat->ecm_count < 0||(stat->ecm_count > cfg->lb_max_ecmcount && stat->time_avg > (int)cfg->ftimeout)) { 366 cs_debug_mask(D_TRACE, "loadbalancer: max ecms (%d) reached by reader %s, resetting statistics", cfg->lb_max_ecmcount, reader[i].label); 350 367 reset_stat(grs->caid, grs->prid, grs->srvid); 351 368 result[i] = 1;//max ecm reached, get new statistics … … 353 370 } 354 371 355 if (stat->rc == 0 && stat->ecm_count < MIN_ECM_COUNT) {372 if (stat->rc == 0 && stat->ecm_count < cfg->lb_min_ecmcount) { 356 373 cs_debug_mask(D_TRACE, "loadbalancer: reader %s needs more statistics", reader[i].label); 357 374 result[i] = 1; //need more statistics! … … 360 377 361 378 362 //Reader can decode this service (rc==0) and has MIN_ECM_COUNTecms:379 //Reader can decode this service (rc==0) and has lb_min_ecmcount ecms: 363 380 if (stat->rc == 0) { 364 381 //get 365 switch (cfg-> reader_auto_loadbalance) {382 switch (cfg->lb_mode) { 366 383 default: 367 384 case LB_NONE: 368 385 //cs_debug_mask(D_TRACE, "loadbalance disabled"); 369 386 result[i] = 1; 387 current = 1; 370 388 break; 371 389 case LB_FASTEST_READER_FIRST: … … 388 406 reader[i].lbvalue = current; 389 407 #endif 390 391 //cs_debug_mask(D_TRACE, "loadbalance reader %s value %d", reader[i].label, current); 392 if (best_ridx==-1 || current < best) { 393 if (!reader[i].ph.c_available 394 || reader[i].ph.c_available(i, 395 AVAIL_CHECK_LOADBALANCE)) { 396 secondbest_ridx = best_ridx; 397 best_ridx = i; 398 best = current; 399 } 408 if (!reader[i].ph.c_available 409 || reader[i].ph.c_available(i, 410 AVAIL_CHECK_LOADBALANCE)) { 411 current=current/2; 400 412 } 401 if (best_ridx2==-1 || current < best2) { 402 secondbest_ridx2 = best_ridx2; 403 best_ridx2 = i; 404 best2 = current; 405 } 413 if (current < 1) 414 re[i]=1; 415 else 416 re[i] = current; 406 417 } 407 418 else 408 419 { 409 if (stat->last_received+ REOPEN_SECONDS< current_time) { //Retrying every 900 seconds420 if (stat->last_received+cfg->lb_reopen_seconds < current_time) { //Retrying every 900 seconds 410 421 stat->last_received = current_time; 411 422 result[i] = 1; … … 422 433 //so all (au) readers ares asked if user can au 423 434 } 424 else 425 result[i] = 2; 426 } 427 } 428 } 429 if (best_ridx == -1) 430 secondbest_ridx = secondbest_ridx2; 431 best_ridx = best_ridx2; 432 if (best_ridx >= 0) { 433 //cs_debug_mask(D_TRACE, "-->loadbalance best reader %s (%d) best value %d", reader[best_ridx].label, best_ridx, best2); 434 result[best_ridx] = 1; 435 436 //OLDEST_READER: 437 cs_ftime(&reader[best_ridx].lb_last); 438 } 439 //else 440 //cs_debug_mask(D_TRACE, "-->loadbalance no best reader!"); 441 442 //setting second best reader as fallbacks: 443 if (secondbest_ridx >= 0 && !result[secondbest_ridx]) { 444 result[secondbest_ridx] = 2; 445 } 446 else 447 { 448 //setting all other readers as fallbacks: 449 for (i=0;i<CS_MAXREADER; i++) { 450 if (grs->reader_avail[i] && !result[i]) { 451 result[i] = 2; 452 } 435 } 436 } 437 } 438 439 int nbest_readers = cfg->lb_nbest_readers; 440 int nfb_readers = cfg->lb_nfb_readers; 441 int best_ridx = -1; 442 443 nfb_readers += nbest_readers; 444 445 int n=0; 446 for (i=0;i<CS_MAXREADER;i++) { 447 int best=0; 448 int best_idx=-1; 449 int j; 450 for (j=0; j<CS_MAXREADER;j++) { 451 if (re[j] && re[j] > best) { 452 best_idx=j; 453 best=re[j]; 454 } 455 } 456 if (best_idx<0) 457 break; 458 else { 459 re[best_idx]=0; 460 n++; 461 if (n<=nbest_readers) { 462 result[best_idx] = 1; 463 //OLDEST_READER: 464 cs_ftime(&reader[best_idx].lb_last); 465 if (best_ridx <0) 466 best_ridx = best_idx; 467 } 468 else if (n<=nfb_readers) { 469 if (!result[best_idx]) 470 result[best_idx] = 2; 471 } 472 else 473 break; 453 474 } 454 475 } -
trunk/oscam-config.c
r3080 r3081 561 561 } 562 562 563 if (!strcmp(token, "readerautoloadbalance") ) {563 if (!strcmp(token, "readerautoloadbalance") || !strcmp(token, "lb_mode")) { 564 564 if (strlen(value) == 0) { 565 cfg-> reader_auto_loadbalance = 0;566 return; 567 } else { 568 cfg-> reader_auto_loadbalance = atoi(value);569 return; 570 } 571 } 572 573 if (!strcmp(token, "readerautoloadbalance_save") ) {565 cfg->lb_mode = 0; 566 return; 567 } else { 568 cfg->lb_mode = atoi(value); 569 return; 570 } 571 } 572 573 if (!strcmp(token, "readerautoloadbalance_save") || !strcmp(token, "lb_save")) { 574 574 if (strlen(value) == 0) { 575 cfg-> reader_auto_loadbalance_save = 0;576 return; 577 } else { 578 cfg-> reader_auto_loadbalance_save = atoi(value);575 cfg->lb_save = 0; 576 return; 577 } else { 578 cfg->lb_save = atoi(value); 579 579 return; 580 580 } 581 581 } 582 582 583 if (!strcmp(token, "lb_nbest_readers")) { 584 if (strlen(value)) 585 cfg->lb_nbest_readers = atoi(value); 586 return; 587 } 588 589 if (!strcmp(token, "lb_nfb_readers")) { 590 if (strlen(value)) 591 cfg->lb_nfb_readers = atoi(value); 592 return; 593 } 594 595 if (!strcmp(token, "lb_min_ecmcount")) { 596 if (strlen(value)) 597 cfg->lb_min_ecmcount = atoi(value); 598 return; 599 } 600 601 if (!strcmp(token, "lb_max_ecmcount")) { 602 if (strlen(value)) 603 cfg->lb_max_ecmcount = atoi(value); 604 return; 605 } 606 607 if (!strcmp(token, "lb_reopen_seconds")) { 608 if (strlen(value)) 609 cfg->lb_reopen_seconds = atoi(value); 610 return; 611 } 612 583 613 if (!strcmp(token, "resolvegethostbyname")) { 584 614 if (strlen(value) == 0) { … … 591 621 } 592 622 623 #ifdef CS_WITH_DOUBLECHECK 624 if (!strcmp(token, "double_check")) { 625 if (strlen(value) == 0) { 626 cfg->double_check = 0; 627 return; 628 } else { 629 cfg->double_check = atoi(value); 630 return; 631 } 632 } 633 #endif 593 634 594 635 … … 1786 1827 fprintf_conf(f, CONFVARWIDTH, "saveinithistory", "%d\n", cfg->saveinithistory); 1787 1828 fprintf_conf(f, CONFVARWIDTH, "readerrestartseconds", "%d\n", cfg->reader_restart_seconds); 1788 fprintf_conf(f, CONFVARWIDTH, "readerautoloadbalance", "%d\n", cfg->reader_auto_loadbalance); 1789 fprintf_conf(f, CONFVARWIDTH, "readerautoloadbalance_save", "%d\n", cfg->reader_auto_loadbalance_save); 1829 1830 fprintf_conf(f, CONFVARWIDTH, "lb_mode", "%d\n", cfg->lb_mode); 1831 fprintf_conf(f, CONFVARWIDTH, "lb_save", "%d\n", cfg->lb_save); 1832 fprintf_conf(f, CONFVARWIDTH, "lb_nbest_readers", "%d\n", cfg->lb_nbest_readers); 1833 fprintf_conf(f, CONFVARWIDTH, "lb_nfb_readers", "%d\n", cfg->lb_nfb_readers); 1834 fprintf_conf(f, CONFVARWIDTH, "lb_min_ecmcount", "%d\n", cfg->lb_min_ecmcount); 1835 fprintf_conf(f, CONFVARWIDTH, "lb_max_ecmcount", "%d\n", cfg->lb_max_ecmcount); 1836 fprintf_conf(f, CONFVARWIDTH, "lb_reopen_seconds", "%d\n", cfg->lb_reopen_seconds); 1837 1790 1838 fprintf_conf(f, CONFVARWIDTH, "resolvegethostbyname", "%d\n", cfg->resolve_gethostbyname); 1839 1840 #ifdef CS_WITH_DOUBLECHECK 1841 fprintf_conf(f, CONFVARWIDTH, "double_check", "%d\n", cfg->double_check); 1842 #endif 1843 1791 1844 fputc((int)'\n', f); 1792 1845 -
trunk/oscam-http.c
r3069 r3081 115 115 tpl_printf(vars, 0, "READERRESTARTSECONDS", "%d", cfg->reader_restart_seconds); 116 116 117 tpl_printf(vars, 0, "TMP", "READERAUTOLOADBALANCE%d", cfg-> reader_auto_loadbalance);117 tpl_printf(vars, 0, "TMP", "READERAUTOLOADBALANCE%d", cfg->lb_mode); 118 118 tpl_addVar(vars, 0, tpl_getVar(vars, "TMP"), "selected"); 119 119 120 tpl_printf(vars, 0, "READERAUTOLOADBALANCES", "%d",cfg-> reader_auto_loadbalance_save);120 tpl_printf(vars, 0, "READERAUTOLOADBALANCES", "%d",cfg->lb_save); 121 121 122 122 if (cfg->resolve_gethostbyname == 1) -
trunk/oscam.c
r3079 r3081 510 510 //Schlocke: restart cardreader after 5 seconds: 511 511 static void restart_cardreader(int pridx, int force_now) { 512 ridx = pridx; 512 ridx = pridx; //set current ridx for fork 513 513 int cs_idx = reader[ridx].cs_idx; 514 514 int pid; … … 939 939 940 940 pthread_mutex_init(&gethostbyname_lock, NULL); 941 init_stat();942 941 943 942 #ifdef CS_LOGHISTORY … … 1483 1482 static void store_ecm(ECM_REQUEST *er) 1484 1483 { 1484 #ifdef CS_WITH_DOUBLECHECK 1485 if (cfg->double_check && er->checked < 2) 1486 return; 1487 #endif 1485 1488 int rc; 1486 1489 rc=*ecmidx; … … 1794 1797 void send_reader_stat(int ridx, ECM_REQUEST *er, int rc) 1795 1798 { 1796 if (!cfg-> reader_auto_loadbalance || rc == 100)1799 if (!cfg->lb_mode || rc == 100) 1797 1800 return; 1798 1801 struct timeb tpe; … … 1991 1994 cs_ddump_mask (D_ATR, er->cw, 16, "cw:"); 1992 1995 if (er->rc==7) er->rc=0; 1996 1997 #ifdef CS_WITH_DOUBLECHECK 1998 if (cfg->double_check && er->rc < 4) { 1999 if (er->checked == 0) {//First CW, save it and wait for next one 2000 er->checked = 1; 2001 er->origin_reader = er->reader[0]; //contains ridx 2002 memcpy(er->cw_checked, er->cw, sizeof(er->cw)); 2003 cs_log("DOUBLE CHECK FIRST CW by %s idx %d cpti %d", reader[er->origin_reader].label, er->idx, er->cpti); 2004 } 2005 else if (er->origin_reader != er->reader[0]) { //Second (or third and so on) cw. We have to compare 2006 if (memcmp(er->cw_checked, er->cw, sizeof(er->cw)) == 0) { 2007 er->checked++; 2008 cs_log("DOUBLE CHECKED! %d. CW by %s idx %d cpti %d", er->checked, reader[er->reader[0]].label, er->idx, er->cpti); 2009 } 2010 else { 2011 cs_log("DOUBLE CHECKED NONMATCHING! %d. CW by %s idx %d cpti %d", er->checked, reader[er->reader[0]].label, er->idx, er->cpti); 2012 } 2013 } 2014 2015 if (er->checked < 2) { //less as two same cw? mark as pending! 2016 er->rc = 100; 2017 return 0; 2018 } 2019 2020 store_ecm(er); //Store in cache! 2021 } 2022 #endif 2023 1993 2024 ph[client[cs_idx].ctyp].send_dcw(er); 1994 2025 return 0; … … 2235 2266 if (status == -1) { 2236 2267 cs_log("request_cw() failed on reader %s (%d) errno=%d, %s", reader[i].label, i, errno, strerror(errno)); 2237 if (reader[i].fd && reader[i].pid) {2268 if (reader[i].fd) { 2238 2269 reader[i].fd_error++; 2239 2270 if (reader[i].fd_error > 5) { 2240 2271 reader[i].fd_error = 0; 2241 kill(client[reader[i].cs_idx].pid, SIGKILL); //Schlocke: This should restartthe reader!2272 send_restart_cardreader(i, 1); //Schlocke: This restarts the reader! 2242 2273 } 2243 2274 } … … 2478 2509 if(er->rc > 99) { 2479 2510 2480 if (cfg-> reader_auto_loadbalance) {2511 if (cfg->lb_mode) { 2481 2512 int reader_avail[CS_MAXREADER]; 2482 2513 for (i =0; i < CS_MAXREADER; i++) … … 2772 2803 if (er->stage) { 2773 2804 er->rc=5; // timeout 2774 if (cfg-> reader_auto_loadbalance) {2805 if (cfg->lb_mode) { 2775 2806 int r; 2776 2807 for (r=0; r<CS_MAXREADER; r++) … … 3043 3074 init_shm(); 3044 3075 init_config(); 3076 init_stat(); 3045 3077 cfg->debuglvl = cs_dblevel; // give static debuglevel to outer world 3046 3078 for (i=0; mod_def[i]; i++) // must be later BEFORE init_config()
Note:
See TracChangeset
for help on using the changeset viewer.