Beispiel #1
0
static int create_fsdev_cache(sigar_t *sigar)
{
    sigar_file_system_list_t fslist;
    int i;
    int status =
        sigar_file_system_list_get(sigar, &fslist);

    if (status != SIGAR_OK) {
        return status;
    }

    sigar->fsdev = sigar_cache_new(15);

    for (i=0; i<fslist.number; i++) {
        sigar_file_system_t *fsp = &fslist.data[i];

        if (fsp->type == SIGAR_FSTYPE_LOCAL_DISK) {
            sigar_cache_entry_t *ent;
            struct stat sb;

            if (stat(fsp->dir_name, &sb) < 0) {
                continue;
            }

            ent = sigar_cache_get(sigar->fsdev, SIGAR_FSDEV_ID(sb));
            ent->value = strdup(fsp->dev_name);
        }
    }

    return SIGAR_OK;
}
Beispiel #2
0
/* XXX: check for stale-ness using start_time */
SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
                                      sigar_proc_cpu_t *proccpu)
{
    sigar_cache_entry_t *entry;
    sigar_proc_cpu_t *prev;
    sigar_uint64_t otime, time_now = sigar_time_now_millis();
    sigar_uint64_t time_diff, total_diff;
    int status;

    if (!sigar->proc_cpu) {
        sigar->proc_cpu = sigar_cache_new(128);
    }

    entry = sigar_cache_get(sigar->proc_cpu, pid);
    if (entry->value) {
        prev = (sigar_proc_cpu_t *)entry->value;
    }
    else {
        prev = entry->value = malloc(sizeof(*prev));
        SIGAR_ZERO(prev);
    }

    time_diff = time_now - prev->last_time;
    proccpu->last_time = prev->last_time = time_now;

    if (time_diff == 0) {
        /* we were just called within < 1 second ago. */
        memcpy(proccpu, prev, sizeof(*proccpu));
        return SIGAR_OK;
    }

    otime = prev->total;

    status =
        sigar_proc_time_get(sigar, pid,
                            (sigar_proc_time_t *)proccpu);

    if (status != SIGAR_OK) {
        return status;
    }

    memcpy(prev, proccpu, sizeof(*prev));

    if (proccpu->total < otime) {
        /* XXX this should not happen */
        otime = 0;
    }

    if (otime == 0) {
        proccpu->percent = 0.0;
        /* first time called */
        return SIGAR_OK;
    }

    total_diff = proccpu->total - otime;
    proccpu->percent = total_diff / (double)time_diff;

    return SIGAR_OK;
}
Beispiel #3
0
static int net_services_parse(sigar_cache_t *names, char *type)
{
    FILE *fp;
    char buffer[8192], *ptr;
    char *file;


    if (!(file = getenv("SIGAR_NET_SERVICES_FILE"))) {
        file = NET_SERVICES_FILE;
    }

    if (!(fp = fopen(file, "r"))) {
        return errno;
    }

    while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
        int port;
        char name[256], proto[56];
        sigar_cache_entry_t *entry;

        while (sigar_isspace(*ptr)) {
            ++ptr;
        }
        if ((*ptr == '#') || (*ptr == '\0')) {
            continue;
        }

        if (sscanf(ptr, "%s%d/%s", name, &port, proto) != 3) {
            continue;
        }
        if (!strEQ(type, proto)) {
            continue;
        }

        entry = sigar_cache_get(names, port);
        if (!entry->value) {
            entry->value = strdup(name);
        }
    }

    fclose(fp);
    return SIGAR_OK;
}
Beispiel #4
0
static int sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
{
    kstat_ctl_t *kc = sigar->kc;
    kstat_t *ksp;
    uint_t cpuinfo[CPU_STATES];
    unsigned int i;
    int is_debug = SIGAR_LOG_IS_DEBUG(sigar);
    sigar_cache_t *chips;

    if (sigar_kstat_update(sigar) == -1) {
        return errno;
    }

    if (cpulist == &sigar->cpulist) {
        if (sigar->cpulist.size == 0) {
            /* create once */
            sigar_cpu_list_create(cpulist);
        }
        else {
            /* reset, re-using cpulist.data */
            sigar->cpulist.number = 0;
        }
    }
    else {
        sigar_cpu_list_create(cpulist);
    }

    if (is_debug) {
        sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
                         "[cpu_list] OS reports %d CPUs",
                         sigar->ncpu);
    }

    chips = sigar_cache_new(16);
    chips->free_value = free_chip_id;

    for (i=0; i<sigar->ncpu; i++) {
        sigar_cpu_t *cpu;
        char *buf;
        int chip_id;
        sigar_cache_entry_t *ent;

        if (!CPU_ONLINE(sigar->ks.cpuid[i])) {
            sigar_log_printf(sigar, SIGAR_LOG_INFO,
                             "cpu %d (id=%d) is offline",
                             i, sigar->ks.cpuid[i]);
            continue;
        }

        if (!(ksp = sigar->ks.cpu[i])) {
            sigar_log_printf(sigar, SIGAR_LOG_ERROR,
                             "NULL ksp for cpu %d (id=%d)",
                             i, sigar->ks.cpuid[i]);
            continue; /* shouldnot happen */
        }

        if (kstat_read(kc, ksp, NULL) < 0) {
            sigar_log_printf(sigar, SIGAR_LOG_ERROR,
                             "kstat_read failed for cpu %d (id=%d): %s",
                             i, sigar->ks.cpuid[i],
                             sigar_strerror(sigar, errno));
            continue; /* shouldnot happen */
        }

        /*
         * cpu_stat_t is not binary compatible between solaris versions.
         * since cpu_stat is a 'raw' kstat and not 'named' we cannot
         * use name based lookups as we do for others.
         * the start of the cpu_stat_t structure is binary compatible,
         * which looks like so:
         * typedef struct cpu_stat {
         *    kmutex_t        cpu_stat_lock;
         *    cpu_sysinfo_t   cpu_sysinfo;
         *    ...
         *    typedef struct cpu_sysinfo {
         *       ulong cpu[CPU_STATES];
         *       ...
         * we just copy the piece we need below:
         */
        buf = ksp->ks_data;
        buf += sizeof(kmutex_t);
        memcpy(&cpuinfo[0], buf, sizeof(cpuinfo));
        chip_id = sigar->cpu_list_cores ? -1 : get_chip_id(sigar, i);

        if (chip_id == -1) {
            SIGAR_CPU_LIST_GROW(cpulist);
            cpu = &cpulist->data[cpulist->number++];
            SIGAR_ZERO(cpu);
        }
        else {
            /* merge times of logical processors */
            ent = sigar_cache_get(chips, chip_id);
            if (ent->value) {
                cpu = &cpulist->data[(long)ent->value-1];
            }
            else {
                SIGAR_CPU_LIST_GROW(cpulist);
                cpu = &cpulist->data[cpulist->number++];
                ent->value = (void *)(long)cpulist->number;
                SIGAR_ZERO(cpu);

                if (is_debug) {
                    sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
                                     "[cpu_list] Merging times of"
                                     " logical processors for chip_id=%d",
                                     chip_id);
                }
            }
        }

        cpu->user += SIGAR_TICK2MSEC(cpuinfo[CPU_USER]);
        cpu->sys  += SIGAR_TICK2MSEC(cpuinfo[CPU_KERNEL]);
        cpu->idle += SIGAR_TICK2MSEC(cpuinfo[CPU_IDLE]);
        cpu->wait += SIGAR_TICK2MSEC(cpuinfo[CPU_WAIT]);
        cpu->nice += 0; /* no cpu->nice */
        cpu->total = cpu->user + cpu->sys + cpu->idle + cpu->wait;
    }

    sigar_cache_destroy(chips);

    return SIGAR_OK;
}
Beispiel #5
0
int sigar_file_system_usage_get(sigar_t *sigar,
                                const char *dirname,
                                sigar_file_system_usage_t *fsusage)
{
    struct statfs buf;
    struct stat sb;
    sigar_uint64_t val, bsize;
    
    if (statfs(dirname, &buf) != 0) {
        return errno;
    }

    bsize = buf.f_bsize / 512;
    val = buf.f_blocks;
    fsusage->total = SIGAR_FS_BLOCKS_TO_BYTES(val, bsize);
    val = buf.f_bfree;
    fsusage->free  = SIGAR_FS_BLOCKS_TO_BYTES(val, bsize);
    val = buf.f_bavail;
    fsusage->avail = SIGAR_FS_BLOCKS_TO_BYTES(val, bsize);
    fsusage->used  = fsusage->total - fsusage->free;
    fsusage->files = buf.f_files;
    fsusage->free_files = buf.f_ffree;
    fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage);

    SIGAR_DISK_STATS_INIT(&fsusage->disk);

    if (!sigar->fsdev) {
        if (create_fsdev_cache(sigar) != SIGAR_OK) {
            return SIGAR_OK;
        }
    }

    if (stat(dirname, &sb) == 0) {
        sigar_cache_entry_t *ent;
        struct pst_lvinfo lv;
        struct stat devsb;
        char *devname;
        int retval;

        ent = sigar_cache_get(sigar->fsdev, SIGAR_FSDEV_ID(sb));
        if (ent->value == NULL) {
            return SIGAR_OK;
        }

        if (stat((char *)ent->value, &devsb) < 0) {
            return SIGAR_OK;
        }

        retval = pstat_getlv(&lv, sizeof(lv), 0, (int)devsb.st_rdev);

        if (retval == 1) {
            fsusage->disk.reads  = lv.psl_rxfer;
            fsusage->disk.writes = lv.psl_wxfer;
            fsusage->disk.read_bytes  = lv.psl_rcount;
            fsusage->disk.write_bytes = lv.psl_wcount;
            fsusage->disk.queue       = SIGAR_FIELD_NOTIMPL;
        }
    }

    return SIGAR_OK;
}