00001 #include "parser.h"
00002 #include "structs.h"
00003 #include "constants.h"
00004 #include "FilterSpec.h"
00005 #include "StreamSpec.h"
00006 #include "Layout.h"
00007 #include "FilterData/Policies.h"
00008 #include "Hosts.h"
00009
00010
00011 static State state = start, lastState = start;
00012 static char errorMsg[200];
00013
00014 static char *stateNames[] = {
00015 "start", "prehost", "hostdec","preplace",
00016 "placement", "prelay", "layout",
00017 "preend", "end", "resources", "filter",
00018 "stream", "fromto", "tostream",
00019 "error", "parseerror"
00020 };
00021
00022 static int currentHostIndex;
00023 static FilterSpec *currentFilter = NULL;
00024 static StreamSpec *currentStream = NULL;
00025 static int remainingInstances, instances;
00026
00027
00028
00029
00030
00031 void abreTag(void *userData, const XML_Char *name, const XML_Char **atts){
00032 Layout *systemLayout = (Layout*)userData;
00033
00034 lastState = state;
00035 switch (state){
00036 case start:
00037
00038 if (strcasecmp("config", name) == 0)
00039 state = prehost;
00040 else {
00041 strcpy(errorMsg, "Expecting <config>\n");
00042 state = error;
00043 }
00044 break;
00045 case prehost:
00046
00047 if (strcasecmp("hostdec", name) == 0){
00048 state = hostdec;
00049 }
00050 else {
00051 strcpy(errorMsg, "Expecting <hostdec>\n");
00052 state = error;
00053 return;
00054 }
00055 break;
00056 case hostdec:
00057
00058 if (strcasecmp("host", name) != 0){
00059 strcpy(errorMsg, "Expecting <host name=\"\" [weight=\"\"]/>\n");
00060 state = error;
00061 return;
00062 }
00063
00064
00065 int wi = -1, ni = -1, mi = -1, weight, mem = -1;
00066 int i=0;
00067 char *hname;
00068
00069 while (atts[i] != NULL){
00070 if (strcasecmp(atts[i], "name") == 0){
00071 ni= i+1;
00072 }
00073 else if (strcasecmp(atts[i], "weight") == 0){
00074 wi = i+1;
00075 }
00076 else if (strcasecmp(atts[i], "mem") == 0){
00077 mi = i+1;
00078 }
00079 else {
00080 strcpy(errorMsg, "Expecting name or weight attribute\n");
00081 state = error;
00082 return;
00083 }
00084 i += 2;
00085 }
00086
00087 if (ni == -1){
00088 strcpy(errorMsg, "Expecting <host name=\"\" [weight="" mem=""]/>\n");
00089 state = error;
00090 return;
00091 }
00092 else {
00093 hname = strdup(atts[ni]);
00094 }
00095
00096 if (wi == -1){
00097 weight = 1;
00098 }
00099 else {
00100 weight = atoi(atts[wi]);
00101 }
00102
00103
00104
00105 if (!((mi == -1) || (strcasecmp(atts[mi], "auto") == 0 ))){
00106 int len = strlen(atts[mi]);
00107 int unitType = 0;
00108
00109
00110 if ((atts[mi][len-1] == 'B') || (atts[mi][len-1] == 'b')){
00111 len--;
00112 }
00113
00114
00115 if ((atts[mi][len-1] == 'G') || (atts[mi][len-1] == 'g')){
00116 unitType = 1;
00117 len --;
00118 }
00119 else if ((atts[mi][len-1] == 'M') || (atts[mi][len-1] == 'm')){
00120 unitType = 0;
00121 len --;
00122 }
00123 else if ((atts[mi][len-1] == 'T') || (atts[mi][len-1] == 't')){
00124 unitType = 2;
00125 len --;
00126 }
00127 mem = atoi(atts[mi]) * pow((double)1024, (double)unitType);
00128 }
00129
00130
00131
00132 int hindex = hostsAdd(systemLayout->hostsStruct);
00133 if (hostsSetName(systemLayout->hostsStruct, hindex, hname) == -1 ) {
00134 state = error;
00135 sprintf(errorMsg, "Could not add host %s", hname);
00136 return;
00137 }
00138 hostsSetWeight(systemLayout->hostsStruct, hindex, weight);
00139 hostsSetMemory(systemLayout->hostsStruct, hindex, mem);
00140 printf("\tparser.c: host %s added to the Void enviroment, weight %d\n", hname, weight);
00141 free(hname);
00142 state = resources;
00143 currentHostIndex = hindex;
00144 break;
00145 case resources:
00146 {
00147
00148 if (strcasecmp(name, "resource") != 0){
00149 sprintf(errorMsg, "Error, expecting <resource tag>");
00150 state = error;
00151 return;
00152 }
00153
00154 int rni = -1, i=0;
00155 char resourceName[MAX_RNAME_LENGTH+1];
00156
00157 while (atts[i] != NULL) {
00158 if (strcasecmp("name", atts[i]) == 0){
00159 rni = i+1;
00160 }
00161 else {
00162 sprintf(errorMsg, "Error, expecting <resource name=\"\">");
00163 state = error;
00164 return;
00165 }
00166 i+=2;
00167 }
00168
00169 if (rni == -1){
00170 sprintf(errorMsg, "Resource name is mandatory");
00171 state=error;
00172 return;
00173 }
00174 else {
00175 strncpy(resourceName, atts[rni], MAX_RNAME_LENGTH);
00176 }
00177
00178 HostsStruct *hs = systemLayout->hostsStruct;
00179 if (hostsAddResource(hs, currentHostIndex, resourceName) < 0){
00180 sprintf(errorMsg, "Error adding resource %s: too many resources for host %s",
00181 resourceName, hostsGetName(hs, currentHostIndex));
00182 state = error;
00183 return;
00184 }
00185 printf("\t\tparser.c: resource %s added to host %s\n", resourceName, hostsGetName(hs, currentHostIndex));
00186
00187 }
00188 break;
00189 case preplace:
00190
00191 if (strcasecmp("placement", name) == 0)
00192 state = placement;
00193 else {
00194 strcpy(errorMsg, "Expecting <placement>");
00195 state = error;
00196 }
00197 break;
00198 case placement:
00199 {
00200 char filterName[MAX_FNAME_LENGTH+1], libname[MAX_LNAME_LENGTH+1];
00201 int nameInd = -1, libInd = -1, instInd=-1, i=0;
00202 instances=-1;
00203
00204
00205 if ( (strcasecmp("filter", name) != 0) ){
00206 state = error;
00207 strcpy(errorMsg, "Expecting <filter name=\"filtername\" [instances=\"N\" libname=\"library.so\"] >");
00208 return;
00209 }
00210
00211
00212 while (atts[i] != NULL){
00213 if ( strcasecmp(atts[i], "name") == 0 ){
00214 nameInd = i+1;
00215
00216 }
00217 else if ( strcasecmp(atts[i], "libname") == 0 ){
00218 libInd = i+1;
00219
00220 }
00221 else if ( strcasecmp(atts[i], "instances") == 0 ){
00222 instInd = i+1;
00223
00224 }
00225 else {
00226 state = error;
00227 strcpy(errorMsg, "Expecting <filter name=\"filtername\" [instances=\"N\" libname=\"library.so\"] >");
00228 break;
00229 }
00230 i+=2;
00231 }
00232
00233
00234 if (nameInd == -1){
00235 state = error;
00236 strcpy(errorMsg, "Name attribute is mandatory, expecting <filter name=\"filtername\" [instances=\"N\" libname=\"library.so\"] >");
00237 return;
00238 }
00239 else {
00240 strncpy(filterName, atts[nameInd], MAX_FNAME_LENGTH);
00241 filterName[MAX_FNAME_LENGTH] = '\0';
00242 }
00243
00244
00245 if (libInd == -1){
00246 sprintf(libname, "lib%s.so", filterName);
00247 }
00248 else {
00249 strncpy(libname, atts[libInd], MAX_LNAME_LENGTH);
00250 libname[MAX_LNAME_LENGTH] = '\0';
00251 }
00252
00253
00254 if (instInd == -1){
00255 instances = -1;
00256 remainingInstances = 1;
00257 }
00258 else {
00259 instances = atoi(atts[instInd]);
00260 remainingInstances = instances;
00261 }
00262
00263
00264 currentFilter = createFilterSpec(filterName, libname);
00265 if (instances == -1){
00266 printf("\tparser.c: reading filter %s, library %s, auto number of instances\n", filterName, libname);
00267 }
00268 else {
00269 printf("\tparser.c: reading filter %s, library %s, %d instances\n", filterName, libname, instances);
00270 }
00271
00272
00273 state = filter;
00274 }
00275 break;
00276 case filter:
00277 {
00278
00279 if (strcasecmp("instance", name) != 0){
00280
00281 state = error;
00282 strcpy(errorMsg, "Expecting <instance demands=\"hostname or resource\" [qty=\"n\"]/>, n >");
00283 return;
00284 }
00285
00286 int demandInd = -1, numInstInd = -1;
00287 int i = 0;
00288
00289 while (atts[i] != NULL){
00290
00291
00292
00293
00294 if (strcasecmp(atts[i], "demands") == 0){
00295 demandInd = i+1;
00296 }
00297 else if (strcasecmp(atts[i], "numinstances") == 0){
00298 numInstInd = i+1;
00299 }
00300 else {
00301 state = error;
00302 strcpy(errorMsg, "Expecting <host name=\"hostname\" [numinstances=\"n\"]/>, n > 0");
00303 return;
00304 }
00305 i+=2;
00306 }
00307
00308 if (demandInd == -1){
00309 state = error;
00310 strcpy(errorMsg, "Instance must demand something, either a hostname or a resource");
00311 return;
00312 }
00313
00314
00315 if ((instances != -1) && (remainingInstances <= 0)){
00316 printf("\t\tparser.c: WARNING: ignoring instance, %d declared\n", instances);
00317 return;
00318 }
00319
00320 int numInstances = 1;
00321
00322 if (numInstInd != -1){
00323 numInstances = atoi(atts[numInstInd]);
00324 }
00325
00326 for (i=0;i<numInstances;i++){
00327 HostsStruct *hs = systemLayout->hostsStruct;
00328
00329 char resourceName[MAX_RNAME_LENGTH+1];
00330 strncpy(resourceName, atts[demandInd], MAX_RNAME_LENGTH);
00331
00332
00333
00334 int hostIndex = hostsGetIndexByResource(hs, resourceName);
00335 if (hostIndex == -1){
00336
00337 hostIndex = hostsGetIndexByName(hs, resourceName);
00338 if (hostIndex == -1){
00339 sprintf(errorMsg, "Error, resource %s invalid or host not found", resourceName);
00340 state = error;
00341 return;
00342 }
00343 }
00344
00345 char hostname[MAX_HNAME_LENGTH+1];
00346 strcpy(hostname, hostsGetName(hs, hostIndex));
00347 printf("\t\tparser.c: host %s running this filter\n", hostname);
00348
00349 addHostToFilter(currentFilter, hs->hosts[hostIndex].name);
00350 remainingInstances--;
00351 }
00352 break;
00353 }
00354 case prelay:
00355
00356 if (strcasecmp("layout", name) == 0)
00357 state = layout;
00358 else {
00359 state = error;
00360 strcpy(errorMsg, "Expecting <layout>");
00361 return;
00362 }
00363 break;
00364 case layout:
00365
00366 if (strcasecmp("stream", name) == 0){
00367 state = stream;
00368
00369
00370 currentStream = createEmptyStreamSpec();
00371 }
00372 else {
00373 state = error;
00374 strcpy(errorMsg, "Expecting <stream>");
00375 return;
00376 }
00377
00378 break;
00379 case stream:
00380
00381 if (strcasecmp(name, "from") == 0){
00382 int filInd = -1, portInd = -1, polInd = -1, polibInd = -1;
00383 #ifdef VOID_TERM
00384 int breakLoop = 0;
00385 #endif
00386 char filterName[MAX_FNAME_LENGTH+1], portName[MAX_PTNAME_LENGTH+1],
00387 policyName[MAX_PLNAME_LENGTH+1], polibName[MAX_PLNAME_LENGTH+1];
00388 int i=0;
00389
00390 policyName[0] = '\0';
00391 polibName[0] = '\0';
00392 filterName[0] = '\0';
00393 portName[0] = '\0';
00394
00395 while (atts[i] != NULL){
00396 if ( strcasecmp(atts[i], "filter") == 0 ){
00397 filInd = i+1;
00398 strncpy(filterName, atts[i+1], MAX_FNAME_LENGTH);
00399 filterName[MAX_FNAME_LENGTH] = '\0';
00400 }
00401 else if ( strcasecmp(atts[i], "port") == 0 ){
00402 portInd = i+1;
00403 strncpy(portName, atts[i+1], MAX_PTNAME_LENGTH);
00404 portName[MAX_PTNAME_LENGTH] = '\0';
00405 }
00406 else if ( strcasecmp(atts[i], "policy") == 0 ){
00407 polInd = i+1;
00408 strncpy(policyName, atts[i+1], MAX_PLNAME_LENGTH);
00409 policyName[MAX_PLNAME_LENGTH] = '\0';
00410 }
00411 else if ( strcasecmp(atts[i], "policyLib") == 0 ){
00412 polibInd = i+1;
00413 strncpy(polibName, atts[i+1], MAX_PLNAME_LENGTH);
00414 polibName[MAX_PLNAME_LENGTH] = '\0';
00415 }
00416 #ifdef VOID_TERM
00417 else if ( strcasecmp(atts[i], "breakLoop") == 0){
00418 if ( strcasecmp(atts[i+1], "yes") == 0){
00419 breakLoop = 1;
00420 }else if ( strcasecmp(atts[i+1], "no") != 0){
00421 state = error;
00422 }
00423 }
00424 #endif
00425 else {
00426
00427 state = error;
00428 }
00429
00430 i+=2;
00431 }
00432
00433 if ( (filInd == -1) || (portInd == -1) || (state == error) ) {
00434 state = error;
00435 strcpy(errorMsg, "Expecting <from filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\" policyLib=\"\"] />");
00436 }
00437 else {
00438
00439 if (strlen(policyName) == 0)
00440 strcpy(policyName, "rr");
00441
00442
00443
00444 if (!setFrom(currentStream,
00445 getFilterSpecByName(systemLayout, filterName),
00446 portName, policyName, polibName
00447 #ifdef VOID_TERM
00448 , breakLoop
00449 #endif
00450 )){
00451 state = error;
00452 strcpy(errorMsg, "Invalid Policy or labeled stream requires a policy lib name");
00453 return;
00454 }
00455 if (polInd != -1)
00456 printf("\tparser.c: filter %s:%s(%s) writes to ", filterName, portName, policyName);
00457 else
00458 printf("\tparser.c: filter %s:%s(default policy) writes to ", filterName, portName);
00459
00460 }
00461 }
00462 else {
00463 state = error;
00464 strcpy(errorMsg, "Expecting <from filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\"] />");
00465 }
00466
00467 break;
00468 case fromto:
00469
00470 if (strcasecmp(name, "to") == 0){
00471 int filInd = -1, portInd = -1, polInd = -1;
00472 int i=0;
00473 char filterName[MAX_FNAME_LENGTH+1], portName[MAX_PTNAME_LENGTH+1],
00474 policyName[MAX_PLNAME_LENGTH+1];
00475
00476 while (atts[i] != NULL){
00477 if ( strcasecmp(atts[i], "filter") == 0 ){
00478 filInd = i+1;
00479 strncpy(filterName, atts[i+1], MAX_FNAME_LENGTH);
00480 filterName[MAX_FNAME_LENGTH] = '\0';
00481 }
00482 else if ( strcasecmp(atts[i], "port") == 0 ){
00483 portInd = i+1;
00484 strncpy(portName, atts[i+1], MAX_PTNAME_LENGTH);
00485 portName[MAX_PTNAME_LENGTH] = '\0';
00486 }
00487 else if ( strcasecmp(atts[i], "policy") == 0 ){
00488 polInd = i+1;
00489 strncpy(policyName, atts[i+1], MAX_PLNAME_LENGTH);
00490 policyName[MAX_PLNAME_LENGTH] = '\0';
00491 }
00492 else {
00493
00494 state = error;
00495 }
00496 i+=2;
00497 }
00498
00499 if ( (filInd == -1) || (portInd == -1) || (state == error) ){
00500 state = error;
00501 strcpy(errorMsg, "Expecting <to filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\"] />");
00502 }
00503 else {
00504
00505
00506 if (!setTo(currentStream,
00507 getFilterSpecByName(systemLayout, filterName),
00508 portName, policyName)){
00509 state = error;
00510 strcpy(errorMsg, "Error setting stream destination");
00511 return;
00512 }
00513 if (polInd != -1)
00514 printf("filter %s:%s\n", filterName, portName);
00515 else
00516 printf("filter %s:%s\n", filterName, portName);
00517 }
00518 }
00519 else {
00520 state = error;
00521 strcpy(errorMsg, "Expecting <to filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\"] />");
00522 }
00523 break;
00524 case tostream:
00525
00526 state = error;
00527 strcpy(errorMsg, "Expecting </stream>");
00528 break;
00529 case preend:
00530
00531 state = error;
00532 strcpy(errorMsg, "Expecting </config>");
00533 break;
00534 case end:
00535
00536 strcpy(errorMsg, "Expecting eof after </config>");
00537 state = error;
00538 break;
00539 default:
00540 break;
00541 }
00542
00543 }
00544
00545
00546 void fechaTag(void *userData, const XML_Char *name){
00547 Layout *systemLayout = (Layout*)userData;
00548
00549 lastState = state;
00550
00551 switch (state){
00552 case hostdec:
00553
00554 if ( strcasecmp("hostdec", name) == 0){
00555 state = preplace;
00556 printf("\tparser.c: ...\n");
00557 }
00558 else {
00559 state = error;
00560 strcpy(errorMsg, "Expecting </hostdec>");
00561 }
00562 break;
00563 case resources:
00564 {
00565 if (strcasecmp("resource", name) == 0){
00566
00567 }
00568 else if ( strcasecmp("host", name) == 0){
00569 state = hostdec;
00570 }
00571 }
00572 break;
00573 case prelay:
00574 break;
00575 case filter:
00576 {
00577
00578
00579 if ( strcasecmp("filter", name) == 0){
00580 while (remainingInstances > 0){
00581
00582 HostsStruct *hs = systemLayout->hostsStruct;
00583 int hid = hostsGetIndex(hs);
00584 if (hid == -1){
00585 state = error;
00586 sprintf(errorMsg, "Error filling remaining hosts");
00587 return;
00588 }
00589
00590
00591 if (addHostToFilter(currentFilter, hostsGetName(hs, hid)) == -1){
00592 state = error;
00593 sprintf(errorMsg, "Error adding host %s to filter %s", hostsGetName(hs, hid), currentFilter->name);
00594 return;
00595 }
00596
00597 printf("\t\tparser.c: instance %s(chosen randomly)\n", systemLayout->hostsStruct->hosts[hid].name);
00598 remainingInstances--;
00599 }
00600
00601 state = placement;
00602 addFilterSpec(systemLayout, currentFilter);
00603 }
00604 else if ( strcasecmp("instance", name) == 0 ){
00605
00606
00607 }
00608 else {
00609 state = error;
00610 strcpy(errorMsg, "Expecting </filter> or <instance />");
00611 }
00612 }
00613 break;
00614 case placement:
00615 if (strcasecmp("placement", name) == 0){
00616 state = prelay;
00617 printf("\tparser.c: ...\n");
00618 }
00619 else {
00620 strcpy(errorMsg, "Expecting </placement>");
00621 state = error;
00622 }
00623 break;
00624 case stream:
00625 if ( strcasecmp("from", name) == 0 ){
00626 state = fromto;
00627 }
00628 else {
00629 strcpy(errorMsg, "Expecting <from />");
00630 state = error;
00631 }
00632 break;
00633 case fromto:
00634 if ( strcasecmp("to", name) == 0 ){
00635 state = tostream;
00636 }
00637 else {
00638 strcpy(errorMsg, "Expecting <to />");
00639 state = error;
00640 }
00641 break;
00642 case tostream:
00643 if ( strcasecmp("stream", name) == 0 ){
00644 state = layout;
00645 addStreamSpec(systemLayout, currentStream);
00646 }
00647 else {
00648 strcpy(errorMsg, "Expecting </stream>");
00649 state = error;
00650 }
00651
00652 break;
00653 case layout:
00654 if ( strcasecmp("layout", name) == 0){
00655 state = preend;
00656 }
00657 else {
00658 strcpy(errorMsg, "Expecting </layout>");
00659 state = error;
00660 }
00661 break;
00662 case preend:
00663 if (strcasecmp(name, "config") == 0)
00664 state = end;
00665 break;
00666 case end:
00667
00668 state = error;
00669 break;
00670 default:
00671 break;
00672 }
00673 }
00674
00675 int readConfig(char *fileName, Layout *l) {
00676 FILE *arq;
00677 char buffer[1];
00678 XML_Parser parser = XML_ParserCreate(NULL);
00679
00680 arq = fopen(fileName, "ro");
00681 if (arq == NULL){
00682 char erro[200];
00683 sprintf(erro, "Error opening configuration file: %s", fileName);
00684 perror(erro);
00685 exit(1);
00686 }
00687
00688
00689 XML_SetElementHandler(parser, abreTag, fechaTag);
00690 XML_SetUserData(parser, (void*)l);
00691
00692
00693 while ( (state != end) && (state != error) && (state != parseerror) && (!feof(arq)) ){
00694 fread(buffer, sizeof(char), 1, arq);
00695
00696 if (XML_Parse(parser, buffer, 1, 0)== 0)
00697 state = parseerror;
00698 }
00699
00700
00701
00702
00703
00704
00705 if (state == parseerror){
00706
00707 printf("\tparser.c: parse error!!!\n");
00708 printf("\tparser.c: %s line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser) );
00709 printf("\tparser.c: state = %s\n", stateNames[lastState]);
00710 return (-1);
00711 }
00712 else if (state == error){
00713
00714 printf("\tparser.c: Parse error!!!\n");
00715 printf("\tparser.c: Wrong file format, line: %d\n", XML_GetCurrentLineNumber(parser));
00716 printf("\tparser.c: %s\n", errorMsg);
00717 printf("\tparser.c: State = %s\n", stateNames[lastState]);
00718 return (-1);
00719 }
00720 else if (state != end){
00721
00722 printf("\tparser.c: Unexpected end of file!!!\n");
00723 printf("\tparser.c: State = %s\n", stateNames[lastState]);
00724 return (-1);
00725 }
00726
00727
00728 fclose(arq);
00729
00730
00731 XML_ParserFree(parser);
00732 return 1;
00733 }
00734