예제 #1
0
static Pvoid_t tokenize_uris(htmlDocPtr doc, Pvoid_t features) {
	xmlTextReaderPtr reader = xmlReaderWalker(doc);

	while (xmlTextReaderRead(reader)) {
		int type = xmlTextReaderNodeType(reader);
		if (type == XML_ELEMENT_NODE) {
			char *uri = (char *) xmlTextReaderGetAttribute(reader, BAD_CAST "href");
			if (uri) {
				features = tokenize_uri(uri, features);
				free(uri);
			}

			uri = (char*) xmlTextReaderGetAttribute(reader, BAD_CAST "src");
			if (uri) {
				features = tokenize_uri(uri, features);
				free(uri);
			}
		}
	}

	xmlFreeTextReader(reader);

	return features;
}
예제 #2
0
Pvoid_t atom_tokenize(const char * atom) {
	Pvoid_t features = NULL;

	if (atom) {
		xmlDocPtr doc = xmlParseDoc(BAD_CAST atom);
		if (doc) {
			xmlXPathContextPtr context = xmlXPathNewContext(doc);
			xmlXPathRegisterNs(context, BAD_CAST "atom", BAD_CAST "http://www.w3.org/2005/Atom");

			char *html = get_element_value(context, "/atom:entry/atom:content/text()");
			if (html) {
				features = html_tokenize_into_features(html, features);
				xmlFree(html);
			}

			char *title = get_element_value(context, "/atom:entry/atom:title/text()");
			if (title) {
				features = tokenize_text(title, strlen(title), features);
				xmlFree(title);
			}

			char *author = get_element_value(context, "/atom:entry/atom:author/atom:name/text()");
			if (author) {
				features = add_token(author, features);
				xmlFree(author);
			}

			char *link = get_attribute_value(context, "/atom:entry/atom:link[@rel='alternate']", "href");
			if (link) {
				features = tokenize_uri(link, features);
				xmlFree(link);
			}

			xmlXPathFreeContext(context);
		}

		xmlFreeDoc(doc);
	}

	return features;
}
예제 #3
0
//!
//!
//!
//! @param[in]  pMeta a pointer to the node controller (NC) metadata structure
//! @param[in]  serviceIds a list of service info.
//! @param[in]  serviceIdsLen the number of service info in the serviceIds list
//! @param[out] outStatuses list of service status
//! @param[out] outStatusesLen number of service status in the outStatuses list
//!
//! @return
//!
//! @pre
//!
//! @note
//!
int doDescribeServices(ncMetadata * pMeta, serviceInfoType * serviceIds, int serviceIdsLen, serviceStatusType ** outStatuses, int *outStatusesLen)
{
    int rc = 0;
    int i = 0;
    int j = 0;
    int port = 0;
    char uri[MAX_PATH] = { 0 };
    char uriType[32] = { 0 };
    char host[MAX_PATH] = { 0 };
    char path[MAX_PATH] = { 0 };
    serviceStatusType *myStatus = NULL;
    int do_report_cluster = 1;         // always do report on the cluster, otherwise CC won't get ENABLED
    int do_report_nodes = 0;
    int do_report_all = 0;
    char *my_partition = NULL;

    rc = initialize(pMeta, TRUE);      // DescribeServices is the only authoritative source of epoch
    if (rc) {
        return (1);
    }

    LOGDEBUG("invoked: userId=%s, serviceIdsLen=%d\n", SP(pMeta ? pMeta->userId : "UNKNOWN"), serviceIdsLen);

    //! @TODO for now, return error if list of services is passed in as parameter
    /*
       if (serviceIdsLen > 0) {
       LOGERROR("DescribeServices(): received non-zero number of input services, returning fail\n");
       *outStatusesLen = 0;
       *outStatuses = NULL;
       return(1);
       }
     */
    sem_mywait(CONFIG);
    {
        if (!strcmp(config->ccStatus.serviceId.name, "self")) {
            for (i = 0; i < serviceIdsLen; i++) {
                LOGDEBUG("received input serviceId[%d]\n", i);
                if (strlen(serviceIds[i].type)) {
                    if (!strcmp(serviceIds[i].type, "cluster")) {
                        snprintf(uri, MAX_PATH, "%s", serviceIds[i].uris[0]);
                        rc = tokenize_uri(uri, uriType, host, &port, path);
                        if (strlen(host)) {
                            LOGDEBUG("setting local serviceId to input serviceId (type=%s name=%s partition=%s)\n",
                                     SP(serviceIds[i].type), SP(serviceIds[i].name), SP(serviceIds[i].partition));
                            memcpy(&(config->ccStatus.serviceId), &(serviceIds[i]), sizeof(serviceInfoType));
                        }
                    } else if (!strcmp(serviceIds[i].type, "node")) {
                        do_report_nodes = 1;    // report on node services if requested explicitly
                    }
                }
            }
        }
    }
    sem_mypost(CONFIG);
    if (serviceIdsLen < 1) {           // if the describe request is not specific, report on everything
        do_report_cluster = 1;
        do_report_nodes = 1;
        do_report_all = 1;
    } else {                           // if the describe request is specific, identify which types are requested
        do_report_cluster = 0;
        do_report_nodes = 0;
        do_report_all = 0;
        for (i = 0; i < serviceIdsLen; i++) {
            LOGDEBUG("received input serviceId[%d]: %s %s %s %s\n", i, serviceIds[i].type, serviceIds[i].partition, serviceIds[i].name, serviceIds[i].uris[0]);
            if (strlen(serviceIds[i].type)) {
                if (!strcmp(serviceIds[i].type, "cluster")) {
                    do_report_cluster = 1;  // report on cluster services if requested explicitly
                } else if (!strcmp(serviceIds[i].type, "node")) {
                    do_report_nodes++; // count number of and report on node services if requested explicitly
                }
            }
        }
    }

    for (i = 0; i < 16; i++) {
        if (strlen(config->services[i].type)) {
            LOGDEBUG("internal serviceInfos type=%s name=%s partition=%s urisLen=%d\n", config->services[i].type,
                     config->services[i].name, config->services[i].partition, config->services[i].urisLen);
            if (!strcmp(config->services[i].type, "cluster")) {
                my_partition = config->services[i].partition;
            }
            for (j = 0; j < MAX_SERVICE_URIS; j++) {
                if (strlen(config->services[i].uris[j])) {
                    LOGDEBUG("internal serviceInfos\t uri[%d]:%s\n", j, config->services[i].uris[j]);
                }
            }
        }
    }

    for (i = 0; i < 16; i++) {
        if (strlen(config->disabledServices[i].type)) {
            LOGDEBUG("internal disabled serviceInfos type=%s name=%s partition=%s urisLen=%d\n", config->disabledServices[i].type,
                     config->disabledServices[i].name, config->disabledServices[i].partition, config->disabledServices[i].urisLen);
            for (j = 0; j < MAX_SERVICE_URIS; j++) {
                if (strlen(config->disabledServices[i].uris[j])) {
                    LOGDEBUG("internal disabled serviceInfos\t uri[%d]:%s\n", j, config->disabledServices[i].uris[j]);
                }
            }
        }
    }

    for (i = 0; i < 16; i++) {
        if (strlen(config->notreadyServices[i].type)) {
            LOGDEBUG("internal not ready serviceInfos type=%s name=%s partition=%s urisLen=%d\n", config->notreadyServices[i].type,
                     config->notreadyServices[i].name, config->notreadyServices[i].partition, config->notreadyServices[i].urisLen);
            for (j = 0; j < MAX_SERVICE_URIS; j++) {
                if (strlen(config->notreadyServices[i].uris[j])) {
                    LOGDEBUG("internal not ready serviceInfos\t uri[%d]:%s\n", j, config->notreadyServices[i].uris[j]);
                }
            }
        }
    }

    *outStatusesLen = 0;
    *outStatuses = NULL;

    if (do_report_cluster) {
        (*outStatusesLen) += 1;
        *outStatuses = EUCA_ZALLOC(1, sizeof(serviceStatusType));
        if (!*outStatuses) {
            LOGFATAL("out of memory!\n");
            unlock_exit(1);
        }

        myStatus = *outStatuses;
        snprintf(myStatus->localState, 32, "%s", config->ccStatus.localState);  // ENABLED, DISABLED, STOPPED, NOTREADY
        snprintf(myStatus->details, 1024, "%s", config->ccStatus.details);  // string that gets printed by 'euca-describe-services -E'
        myStatus->localEpoch = config->ccStatus.localEpoch;
        memcpy(&(myStatus->serviceId), &(config->ccStatus.serviceId), sizeof(serviceInfoType));
        LOGDEBUG("external services\t uri[%d]: %s %s %s %s %s\n",
                 0, myStatus->serviceId.type, myStatus->serviceId.partition, myStatus->serviceId.name, myStatus->localState, myStatus->serviceId.uris[0]);
    }

    if (do_report_nodes) {
        extern ccResourceCache *resourceCache;
        ccResourceCache resourceCacheLocal;

        sem_mywait(RESCACHE);
        memcpy(&resourceCacheLocal, resourceCache, sizeof(ccResourceCache));
        sem_mypost(RESCACHE);

        if (resourceCacheLocal.numResources > 0 && my_partition != NULL) {  // parition is unknown at early stages of CC initialization
            for (int idIdx = 0; idIdx < serviceIdsLen; idIdx++) {
                if (do_report_all || !strcmp(serviceIds[idIdx].type, "node")) {
                    for (int rIdx = 0; rIdx < resourceCacheLocal.numResources; rIdx++) {
                        ccResource *r = resourceCacheLocal.resources + rIdx;
                        if (do_report_all || (strlen(serviceIds[idIdx].name) && strlen(r->ip) && !strcmp(serviceIds[idIdx].name, r->ip))) {

                            // we have a node that we want to report about
                            (*outStatusesLen) += 1;
                            *outStatuses = EUCA_REALLOC(*outStatuses, *outStatusesLen, sizeof(serviceStatusType));
                            if (*outStatuses == NULL) {
                                LOGFATAL("out of memory! (outStatusesLen=%d)\n", *outStatusesLen);
                                unlock_exit(1);
                            }
                            myStatus = *outStatuses + *outStatusesLen - 1;
                            {
                                int resState = r->state;
                                int resNcState = r->ncState;
                                char *state = "BUGGY";
                                char *msg = "";
                                if (resState == RESUP) {
                                    if (resNcState == ENABLED) {
                                        state = "ENABLED";
                                        msg = "the node is operating normally";
                                    } else if (resNcState == STOPPED) {
                                        state = "STOPPED";
                                        msg = "the node is not accepting new instances";
                                    } else if (resNcState == NOTREADY) {
                                        state = "NOTREADY";
                                        if (strnlen(r->nodeMessage, 1024)) {
                                            msg = r->nodeMessage;
                                        } else {
                                            msg = "the node is currently experiencing problems and needs attention";
                                        }
                                    }
                                } else if (resState == RESASLEEP || resState == RESWAKING) {
                                    state = "NOTREADY";
                                    msg = "the node is currently in the sleep state";
                                } else if (resState == RESDOWN) {
                                    state = "NOTREADY";
                                    if (strnlen(r->nodeMessage, 1024)) {
                                        msg = r->nodeMessage;
                                    } else {
                                        msg = "the node is not responding to the cluster controller";
                                    }
                                }
                                snprintf(myStatus->localState, 32, "%s", state);
                                snprintf(myStatus->details, 1024, "%s", msg);   // string that gets printed by 'euca-describe-services -E'
                            }
                            myStatus->localEpoch = config->ccStatus.localEpoch;
                            sprintf(myStatus->serviceId.type, "node");
                            sprintf(myStatus->serviceId.name, r->hostname);
                            sprintf(myStatus->serviceId.partition, config->ccStatus.serviceId.partition);
                            sprintf(myStatus->serviceId.uris[0], r->ncURL);
                            myStatus->serviceId.urisLen = 1;
                            LOGDEBUG("external services\t uri[%d]: %s %s %s %s %s\n",
                                     idIdx, myStatus->serviceId.type, myStatus->serviceId.partition, myStatus->serviceId.name, myStatus->localState, myStatus->serviceId.uris[0]);
                        }
                    }
                }
            }
        }
    }

    LOGDEBUG("done\n");
    return (0);
}
예제 #4
0
//!
//! Function description.
//!
//! @param[in] file
//! @param[in] file_updated
//!
//! @return
//!
//! @see
//!
//! @pre List of pre-conditions
//!
//! @post List of post conditions
//!
//! @note
//!
int atomic_file_get(atomic_file * file, int *file_updated)
{
    int port = 0;
    int fd = 0;
    int ret = 0;
    int rc = 0;
    char *hash = NULL;
    char type[32] = "";
    char hostname[512] = "";
    char path[MAX_PATH] = "";
    char tmpsource[MAX_PATH] = "";
    char tmppath[MAX_PATH] = "";

    if (!file || !file_updated) {
        return (1);
    }

    ret = 0;
    *file_updated = 0;

    snprintf(file->tmpfile, MAX_PATH, "%s", file->tmpfilebase);
    fd = safe_mkstemp(file->tmpfile);
    if (fd < 0) {
        LOGERROR("cannot open tmpfile '%s'\n", file->tmpfile);
        return (1);
    }
    chmod(file->tmpfile, 0644);
    close(fd);

    snprintf(tmpsource, MAX_PATH, "%s", file->source);
    type[0] = tmppath[0] = path[0] = hostname[0] = '\0';
    port = 0;

    tokenize_uri(tmpsource, type, hostname, &port, tmppath);
    snprintf(path, MAX_PATH, "/%s", tmppath);

    if (!strcmp(type, "http")) {
        rc = http_get_timeout(file->source, file->tmpfile, 0, 0, 10, 15);
        if (rc) {
            LOGERROR("http client failed to fetch file URL=%s\n", file->source);
            ret = 1;
        }
    } else if (!strcmp(type, "file")) {
        if (!strlen(path) || copy_file(path, file->tmpfile)) {
            LOGERROR("could not copy source file (%s) to dest file (%s)\n", path, file->tmpfile);
            ret = 1;
        }
    } else {
        LOGWARN("BUG: incompatible URI type (only support http, file): (%s)\n", type);
        ret = 1;
    }

    if (!ret) {
        if (file->tosort) {
            rc = atomic_file_sort_tmpfile(file);
            if (rc) {
                LOGWARN("could not sort tmpfile (%s) inplace\n", file->tmpfile);
            }
        }
        // do checksum - only copy if file has changed
        hash = file2md5str(file->tmpfile);
        if (!hash) {
            LOGERROR("could not compute hash of tmpfile (%s)\n", file->tmpfile);
            ret = 1;
        } else {
            if (file->currhash)
                EUCA_FREE(file->currhash);
            file->currhash = hash;
            if (check_file(file->dest) || strcmp(file->currhash, file->lasthash)) {
                // hashes are different, put new file in place
                LOGINFO("source and destination file contents have changed, triggering update of dest (%s)\n", file->dest);
                LOGDEBUG("renaming file %s -> %s\n", file->tmpfile, file->dest);
                if (rename(file->tmpfile, file->dest)) {
                    LOGERROR("could not rename local copy to dest (%s -> %s)\n", file->tmpfile, file->dest);
                    ret = 1;
                } else {
                    EUCA_FREE(file->lasthash);
                    file->lasthash = strdup(file->currhash);
                    *file_updated = 1;
                }
            }
        }
    }

    unlink(file->tmpfile);
    return (ret);
}
예제 #5
0
int doDescribeServices(ncMetadata *ccMeta, serviceInfoType *serviceIds, int serviceIdsLen, serviceStatusType **outStatuses, int *outStatusesLen) {
  int i, rc, ret=0;
  serviceStatusType *myStatus=NULL;

  rc = initialize(ccMeta);
  if (rc) {
    return(1);
  }

  logprintfl(EUCAINFO, "DescribeServices(): called\n");
  logprintfl(EUCADEBUG, "DescribeServices(): params: userId=%s, serviceIdsLen=%d\n", SP(ccMeta ? ccMeta->userId : "UNSET"), serviceIdsLen);

  // TODO: for now, return error if list of services is passed in as parameter
  /*
  if (serviceIdsLen > 0) {
    logprintfl(EUCAERROR, "DescribeServices(): received non-zero number of input services, returning fail\n");
    *outStatusesLen = 0;
    *outStatuses = NULL;
    return(1);
  }
  */
  sem_mywait(CONFIG);
  if (!strcmp(config->ccStatus.serviceId.name, "self")) {
    for (i=0; i<serviceIdsLen; i++) {
      logprintfl(EUCADEBUG, "DescribeServices(): received input serviceId[%d]\n", i);
      if (strlen(serviceIds[i].type)) {
	if (!strcmp(serviceIds[i].type, "cluster")) {
	  char uri[MAX_PATH], uriType[32], host[MAX_PATH], path[MAX_PATH];
	  int port;
	  snprintf(uri, MAX_PATH, "%s", serviceIds[i].uris[0]);
	  rc = tokenize_uri(uri, uriType, host, &port, path);
	  if (strlen(host)) {
	    logprintfl(EUCADEBUG, "DescribeServices(): setting local serviceId to input serviceId (type=%s name=%s partition=%s)\n", SP(serviceIds[i].type), SP(serviceIds[i].name), SP(serviceIds[i].partition));
	    memcpy(&(config->ccStatus.serviceId), &(serviceIds[i]), sizeof(serviceInfoType));
	  }
	}
      }
    }
  }
  sem_mypost(CONFIG);

  for (i=0; i<16; i++) {
    int j;
    if (strlen(config->services[i].type)) {
      logprintfl(EUCADEBUG, "DescribeServices(): internal serviceInfos type=%s name=%s partition=%s urisLen=%d\n", config->services[i].type, config->services[i].name, config->services[i].partition, config->services[i].urisLen);
      for (j=0; j<8; j++) {
	if (strlen(config->services[i].uris[j])) {
	  logprintfl(EUCADEBUG, "DescribeServices(): internal serviceInfos\t uri[%d]:%s\n", j, config->services[i].uris[j]);
	}
      }
    }
  }

  for (i=0; i<16; i++) {
    int j;
    if (strlen(config->disabledServices[i].type)) {
      logprintfl(EUCADEBUG, "DescribeServices(): internal disabled serviceInfos type=%s name=%s partition=%s urisLen=%d\n", config->disabledServices[i].type, config->disabledServices[i].name, config->disabledServices[i].partition, config->disabledServices[i].urisLen);
      for (j=0; j<8; j++) {
	if (strlen(config->disabledServices[i].uris[j])) {
	  logprintfl(EUCADEBUG, "DescribeServices(): internal disabled serviceInfos\t uri[%d]:%s\n", j, config->disabledServices[i].uris[j]);
	}
      }
    }
  }

  for (i=0; i<16; i++) {
    int j;
    if (strlen(config->notreadyServices[i].type)) {
      logprintfl(EUCADEBUG, "DescribeServices(): internal not ready serviceInfos type=%s name=%s partition=%s urisLen=%d\n", config->notreadyServices[i].type, config->notreadyServices[i].name, config->notreadyServices[i].partition, config->notreadyServices[i].urisLen);
      for (j=0; j<8; j++) {
	if (strlen(config->notreadyServices[i].uris[j])) {
	  logprintfl(EUCADEBUG, "DescribeServices(): internal not ready serviceInfos\t uri[%d]:%s\n", j, config->notreadyServices[i].uris[j]);
	}
      }
    }
  }
  
  *outStatusesLen = 1;
  *outStatuses = malloc(sizeof(serviceStatusType));
  if (!*outStatuses) {
    logprintfl(EUCAFATAL, "DescribeServices(): out of memory!\n");
    unlock_exit(1);
  }

  myStatus = *outStatuses;
  snprintf(myStatus->localState, 32, "%s", config->ccStatus.localState);
  snprintf(myStatus->details, 1024, "%s", config->ccStatus.details);
  myStatus->localEpoch = config->ccStatus.localEpoch;
  memcpy(&(myStatus->serviceId), &(config->ccStatus.serviceId), sizeof(serviceInfoType));

  logprintfl(EUCAINFO, "DescribeServices(): done\n");
  return(0);
}
예제 #6
0
//!
//! Function description.
//!
//! @param[in] file
//! @param[in] file_updated
//!
//! @return
//!
//! @see
//!
//! @pre List of pre-conditions
//!
//! @post List of post conditions
//!
//! @note
//!
int atomic_file_get(atomic_file * file, boolean * file_updated)
{
    int port = 0;
    int fd = 0;
    int ret = 0;
    int rc = 0;
    char *hash = NULL;
    char type[32] = "";
    char hostname[512] = "";
    char path[EUCA_MAX_PATH] = "";
    char tmpsource[EUCA_MAX_PATH] = "";
    char tmppath[EUCA_MAX_PATH] = "";

    if (!file || !file_updated) {
        return (1);
    }

    ret = 0;
    *file_updated = FALSE;

    snprintf(file->tmpfile, EUCA_MAX_PATH, "%s", file->tmpfilebase);
    fd = safe_mkstemp(file->tmpfile);
    if (fd < 0) {
        LOGERROR("cannot open tmpfile '%s': check permissions\n", file->tmpfile);
        return (1);
    }
    if (chmod(file->tmpfile, 0600)) {
        LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", file->tmpfile);
    }
    close(fd);

    snprintf(tmpsource, EUCA_MAX_PATH, "%s", file->source);
    type[0] = tmppath[0] = path[0] = hostname[0] = '\0';
    port = 0;

    tokenize_uri(tmpsource, type, hostname, &port, tmppath);
    snprintf(path, EUCA_MAX_PATH, "/%s", tmppath);

    if (!strcmp(type, "http")) {
        rc = http_get_timeout(file->source, file->tmpfile, 0, 0, 10, 15, NULL);
        if (rc) {
            LOGERROR("http client failed to fetch file URL=%s: check http server status\n", file->source);
            ret = 1;
        }
    } else if (!strcmp(type, "file")) {
        if (!strlen(path) || copy_file(path, file->tmpfile)) {
            LOGERROR("could not copy source file (%s) to dest file (%s): check permissions\n", path, file->tmpfile);
            ret = 1;
        }
    } else {
        LOGWARN("BUG: incompatible URI type (%s) passed to routine (only supports http, file)\n", type);
        ret = 1;
    }

    if (!ret) {
        if (file->dosort) {
            rc = atomic_file_sort_tmpfile(file);
            if (rc) {
                LOGWARN("could not sort tmpfile (%s) inplace: continuing without sort\n", file->tmpfile);
            }
        }
        // do checksum - only copy if file has changed
        hash = file2md5str(file->tmpfile);
        if (!hash) {
            LOGERROR("could not compute hash of tmpfile (%s): check permissions\n", file->tmpfile);
            ret = 1;
        } else {
            if (file->currhash)
                EUCA_FREE(file->currhash);
            file->currhash = hash;
            if (check_file(file->dest) || strcmp(file->currhash, file->lasthash)) {
                // hashes are different, put new file in place
                LOGDEBUG("update triggered due to file update (%s)\n", file->dest);
                LOGDEBUG("source and destination file contents have become different, triggering update of dest (%s)\n", file->dest);
                LOGDEBUG("renaming file %s -> %s\n", file->tmpfile, file->dest);
                if (rename(file->tmpfile, file->dest)) {
                    LOGERROR("could not rename (move) source file '%s' to dest file '%s': check permissions\n", file->tmpfile, file->dest);
                    ret = 1;
                } else {
                    EUCA_FREE(file->lasthash);
                    file->lasthash = strdup(file->currhash);
                    *file_updated = TRUE;
                }
            }
        }
    }

    unlink(file->tmpfile);
    return (ret);
}