コード例 #1
0
ファイル: common.c プロジェクト: tvieira/netdata
long get_system_cpus(void) {
    processors = 1;

    #ifdef __APPLE__
        int32_t tmp_processors;

        if (unlikely(GETSYSCTL_BY_NAME("hw.logicalcpu", tmp_processors))) {
            error("Assuming system has %d processors.", processors);
        } else {
            processors = tmp_processors;
        }

        return processors;
    #elif __FreeBSD__
        int32_t tmp_processors;

        if (unlikely(GETSYSCTL_BY_NAME("hw.ncpu", tmp_processors))) {
            error("Assuming system has %d processors.", processors);
        } else {
            processors = tmp_processors;
        }

        return processors;
    #else

    char filename[FILENAME_MAX + 1];
    snprintfz(filename, FILENAME_MAX, "%s/proc/stat", netdata_configured_host_prefix);

    procfile *ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
    if(!ff) {
        error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
        return processors;
    }

    ff = procfile_readall(ff);
    if(!ff) {
        error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
        return processors;
    }

    processors = 0;
    unsigned int i;
    for(i = 0; i < procfile_lines(ff); i++) {
        if(!procfile_linewords(ff, i)) continue;

        if(strncmp(procfile_lineword(ff, i, 0), "cpu", 3) == 0) processors++;
    }
    processors--;
    if(processors < 1) processors = 1;

    procfile_close(ff);

    debug(D_SYSTEM, "System has %d processors.", processors);
    return processors;

    #endif /* __APPLE__, __FreeBSD__ */
}
コード例 #2
0
// read the whole mountinfo into a linked list
struct mountinfo *mountinfo_read(int do_statvfs) {
    char filename[FILENAME_MAX + 1];
    snprintfz(filename, FILENAME_MAX, "%s/proc/self/mountinfo", netdata_configured_host_prefix);
    procfile *ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
    if(unlikely(!ff)) {
        snprintfz(filename, FILENAME_MAX, "%s/proc/1/mountinfo", netdata_configured_host_prefix);
        ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
        if(unlikely(!ff)) return NULL;
    }

    ff = procfile_readall(ff);
    if(unlikely(!ff))
        return NULL;

    struct mountinfo *root = NULL, *last = NULL, *mi = NULL;

    unsigned long l, lines = procfile_lines(ff);
    for(l = 0; l < lines ;l++) {
        if(unlikely(procfile_linewords(ff, l) < 5))
            continue;

        mi = mallocz(sizeof(struct mountinfo));

        unsigned long w = 0;
        mi->id = str2ul(procfile_lineword(ff, l, w)); w++;
        mi->parentid = str2ul(procfile_lineword(ff, l, w)); w++;

        char *major = procfile_lineword(ff, l, w), *minor; w++;
        for(minor = major; *minor && *minor != ':' ;minor++) ;

        if(unlikely(!*minor)) {
            error("Cannot parse major:minor on '%s' at line %lu of '%s'", major, l + 1, filename);
            freez(mi);
            continue;
        }

        *minor = '\0';
        minor++;

        mi->flags = 0;

        mi->major = str2ul(major);
        mi->minor = str2ul(minor);

        mi->root = strdupz(procfile_lineword(ff, l, w)); w++;
        mi->root_hash = simple_hash(mi->root);

        mi->mount_point = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++;
        mi->mount_point_hash = simple_hash(mi->mount_point);

        mi->persistent_id = strdupz(mi->mount_point);
        netdata_fix_chart_id(mi->persistent_id);
        mi->persistent_id_hash = simple_hash(mi->persistent_id);

        mi->mount_options = strdupz(procfile_lineword(ff, l, w)); w++;

        if(unlikely(is_read_only(mi->mount_options)))
            mi->flags |= MOUNTINFO_READONLY;

        // count the optional fields
/*
        unsigned long wo = w;
*/
        mi->optional_fields_count = 0;
        char *s = procfile_lineword(ff, l, w);
        while(*s && *s != '-') {
            w++;
            s = procfile_lineword(ff, l, w);
            mi->optional_fields_count++;
        }

/*
        if(unlikely(mi->optional_fields_count)) {
            // we have some optional fields
            // read them into a new array of pointers;

            mi->optional_fields = mallocz(mi->optional_fields_count * sizeof(char *));

            int i;
            for(i = 0; i < mi->optional_fields_count ; i++) {
                *mi->optional_fields[wo] = strdupz(procfile_lineword(ff, l, w));
                wo++;
            }
        }
        else
            mi->optional_fields = NULL;
*/

        if(likely(*s == '-')) {
            w++;

            mi->filesystem = strdupz(procfile_lineword(ff, l, w)); w++;
            mi->filesystem_hash = simple_hash(mi->filesystem);

            mi->mount_source = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++;
            mi->mount_source_hash = simple_hash(mi->mount_source);

            mi->super_options = strdupz(procfile_lineword(ff, l, w)); w++;

            if(unlikely(is_read_only(mi->super_options)))
                mi->flags |= MOUNTINFO_READONLY;

            if(unlikely(ME_DUMMY(mi->mount_source, mi->filesystem)))
                mi->flags |= MOUNTINFO_IS_DUMMY;

            if(unlikely(ME_REMOTE(mi->mount_source, mi->filesystem)))
                mi->flags |= MOUNTINFO_IS_REMOTE;

            // mark as BIND the duplicates (i.e. same filesystem + same source)
            if(do_statvfs) {
                struct stat buf;
                if(unlikely(stat(mi->mount_point, &buf) == -1)) {
                    mi->st_dev = 0;
                    mi->flags |= MOUNTINFO_NO_STAT;
                }
                else {
                    mi->st_dev = buf.st_dev;

                    struct mountinfo *mt;
                    for(mt = root; mt; mt = mt->next) {
                        if(unlikely(mt->st_dev == mi->st_dev && !(mt->flags & MOUNTINFO_IS_SAME_DEV))) {
                            if(strlen(mi->mount_point) < strlen(mt->mount_point))
                                mt->flags |= MOUNTINFO_IS_SAME_DEV;
                            else
                                mi->flags |= MOUNTINFO_IS_SAME_DEV;
                        }
                    }
                }
            }
            else {
                mi->st_dev = 0;
            }
        }
        else {
            mi->filesystem = NULL;
            mi->filesystem_hash = 0;

            mi->mount_source = NULL;
            mi->mount_source_hash = 0;

            mi->super_options = NULL;

            mi->st_dev = 0;
        }

        // check if it has size
        if(do_statvfs && !(mi->flags & MOUNTINFO_IS_DUMMY)) {
            struct statvfs buff_statvfs;
            if(unlikely(statvfs(mi->mount_point, &buff_statvfs) < 0)) {
                mi->flags |= MOUNTINFO_NO_STAT;
            }
            else if(unlikely(!buff_statvfs.f_blocks /* || !buff_statvfs.f_files */)) {
                mi->flags |= MOUNTINFO_NO_SIZE;
            }
        }

        // link it
        if(unlikely(!root))
            root = mi;
        else
            last->next = mi;

        last = mi;
        mi->next = NULL;

/*
#ifdef NETDATA_INTERNAL_CHECKS
        fprintf(stderr, "MOUNTINFO: %ld %ld %lu:%lu root '%s', persistent id '%s', mount point '%s', mount options '%s', filesystem '%s', mount source '%s', super options '%s'%s%s%s%s%s%s\n",
             mi->id,
             mi->parentid,
             mi->major,
             mi->minor,
             mi->root,
             mi->persistent_id,
                (mi->mount_point)?mi->mount_point:"",
                (mi->mount_options)?mi->mount_options:"",
                (mi->filesystem)?mi->filesystem:"",
                (mi->mount_source)?mi->mount_source:"",
                (mi->super_options)?mi->super_options:"",
                (mi->flags & MOUNTINFO_IS_DUMMY)?" DUMMY":"",
                (mi->flags & MOUNTINFO_IS_BIND)?" BIND":"",
                (mi->flags & MOUNTINFO_IS_REMOTE)?" REMOTE":"",
                (mi->flags & MOUNTINFO_NO_STAT)?" NOSTAT":"",
                (mi->flags & MOUNTINFO_NO_SIZE)?" NOSIZE":"",
                (mi->flags & MOUNTINFO_IS_SAME_DEV)?" SAMEDEV":""
        );
#endif
*/
    }

/* find if the mount options have "bind" in them
    {
        FILE *fp = setmntent(MOUNTED, "r");
        if (fp != NULL) {
            struct mntent mntbuf;
            struct mntent *mnt;
            char buf[4096 + 1];

            while ((mnt = getmntent_r(fp, &mntbuf, buf, 4096))) {
                char *bind = hasmntopt(mnt, "bind");
                if(unlikely(bind)) {
                    struct mountinfo *mi;
                    for(mi = root; mi ; mi = mi->next) {
                        if(unlikely(strcmp(mnt->mnt_dir, mi->mount_point) == 0)) {
                            fprintf(stderr, "Mount point '%s' is BIND\n", mi->mount_point);
                            mi->flags |= MOUNTINFO_IS_BIND;
                            break;
                        }
                    }

#ifdef NETDATA_INTERNAL_CHECKS
                    if(unlikely(!mi)) {
                        error("Mount point '%s' not found in /proc/self/mountinfo", mnt->mnt_dir);
                    }
#endif
                }
            }
            endmntent(fp);
        }
    }
*/

    procfile_close(ff);
    return root;
}
コード例 #3
0
ファイル: proc_stat.c プロジェクト: firehol/netdata
static int read_per_core_time_in_state_files(struct cpu_chart *all_cpu_charts, size_t len, size_t index) {
    size_t x, files_read = 0, files_nonzero = 0;

    for(x = 0; x < len ; x++) {
        struct per_core_single_number_file *f = &all_cpu_charts[x].files[index];
        struct per_core_time_in_state_file *tsf = &all_cpu_charts[x].time_in_state_files;

        f->found = 0;

        if(unlikely(!tsf->filename))
            continue;

        if(unlikely(!tsf->ff)) {
            tsf->ff = procfile_open(tsf->filename, " \t:", PROCFILE_FLAG_DEFAULT);
            if(unlikely(!tsf->ff))
            {
                error("Cannot open file '%s'", tsf->filename);
                continue;
            }
        }

        tsf->ff = procfile_readall(tsf->ff);
        if(unlikely(!tsf->ff)) {
            error("Cannot read file '%s'", tsf->filename);
            procfile_close(tsf->ff);
            tsf->ff = NULL;
            continue;
        }
        else {
            // successful read

            size_t lines = procfile_lines(tsf->ff), l;
            size_t words;
            unsigned long long total_ticks_since_last = 0, avg_freq = 0;

            // Check if there is at least one frequency in time_in_state
            if (procfile_word(tsf->ff, 0)[0] == '\0') {
                if(unlikely(keep_per_core_fds_open != CONFIG_BOOLEAN_YES)) {
                    procfile_close(tsf->ff);
                    tsf->ff = NULL;
                }
                // TODO: Is there a better way to avoid spikes than calculating the average over
                // the whole period under schedutil governor?
                // freez(tsf->last_ticks);
                // tsf->last_ticks = NULL;
                // tsf->last_ticks_len = 0;
                continue;
            }

            if (unlikely(tsf->last_ticks_len < lines || tsf->last_ticks == NULL)) {
                tsf->last_ticks = reallocz(tsf->last_ticks, sizeof(struct last_ticks) * lines);
                memset(tsf->last_ticks, 0, sizeof(struct last_ticks) * lines);
                tsf->last_ticks_len = lines;
            }

            f->value = 0;

            for(l = 0; l < lines - 1 ;l++) {
                unsigned long long frequency = 0, ticks = 0, ticks_since_last = 0;

                words = procfile_linewords(tsf->ff, l);
                if(unlikely(words < 2)) {
                    error("Cannot read time_in_state line. Expected 2 params, read %zu.", words);
                    continue;
                }
                frequency = str2ull(procfile_lineword(tsf->ff, l, 0));
                ticks     = str2ull(procfile_lineword(tsf->ff, l, 1));

                // It is assumed that frequencies are static and sorted
                ticks_since_last = ticks - tsf->last_ticks[l].ticks;
                tsf->last_ticks[l].frequency = frequency;
                tsf->last_ticks[l].ticks = ticks;

                total_ticks_since_last += ticks_since_last;
                avg_freq += frequency * ticks_since_last;

            }

            if (likely(total_ticks_since_last)) {
                avg_freq /= total_ticks_since_last;
                f->value = avg_freq;
            }

            if(unlikely(keep_per_core_fds_open != CONFIG_BOOLEAN_YES)) {
                procfile_close(tsf->ff);
                tsf->ff = NULL;
            }
        }

        files_read++;

        f->found = 1;

        if(likely(f->value != 0))
            files_nonzero++;
    }

    if(unlikely(files_read == 0))
        return -1;

    if(unlikely(files_nonzero == 0))
        return 0;

    return (int)files_nonzero;
}
コード例 #4
0
// read the whole mountinfo into a linked list
struct mountinfo *mountinfo_read() {
	procfile *ff = NULL;

	char filename[FILENAME_MAX + 1];
	snprintfz(filename, FILENAME_MAX, "%s/proc/self/mountinfo", global_host_prefix);
	ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
	if(!ff) {
		snprintfz(filename, FILENAME_MAX, "%s/proc/1/mountinfo", global_host_prefix);
		ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
		if(!ff) return NULL;
	}

	ff = procfile_readall(ff);
	if(!ff) return NULL;

	struct mountinfo *root = NULL, *last = NULL, *mi = NULL;

	unsigned long l, lines = procfile_lines(ff);
	for(l = 0; l < lines ;l++) {
		if(procfile_linewords(ff, l) < 5)
			continue;

		mi = malloc(sizeof(struct mountinfo));
		if(unlikely(!mi)) fatal("Cannot allocate memory for mountinfo");

		if(unlikely(!root))
			root = last = mi;
		else
			last->next = mi;

		last = mi;
		mi->next = NULL;

		unsigned long w = 0;
		mi->id = strtoul(procfile_lineword(ff, l, w), NULL, 10); w++;
		mi->parentid = strtoul(procfile_lineword(ff, l, w), NULL, 10); w++;

		char *major = procfile_lineword(ff, l, w), *minor; w++;
		for(minor = major; *minor && *minor != ':' ;minor++) ;
		*minor = '\0';
		minor++;

		mi->major = strtoul(major, NULL, 10);
		mi->minor = strtoul(minor, NULL, 10);

		mi->root = strdup(procfile_lineword(ff, l, w)); w++;
		if(unlikely(!mi->root)) fatal("Cannot allocate memory");
		mi->root_hash = simple_hash(mi->root);

		mi->mount_point = strdup(procfile_lineword(ff, l, w)); w++;
		if(unlikely(!mi->mount_point)) fatal("Cannot allocate memory");
		mi->mount_point_hash = simple_hash(mi->mount_point);

		mi->mount_options = strdup(procfile_lineword(ff, l, w)); w++;
		if(unlikely(!mi->mount_options)) fatal("Cannot allocate memory");

		// count the optional fields
/*
		unsigned long wo = w;
*/
		mi->optional_fields_count = 0;
		char *s = procfile_lineword(ff, l, w);
		while(*s && *s != '-') {
			w++;
			s = procfile_lineword(ff, l, w);
			mi->optional_fields_count++;
		}

/*
		if(unlikely(mi->optional_fields_count)) {
			// we have some optional fields
			// read them into a new array of pointers;

			mi->optional_fields = malloc(mi->optional_fields_count * sizeof(char *));
			if(unlikely(!mi->optional_fields))
				fatal("Cannot allocate memory for %d mountinfo optional fields", mi->optional_fields_count);

			int i;
			for(i = 0; i < mi->optional_fields_count ; i++) {
				*mi->optional_fields[wo] = strdup(procfile_lineword(ff, l, w));
				if(!mi->optional_fields[wo]) fatal("Cannot allocate memory");
				wo++;
			}
		}
		else
			mi->optional_fields = NULL;
*/

		if(likely(*s == '-')) {
			w++;

			mi->filesystem = strdup(procfile_lineword(ff, l, w)); w++;
			if(!mi->filesystem) fatal("Cannot allocate memory");
			mi->filesystem_hash = simple_hash(mi->filesystem);

			mi->mount_source = strdup(procfile_lineword(ff, l, w)); w++;
			if(!mi->mount_source) fatal("Cannot allocate memory");
			mi->mount_source_hash = simple_hash(mi->mount_source);

			mi->super_options = strdup(procfile_lineword(ff, l, w)); w++;
			if(!mi->super_options) fatal("Cannot allocate memory");
		}
		else {
			mi->filesystem = NULL;
			mi->mount_source = NULL;
			mi->super_options = NULL;
		}

/*
		info("MOUNTINFO: %u %u %u:%u root '%s', mount point '%s', mount options '%s', filesystem '%s', mount source '%s', super options '%s'",
		     mi->id,
		     mi->parentid,
		     mi->major,
		     mi->minor,
		     mi->root,
		     mi->mount_point,
		     mi->mount_options,
		     mi->filesystem,
		     mi->mount_source,
		     mi->super_options
		);
*/
	}

	procfile_close(ff);
	return root;
}