//!
//! Handles the client describe instance request.
//!
//! @param[in]  pStub a pointer to the node controller (NC) stub structure
//! @param[in]  pMeta a pointer to the node controller (NC) metadata structure
//! @param[in]  instIds a pointer the list of instance identifiers to retrieve data for
//! @param[in]  instIdsLen the number of instance identifiers in the instIds list
//! @param[out] outInsts a pointer the list of instances for which we have data
//! @param[out] outInstsLen the number of instances in the outInsts list.
//!
//! @return EUCA_OK on success or EUCA_ERROR on failure.
//!
int ncDescribeInstancesStub(ncStub * pStub, ncMetadata * pMeta, char **instIds, int instIdsLen, ncInstance *** outInsts, int *outInstsLen)
{
    int i = 0;
    int numinsts = 0;
    ncInstance *newinst = NULL;

    LOGDEBUG("fakeNC: describeInstances(): params: instIdsLen=%d\n", instIdsLen);

    if (instIdsLen < 0) {
        LOGERROR("fakeNC: describeInstances(): bad input params\n");
        return (EUCA_ERROR);
    }

    loadNcStuff();

    //  *outInstsLen = myconfig->instanceidx+1;
    *outInsts = EUCA_ZALLOC(MAX_FAKE_INSTANCES, sizeof(ncInstance *));
    for (i = 0; i < MAX_FAKE_INSTANCES; i++) {
        if (strlen(myconfig->global_instances[i].instanceId)) {
            newinst = EUCA_ZALLOC(1, sizeof(ncInstance));
            if (!strcmp(myconfig->global_instances[i].stateName, "Pending")) {
                snprintf(myconfig->global_instances[i].stateName, 8, "Extant");
            }

            memcpy(newinst, &(myconfig->global_instances[i]), sizeof(ncInstance));
            (*outInsts)[numinsts] = newinst;
            LOGDEBUG("fakeNC: describeInstances(): idx=%d numinsts=%d instanceId=%s stateName=%s\n", i, numinsts, newinst->instanceId, newinst->stateName);
            numinsts++;
        }
    }
    *outInstsLen = numinsts;

    saveNcStuff();
    return (EUCA_OK);
}
Beispiel #2
0
//!
//! Handles the reboot request of an instance.
//!
//! @param[in] nc a pointer to the NC state structure to initialize
//! @param[in] pMeta a pointer to the node controller (NC) metadata structure
//! @param[in] instanceId the instance identifier string (i-XXXXXXXX)
//!
//! @return EUCA_OK on success or proper error code. Known error code returned include:
//!         EUCA_ERROR, EUCA_NOT_FOUND_ERROR, and EUCA_FATAL_ERROR.
//!
static int doRebootInstance(struct nc_state_t *nc, ncMetadata * pMeta, char *instanceId)
{
    pthread_t tcb = { 0 };
    ncInstance *instance = NULL;
    rebooting_thread_params *params = NULL;

    sem_p(inst_sem);
    {
        instance = find_instance(&global_instances, instanceId);
    }
    sem_v(inst_sem);

    if (instance == NULL) {
        LOGERROR("[%s] cannot find instance\n", instanceId);
        return (EUCA_NOT_FOUND_ERROR);
    }

    params = EUCA_ZALLOC(1, sizeof(rebooting_thread_params));
    memcpy(&(params->instance), instance, sizeof(ncInstance));
    memcpy(&(params->nc), nc, sizeof(struct nc_state_t));
    // since shutdown/restart may take a while, we do them in a thread
    if (pthread_create(&tcb, NULL, rebooting_thread, params)) {
        LOGERROR("[%s] failed to spawn a reboot thread\n", instanceId);
        return (EUCA_FATAL_ERROR);
    }
    set_corrid_pthread(get_corrid() != NULL ? get_corrid()->correlation_id : NULL, tcb);
    if (pthread_detach(tcb)) {
        LOGERROR("[%s] failed to detach the rebooting thread\n", instanceId);
        return (EUCA_FATAL_ERROR);
    }

    return (EUCA_OK);
}
Beispiel #3
0
//!
//! Initialize the network driver.
//!
//! @param[in] pConfig a pointer to our application configuration
//!
//! @return 0 on success or 1 if any failure occured.
//!
//! @see
//!
//! @pre
//!     - The core application configuration must be completed prior calling
//!     - The driver should not be already initialized (if its the case, a no-op will occur)
//!     - The pConfig parameter must not be NULL
//!
//! @post
//!     On success the driver is properly configured. On failure, the state of
//!     the driver is non-deterministic. If the driver was previously initialized,
//!     this will result into a no-op.
//!
//! @note
//!
static int network_driver_init(eucanetdConfig * pConfig)
{
    int rc = 0;

    LOGINFO("Initializing '%s' network driver.\n", DRIVER_NAME());

    // Make sure our given pointer is valid
    if (!pConfig) {
        LOGERROR("Failure to initialize '%s' networking mode. Invalid configuration parameter provided.\n", DRIVER_NAME());
        return (1);
    }
    // Are we already initialized?
    if (IS_INITIALIZED()) {
        LOGERROR("Networking '%s' mode already initialized. Skipping!\n", DRIVER_NAME());
        return (0);
    }

    //    if (PEER_IS_NC(eucanetdPeer)) {
        if ((pMidoConfig = EUCA_ZALLOC(1, sizeof(mido_config))) == NULL) {
            LOGERROR("Failed to initialize '%s' networking mode. Out of memory!\n", DRIVER_NAME());
            return (1);
        }

        rc = initialize_mido(pMidoConfig, pConfig->eucahome, pConfig->midosetupcore, pConfig->midoeucanetdhost, pConfig->midogwhost, pConfig->midogwip, pConfig->midogwiface,
                             pConfig->midopubnw, pConfig->midopubgwip, "169.254.0.0", "17");
        if (rc) {
            LOGERROR("could not initialize mido: please ensure that all required config options for MIDOVPC mode are set in eucalyptus.conf\n");
            return (1);
        }
        //    }
    // We are now initialize
    gInitialized = TRUE;
    return (0);
}
Beispiel #4
0
//!
//! Allocate and initialize a resource structure with given information. Resource is
//! used to return information about resources
//!
//! @param[in] sNodeStatus the current node status string
//! @param[in] migrationCapable flag indicating whether node can participate in live migration
//! @param[in] sIQN
//! @param[in] memorySizeMax the maximum amount of memory available on this node
//! @param[in] memorySizeAvailable the current amount of memory available on this node
//! @param[in] diskSizeMax the maximum amount of disk space available on this node
//! @param[in] diskSizeAvailable the current amount of disk space available on this node
//! @param[in] numberOfCoresMax the maximum number of cores available on this node
//! @param[in] numberOfCoresAvailable the current number of cores available on this node
//! @param[in] sPublicSubnets the available public subnet for this node
//! @param[in] sHypervisor node's hypervisor
//!
//! @return a pointer to the newly allocated resource structure or NULL if any error occured.
//!
//! @see free_resource()
//!
//! @pre The \p sNodeStatus field must not be NULL.
//!
//! @post On success, a resource structure is allocated and initialized with the given information
//!
//! @note Caller is responsible to free the allocated memory using the free_resource() function call.
//!
ncResource *allocate_resource(const char *sNodeStatus, boolean migrationCapable, const char *sIQN, int memorySizeMax, int memorySizeAvailable, int diskSizeMax,
                              int diskSizeAvailable, int numberOfCoresMax, int numberOfCoresAvailable, const char *sPublicSubnets, const char *sHypervisor)
{
    ncResource *pResource = NULL;

    // Make sure we have a valid parameter
    if (sNodeStatus == NULL)
        return (NULL);

    // See if we can allocate our resource structure
    if ((pResource = EUCA_ZALLOC(1, sizeof(ncResource))) == NULL)
        return (NULL);

    //
    // Initialize the structure with the given values
    //
    euca_strncpy(pResource->nodeStatus, sNodeStatus, CHAR_BUFFER_SIZE);
    if (sIQN)
        euca_strncpy(pResource->iqn, sIQN, CHAR_BUFFER_SIZE);
    pResource->migrationCapable = migrationCapable;
    if (sPublicSubnets)
        euca_strncpy(pResource->publicSubnets, sPublicSubnets, CHAR_BUFFER_SIZE);
    if (sHypervisor)
        euca_strncpy(pResource->hypervisor, sHypervisor, CHAR_BUFFER_SIZE);
    pResource->memorySizeMax = memorySizeMax;
    pResource->memorySizeAvailable = memorySizeAvailable;
    pResource->diskSizeMax = diskSizeMax;
    pResource->diskSizeAvailable = diskSizeAvailable;
    pResource->numberOfCoresMax = numberOfCoresMax;
    pResource->numberOfCoresAvailable = numberOfCoresAvailable;
    return (pResource);
}
Beispiel #5
0
//!
//! Serializes the ebs_volume_data struct into a single string that is
//! pointed to by the 'dest' argument
//!
//! @param[in] vol_data
//! @param[in] dest
//!
//! @return
//!
//! @pre
//!
//! @post
//!
//! @note
//!
int serialize_volume(ebs_volume_data * vol_data, char **dest)
{
    int out_size = -1;
    char *working_string = NULL;
    int working_size = -1;

    if (vol_data == NULL) {
        LOGTRACE("Cannot serialize a NULL to volume string\n");
        return EUCA_ERROR;
    }

    working_size = strlen(vol_data->token) + 1 + strlen(vol_data->volumeId) + 1;
    working_string = EUCA_ZALLOC(1, working_size);
    if (working_string == NULL) {
        LOGERROR("Cannot allocate memory!\n");
        return EUCA_ERROR;
    }
    //Ensure / at end of scURL
    out_size = snprintf(working_string, working_size, "%s%s,%s", VOLUME_STRING_PREFIX, vol_data->volumeId, vol_data->token);
    if (out_size <= 0 || out_size > working_size) {
        EUCA_FREE(working_string);
        return EUCA_ERROR;
    }

    LOGTRACE("Serialized volume struct into %s\n", working_string);
    *dest = working_string;
    return EUCA_OK;
}
Beispiel #6
0
//!
//! Clones an existing instance structure
//!
//! @param[in] old_instance a pointer to the instance to duplicate
//!
//! @return A clone of the existing instance of NULL on failure
//!
//! @see free_instance(), allocate_instance()
//!
//! @pre The \p old_instance field must not be NULL
//!
//! @post A clone of our existing instance is created.
//!
//! @note The caller is responsible to free the allocated instance using the free_instance() API.
//!
ncInstance *clone_instance(const ncInstance * old_instance)
{
    ncInstance *new_instance;

    // zeroed out for cleaner-looking checkpoints and strings that are empty unless set
    if ((new_instance = EUCA_ZALLOC(1, sizeof(ncInstance))) == NULL)
        return (NULL);

    //! @TODO do not just copy everything
    memcpy(new_instance, old_instance, sizeof(ncInstance));

    return new_instance;
}
Beispiel #7
0
//!
//! Allocate a metadata structure and initialize it. Metadata is present in every type of nc request
//!
//! @param[in] sCorrelationId the correlation identifier string
//! @param[in] sUserId the user identifier
//!
//! @return a pointer to the newly allocated metadata structure or NULL if any error occured.
//!
//! @see free_metadata()
//!
//! @post A metadata structure is allocated and initialized with the provided information
//!
//! @note Caller is responsible for freeing the allocated memory using free_metadata() call.
//!
ncMetadata *allocate_metadata(const char *sCorrelationId, const char *sUserId)
{
    ncMetadata *pMeta;

    // Try to allocate the structure
    if ((pMeta = EUCA_ZALLOC(1, sizeof(ncMetadata))) == NULL)
        return (NULL);

    //
    // Initialize with the provided information
    //
    pMeta->correlationId = ((sCorrelationId != NULL) ? strdup(sCorrelationId) : NULL);
    pMeta->userId = ((sUserId != NULL) ? strdup(sUserId) : NULL);
    return (pMeta);
}
Beispiel #8
0
//!
//! Initialize the network driver.
//!
//! @param[in] pConfig a pointer to our application configuration
//!
//! @return 0 on success or 1 if any failure occurred.
//!
//! @see
//!
//! @pre
//!     - The core application configuration must be completed prior calling
//!     - The driver should not be already initialized (if its the case, a no-op will occur)
//!     - The pConfig parameter must not be NULL
//!
//! @post
//!     On success the driver is properly configured. On failure, the state of
//!     the driver is non-deterministic. If the driver was previously initialized,
//!     this will result into a no-op.
//!
//! @note
//!
static int network_driver_init(eucanetdConfig * pConfig)
{
    int rc = 0;

    LOGINFO("Initializing '%s' network driver.\n", DRIVER_NAME());

    // Make sure our given pointer is valid
    if (!pConfig) {
        LOGERROR("Failure to initialize '%s' networking mode. Invalid configuration parameter provided.\n", DRIVER_NAME());
        return (1);
    }
    // Are we already initialized?
    if (IS_INITIALIZED()) {
        LOGERROR("Networking '%s' mode already initialized. Skipping!\n", DRIVER_NAME());
        return (0);
    }

    if ((pMidoConfig = EUCA_ZALLOC(1, sizeof (mido_config))) == NULL) {
        LOGERROR("Failed to initialize '%s' networking mode. Out of memory!\n", DRIVER_NAME());
        return (1);
    }

    rc = initialize_mido(pMidoConfig, pConfig->eucahome, pConfig->flushmode, pConfig->disable_l2_isolation, pConfig->midoeucanetdhost, pConfig->midogwhosts,
            pConfig->midopubnw, pConfig->midopubgwip, "169.254.0.0", "17");
    if (rc) {
        LOGERROR("could not initialize mido: please ensure that all required config options for VPCMIDO mode are set in eucalyptus.conf\n");
        EUCA_FREE(pMidoConfig);
        return (1);
    }
    
    // Release unnecessary handlers
    if (pConfig->ipt) {
        ipt_handler_close(pConfig->ipt);
    }
    if (pConfig->ips) {
        ips_handler_close(pConfig->ips);
    }
    if (pConfig->ebt) {
        ebt_handler_close(pConfig->ebt);
    }

    // We are now initialized
    gInitialized = TRUE;

    return (0);
}
Beispiel #9
0
//!
//!
//!
//! @param[in] file
//! @param[in] size
//! @param[in] mode
//!
//! @return the newly allocated string or NULL if any error occured
//!
//! @note caller is responsible to free the allocated memory
//!
char *file2str_seek(char *file, size_t size, int mode)
{
    int rc = 0;
    int fd = 0;
    char *ret = NULL;
    struct stat statbuf = { 0 };

    if (!file || size <= 0) {
        LOGERROR("bad input parameters\n");
        return (NULL);
    }

    if ((ret = EUCA_ZALLOC(size, sizeof(char))) == NULL) {
        LOGERROR("out of memory!\n");
        return (NULL);
    }

    if ((rc = stat(file, &statbuf)) >= 0) {
        if ((fd = open(file, O_RDONLY)) >= 0) {
            if (mode == 1) {
                if ((rc = lseek(fd, (off_t) (-1 * size), SEEK_END)) < 0) {
                    if ((rc = lseek(fd, (off_t) 0, SEEK_SET)) < 0) {
                        LOGERROR("cannot seek\n");
                        EUCA_FREE(ret);
                        close(fd);
                        return (NULL);
                    }
                }
            }

            rc = read(fd, ret, (size) - 1);
            close(fd);
        } else {
            LOGERROR("cannot open '%s' read-only\n", file);
            EUCA_FREE(ret);
            return (NULL);
        }
    } else {
        LOGERROR("cannot stat console_output file '%s'\n", file);
        EUCA_FREE(ret);
        return (NULL);
    }

    return (ret);
}
Beispiel #10
0
//!
//! Allocates sem structure from an already allocated Posix named semaphore; sem_p/v can
//! be used with it; freeing the sem struct also closes the Posix semaphore that was passed
//! in.
//!
//! @param[in] pExternalLock a pointer to the posix semaphore structure to use.
//!
//! @return a pointer to the newly created semaphore or NULL if any failure occured.
//!
//! @pre The external_lock parameter must not be NULL
//!
//! @post On success a new sem structure is allocated and initialized with the external_lock.
//!
sem *sem_alloc_posix(sem_t * pExternalLock)
{
    sem *pSem = NULL;

    // Name sure or parameter is valid
    if (pExternalLock != NULL) {
        // Allocate memory for our duplicate semaphore
        if ((pSem = EUCA_ZALLOC(1, sizeof(sem))) == NULL)
            return (NULL);

        // Set the dependency
        pSem->posix = pExternalLock;
        pSem->name = strdup("unknown");
        return (pSem);
    }

    return (NULL);
}
Beispiel #11
0
//!
//! Allocate a new bundle task for the given instance
//!
//! @param[in] pInstance pointer to the instance we're creating a bundling task for
//!
//! @return A newly allocated pointer to the bundle task structure if successful or NULL if
//!         the given pInstance structure is NULL or if we cannot allocate memory.
//!
//! @pre The \p pInstance field must not be NULL
//!
//! @post A newly allocated structure is allocated and initialized.
//!
//! @note The caller is responsible for freeing the allocated memory
//!
bundleTask *allocate_bundleTask(ncInstance * pInstance)
{
    bundleTask *pBundle = NULL;

    // Make sure out given parameter is valid
    if (pInstance != NULL) {
        if ((pBundle = EUCA_ZALLOC(1, sizeof(bundleTask))) == NULL) {
            LOGERROR("out of memory\n");
            return (NULL);
        }
        // initialize our newly allocated structure.
        snprintf(pBundle->instanceId, CHAR_BUFFER_SIZE, "%s", pInstance->instanceId);
        snprintf(pBundle->state, CHAR_BUFFER_SIZE, "%s", pInstance->bundleTaskStateName);
        return (pBundle);
    }

    return (NULL);
}
Beispiel #12
0
//!
//! Adds an instance to an instance linked list
//!
//! @param[in,out] ppHead a pointer to the pointer to the head of the list
//! @param[in]     pInstance a pointer to the instance to add to the list
//!
//! @return EUCA_OK on success or the following error code:
//!         \li EUCA_MEMORY_ERROR: if we fail to allocate memory
//!         \li EUCA_INVALID_ERROR: if any of our parameter does not meet the pre-condition
//!         \li EUCA_DUPLICATE_ERROR: if the instance is already part of this list
//!
//! @pre \li Both \p ppHead and \p pInstance field must not be NULL.
//!      \li The instance must not be part of the list
//!
//! @post The instance is added to the list. If this is the first instance in the list,
//!       the \p ppHead value is updated to point to this instance.
//!
int add_instance(bunchOfInstances ** ppHead, ncInstance * pInstance)
{
    bunchOfInstances *pNew = NULL;
    bunchOfInstances *pLast = NULL;
    bunchOfInstances *pNext = NULL;

    // Make sure our paramters are valid
    if ((ppHead == NULL) || (pInstance == NULL))
        return (EUCA_INVALID_ERROR);

    // Try to allocate memory for our instance list node
    if ((pNew = EUCA_ZALLOC(1, sizeof(bunchOfInstances))) == NULL)
        return (EUCA_MEMORY_ERROR);

    // Initialize our node
    pNew->instance = pInstance;
    pNew->next = NULL;

    // Are we the first item in this list?
    if (*ppHead == NULL) {
        *ppHead = pNew;
        (*ppHead)->count = 1;
    } else {
        pNext = *ppHead;

        //
        // Process the list to make sure we're not trying to add a duplicate
        //
        do {
            pLast = pNext;
            if (!strcmp(pLast->instance->instanceId, pInstance->instanceId)) {
                EUCA_FREE(pNew);
                return (EUCA_DUPLICATE_ERROR);
            }
            pNext = pLast->next;
        } while (pLast->next);

        // We're at the end so add it there.
        pLast->next = pNew;
        (*ppHead)->count++;
    }

    return (EUCA_OK);
}
Beispiel #13
0
//!
//! Parses the volume string and returns a newly allocated ebs_volume_data structure via the parameter.
//! Caller must free the returned structure.
//! Format expected:
//!    sc://volumeId,token.
//!    OR
//!    http://schost:port/services/Storage/volumeId,token
//!
//! @param[in] volume_string containing the encoded volume information
//! @param[in] dest a pointer to a pointer for ebs_volume_data, the referenced pointer will be set to newly allocated struct
//!
//! @return ok|fail
//!
//! @pre
//!
//! @post
//!
//! @note
//!
int deserialize_volume(char *volume_string, ebs_volume_data ** dest)
{
    if (volume_string == NULL || strlen(volume_string) <= strlen(VOLUME_STRING_PREFIX)) {
        *dest = NULL;
        return EUCA_ERROR;
    }

    ebs_volume_data *vol_data = EUCA_ZALLOC(1, sizeof(ebs_volume_data));
    if (vol_data == NULL) {
        LOGERROR("Cannot allocate memory!\n");
        *dest = NULL;
        return EUCA_ERROR;
    }

    char *volume_start = volume_string + strlen(VOLUME_STRING_PREFIX);  //skip the prefix.
    if (volume_start == NULL) {
        LOGERROR("Failed parsing token string: %s\n", volume_string);
        EUCA_FREE(vol_data);
        return EUCA_ERROR;
    }
    char *token_start = strchr(volume_start, ',');
    if (token_start == NULL) {
        LOGERROR("Failed parsing token string: %s\n", volume_string);
        EUCA_FREE(vol_data);
        return EUCA_ERROR;
    }
    token_start += sizeof(char);       //Go 1 past the comma delimiter

    if (euca_strncpy(vol_data->volumeId, volume_start, token_start - volume_start) == NULL) {
        EUCA_FREE(vol_data);
        return EUCA_ERROR;
    }

    if (euca_strncpy(vol_data->token, token_start, strlen(token_start) + 1) == NULL) {
        EUCA_FREE(vol_data);
        return EUCA_ERROR;
    }

    *dest = vol_data;
    return EUCA_OK;
}
Beispiel #14
0
//!
//!
//!
//! @return
//!
//! @pre
//!
//! @note
//!
int clean_network_state(void)
{
    int rc = 0;
    int i = 0;
    char cmd[MAX_PATH] = { 0 };
    char file[MAX_PATH] = { 0 };
    char rootwrap[MAX_PATH] = { 0 };
    char *pidstr = NULL;
    char *ipstr = NULL;
    vnetConfig *tmpvnetconfig = NULL;

    tmpvnetconfig = EUCA_ZALLOC(1, sizeof(vnetConfig));
    if (!tmpvnetconfig) {
        LOGERROR("out of memory\n");
        return -1;
    }

    memcpy(tmpvnetconfig, vnetconfig, sizeof(vnetConfig));

    rc = vnetUnsetMetadataRedirect(tmpvnetconfig);
    if (rc) {
        LOGWARN("failed to unset metadata redirect\n");
    }

    for (i = 1; i < NUMBER_OF_PUBLIC_IPS; i++) {
        if (tmpvnetconfig->publicips[i].ip != 0 && tmpvnetconfig->publicips[i].allocated != 0) {
            ipstr = hex2dot(tmpvnetconfig->publicips[i].ip);
            snprintf(cmd, MAX_PATH, EUCALYPTUS_ROOTWRAP " ip addr del %s/32 dev %s", config->eucahome, SP(ipstr), tmpvnetconfig->pubInterface);
            LOGDEBUG("running command '%s'\n", cmd);
            rc = system(cmd);
            rc = rc >> 8;
            if (rc && rc != 2) {
                LOGERROR("running cmd '%s' failed: cannot remove ip %s\n", cmd, SP(ipstr));
            }
            EUCA_FREE(ipstr);
        }
    }
//!
//! Loads an instance structure data from the instance.xml file under the instance's
//! work blobstore path.
//!
//! @param[in] instanceId the instance identifier string (i-XXXXXXXX)
//!
//! @return A pointer to the instance structure if successful or otherwise NULL.
//!
//! @pre The instanceId parameter must not be NULL.
//!
//! @post On success, a newly allocated pointer to the instance is returned where the stateCode
//!       is set to NO_STATE.
//!
ncInstance *load_instance_struct(const char *instanceId)
{
    DIR *insts_dir = NULL;
    char tmp_path[EUCA_MAX_PATH] = "";
    char user_paths[EUCA_MAX_PATH] = "";
    char checkpoint_path[EUCA_MAX_PATH] = "";
    ncInstance *instance = NULL;
    struct dirent *dir_entry = NULL;
    struct stat mystat = { 0 };

    // Allocate memory for our instance
    if ((instance = EUCA_ZALLOC(1, sizeof(ncInstance))) == NULL) {
        LOGERROR("out of memory (for instance struct)\n");
        return (NULL);
    }
    // We know the instance indentifier
    euca_strncpy(instance->instanceId, instanceId, sizeof(instance->instanceId));

    // we don't know userId, so we'll look for instanceId in every user's
    // directory (we're assuming that instanceIds are unique in the system)
    set_path(user_paths, sizeof(user_paths), NULL, NULL);
    if ((insts_dir = opendir(user_paths)) == NULL) {
        LOGERROR("failed to open %s\n", user_paths);
        goto free;
    }
    // Scan every path under the user path for one that conaints our instance
    while ((dir_entry = readdir(insts_dir)) != NULL) {
        snprintf(tmp_path, sizeof(tmp_path), "%s/%s/%s", user_paths, dir_entry->d_name, instance->instanceId);
        if (stat(tmp_path, &mystat) == 0) {
            // found it. Now save our user identifier
            euca_strncpy(instance->userId, dir_entry->d_name, sizeof(instance->userId));
            break;
        }
    }

    // Done with the directory
    closedir(insts_dir);
    insts_dir = NULL;

    // Did we really find one?
    if (strlen(instance->userId) < 1) {
        LOGERROR("didn't find instance %s\n", instance->instanceId);
        goto free;
    }
    // set various instance-directory-relative paths in the instance struct
    set_instance_paths(instance);

    // Check if there is a binary checkpoint file, used by versions up to 3.3,
    // and load metadata from it (as part of a "warm" upgrade from 3.3.0 and 3.3.1).
    set_path(checkpoint_path, sizeof(checkpoint_path), instance, "instance.checkpoint");
    set_path(instance->xmlFilePath, sizeof(instance->xmlFilePath), instance, INSTANCE_FILE_NAME);
    if (check_file(checkpoint_path) == 0) {
        ncInstance33 instance33;
        {                              // read in the checkpoint
            int fd = open(checkpoint_path, O_RDONLY);
            if (fd < 0) {
                LOGERROR("failed to load metadata for %s from %s: %s\n", instance->instanceId, checkpoint_path, strerror(errno));
                goto free;
            }

            size_t meta_size = (size_t) sizeof(ncInstance33);
            assert(meta_size <= SSIZE_MAX); // beyond that read() behavior is unspecified
            ssize_t bytes_read = read(fd, &instance33, meta_size);
            close(fd);
            if (bytes_read < meta_size) {
                LOGERROR("metadata checkpoint for %s (%ld bytes) in %s is too small (< %ld)\n", instance->instanceId, bytes_read, checkpoint_path, meta_size);
                goto free;
            }
        }
        // Convert the 3.3 struct into the current struct.
        // Currently, a copy is sufficient, but if ncInstance
        // ever changes so that its beginning differs from ncInstanc33,
        // we may have to write something more elaborate or to break
        // the ability to upgrade from 3.3. We attempt to detect such a
        // change with the following if-statement, which compares offsets
        // in the structs of the last member in the 3.3 version.
        if (((unsigned long)&(instance->last_stat) - (unsigned long)instance)
            != ((unsigned long)&(instance33.last_stat) - (unsigned long)&instance33)) {
            LOGERROR("BUG: upgrade from v3.3 is not possible due to changes to instance struct\n");
            goto free;
        }
        memcpy(instance, &instance33, sizeof(ncInstance33));
        LOGINFO("[%s] upgraded instance checkpoint from v3.3\n", instance->instanceId);
    } else {                           // no binary checkpoint, so we expect an XML-formatted checkpoint
        if (read_instance_xml(instance->xmlFilePath, instance) != EUCA_OK) {
            LOGERROR("failed to read instance XML\n");
            goto free;
        }
    }

    // Reset some fields for safety since they would now be wrong
    instance->stateCode = NO_STATE;
    instance->params.root = NULL;
    instance->params.kernel = NULL;
    instance->params.ramdisk = NULL;
    instance->params.swap = NULL;
    instance->params.ephemeral0 = NULL;

    // fix up the pointers
    vbr_parse(&(instance->params), NULL);

    // perform any upgrade-related manipulations to bring the struct up to date

    // save the struct back to disk after the upgrade routine had a chance to modify it
    if (gen_instance_xml(instance) != EUCA_OK) {
        LOGERROR("failed to create instance XML in %s\n", instance->xmlFilePath);
        goto free;
    }
    // remove the binary checkpoint because it is no longer needed and not used past 3.3
    unlink(checkpoint_path);

    return (instance);

free:
    EUCA_FREE(instance);
    return (NULL);
}
//!
//!
//!
//! @param[in] euca_home
//! @param[in] rundir_path
//! @param[in] instName
//!
//! @return EUCA_OK on success or proper error code. Known error code returned include: EUCA_ERROR,
//!         EUCA_IO_ERROR and EUCA_MEMORY_ERROR.
//!
int make_credential_floppy(char *euca_home, ncInstance * instance)
{
    int fd = 0;
    int rc = 0;
    int rbytes = 0;
    int count = 0;
    int ret = EUCA_ERROR;
    char dest_path[1024] = "";
    char source_path[1024] = "";
    char *ptr = NULL;
    char *buf = NULL;
    char *tmp = NULL;

    char *rundir_path = instance->instancePath;

    if (!euca_home || !rundir_path || !strlen(euca_home) || !strlen(rundir_path)) {
        return (EUCA_ERROR);
    }

    snprintf(source_path, 1024, EUCALYPTUS_HELPER_DIR "/floppy", euca_home);
    snprintf(dest_path, 1024, "%s/floppy", rundir_path);

    if ((buf = EUCA_ALLOC(1024 * 2048, sizeof(char))) == NULL) {
        ret = EUCA_MEMORY_ERROR;
        goto cleanup;
    }

    if ((fd = open(source_path, O_RDONLY)) < 0) {
        ret = EUCA_IO_ERROR;
        goto cleanup;
    }

    rbytes = read(fd, buf, 1024 * 2048);
    close(fd);
    if (rbytes < 0) {
        ret = EUCA_IO_ERROR;
        goto cleanup;
    }

    tmp = EUCA_ZALLOC(KEY_STRING_SIZE, sizeof(char));
    if (!tmp) {
        ret = EUCA_MEMORY_ERROR;
        goto cleanup;
    }

    ptr = buf;
    count = 0;
    while (count < rbytes) {
        memcpy(tmp, ptr, strlen("MAGICEUCALYPTUSINSTPUBKEYPLACEHOLDER"));
        if (!strcmp(tmp, "MAGICEUCALYPTUSINSTPUBKEYPLACEHOLDER")) {
            memcpy(ptr, instance->instancePubkey, strlen(instance->instancePubkey));
        } else if (!strcmp(tmp, "MAGICEUCALYPTUSAUTHPUBKEYPLACEHOLDER")) {
            memcpy(ptr, instance->euareKey, strlen(instance->euareKey));
        } else if (!strcmp(tmp, "MAGICEUCALYPTUSAUTHSIGNATPLACEHOLDER")) {
            memcpy(ptr, instance->instanceToken, strlen(instance->instanceToken));
        } else if (!strcmp(tmp, "MAGICEUCALYPTUSINSTPRIKEYPLACEHOLDER")) {
            memcpy(ptr, instance->instancePk, strlen(instance->instancePk));
        }

        ptr++;
        count++;
    }

    if ((fd = open(dest_path, O_CREAT | O_TRUNC | O_RDWR, 0700)) < 0) {
        ret = EUCA_IO_ERROR;
        goto cleanup;
    }

    rc = write(fd, buf, rbytes);
    close(fd);

    if (rc != rbytes) {
        ret = EUCA_IO_ERROR;
        goto cleanup;
    }

    ret = EUCA_OK;

cleanup:
    if (buf != NULL)
        EUCA_FREE(buf);
    if (tmp != NULL)
        EUCA_FREE(tmp);
    return ret;
}
Beispiel #17
0
//!
//! Allocate a new semaphore with the given name and mutex starting value.
//!
//! @param[in] val   the starting mutex count
//! @param[in] typeName  the type of semaphore. If 'mutex' then pthread mutexis used if any other
//!                      name then posix named semaphore is used if an empty name then SYS V IPC
//!                      semaphore is implied.
//! @param[in] flags Kernel encoding of open mode
//!
//! @return a pointer to the newly allocated semaphore or NULL if a failure occured
//!
//! @see sem_free()
//!
//! @pre The name field must not be NULL.
//!
//! @post On success, a semaphore structure is allocated and initialized
//!
//! @note Caller is responsible to free allocated memory for this semaphore. Call to sem_free() is
//!       prefered for this operation
//!
sem *sem_realloc(const int val, const char *typeName, u32 flags)
{
    sem *pSem = NULL;
    char addr[24] = "";
    DECLARE_ARG;

    // Validate the name parameter
    assert(typeName);

    // Check if we can allocate memory for our zemaphore
    if ((pSem = EUCA_ZALLOC(1, sizeof(sem))) == NULL)
        return (NULL);

    // Initialize our type independent fields
    pSem->sysv = -1;
    pSem->flags = flags;

    // save the address of this semaphore for future use
    snprintf(addr, sizeof(addr), "%p", pSem);

    //
    // Initialize our semphore base on the requested type
    //
    if (!strcmp(typeName, IPC_MUTEX_SEMAPHORE)) {
        // use pthread mutex
        pSem->usemutex = 1;
        pSem->mutcount = val;
        pSem->mutwaiters = 0;
        pthread_mutex_init(&(pSem->mutex), NULL);
        pthread_cond_init(&(pSem->cond), NULL);

        // In this case we'll use the address of the semaphore rather than the name
        pSem->name = strdup(addr);
    } else if (strlen(typeName) > 0) {
        // named semaphores
        if (pSem->flags & O_EXCL) {
            // clean up in case previous sem holder crashed
            if (sem_unlink(typeName) == 0) {
                LOGINFO("cleaning up old semaphore %s\n", typeName);
            }
        }
        // Create a new semaphore with this name.
        if ((pSem->posix = sem_open(typeName, O_CREAT | flags, 0644, val)) == SEM_FAILED) {
            EUCA_FREE(pSem);
            return (NULL);
        }

        pSem->name = strdup(typeName);
    } else {
        // SYS V IPC semaphores
        if ((pSem->sysv = semget(IPC_PRIVATE, 1, (IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR))) < 0) {
            EUCA_FREE(pSem);
            return (NULL);
        }
        // Set the value
        arg.val = val;
        if (semctl(pSem->sysv, 0, SETVAL, arg) == -1) {
            EUCA_FREE(pSem);
            return (NULL);
        }
        // In this case we'll use the address of the semaphore rather than the name
        pSem->name = strdup(addr);
    }

    return (pSem);
}
Beispiel #18
0
//!
//!
//!
//! @param[in] describeServices
//! @param[in] env pointer to the AXIS2 environment structure
//!
//! @return
//!
//! @pre
//!
//! @note
//!
adb_DescribeServicesResponse_t *DescribeServicesMarshal(adb_DescribeServices_t * describeServices, const axutil_env_t * env)
{
    adb_DescribeServicesResponse_t *ret = NULL;
    adb_describeServicesResponseType_t *adbresp = NULL;
    adb_describeServicesType_t *adbinput = NULL;

    int rc;
    axis2_bool_t status = AXIS2_TRUE;
    char statusMessage[256];
    ncMetadata ccMeta;

    serviceStatusType *outStatuses = NULL;
    serviceInfoType *serviceIds = NULL;
    int serviceIdsLen = 0, outStatusesLen = 0, i;

    adbinput = adb_DescribeServices_get_DescribeServices(describeServices, env);
    adbresp = adb_describeServicesResponseType_create(env);

    EUCA_MESSAGE_UNMARSHAL(describeServicesType, adbinput, (&ccMeta));

    adb_describeServicesResponseType_set_correlationId(adbresp, env, adb_describeServicesType_get_correlationId(adbinput, env));
    adb_describeServicesResponseType_set_userId(adbresp, env, adb_describeServicesType_get_userId(adbinput, env));

    //  localDev = adb_describeServicesType_get_localDev(adbinput, env);
    serviceIdsLen = adb_describeServicesType_sizeof_serviceIds(adbinput, env);
    serviceIds = EUCA_ZALLOC(serviceIdsLen, sizeof(serviceInfoType));
    for (i = 0; i < serviceIdsLen; i++) {
        copy_service_info_type_from_adb(&(serviceIds[i]), adb_describeServicesType_get_serviceIds_at(adbinput, env, i), env);
    }

    status = AXIS2_TRUE;
    rc = doDescribeServices(&ccMeta, serviceIds, serviceIdsLen, &outStatuses, &outStatusesLen);

    if (rc) {
        logprintf("ERROR: doDescribeServices() returned FAIL\n");
        status = AXIS2_FALSE;
        snprintf(statusMessage, 255, "ERROR");
    }

    for (i = 0; i < outStatusesLen; i++) {
        adb_serviceStatusType_t *stt;
        adb_serviceInfoType_t *sit;

        stt = adb_serviceStatusType_create(env);

        adb_serviceStatusType_set_localState(stt, env, outStatuses[i].localState);
        adb_serviceStatusType_set_localEpoch(stt, env, outStatuses[i].localEpoch);
        adb_serviceStatusType_add_details(stt, env, outStatuses[i].details);
        sit = copy_service_info_type_to_adb(env, &(outStatuses[i].serviceId));
        adb_serviceStatusType_set_serviceId(stt, env, sit);

        adb_describeServicesResponseType_add_serviceStatuses(adbresp, env, stt);
    }
    EUCA_FREE(outStatuses);
    EUCA_FREE(serviceIds);

    adb_describeServicesResponseType_set_return(adbresp, env, status);
    if (status == AXIS2_FALSE) {
        adb_describeServicesResponseType_set_statusMessage(adbresp, env, statusMessage);
    }

    ret = adb_DescribeServicesResponse_create(env);
    adb_DescribeServicesResponse_set_DescribeServicesResponse(ret, env, adbresp);

    return (ret);
}
Beispiel #19
0
//!
//!
//!
//! @param[in] req
//!
//! @return EUCA_OK on success or EUCA_ERROR on failure
//!
int prepare_validate(imager_request * req)
{
    int i = 0;
    int num_sda_parts = 0;
    imager_param *p = NULL;
    prepare_params *state = NULL;

    print_req(req);

    if ((state = EUCA_ZALLOC(1, sizeof(prepare_params))) == NULL)
        err("out of memory");

    // set defaults
    state->bootable = FALSE;
    state->cache = TRUE;
    state->work = FALSE;
    state->action = ACTION_DOWNLOAD | ACTION_CONVERT;

    // record in 'state' all specified parameters
    for (p = req->params; p != NULL && p->key != NULL; p++) {
        if (strcmp(p->key, _CACHE) == 0) {
            state->cache = parse_boolean(p->val);
        } else if (strcmp(p->key, _BOOT) == 0) {
            state->bootable = parse_boolean(p->val);
        } else if (strcmp(p->key, _ID) == 0) {
            state->id = p->val;
        } else if (strcmp(p->key, _KEY) == 0) {
            state->sshkey = parse_loginpassword(p->val);
        } else if (strcmp(p->key, _OUT) == 0) {
            state->out = p->val;
        } else if (strcmp(p->key, _WORK) == 0) {
            state->work = parse_boolean(p->val);
        } else if (strcmp(p->key, _VBR) == 0) {
            if (state->total_vbrs == (EUCA_MAX_VBRS - 1))
                err("too many vbr= parameters");
            state->vbrs[state->total_vbrs++] = p->val;
            if (strstr(p->val, ":sda1:") != NULL || strstr(p->val, ":sda2:") != NULL || strstr(p->val, ":sda3:") != NULL) {
                num_sda_parts++;
            }
        } else if (strcmp(p->key, _ACTION) == 0) {
            if (strcmp(p->val, "download") == 0) {
                state->action = ACTION_DOWNLOAD;
            } else if (strcmp(p->val, "convert") == 0) {
                state->action = ACTION_CONVERT;
            } else {
                err("unknown action parameter '%s' for command 'prepare'", p->val);
            }
        } else {
            err("invalid parameter '%s' for command 'prepare'", p->key);
        }
    }

    // ensure mandatory params are present
    if (state->total_vbrs < 1)
        err("not a single VBR was specified");

    LOGINFO("actions: download=%s convert=%s\n",
            (state->action & ACTION_DOWNLOAD) ? ("yes") : ("no"),
            (state->action & ACTION_CONVERT) ? ("yes") : ("no"))

    // if a bootable disk is requested and the expected number of partitions is present,
    // then add the boot VBR entry so an extra, 4th, boot partition will get created
    if (state->bootable && num_sda_parts > 0) {
        char buf[1024];
        snprintf(buf, sizeof(buf), BOOT_VBR_FORMAT, num_sda_parts+1);
        state->vbrs[state->total_vbrs++] = strdup(buf);
    }

    for (i = 0; i < state->total_vbrs; i++) {
        if (vbr_add_ascii(state->vbrs[i], &(state->vm)))
            err("failed to add VBR record '%s'", state->vbrs[i]);
    }

    if (vbr_parse(&(state->vm), NULL) != EUCA_OK)
        err("failed to validate VBR records");

    // if given an empty key file, just set the pointer to NULL
    if (state->sshkey && strlen(state->sshkey) == 0) {
        EUCA_FREE(state->sshkey);
    }
    // save pointer to find it later
    req->internal = ((void *)state);
    return (EUCA_OK);
}
Beispiel #20
0
//!
//! Allocate a new MAP entry
//!
//! @param[in] size unused parameter
//!
//! @return a pointer to the new map entry structure or NULL if any error occured
//!
map *map_create(int size)
{
    return ((map *) EUCA_ZALLOC(1, sizeof(map)));
}
//!
//! Creates and initialize an NC stub entry
//!
//! @param[in] endpoint_uri the endpoint URI string
//! @param[in] logfile the log file name string
//! @param[in] homedir the home directory path string
//!
//! @return a pointer to the newly created NC stub structure
//!
ncStub *ncStubCreate(char *endpoint_uri, char *logfile, char *homedir)
{
    return (EUCA_ZALLOC(1, sizeof(ncStub)));
}
Beispiel #22
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);
}
Beispiel #23
0
//!
//! Allocate and initialize an instance structure with given information. Instances are
//! present in instance-related requests.
//!
//! @param[in] sUUID the unique user identifier string
//! @param[in] sInstanceId the instance identifier string (i-XXXXXXXX)
//! @param[in] sReservationId the reservation identifier string
//! @param[in] pVirtMachine a pointer to our virtual machine parametes
//! @param[in] sStateName the current instance state name string
//! @param[in] stateCode the current instance state code
//! @param[in] sUserId the user identifier string
//! @param[in] sOwnerId the owner identifier string
//! @param[in] sAccountId the account identifier string
//! @param[in] pNetCfg a pointer to the network configuration of this instance
//! @param[in] sKeyName the SSH key name to use
//! @param[in] sUserData user data string to pass to the instance
//! @param[in] sLaunchIndex the instance's launch index
//! @param[in] sPlatform the instance's platform type
//! @param[in] expiryTime the instance's expiration time before it reaches running
//! @param[in] asGroupNames an array list of group name string
//! @param[in] groupNamesSize the number of group name in the asGroupNames list
//! @param[in] asGroupIds an array list of group identifier string
//! @param[in] groupIdsSize the number of group name in the asGroupIds list
//!
//! @return a pointer to the newly allocated instance structure or NULL if any error occured.
//!
//! @see add_instance()
//! @see free_instance()
//!
//! @post On succes an instance structure is allocated and initialized with the given information.
//!
ncInstance *allocate_instance(const char *sUUID, const char *sInstanceId, const char *sReservationId, virtualMachine * pVirtMachine,
                              const char *sStateName, int stateCode, const char *sUserId, const char *sOwnerId, const char *sAccountId,
                              netConfig * pNetCfg, const char *sKeyName, const char *sUserData, const char *sLaunchIndex, const char *sPlatform,
                              int expiryTime, char **asGroupNames, int groupNamesSize, char **asGroupIds, int groupIdsSize)
{
    u32 i = 0;
    ncInstance *pInstance = NULL;

    /* zeroed out for cleaner-looking checkpoints and strings that are empty unless set */
    if ((pInstance = EUCA_ZALLOC(1, sizeof(ncInstance))) == NULL)
        return (NULL);

    if (sUserData)
        euca_strncpy(pInstance->userData, sUserData, CHAR_BUFFER_SIZE * 32);

    if (sLaunchIndex)
        euca_strncpy(pInstance->launchIndex, sLaunchIndex, CHAR_BUFFER_SIZE);

    if (sPlatform)
        euca_strncpy(pInstance->platform, sPlatform, CHAR_BUFFER_SIZE);

    pInstance->groupNamesSize = groupNamesSize;
    if ((asGroupNames != NULL) && (groupNamesSize > 0)) {
        for (i = 0; i < groupNamesSize && asGroupNames[i]; i++)
            euca_strncpy(pInstance->groupNames[i], asGroupNames[i], CHAR_BUFFER_SIZE);
    }

    pInstance->groupIdsSize = groupIdsSize;
    if ((asGroupIds != NULL) && (groupIdsSize > 0)) {
        for (i = 0; i < groupIdsSize && asGroupIds[i]; i++)
            euca_strncpy(pInstance->groupIds[i], asGroupIds[i], CHAR_BUFFER_SIZE);
    }

    if (pNetCfg != NULL)
        memcpy(&(pInstance->ncnet), pNetCfg, sizeof(netConfig));

    if (sUUID)
        euca_strncpy(pInstance->uuid, sUUID, CHAR_BUFFER_SIZE);

    if (sInstanceId)
        euca_strncpy(pInstance->instanceId, sInstanceId, CHAR_BUFFER_SIZE);

    if (sKeyName)
        euca_strncpy(pInstance->keyName, sKeyName, CHAR_BUFFER_SIZE * 4);

    if (sReservationId)
        euca_strncpy(pInstance->reservationId, sReservationId, CHAR_BUFFER_SIZE);

    if (sStateName)
        euca_strncpy(pInstance->stateName, sStateName, CHAR_BUFFER_SIZE);

    if (sUserId)
        euca_strncpy(pInstance->userId, sUserId, CHAR_BUFFER_SIZE);

    if (sOwnerId)
        euca_strncpy(pInstance->ownerId, sOwnerId, CHAR_BUFFER_SIZE);

    if (sAccountId)
        euca_strncpy(pInstance->accountId, sAccountId, CHAR_BUFFER_SIZE);

    if (pVirtMachine)
        memcpy(&(pInstance->params), pVirtMachine, sizeof(virtualMachine));

    pInstance->stateCode = stateCode;
    euca_strncpy(pInstance->bundleTaskStateName, bundling_progress_names[NOT_BUNDLING], CHAR_BUFFER_SIZE);
    pInstance->expiryTime = expiryTime;
    return (pInstance);
}
//!
//! Creates and initialize an NC stub entry
//!
//! @param[in] endpoint_uri the endpoint URI string
//! @param[in] logfile the log file name string
//! @param[in] homedir the home directory path string
//!
//! @return a pointer to the newly created NC stub structure
//!
scStub *scStubCreate(char *endpoint_uri, char *logfile, char *homedir)
{
    char *uri = NULL;
    char *p = NULL;
    char *node_name = NULL;
    scStub *pStub = NULL;
    axutil_env_t *env = NULL;
    axis2_char_t *client_home;
    axis2_stub_t *stub;

    if (logfile) {
        env = axutil_env_create_all(logfile, AXIS2_LOG_LEVEL_TRACE);
    } else {
        env = axutil_env_create_all(NULL, 0);
    }

    if (homedir) {
        client_home = (axis2_char_t *) homedir;
    } else {
        client_home = AXIS2_GETENV("AXIS2C_HOME");
    }

    if (client_home == NULL) {
        LOGERROR("cannot get AXIS2C_HOME");
        return NULL;
    }

    if (endpoint_uri == NULL) {
        LOGERROR("empty endpoint_url");
        return NULL;
    }

    uri = endpoint_uri;

    // extract node name from the endpoint
    p = strstr(uri, "://");            // find "http[s]://..."
    if (p == NULL) {
        LOGERROR("received invalid URI %s\n", uri);
        return NULL;
    }

    node_name = strdup(p + 3);         // copy without the protocol prefix
    if (node_name == NULL) {
        LOGERROR("is out of memory\n");
        return NULL;
    }

    if ((p = strchr(node_name, ':')) != NULL)
        *p = '\0';                     // cut off the port

    if ((p = strchr(node_name, '/')) != NULL)
        *p = '\0';                     // if there is no port

    //! @todo what if endpoint_uri, home, or env are NULL?
    stub = axis2_stub_create_EucalyptusSC(env, client_home, (axis2_char_t *) uri);

    if (stub) {
        if ((pStub = EUCA_ZALLOC(1, sizeof(scStub))) != NULL) {
            pStub->env = env;
            pStub->client_home = strdup((char *)client_home);
            pStub->endpoint_uri = (axis2_char_t *) strdup(endpoint_uri);
            pStub->node_name = (axis2_char_t *) strdup(node_name);
            pStub->stub = stub;
            if (pStub->client_home == NULL || pStub->endpoint_uri == NULL || pStub->node_name == NULL) {
                LOGWARN("out of memory (%s:%s:%d client_home=%s endpoint_uri=%s node_name=%s)", __FILE__, __FUNCTION__, __LINE__,
                        pStub->client_home, pStub->endpoint_uri, pStub->node_name);
            }
        } else {
            LOGWARN("out of memory for 'st' (%s:%s:%d)\n", __FILE__, __FUNCTION__, __LINE__);
        }
    } else {
        LOGERROR("failed to create a stub for EucalyptusNC service (stub=%p env=%p client_home=%s)\n", stub, env, client_home);
    }

    EUCA_FREE(node_name);
    return (pStub);
}
Beispiel #25
0
//!
//! find value of the given param in the eucalyptus.conf,
//! return NULL if the param is commented out
//!
//! @param[in] eucahome the path where Eucalyptus is installed
//! @param[in] param the parameter value we're looking for
//!
//! @return the matching value or NULL
//!
static char *find_conf_value(const char *eucahome, const char *param)
{
    int i = 0;
    int j = 0;
    int quote = 0;
    char *pch = NULL;
    char conf_path[1024] = "";
    char line[1024] = "";
    char *value = NULL;
    FILE *f_conf = NULL;

    if (!eucahome || !param)
        return (NULL);

    snprintf(conf_path, 1024, EUCALYPTUS_CONF_LOCATION, eucahome);
    if ((f_conf = fopen(conf_path, "r")) == NULL) {
        return (NULL);
    }

    while (fgets(line, 1024, f_conf) != NULL) {
        if (strstr(line, param) != NULL) {  // found the param in the line
            if (strchr(line, '#') != NULL) {    // the line is commented out (assume # can't appear in the middle)
                break;
            } else {
                pch = strtok(line, "=");    // again assume '=' can't appear in the middle of value
                pch = strtok(NULL, "=");
                if (pch && (strlen(pch) > 0)) {
                    if ((value = EUCA_ZALLOC(strlen(pch) + 1, 1)) == NULL) {
                        fclose(f_conf);
                        return (NULL);
                    }
                    snprintf(value, strlen(pch) + 1, "%s", pch);
                }
                break;
            }
        }
        bzero(line, 1024);
    }

    // remove "" from the value
    if (value) {
        quote = 0;
        for (i = 0; i < strlen(value); i++) {
            if (value[i] == '\"')
                quote++;
            else
                value[i - quote] = value[i];
        }
        value[strlen(value) - quote] = 0x00;

        // remove spaces
        i = 0;
        while ((value[i] == ' ') || (value[i] == '\t'))
            i++;

        for (j = i; j < strlen(value); j++)
            value[j - i] = value[j];
        value[strlen(value) - i] = 0x00;

        if (value[strlen(value) - 1] == '\n')
            value[strlen(value) - 1] = 0x00;
    }

    fclose(f_conf);
    return (value);
}
//!
//! Creates and initialize an NC stub entry
//!
//! @param[in] endpoint_uri the endpoint URI string
//! @param[in] logfile the log file name string
//! @param[in] homedir the home directory path string
//!
//! @return a pointer to the newly created NC stub structure
//!
ncStub *ncStubCreate(char *endpoint_uri, char *logfile, char *homedir)
{
    char *uri = NULL;
    char *p = NULL;
    char *node_name = NULL;
    axutil_env_t *env = NULL;
    axis2_char_t *client_home = NULL;
    axis2_stub_t *stub = NULL;
    ncStub *st = NULL;

    if (logfile) {
        env = axutil_env_create_all(logfile, AXIS2_LOG_LEVEL_TRACE);
    } else {
        env = axutil_env_create_all(NULL, 0);
    }

    if (homedir) {
        client_home = (axis2_char_t *) homedir;
    } else {
        client_home = AXIS2_GETENV("AXIS2C_HOME");
    }

    if (client_home == NULL) {
        LOGERROR("fakeNC: ERROR: cannot get AXIS2C_HOME");
        return NULL;
    }

    if (endpoint_uri == NULL) {
        LOGERROR("fakeNC: ERROR: empty endpoint_url");
        return NULL;
    }

    uri = endpoint_uri;

    // extract node name from the endpoint
    p = strstr(uri, "://");            // find "http[s]://..."
    if (p == NULL) {
        LOGERROR("fakeNC: ncStubCreate received invalid URI %s\n", uri);
        return NULL;
    }

    node_name = strdup(p + 3);         // copy without the protocol prefix
    if (node_name == NULL) {
        LOGERROR("fakeNC: ncStubCreate is out of memory\n");
        return NULL;
    }

    if ((p = strchr(node_name, ':')) != NULL)
        *p = '\0';                     // cut off the port

    if ((p = strchr(node_name, '/')) != NULL)
        *p = '\0';                     // if there is no port

    LOGDEBUG("fakeNC: DEBUG: requested URI %s\n", uri);

    // see if we should redirect to a local broker
    if (strstr(uri, "EucalyptusBroker")) {
        uri = "http://localhost:8773/services/EucalyptusBroker";
        LOGDEBUG("fakeNC: DEBUG: redirecting request to %s\n", uri);
    }
    //! @todo what if endpoint_uri, home, or env are NULL?
    stub = axis2_stub_create_EucalyptusNC(env, client_home, (axis2_char_t *) uri);

    if (stub && (st = EUCA_ZALLOC(1, sizeof(ncStub)))) {
        st->env = env;
        st->client_home = strdup((char *)client_home);
        st->endpoint_uri = (axis2_char_t *) strdup(endpoint_uri);
        st->node_name = (axis2_char_t *) strdup(node_name);
        st->stub = stub;
        if (st->client_home == NULL || st->endpoint_uri == NULL) {
            LOGWARN("fakeNC: WARNING: out of memory");
        }
    } else {
        LOGWARN("fakeNC: WARNING: out of memory");
    }

    EUCA_FREE(node_name);
    return (st);
}
Beispiel #27
0
//!
//! Handles the console output retrieval request.
//!
//! @param[in]  nc a pointer to the NC state structure to initialize
//! @param[in]  pMeta a pointer to the node controller (NC) metadata structure
//! @param[in]  instanceId the instance identifier string (i-XXXXXXXX)
//! @param[out] consoleOutput a pointer to the unallocated string that will contain the output
//!
//! @return EUCA_OK on success or EUCA_ERROR and EUCA_NOT_FOUND_ERROR on failure.
//!
static int doGetConsoleOutput(struct nc_state_t *nc, ncMetadata * pMeta, char *instanceId, char **consoleOutput)
{
    int rc = 0;
    int fd = 0;
    int ret = EUCA_OK;
    int readsize = 0;
    char *console_output = NULL;
    char *console_append = NULL;
    char *console_main = NULL;
    char console_file[MAX_PATH] = "";
    char userId[48] = "";
    ncInstance *instance = NULL;
    struct stat statbuf = { 0 };

    *consoleOutput = NULL;
    readsize = 64 * 1024;

    // find the instance record
    sem_p(inst_sem);
    {
        if ((instance = find_instance(&global_instances, instanceId)) != NULL) {
            snprintf(console_file, 1024, "%s/console.append.log", instance->instancePath);
            snprintf(userId, 48, "%s", instance->userId);
        }
    }
    sem_v(inst_sem);

    if (!instance) {
        logprintfl(EUCAERROR, "[%s] cannot locate instance\n", instanceId);
        return (EUCA_NOT_FOUND_ERROR);
    }
    // read from console.append.log if it exists into dynamically allocated 4K console_append buffer
    if ((rc = stat(console_file, &statbuf)) >= 0) {
        if (diskutil_ch(console_file, nc->admin_user_id, nc->admin_user_id, 0) != EUCA_OK) {
            logprintfl(EUCAERROR, "[%s] failed to change ownership of %s\n", instanceId, console_file);
            return (EUCA_ERROR);
        }

        if ((fd = open(console_file, O_RDONLY)) >= 0) {
            if ((console_append = EUCA_ZALLOC(4096, sizeof(char))) != NULL) {
                rc = read(fd, console_append, (4096) - 1);
            }
            close(fd);
        }
    }

    sem_p(inst_sem);
    {
        snprintf(console_file, MAX_PATH, "%s/console.log", instance->instancePath);
    }
    sem_v(inst_sem);

    // read the last 64K from console.log or the whole file, if smaller, into dynamically allocated 64K console_main buffer
    if ((rc = stat(console_file, &statbuf)) >= 0) {
        if (diskutil_ch(console_file, nc->admin_user_id, nc->admin_user_id, 0) != EUCA_OK) {
            logprintfl(EUCAERROR, "[%s] failed to change ownership of %s\n", instanceId, console_file);
            EUCA_FREE(console_append);
            return (EUCA_ERROR);
        }

        if ((fd = open(console_file, O_RDONLY)) >= 0) {
            if ((rc = lseek(fd, (off_t) (-1 * readsize), SEEK_END)) < 0) {
                if ((rc = lseek(fd, (off_t) 0, SEEK_SET)) < 0) {
                    logprintfl(EUCAERROR, "[%s] cannot seek to beginning of file\n", instanceId);
                    if (console_append)
                        EUCA_FREE(console_append);
                    close(fd);
                    return (EUCA_ERROR);
                }
            }

            if ((console_main = EUCA_ZALLOC(readsize, sizeof(char))) != NULL) {
                rc = read(fd, console_main, (readsize) - 1);
            }
            close(fd);
        } else {
            logprintfl(EUCAERROR, "[%s] cannot open '%s' read-only\n", instanceId, console_file);
        }
    } else {
        logprintfl(EUCAERROR, "[%s] cannot stat console_output file '%s'\n", instanceId, console_file);
    }

    // concatenate console_append with console_main, base64-encode this, and put into dynamically allocated buffer consoleOutput
    ret = EUCA_ERROR;
    if ((console_output = EUCA_ZALLOC((readsize) + 4096, sizeof(char))) != NULL) {
        if (console_append) {
            strncat(console_output, console_append, 4096);
        }

        if (console_main) {
            strncat(console_output, console_main, readsize);
        }

        *consoleOutput = base64_enc((unsigned char *)console_output, strlen(console_output));
        ret = EUCA_OK;
    }

    EUCA_FREE(console_append);
    EUCA_FREE(console_main);
    EUCA_FREE(console_output);
    return (ret);
}
Beispiel #28
0
//!
//!
//!
//! @param[in] log_error
//! @param[in] format
//! @param[in] ...
//!
//! @return
//!
//! @pre
//!
//! @note
//!
static char *execlp_output(boolean log_error, ...)
{
    va_list ap;
    int ntokens = 0;
    char cmd[256] = "";                // for logging, OK if command gets truncated

    // run through arguments once to count them
    va_start(ap, log_error);
    {
        char *s;
        while ((s = va_arg(ap, char *)) != NULL) {
            ntokens++;
        }
    }
    va_end(ap);
    if (ntokens < 1) {
        LOGERROR("internal error: too few arguments to %s\n", __func__);
        return NULL;
    }
    // allocate an array and run through arguments again, copying them into the array
    char **argv = EUCA_ZALLOC(ntokens + 1, sizeof(char *)); // one extra for the terminating NULL
    va_start(ap, log_error);
    {
        for (int i = 0; i < ntokens; i++) {
            argv[i] = strdup(va_arg(ap, char *));

            // append tokens to 'cmd', strictly for logging purposes
            int left_in_cmd = sizeof(cmd) - strlen(cmd);
            if (left_in_cmd > 1)       // has room for at least one character and '\0'
                snprintf(cmd + strlen(cmd), left_in_cmd, "%s%s%s%s", (i > 0) ? (" ") : (""),    // add space in front all but the first argument
                         (i == 0 || argv[i][0] == '-') ? ("") : ("'"),  // add quoates around non-flags
                         argv[i], (i == 0 || argv[i][0] == '-') ? ("") : ("'"));
        }
    }
    va_end(ap);

    char *output = NULL;

    // set up a pipe for getting stdout and stderror from child process
    int filedes[2];
    if (pipe(filedes)) {
        LOGERROR("failed to create a pipe\n");
        goto free;
    }
    LOGTRACE("executing: %s\n", cmd);

    pid_t cpid = fork();
    int rc = -1;
    if (cpid == -1) {
        LOGERROR("failed to fork\n");
        close(filedes[0]);
        close(filedes[1]);
        goto free;
    } else if (cpid == 0) {            // child
        close(filedes[0]);
        if (dup2(filedes[1], STDOUT_FILENO) == -1) {
            LOGERROR("failed to dup2\n");
            exit(-1);
        }
        if (dup2(filedes[1], STDERR_FILENO) == -1) {
            LOGERROR("failed to dup2\n");
            exit(-1);
        }
        exit(execvp(argv[0], argv));
    }
    // parent reads stdout and stdin from child into a string
    close(filedes[1]);

    int outsize = OUTPUT_ALLOC_CHUNK;  // allocate in chunks of this size
    int nextchar = 0;                  // offset of the next usable char
    int bytesread;
    output = EUCA_ALLOC(outsize, sizeof(char));
    if (output) {
        output[0] = '\0';              // return an empty string if there is no output
    }

    while ((output != NULL) && (bytesread = read(filedes[0], output + nextchar, outsize - nextchar - 1)) > 0) {
        nextchar += bytesread;
        output[nextchar] = '\0';
        if (nextchar + 1 == outsize) {
            outsize += OUTPUT_ALLOC_CHUNK;
            if (outsize > MAX_OUTPUT_BYTES) {
                LOGERROR("internal error: output from command is too long\n");
                EUCA_FREE(output);
                break;
            }
            output = EUCA_REALLOC(output, outsize, sizeof(char));
        }
    }
    if (output == NULL) {
        LOGERROR("failed to allocate mem for output\n");
    }
    close(filedes[0]);

    {                                  // wait for the child to reap status
        int status;
        rc = waitpid(cpid, &status, 0);
        if (rc == -1) {
            LOGERROR("failed to wait for child process\n");
        } else if (WIFEXITED(status)) {
            rc = WEXITSTATUS(status);
            if (rc) {
                LOGERROR("child return non-zero status (%d)\n", rc);
            }
        } else {
            LOGERROR("child process did not terminate normally\n");
            rc = -1;
        }
    }

    if (rc) {
        // there were problems above
        if ((output != NULL) && strstr(cmd, "losetup") && strstr(output, ": No such device or address")) {
            rc = 0;
        } else {
            if (log_error) {
                LOGERROR("bad return code from cmd %s\n", cmd);
                LOGDEBUG("%s\n", output);
            }
            EUCA_FREE(output);         // will be set to NULL
        }
    }

free:
    for (int i = 0; i < ntokens; i++) {
        EUCA_FREE(argv[i]);
    }
    EUCA_FREE(argv);

    return output;
}