static int doDescribeResource(struct nc_state_t *nc, ncMetadata * pMeta, char *resourceType, ncResource ** outRes)
{
    ncResource *res = NULL;
    ncInstance *inst = NULL;

    // stats to re-calculate now
    long long mem_free = 0;
    long long disk_free = 0;
    int cores_free = 0;

    // intermediate sums
    long long sum_mem = 0;             // for known domains: sum of requested memory
    long long sum_disk = 0;            // for known domains: sum of requested disk sizes
    int sum_cores = 0;                 // for known domains: sum of requested cores

    *outRes = NULL;

    sem_p(inst_copy_sem);
    while ((inst = get_instance(&global_instances_copy)) != NULL) {
        if (inst->state == TEARDOWN)
            continue;                  // they don't take up resources
        sum_mem += inst->params.mem;
        sum_disk += (inst->params.disk);
        sum_cores += inst->params.cores;
    }
    sem_v(inst_copy_sem);

    disk_free = nc->disk_max - sum_disk;
    if (disk_free < 0)
        disk_free = 0;                 // should not happen

    cores_free = nc->cores_max - sum_cores; //! @todo should we -1 for dom0?
    if (cores_free < 0)
        cores_free = 0;                // due to timesharing

    mem_free = nc->mem_max - sum_mem;
    if (mem_free < 0)
        mem_free = 0;                  // should not happen

    // check for potential overflow - should not happen
    if (nc->mem_max > INT_MAX || mem_free > INT_MAX || nc->disk_max > INT_MAX || disk_free > INT_MAX) {
        LOGERROR("stats integer overflow error (bump up the units?)\n");
        LOGERROR("   memory: max=%-10lld free=%-10lld\n", nc->mem_max, mem_free);
        LOGERROR("     disk: max=%-10lld free=%-10lld\n", nc->disk_max, disk_free);
        LOGERROR("    cores: max=%-10lld free=%-10d\n", nc->cores_max, cores_free);
        LOGERROR("       INT_MAX=%-10d\n", INT_MAX);
        return EUCA_OVERFLOW_ERROR;
    }
    res = allocate_resource(nc->is_enabled ? "enabled" : "disabled",
                            nc->migration_capable, nc->iqn, nc->mem_max, mem_free, nc->disk_max, disk_free, nc->cores_max, cores_free, "none");
    if (res == NULL) {
        LOGERROR("out of memory\n");
        return EUCA_MEMORY_ERROR;
    }
    *outRes = res;

    LOGDEBUG("Core status:   in-use %d physical %lld over-committed %s\n", sum_cores, nc->phy_max_cores, (((sum_cores - cores_free) > nc->phy_max_cores) ? "yes" : "no"));
    LOGDEBUG("Memory status: in-use %lld physical %lld over-committed %s\n", sum_mem, nc->phy_max_mem, (((sum_mem - mem_free) > nc->phy_max_mem) ? "yes" : "no"));
    LOGDEBUG("returning status=%s cores=%d/%d mem=%d/%d disk=%d/%d iqn=%s\n",
             res->nodeStatus, res->numberOfCoresAvailable, res->numberOfCoresMax, res->memorySizeAvailable, res->memorySizeMax, res->diskSizeAvailable, res->diskSizeMax, res->iqn);
    return EUCA_OK;
}
static int doDescribeResource(struct nc_state_t *nc, ncMetadata * pMeta, char *resourceType, ncResource ** outRes)
{
    ncResource *res = NULL;
    ncInstance *inst = NULL;

     
    long long mem_free = 0;
    long long disk_free = 0;
    int cores_free = 0;

     
    long long sum_mem = 0;              
    long long sum_disk = 0;             
    int sum_cores = 0;                  

    *outRes = NULL;

    sem_p(inst_copy_sem);
    while ((inst = get_instance(&global_instances_copy)) != NULL) {
        if (inst->state == TEARDOWN)
            continue;                   
        sum_mem += inst->params.mem;
        sum_disk += (inst->params.disk);
        sum_cores += inst->params.cores;
    }
    sem_v(inst_copy_sem);

    disk_free = nc->disk_max - sum_disk;
    if (disk_free < 0)
        disk_free = 0;                  

    cores_free = nc->cores_max - sum_cores;  
    if (cores_free < 0)
        cores_free = 0;                 

    mem_free = nc->mem_max - sum_mem;
    if (mem_free < 0)
        mem_free = 0;                   

     
    if (nc->mem_max > INT_MAX || mem_free > INT_MAX || nc->disk_max > INT_MAX || disk_free > INT_MAX) {
        LOGERROR("stats integer overflow error (bump up the units?)\n");
        LOGERROR("   memory: max=%-10lld free=%-10lld\n", nc->mem_max, mem_free);
        LOGERROR("     disk: max=%-10lld free=%-10lld\n", nc->disk_max, disk_free);
        LOGERROR("    cores: max=%-10lld free=%-10d\n", nc->cores_max, cores_free);
        LOGERROR("       INT_MAX=%-10d\n", INT_MAX);
        return EUCA_OVERFLOW_ERROR;
    }
    res = allocate_resource(nc->is_enabled ? "enabled" : "disabled",
                            nc->migration_capable, nc->iqn, nc->mem_max, mem_free, nc->disk_max, disk_free, nc->cores_max, cores_free, "none");
    if (res == NULL) {
        LOGERROR("out of memory\n");
        return EUCA_MEMORY_ERROR;
    }
    *outRes = res;

    LOGDEBUG("Core status:   in-use %d physical %lld over-committed %s\n", sum_cores, nc->phy_max_cores, (((sum_cores - cores_free) > nc->phy_max_cores) ? "yes" : "no"));
    LOGDEBUG("Memory status: in-use %lld physical %lld over-committed %s\n", sum_mem, nc->phy_max_mem, (((sum_mem - mem_free) > nc->phy_max_mem) ? "yes" : "no"));
    LOGDEBUG("returning status=%s cores=%d/%d mem=%d/%d disk=%d/%d iqn=%s\n",
             res->nodeStatus, res->numberOfCoresAvailable, res->numberOfCoresMax, res->memorySizeAvailable, res->memorySizeMax, res->diskSizeAvailable, res->diskSizeMax, res->iqn);
    return EUCA_OK;
}