static int restart_instance(ncInstance * instance)
{
    int error = EUCA_ERROR;
    pthread_attr_t *attr = NULL;

    // Reset a few fields to prevent future confusion
    instance->state = STAGING;
    instance->retries = LIBVIRT_QUERY_RETRIES;
    instance->launchTime = time(NULL);
    //instance->expiryTime           = xxx?
    instance->bootTime = 0;
    instance->bundlingTime = 0;
    instance->createImageTime = 0;
    instance->terminationTime = 0;
    instance->bundlePid = 0;
    instance->bundleCanceled = 0;
    instance->bundleBucketExists = 0;
    instance->stateCode = EXTANT;
    instance->bundleTaskState = NOT_BUNDLING;
    instance->createImageTaskState = NOT_CREATEIMAGE;
    instance->createImagePid = 0;
    instance->createImageCanceled = 0;

    euca_strncpy(instance->stateName, instance_state_names[EXTANT], CHAR_BUFFER_SIZE);
    euca_strncpy(instance->bundleTaskStateName, bundling_progress_names[NOT_BUNDLING], CHAR_BUFFER_SIZE);
    euca_strncpy(instance->createImageTaskStateName, createImage_progress_names[NOT_CREATEIMAGE], CHAR_BUFFER_SIZE);

    // Reset our pthread structure
    memset(&(instance->tcb), 0, sizeof(instance->tcb));

    // to enable NC recovery
    save_instance_struct(instance);

    // do the potentially long tasks in a thread
    if ((attr = (pthread_attr_t *) EUCA_ZALLOC(1, sizeof(pthread_attr_t))) == NULL) {
        LOGERROR("[%s] out of memory\n", instance->instanceId);
        error = EUCA_MEMORY_ERROR;
        goto error;
    }

    pthread_attr_init(attr);
    pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);

    if (pthread_create(&(instance->tcb), attr, restart_thread, ((void *)instance))) {
        pthread_attr_destroy(attr);
        LOGERROR("[%s] failed to spawn a VM startup thread\n", instance->instanceId);
        error = EUCA_THREAD_ERROR;
        sem_p(inst_sem);
        {
            remove_instance(&global_instances, instance);
            copy_instances();
        }
        sem_v(inst_sem);

        EUCA_FREE(attr);
        goto error;
    }

    pthread_attr_destroy(attr);
    EUCA_FREE(attr);
    return (EUCA_OK);

error:
    free_instance(&instance);
    return (error);
}
static int restart_instance(ncInstance * instance)
{
    int error = EUCA_ERROR;
    pthread_attr_t *attr = NULL;

     
    instance->state = STAGING;
    instance->retries = LIBVIRT_QUERY_RETRIES;
    instance->launchTime = time(NULL);
     
    instance->bootTime = 0;
    instance->bundlingTime = 0;
    instance->createImageTime = 0;
    instance->terminationTime = 0;
    instance->bundlePid = 0;
    instance->bundleCanceled = 0;
    instance->bundleBucketExists = 0;
    instance->stateCode = EXTANT;
    instance->bundleTaskState = NOT_BUNDLING;
    instance->createImageTaskState = NOT_CREATEIMAGE;
    instance->createImagePid = 0;
    instance->createImageCanceled = 0;

    euca_strncpy(instance->stateName, instance_state_names[EXTANT], CHAR_BUFFER_SIZE);
    euca_strncpy(instance->bundleTaskStateName, bundling_progress_names[NOT_BUNDLING], CHAR_BUFFER_SIZE);
    euca_strncpy(instance->createImageTaskStateName, createImage_progress_names[NOT_CREATEIMAGE], CHAR_BUFFER_SIZE);

     
    memset(&(instance->tcb), 0, sizeof(instance->tcb));

     
    save_instance_struct(instance);

     
    if ((attr = (pthread_attr_t *) EUCA_ZALLOC(1, sizeof(pthread_attr_t))) == NULL) {
        LOGERROR("[%s] out of memory\n", instance->instanceId);
        error = EUCA_MEMORY_ERROR;
        goto error;
    }

    pthread_attr_init(attr);
    pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);

    if (pthread_create(&(instance->tcb), attr, restart_thread, ((void *)instance))) {
        pthread_attr_destroy(attr);
        LOGERROR("[%s] failed to spawn a VM startup thread\n", instance->instanceId);
        error = EUCA_THREAD_ERROR;
        sem_p(inst_sem);
        {
            remove_instance(&global_instances, instance);
            copy_instances();
        }
        sem_v(inst_sem);

        EUCA_FREE(attr);
        goto error;
    }

    pthread_attr_destroy(attr);
    EUCA_FREE(attr);
    return (EUCA_OK);

error:
    free_instance(&instance);
    return (error);
}