Ejemplo n.º 1
0
static int
checkfs(const char *vfst, const char *spec, const char *mntpt, void *auxarg,
    pid_t *pidp)
{
	/* List of directories containing fsck_xxx subcommands. */
	static const char *edirs[] = {
#ifdef RESCUEDIR
		RESCUEDIR,
#endif
		_PATH_SBIN,
		_PATH_USRSBIN,
		NULL
	};
	const char ** volatile argv, **edir;
	const char * volatile vfstype = vfst;
	pid_t pid;
	int argc, i, status, maxargc;
	char *optb;
	char *volatile optbuf;
	char execname[MAXPATHLEN + 1], execbase[MAXPATHLEN];
	const char *extra = getoptions(vfstype);

	if (!strcmp(vfstype, "ufs"))
		vfstype = MOUNT_UFS;

	optb = NULL;
	if (options)
		catopt(&optb, options);
	if (extra)
		catopt(&optb, extra);
	optbuf = optb;

	maxargc = 64;
	argv = emalloc(sizeof(char *) * maxargc);

	(void) snprintf(execbase, sizeof(execbase), "fsck_%s", vfstype);
	argc = 0;
	argv[argc++] = execbase;
	if (optbuf)
		mangle(optbuf, &argc, &argv, &maxargc);
	argv[argc++] = spec;
	argv[argc] = NULL;

	if (flags & (CHECK_DEBUG|CHECK_VERBOSE)) {
		(void)printf("start %s %swait", mntpt, 
			pidp ? "no" : "");
		for (i = 0; i < argc; i++)
			(void)printf(" %s", argv[i]);
		(void)printf("\n");
	}

	switch (pid = vfork()) {
	case -1:				/* Error. */
		warn("vfork");
		if (optbuf)
			free(optbuf);
		free(argv);
		return FSCK_EXIT_CHECK_FAILED;

	case 0:					/* Child. */
		if ((flags & CHECK_FORCE) == 0) {
			struct statvfs	sfs;

				/*
				 * if mntpt is a mountpoint of a mounted file
				 * system and it's mounted read-write, skip it
				 * unless -f is given.
				 */
			if ((statvfs(mntpt, &sfs) == 0) &&
			    (strcmp(mntpt, sfs.f_mntonname) == 0) &&
			    ((sfs.f_flag & MNT_RDONLY) == 0)) {
				printf(
		"%s: file system is mounted read-write on %s; not checking\n",
				    spec, mntpt);
				if ((flags & CHECK_PREEN) && auxarg != NULL)
					_exit(FSCK_EXIT_OK);	/* fsck -p */
				else
					_exit(FSCK_EXIT_CHECK_FAILED);	/* fsck [[-p] ...] */
			}
		}

		if (flags & CHECK_DEBUG)
			_exit(FSCK_EXIT_OK);

		/* Go find an executable. */
		edir = edirs;
		do {
			(void)snprintf(execname,
			    sizeof(execname), "%s/%s", *edir, execbase);
			execv(execname, (char * const *)__UNCONST(argv));
			if (errno != ENOENT) {
				if (spec)
					warn("exec %s for %s", execname, spec);
				else
					warn("exec %s", execname);
			}
		} while (*++edir != NULL);

		if (errno == ENOENT) {
			if (spec)
				warn("exec %s for %s", execname, spec);
			else
				warn("exec %s", execname);
		}
		_exit(FSCK_EXIT_CHECK_FAILED);
		/* NOTREACHED */

	default:				/* Parent. */
		if (optbuf)
			free(optbuf);
		free(argv);

		if (pidp) {
			*pidp = pid;
			return FSCK_EXIT_OK;
		}

		if (waitpid(pid, &status, 0) < 0) {
			warn("waitpid");
			return FSCK_EXIT_CHECK_FAILED;
		}

		if (WIFEXITED(status)) {
			if (WEXITSTATUS(status) != 0)
				return WEXITSTATUS(status);
		}
		else if (WIFSIGNALED(status)) {
			warnx("%s: %s", spec, strsignal(WTERMSIG(status)));
			return FSCK_EXIT_CHECK_FAILED;
		}
		break;
	}

	return FSCK_EXIT_OK;
}
Ejemplo n.º 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;
}
Ejemplo n.º 3
0
/*
 * get_tmp_disk - Return the total size of temporary file system on
 *    this system
 * Input: tmp_disk - buffer for the disk space size
 *        tmp_fs - pathname of the temporary file system to status,
 *		   defaults to "/tmp"
 * Output: tmp_disk - filled in with disk space size in MB, zero if error
 *         return code - 0 if no error, otherwise errno
 */
extern int
get_tmp_disk(uint32_t *tmp_disk, char *tmp_fs)
{
	int error_code = 0;

#if defined(HAVE_STATVFS)
	struct statvfs stat_buf;
	uint64_t total_size = 0;
	char *tmp_fs_name = tmp_fs;

	*tmp_disk = 0;
	total_size = 0;

	if (tmp_fs_name == NULL)
		tmp_fs_name = "/tmp";
	if (statvfs(tmp_fs_name, &stat_buf) == 0) {
		total_size = stat_buf.f_blocks * stat_buf.f_frsize;
		total_size /= 1024 * 1024;
	}
	else if (errno != ENOENT) {
		error_code = errno;
		error ("get_tmp_disk: error %d executing statvfs on %s",
			errno, tmp_fs_name);
	}
	*tmp_disk += (uint32_t)total_size;

#elif defined(HAVE_STATFS)
	struct statfs stat_buf;
	long   total_size;
	float page_size;
	char *tmp_fs_name = tmp_fs;

	*tmp_disk = 0;
	total_size = 0;
	page_size = (sysconf(_SC_PAGE_SIZE) / 1048576.0); /* MG per page */

	if (tmp_fs_name == NULL)
		tmp_fs_name = "/tmp";
#if defined (__sun)
	if (statfs(tmp_fs_name, &stat_buf, 0, 0) == 0) {
#else
	if (statfs(tmp_fs_name, &stat_buf) == 0) {
#endif
		total_size = (long)stat_buf.f_blocks;
	}
	else if (errno != ENOENT) {
		error_code = errno;
		error ("get_tmp_disk: error %d executing statfs on %s",
			errno, tmp_fs_name);
	}

	*tmp_disk += (uint32_t)(total_size * page_size);
#else
	*tmp_disk = 1;
#endif
	return error_code;
}

extern int get_up_time(uint32_t *up_time)
{
#if defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
	clock_t tm;
	struct tms buf;

	tm = times(&buf);
	if (tm == (clock_t) -1) {
		*up_time = 0;
		return errno;
	}

	*up_time = tm / sysconf(_SC_CLK_TCK);
#else
	/* NOTE for Linux: The return value of times() may overflow the
	 * possible range of type clock_t. There is also an offset of
	 * 429 million seconds on some implementations. We just use the
	 * simpler sysinfo() function instead. */
	struct sysinfo info;

	if (sysinfo(&info) < 0) {
		*up_time = 0;
		return errno;
	}


	if (conf->boot_time) {
		/* Make node look like it rebooted when slurmd started */
		static uint32_t orig_uptime = 0;
		if (orig_uptime == 0)
			orig_uptime = info.uptime;
		*up_time = info.uptime - orig_uptime;
	} else {
		*up_time = info.uptime;
	}
#endif
	return 0;
}
Ejemplo n.º 4
0
void getDisk() {
    struct statvfs root;
    statvfs("/", &root);
    remaining = root.f_bfree * root.f_bsize;
    getSizeUnit();
}
Ejemplo n.º 5
0
static bool below_threshold(struct statfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) {
#else
static bool below_threshold(struct statvfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) {
#endif
    if (strcasecmp(threshold_type, "percentage_free") == 0) {
        return 100.0 * (double)buf.f_bfree / (double)buf.f_blocks < low_threshold;
    } else if (strcasecmp(threshold_type, "percentage_avail") == 0) {
        return 100.0 * (double)buf.f_bavail / (double)buf.f_blocks < low_threshold;
    } else if (strcasecmp(threshold_type, "bytes_free") == 0) {
        return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold;
    } else if (strcasecmp(threshold_type, "bytes_avail") == 0) {
        return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold;
    } else if (threshold_type[0] != '\0' && strncasecmp(threshold_type + 1, "bytes_", strlen("bytes_")) == 0) {
        uint64_t base = strcasecmp(prefix_type, "decimal") == 0 ? DECIMAL_BASE : BINARY_BASE;
        double factor = 1;

        switch (threshold_type[0]) {
            case 'T':
            case 't':
                factor *= base;
            case 'G':
            case 'g':
                factor *= base;
            case 'M':
            case 'm':
                factor *= base;
            case 'K':
            case 'k':
                factor *= base;
                break;
            default:
                return false;
        }

        if (strcasecmp(threshold_type + 1, "bytes_free") == 0) {
            return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold * factor;
        } else if (strcasecmp(threshold_type + 1, "bytes_avail") == 0) {
            return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold * factor;
        }
    }

    return false;
}

/*
 * Does a statvfs and prints either free, used or total amounts of bytes in a
 * human readable manner.
 *
 */
void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *format_not_mounted, const char *prefix_type, const char *threshold_type, const double low_threshold) {
    const char *walk;
    char *outwalk = buffer;
    bool colorful_output = false;

    INSTANCE(path);

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__)
    struct statfs buf;

    if (statfs(path, &buf) == -1)
        return;
#else
    struct statvfs buf;

    if (statvfs(path, &buf) == -1)
        return;

    if (format_not_mounted != NULL) {
        FILE *mntentfile = setmntent("/etc/mtab", "r");
        struct mntent *m;
        bool found = false;

        while ((m = getmntent(mntentfile)) != NULL) {
            if (strcmp(m->mnt_dir, path) == 0) {
                found = true;
                break;
            }
        }
        endmntent(mntentfile);

        if (!found) {
            format = format_not_mounted;
        }
    }
#endif

    if (low_threshold > 0 && below_threshold(buf, prefix_type, threshold_type, low_threshold)) {
        START_COLOR("color_bad");
        colorful_output = true;
    }

    for (walk = format; *walk != '\0'; walk++) {
        if (*walk != '%') {
            *(outwalk++) = *walk;
            continue;
        }

        if (BEGINS_WITH(walk + 1, "free")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree, prefix_type);
            walk += strlen("free");
        }

        if (BEGINS_WITH(walk + 1, "used")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree), prefix_type);
            walk += strlen("used");
        }

        if (BEGINS_WITH(walk + 1, "total")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks, prefix_type);
            walk += strlen("total");
        }

        if (BEGINS_WITH(walk + 1, "avail")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail, prefix_type);
            walk += strlen("avail");
        }

        if (BEGINS_WITH(walk + 1, "percentage_free")) {
            outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bfree / (double)buf.f_blocks);
            walk += strlen("percentage_free");
        }

        if (BEGINS_WITH(walk + 1, "percentage_used_of_avail")) {
            outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bavail) / (double)buf.f_blocks);
            walk += strlen("percentage_used_of_avail");
        }

        if (BEGINS_WITH(walk + 1, "percentage_used")) {
            outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks);
            walk += strlen("percentage_used");
        }

        if (BEGINS_WITH(walk + 1, "percentage_avail")) {
            outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bavail / (double)buf.f_blocks);
            walk += strlen("percentage_avail");
        }
    }

    if (colorful_output)
        END_COLOR;

    *outwalk = '\0';
    OUTPUT_FULL_TEXT(buffer);
}
Ejemplo n.º 6
0
/*
 * Does a statvfs and prints either free, used or total amounts of bytes in a
 * human readable manner.
 *
 */
void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const int half_threshold, const int full_threshold) {
        const char *walk;
        char *outwalk = buffer;
        double usage=0;
        bool colorful_output = half_threshold>0 || full_threshold>0;

        INSTANCE(path);

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__)
        struct statfs buf;

        if (statfs(path, &buf) == -1)
                return;
#else
        struct statvfs buf;

        if (statvfs(path, &buf) == -1)
                return;
#endif

        if (colorful_output) {
                usage=100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks;
                if(usage>full_threshold) {
                        START_COLOR("color_bad");
                }
                else if(usage > half_threshold) {
                        START_COLOR("color_degraded");
                }
        }

        for (walk = format; *walk != '\0'; walk++) {
                if (*walk != '%') {
                        *(outwalk++) = *walk;
                        continue;
                }

                if (BEGINS_WITH(walk+1, "free")) {
                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree);
                        walk += strlen("free");
                }

                if (BEGINS_WITH(walk+1, "used")) {
                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree));
                        walk += strlen("used");
                }

                if (BEGINS_WITH(walk+1, "total")) {
                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks);
                        walk += strlen("total");
                }

                if (BEGINS_WITH(walk+1, "avail")) {
                        outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail);
                        walk += strlen("avail");
                }

                if (BEGINS_WITH(walk+1, "percentage_free")) {
                        outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bfree / (double)buf.f_blocks);
                        walk += strlen("percentage_free");
                }

                if (BEGINS_WITH(walk+1, "percentage_used_of_avail")) {
                        outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bavail) / (double)buf.f_blocks);
                        walk += strlen("percentage_used_of_avail");
                }

                if (BEGINS_WITH(walk+1, "percentage_used")) {
                        outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks);
                        walk += strlen("percentage_used");
                }

                if (BEGINS_WITH(walk+1, "percentage_avail")) {
                        outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bavail / (double)buf.f_blocks);
                        walk += strlen("percentage_avail");
                }
        }

        if(colorful_output) {
                END_COLOR;
        }

        *outwalk = '\0';
        OUTPUT_FULL_TEXT(buffer);
}
Ejemplo n.º 7
0
static int
getentropy_fallback(void *buf, size_t len)
{
	uint8_t results[SHA512_DIGEST_LENGTH];
	int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
	static int cnt;
	struct timespec ts;
	struct timeval tv;
	struct rusage ru;
	sigset_t sigset;
	struct stat st;
	SHA512_CTX ctx;
	static pid_t lastpid;
	pid_t pid;
	size_t i, ii, m;
	char *p;
	struct tcpstat tcpstat;
	struct udpstat udpstat;
	struct ipstat ipstat;
	u_int64_t mach_time;
	unsigned int idata;
	void *addr;

	pid = getpid();
	if (lastpid == pid) {
		faster = 1;
		repeat = 2;
	} else {
		faster = 0;
		lastpid = pid;
		repeat = REPEAT;
	}
	for (i = 0; i < len; ) {
		int j;
		SHA512_Init(&ctx);
		for (j = 0; j < repeat; j++) {
			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			mach_time = mach_absolute_time();
			HD(mach_time);

			ii = sizeof(addr);
			HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]),
			    &addr, &ii, NULL, 0) == -1, addr);

			ii = sizeof(idata);
			HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
			    &idata, &ii, NULL, 0) == -1, idata);

			ii = sizeof(tcpstat);
			HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
			    &tcpstat, &ii, NULL, 0) == -1, tcpstat);

			ii = sizeof(udpstat);
			HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]),
			    &udpstat, &ii, NULL, 0) == -1, udpstat);

			ii = sizeof(ipstat);
			HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
			    &ipstat, &ii, NULL, 0) == -1, ipstat);

			HX((pid = getpid()) == -1, pid);
			HX((pid = getsid(pid)) == -1, pid);
			HX((pid = getppid()) == -1, pid);
			HX((pid = getpgid(0)) == -1, pid);
			HX((e = getpriority(0, 0)) == -1, e);

			if (!faster) {
				ts.tv_sec = 0;
				ts.tv_nsec = 1;
				(void) nanosleep(&ts, NULL);
			}

			HX(sigpending(&sigset) == -1, sigset);
			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
			    sigset);

#if 0
			HF(main);		/* an addr in program */
#endif
			HF(getentropy);	/* an addr in this library */
			HF(printf);		/* an addr in libc */
			p = (char *)&p;
			HD(p);		/* an addr on stack */
			p = (char *)&errno;
			HD(p);		/* the addr of errno */

			if (i == 0) {
				struct sockaddr_storage ss;
				struct statvfs stvfs;
				struct termios tios;
				struct statfs stfs;
				socklen_t ssl;
				off_t off;

				/*
				 * Prime-sized mappings encourage fragmentation;
				 * thus exposing some address entropy.
				 */
				struct mm {
					size_t	npg;
					void	*p;
				} mm[] =	 {
					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
				};

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					HX(mm[m].p = mmap(NULL,
					    mm[m].npg * pgs,
					    PROT_READ|PROT_WRITE,
					    MAP_PRIVATE|MAP_ANON, -1,
					    (off_t)0), mm[m].p);
					if (mm[m].p != MAP_FAILED) {
						size_t mo;

						/* Touch some memory... */
						p = mm[m].p;
						mo = cnt %
						    (mm[m].npg * pgs - 1);
						p[mo] = 1;
						cnt += (int)((long)(mm[m].p)
						    / pgs);
					}

					/* Check cnts and times... */
					mach_time = mach_absolute_time();
					HD(mach_time);
					cnt += (int)mach_time;

					HX((e = getrusage(RUSAGE_SELF,
					    &ru)) == -1, ru);
					if (e != -1) {
						cnt += (int)ru.ru_utime.tv_sec;
						cnt += (int)ru.ru_utime.tv_usec;
					}
				}

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					if (mm[m].p != MAP_FAILED)
						munmap(mm[m].p, mm[m].npg * pgs);
					mm[m].p = MAP_FAILED;
				}

				HX(stat(".", &st) == -1, st);
				HX(statvfs(".", &stvfs) == -1, stvfs);
				HX(statfs(".", &stfs) == -1, stfs);

				HX(stat("/", &st) == -1, st);
				HX(statvfs("/", &stvfs) == -1, stvfs);
				HX(statfs("/", &stfs) == -1, stfs);

				HX((e = fstat(0, &st)) == -1, st);
				if (e == -1) {
					if (S_ISREG(st.st_mode) ||
					    S_ISFIFO(st.st_mode) ||
					    S_ISSOCK(st.st_mode)) {
						HX(fstatvfs(0, &stvfs) == -1,
						    stvfs);
						HX(fstatfs(0, &stfs) == -1,
						    stfs);
						HX((off = lseek(0, (off_t)0,
						    SEEK_CUR)) < 0, off);
					}
					if (S_ISCHR(st.st_mode)) {
						HX(tcgetattr(0, &tios) == -1,
						    tios);
					} else if (S_ISSOCK(st.st_mode)) {
						memset(&ss, 0, sizeof ss);
						ssl = sizeof(ss);
						HX(getpeername(0,
						    (void *)&ss, &ssl) == -1,
						    ss);
					}
				}

				HX((e = getrusage(RUSAGE_CHILDREN,
				    &ru)) == -1, ru);
				if (e != -1) {
					cnt += (int)ru.ru_utime.tv_sec;
					cnt += (int)ru.ru_utime.tv_usec;
				}
			} else {
				/* Subsequent hashes absorb previous result */
				HD(results);
			}

			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			HD(cnt);
		}

		SHA512_Final(results, &ctx);
		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
		i += min(sizeof(results), len - i);
	}
	memset(results, 0, sizeof results);
	if (gotdata(buf, len) == 0) {
		errno = save_errno;
		return 0;		/* satisfied */
	}
	errno = EIO;
	return -1;
}
Ejemplo n.º 8
0
/*
 * Create a snapshot of the file system currently mounted on the first argument
 * using the second argument as backing store and return an open file
 * descriptor for the snapshot.  If the second argument is NULL, use the first
 * as backing store.  If the third argument is not NULL, it gets the time the
 * snapshot was created.  If the fourth argument is not NULL, it gets the
 * snapshot device path.
 */
int
snap_open(char *file, char *backup, time_t *snap_date, char **snap_dev)
{
	int i, n, fd, israw, fsinternal, dounlink;
	char path[MAXPATHLEN], fss_dev[14], *cp;
	dev_t mountdev;
	struct fss_set fss;
	struct fss_get fsg;
	struct stat sb;
	struct statvfs *mntbuf, *fs, fsb;

	dounlink = 0;
	fd = -1;
	mntbuf = NULL;

	/*
	 * Lookup the mount point. `file' is either a directory or a raw
	 * character device.
	 */
	if (lstat(file, &sb) < 0)
		goto fail;
	fss.fss_mount = NULL;
	if (S_ISCHR(sb.st_mode)) {
		if ((cp = strrchr(file, '/')) == NULL || cp[1] != 'r') {
			errno = EINVAL;
			goto fail;
		}
		snprintf(path, sizeof(path), "%.*s/%s",
		    (int)(cp - file), file, cp + 2);
		n = getmntinfo(&mntbuf, MNT_NOWAIT);
		for (fs = mntbuf, i = 0; i < n; i++, fs++) {
			if (strcmp(fs->f_mntfromname, path) == 0) {
				fss.fss_mount = fs->f_mntonname;
				if (stat(fss.fss_mount, &sb) < 0)
					goto fail;
				break;
			}
		}
	} else if (S_ISDIR(sb.st_mode))
		fss.fss_mount = file;
	if (fss.fss_mount == NULL) {
		errno = EINVAL;
		goto fail;
	}
	fss.fss_bstore = backup ? backup : fss.fss_mount;
	fss.fss_csize = 0;
	mountdev = sb.st_dev;

	/*
	 * Prepare the backing store. `backup' is either a raw device,
	 * a file or a directory.  If it is a file, it must not exist.
	 */
	israw = 0;
	if (stat(fss.fss_bstore, &sb) == 0) {
		if (S_ISDIR(sb.st_mode)) {
			snprintf(path, sizeof(path),
			    "%s/XXXXXXXXXX", fss.fss_bstore);
			fd = mkstemp(path);
			fss.fss_bstore = path;
			dounlink = 1;
		} else if (S_ISCHR(sb.st_mode)) {
			fd = open(fss.fss_bstore, O_RDWR);
			israw = 1;
		} else
			goto fail;
	} else {
		fd = open(fss.fss_bstore, O_CREAT|O_EXCL|O_WRONLY, 0600);
		dounlink = 1;
	}
	if (fd < 0)
		goto fail;

	if (fstat(fd, &sb) < 0)
		goto fail;
	fsinternal = (!israw && sb.st_dev == mountdev);

	/*
	 * If the backing store is a plain file and the snapshot
	 * is not file system internal, truncate to file system
	 * free space.
	 */
	if (!israw && !fsinternal) {
		if (statvfs(fss.fss_bstore, &fsb) < 0)
			goto fail;
		if (ftruncate(fd, (off_t)fsb.f_frsize*fsb.f_bavail) < 0)
			goto fail;
	}

	if (close(fd) < 0)
		goto fail;

	fss.fss_flags = FSS_UNCONFIG_ON_CLOSE;
	if (dounlink)
		fss.fss_flags |= FSS_UNLINK_ON_CREATE;
	/*
	 * Create the snapshot on the first free snapshot device.
	 */
	for (i = 0; ; i++) {
		snprintf(fss_dev, sizeof(fss_dev), "/dev/rfss%d", i);
		if ((fd = open(fss_dev, O_RDWR, 0)) < 0)
			goto fail;

		if (ioctl(fd, FSSIOCSET, &fss) < 0) {
			if (errno != EBUSY)
				goto fail;
			close(fd);
			fd = -1;
			continue;
		}
		dounlink = 0;

		if (snap_dev != NULL) {
			*snap_dev = strdup(fss_dev);
			if (*snap_dev == NULL) {
				ioctl(fd, FSSIOCCLR);
				goto fail;
			}
		}

		if (ioctl(fd, FSSIOCGET, &fsg) < 0) {
			ioctl(fd, FSSIOCCLR);
			goto fail;
		}

		if (mntbuf)
			free(mntbuf);
		if (snap_date != NULL)
			*snap_date = fsg.fsg_time.tv_sec;
		return fd;
	}

fail:
	if (mntbuf)
		free(mntbuf);
	if (dounlink)
		unlink(fss.fss_bstore);
	if (fd >= 0)
		close(fd);

	return -1;
}
Ejemplo n.º 9
0
static int
getentropy_fallback(void *buf, size_t len)
{
	uint8_t results[SHA512_DIGEST_LENGTH];
	int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat;
	static int cnt;
	struct timespec ts;
	struct timeval tv;
	struct pst_vminfo pvi;
	struct pst_vm_status pvs;
	struct pst_dynamic pdy;
	struct rusage ru;
	sigset_t sigset;
	struct stat st;
	SHA512_CTX ctx;
	static pid_t lastpid;
	pid_t pid;
	size_t i, ii, m;
	char *p;

	pid = getpid();
	if (lastpid == pid) {
		faster = 1;
		repeat = 2;
	} else {
		faster = 0;
		lastpid = pid;
		repeat = REPEAT;
	}
	for (i = 0; i < len; ) {
		int j;
		SHA512_Init(&ctx);
		for (j = 0; j < repeat; j++) {
			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			HX(pstat_getvminfo(&pvi, sizeof(pvi), 1, 0) != 1, pvi);
			HX(pstat_getprocvm(&pvs, sizeof(pvs), 0, 0) != 1, pvs);

			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
				HX(clock_gettime(cl[ii], &ts) == -1, ts);

			HX((pid = getpid()) == -1, pid);
			HX((pid = getsid(pid)) == -1, pid);
			HX((pid = getppid()) == -1, pid);
			HX((pid = getpgid(0)) == -1, pid);
			HX((e = getpriority(0, 0)) == -1, e);

			if(pstat_getdynamic(&pdy, sizeof(pdy), 1, 0) != 1) {
				HD(errno);
			} else {
				HD(pdy.psd_avg_1_min);
				HD(pdy.psd_avg_5_min);
				HD(pdy.psd_avg_15_min);
			}

			if (!faster) {
				ts.tv_sec = 0;
				ts.tv_nsec = 1;
				(void) nanosleep(&ts, NULL);
			}

			HX(sigpending(&sigset) == -1, sigset);
			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
			    sigset);

			HF(getentropy);	/* an addr in this library */
			HF(printf);		/* an addr in libc */
			p = (char *)&p;
			HD(p);		/* an addr on stack */
			p = (char *)&errno;
			HD(p);		/* the addr of errno */

			if (i == 0) {
				struct sockaddr_storage ss;
				struct statvfs stvfs;
				struct termios tios;
				socklen_t ssl;
				off_t off;

				/*
				 * Prime-sized mappings encourage fragmentation;
				 * thus exposing some address entropy.
				 */
				struct mm {
					size_t	npg;
					void	*p;
				} mm[] =	 {
					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
				};

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					HX(mm[m].p = mmap(NULL,
					    mm[m].npg * pgs,
					    PROT_READ|PROT_WRITE,
					    MAP_PRIVATE|MAP_ANON, -1,
					    (off_t)0), mm[m].p);
					if (mm[m].p != MAP_FAILED) {
						size_t mo;

						/* Touch some memory... */
						p = mm[m].p;
						mo = cnt %
						    (mm[m].npg * pgs - 1);
						p[mo] = 1;
						cnt += (int)((long)(mm[m].p)
						    / pgs);
					}

					/* Check cnts and times... */
					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
					    ii++) {
						HX((e = clock_gettime(cl[ii],
						    &ts)) == -1, ts);
						if (e != -1)
							cnt += (int)ts.tv_nsec;
					}

					HX((e = getrusage(RUSAGE_SELF,
					    &ru)) == -1, ru);
					if (e != -1) {
						cnt += (int)ru.ru_utime.tv_sec;
						cnt += (int)ru.ru_utime.tv_usec;
					}
				}

				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
					if (mm[m].p != MAP_FAILED)
						munmap(mm[m].p, mm[m].npg * pgs);
					mm[m].p = MAP_FAILED;
				}

				HX(stat(".", &st) == -1, st);
				HX(statvfs(".", &stvfs) == -1, stvfs);

				HX(stat("/", &st) == -1, st);
				HX(statvfs("/", &stvfs) == -1, stvfs);

				HX((e = fstat(0, &st)) == -1, st);
				if (e == -1) {
					if (S_ISREG(st.st_mode) ||
					    S_ISFIFO(st.st_mode) ||
					    S_ISSOCK(st.st_mode)) {
						HX(fstatvfs(0, &stvfs) == -1,
						    stvfs);
						HX((off = lseek(0, (off_t)0,
						    SEEK_CUR)) < 0, off);
					}
					if (S_ISCHR(st.st_mode)) {
						HX(tcgetattr(0, &tios) == -1,
						    tios);
					} else if (S_ISSOCK(st.st_mode)) {
						memset(&ss, 0, sizeof ss);
						ssl = sizeof(ss);
						HX(getpeername(0,
						    (void *)&ss, &ssl) == -1,
						    ss);
					}
				}

				HX((e = getrusage(RUSAGE_CHILDREN,
				    &ru)) == -1, ru);
				if (e != -1) {
					cnt += (int)ru.ru_utime.tv_sec;
					cnt += (int)ru.ru_utime.tv_usec;
				}
			} else {
				/* Subsequent hashes absorb previous result */
				HD(results);
			}

			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
			if (e != -1) {
				cnt += (int)tv.tv_sec;
				cnt += (int)tv.tv_usec;
			}

			HD(cnt);
		}
		SHA512_Final(results, &ctx);
		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
		i += min(sizeof(results), len - i);
	}
	explicit_bzero(&ctx, sizeof ctx);
	explicit_bzero(results, sizeof results);
	if (gotdata(buf, len) == 0) {
		errno = save_errno;
		return 0;		/* satisfied */
	}
	errno = EIO;
	return -1;
}
Ejemplo n.º 10
0
static void *kqemu_vmalloc(size_t size)
{
    static int phys_ram_fd = -1;
    static int phys_ram_size = 0;
    void *ptr;

/* no need (?) for a dummy file on OpenBSD/FreeBSD */
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
    int map_anon = MAP_ANON;
#else
    int map_anon = 0;
    const char *tmpdir;
    char phys_ram_file[1024];
#ifdef HOST_SOLARIS
    struct statvfs stfs;
#else
    struct statfs stfs;
#endif

    if (phys_ram_fd < 0) {
        tmpdir = getenv("QEMU_TMPDIR");
        if (!tmpdir)
#ifdef HOST_SOLARIS
            tmpdir = "/tmp";
        if (statvfs(tmpdir, &stfs) == 0) {
#else
            tmpdir = "/dev/shm";
        if (statfs(tmpdir, &stfs) == 0) {
#endif
            int64_t free_space;
            int ram_mb;

            free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
            if ((ram_size + 8192 * 1024) >= free_space) {
                ram_mb = (ram_size / (1024 * 1024));
                fprintf(stderr,
                        "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
                        tmpdir, ram_mb);
                if (strcmp(tmpdir, "/dev/shm") == 0) {
                    fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
                            "mount -o remount,size=%dm /dev/shm\n",
                            ram_mb + 16);
                } else {
                    fprintf(stderr,
                            "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
                            "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
                            "temporary RAM file will be opened.\n");
                }
                fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
                exit(1);
            }
        }
        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
                 tmpdir);
        phys_ram_fd = mkstemp(phys_ram_file);
        if (phys_ram_fd < 0) {
            fprintf(stderr,
                    "warning: could not create temporary file in '%s'.\n"
                    "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
                    "Using '/tmp' as fallback.\n",
                    tmpdir);
            snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
                     "/tmp");
            phys_ram_fd = mkstemp(phys_ram_file);
            if (phys_ram_fd < 0) {
                fprintf(stderr, "Could not create temporary memory file '%s'\n",
                        phys_ram_file);
                exit(1);
            }
        }
        unlink(phys_ram_file);
    }
    size = (size + 4095) & ~4095;
    ftruncate(phys_ram_fd, phys_ram_size + size);
#endif /* !(__OpenBSD__ || __FreeBSD__ || __DragonFly__) */
    ptr = mmap(NULL,
               size,
               PROT_WRITE | PROT_READ, map_anon | MAP_SHARED,
               phys_ram_fd, phys_ram_size);
    if (ptr == MAP_FAILED) {
        fprintf(stderr, "Could not map physical memory\n");
        exit(1);
    }
    phys_ram_size += size;
    return ptr;
}

static void kqemu_vfree(void *ptr)
{
    /* may be useful some day, but currently we do not need to free */
}

#endif

void *qemu_memalign(size_t alignment, size_t size)
{
#if defined(_POSIX_C_SOURCE)
    int ret;
    void *ptr;
    ret = posix_memalign(&ptr, alignment, size);
    if (ret != 0)
        return NULL;
    return ptr;
#elif defined(HOST_BSD)
    return valloc(size);
#else
    return memalign(alignment, size);
#endif
}
Ejemplo n.º 11
0
void *
save_crashdump(void *arg)
{
	struct mic_info *mic = (struct mic_info *)arg;
	struct mpssd_info *mpssdi = (struct mpssd_info *)mic->data;
	int cdfd = -1;
	int procfd = -1;
	void *addr = NULL;
	ssize_t bytes;
	ssize_t total_bytes = 0;
	ssize_t dirlimit;
	ssize_t diractual;
	struct tm *tm = NULL;
	char pathname[PATH_MAX];
	time_t t;
	pid_t pid1 = 0;
	char *state;
	char *save;
	struct stat sbuf;
	struct statvfs vbuf;
	int err;

	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	if ((dirlimit = atoi(CD_LIMIT) * (1024 * 1024 * 1024ULL)) == 0) {
		mpsslog(PWARN, "%s: [SaveCrashDump] Dump disabled\n", mic->name);
		goto reboot;
	}

	if (stat(CD_DIR, &sbuf) < 0) {
		if (mkdir(CD_DIR, 0755) < 0) {
			mpsslog(PWARN, "%s: [SaveCrashDump] Avborted - create directory %s failed: %s\n",
					mic->name, CD_DIR, strerror(errno));
			goto reboot;
		}

		diractual = dirlimit;
	} else {	/* Check size of crash directory with configured limits */
		if ((diractual = get_dir_size(mic, CD_DIR)) < 0) {
			mpsslog(PINFO, "%s: [SaveCrashDump] Avborted - get directory %s size failed: %s\n",
					mic->name, CD_DIR, strerror(errno));
			goto reboot;
		}
	}

	if (diractual > dirlimit) {
		mpsslog(PINFO, "%s: [SaveCrashDump] Avborted - %s current size 0x%lx configured limit 0x%lx\n",
			mic->name, CD_DIR, diractual, dirlimit);
		goto reboot;
	}

	/* Open core dump file with time details embedded in file name */
	time(&t);
	if ((tm = localtime(&t)) == 0) {
		mpsslog(PERROR, "%s: [SaveCrashdump] Aborted - get system date failed\n", mic->name);
		goto reboot;
	}

	/* Create crash directories if not done already */
	snprintf(pathname, PATH_MAX - 1, "%s/%s", CD_DIR, mic->name);
	if (mkdir(pathname, 0755) && errno != EEXIST) {
		mpsslog(PERROR, "%s: [SaveCrashDump] Aborted - create directory %s failed %s\n",
					mic->name, pathname, strerror(errno));
		goto reboot;
	}

	if (statvfs(pathname, &vbuf) < 0) {
		mpsslog(PERROR, "%s: [SaveCrashDump] Aborted - cannot read free disk size of %s: %s\n",
					mic->name, pathname, strerror(errno));
		goto reboot;
	}

	if (CD_MIN_DISK > (vbuf.f_bsize * vbuf.f_bfree)) {
		mpsslog(PERROR, "%s: [SaveCrashDump] Aborted - free disk space less than required 32Gb\n", mic->name);
		goto reboot;
	}

	/* Open vmcore entry for crashed card */
	snprintf(pathname, PATH_MAX - 1, "/proc/mic_vmcore/%s", mic->name);
	if ((procfd = open(pathname, O_RDONLY)) < 0) {
		mpsslog(PERROR, "%s: [SaveCrashdump] Aborted - open %s failed: %s\n",
					mic->name, pathname, strerror(errno));
		goto reboot;
	}

	snprintf(pathname, PATH_MAX - 1, "%s/%s/vmcore-%d-%d-%d-%d:%d:%d", CD_DIR, mic->name,
			tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
			tm->tm_hour, tm->tm_min, tm->tm_sec);

	if ((cdfd = open(pathname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
		mpsslog(PERROR, "%s: [SaveCrashDump] Aborted - open %s failed %s\n",
					mic->name, pathname, strerror(errno));
		goto cleanup1;
	}

	mpsslog(PINFO, "%s: [SaveCrashDump] Capturing uOS kernel crash dump\n", mic->name);

	/* Read from the proc entry and write to the core dump file */
	do {
		if (lseek(cdfd, CD_READ_CHUNK, SEEK_CUR) < 0) {
			mpsslog(PERROR, "%s: [SaveCrashDump] Aborted lseek failed %s\n", mic->name, strerror(errno));
			remove(pathname);
			goto cleanup2;
		}

		bytes = write(cdfd, "", 1);
		if (bytes != 1) {
			mpsslog(PERROR, "%s: [SaveCrashDump] Aborted write failed %s\n", mic->name, strerror(errno));
			remove(pathname);
			goto cleanup2;
		}

		if ((addr = mmap(NULL, CD_READ_CHUNK, PROT_READ|PROT_WRITE,
					MAP_SHARED, cdfd, total_bytes)) == MAP_FAILED) {
			mpsslog(PERROR, "%s: [SaveCrasdDump] Aborted mmap failed %s\n", mic->name, strerror(errno));
			remove(pathname);
			goto cleanup2;
		}

		if ((bytes = read(procfd, addr, CD_READ_CHUNK)) < 0) {
			mpsslog(PERROR, "%s: [SaveCrashDump] Aborted read failed %s\n", mic->name, strerror(errno));
			remove(pathname);
			munmap(addr, CD_READ_CHUNK);
			goto cleanup2;
		}

		total_bytes += bytes;
		munmap(addr, CD_READ_CHUNK);
		if (ftruncate(cdfd, total_bytes + 1) < 0) {
			mpsslog(PERROR, "%s: [SaveCrashDump] Aborted ftruncate failed %s\n", mic->name, strerror(errno));
			remove(pathname);
			goto cleanup2;
		}
	} while (bytes == CD_READ_CHUNK);

	mpsslog(PNORM, "%s: [SaveCrashDump] Completed raw dump size 0x%lx\n", mic->name, total_bytes);
	mpsslog(PNORM, "%s: [SaveCrashDump] Gzip started\n", mic->name);
	pid1 = gzip(pathname); /* Initiate compression of the file and reset MIC in parallel */


cleanup2:
	close(cdfd);

cleanup1:
	close(procfd);

reboot:
	if ((err = mpss_setsysfs(mic->name, "state", "reset:force")) != 0) {
		mpsslog(PINFO, "%s: [SaveCrashDump] Failed to set state sysfs - cannot reset: %s\n",
				mic->name, strerror(err));
		goto done;
	}

	if ((state = mpss_readsysfs(mic->name, "state")) == NULL) {
		mpsslog(PINFO, "%s: [SaveCrashDump] Failed to read state sysfs - state of reset unknown\n", mic->name);
		goto done;
	}

	while (strcmp(state, "ready") && strcmp(state, "reset failed")) {
		if (!strcmp(state, "online") || !strcmp(state, "booting")) {
			mpsslog(PINFO, "%s: [SaveCrashDump] External entity has already rebooted card\n", mic->name);
			free(state);
			goto done;
		}

		mpsslog(PINFO, "%s: [SaveCrashDump] Waiting for reset\n", mic->name);
		sleep(2);
		save = state;

		if ((state = mpss_readsysfs(mic->name, "state")) == NULL) {
			mpsslog(PWARN, "%s: [SaveCrashDump] wait for ready failed to read state sysfs - try again\n",
					mic->name);
			state = save;
		} else {
			free(save);
		}
	}

	if (strcmp(state, "ready")) {
		mpsslog(PERROR, "%s: [SaveCrashDump] Failed to reset card.  Aborting reboot\n", mic->name);
		free(state);
		goto done;
	}

	if (pid1 && (pid1 < 0 || ((waitpid(pid1, NULL, 0)) < 0)))
		remove(pathname);

	if (autoreboot(mic)) {
		while (pthread_mutex_lock(&start_lock) != 0);
		start_count++;
		while (pthread_mutex_lock(&mpssdi->pth_lock) != 0);
		pthread_create(&mpssdi->boot_pth, NULL, boot_mic, mic);
		while (pthread_mutex_unlock(&mpssdi->pth_lock) != 0);
		while (pthread_mutex_unlock(&start_lock) != 0);
	}
done:
	pthread_exit(NULL);
}
Ejemplo n.º 12
0
static off_t Unix_GetDiskUsage(char *file, enum cfsizes type)
{
# if defined SOLARIS || defined OSF || defined UNIXWARE || defined OPENBSD || (defined(__NetBSD__) && __NetBSD_Version__ >= 200040000)
    struct statvfs buf;
# elif defined ULTRIX
    struct fs_data buf;
# else
    struct statfs buf;
# endif
    off_t used = 0, avail = 0;
    int capacity = 0;

    memset(&buf, 0, sizeof(buf));

# if defined ULTRIX
    if (getmnt(NULL, &buf, sizeof(struct fs_data), STAT_ONE, file) == -1)
    {
        CfOut(cf_error, "getmnt", "Couldn't get filesystem info for %s\n", file);
        return CF_INFINITY;
    }
# elif defined SOLARIS || defined OSF || defined UNIXWARE || (defined(__NetBSD__) && __NetBSD_Version__ >= 200040000)
    if (statvfs(file, &buf) != 0)
    {
        CfOut(cf_error, "statvfs", "Couldn't get filesystem info for %s\n", file);
        return CF_INFINITY;
    }
# elif defined IRIX || defined SCO || defined CFCRAY || (defined(__NetBSD__) && __NetBSD_Version__ >= 200040000)
    if (statfs(file, &buf, sizeof(struct statfs), 0) != 0)
    {
        CfOut(cf_error, "statfs", "Couldn't get filesystem info for %s\n", file);
        return CF_INFINITY;
    }
# else
    if (statfs(file, &buf) != 0)
    {
        CfOut(cf_error, "statfs", "Couldn't get filesystem info for %s\n", file);
        return CF_INFINITY;
    }
# endif

# if defined ULTRIX
    used = buf.fd_btot - buf.fd_bfree;
    avail = buf.fd_bfreen;
# endif

# if defined SOLARIS || defined OSF
    used = (buf.f_blocks - buf.f_bfree) * buf.f_frsize;
    avail = buf.f_bavail * buf.f_frsize;
# endif

# if defined NETBSD || defined FREEBSD || defined OPENBSD || defined SUNOS || defined HPuUX || defined DARWIN
    used = (buf.f_blocks - buf.f_bfree) * buf.f_bsize;
    avail = buf.f_bavail * buf.f_bsize;
# endif

# if defined AIX || defined SCO || defined CFCRAY
    used = (buf.f_blocks - buf.f_bfree) * (float) buf.f_bsize;
    avail = buf.f_bfree * (float) buf.f_bsize;
# endif

# if defined LINUX
    used = (buf.f_blocks - buf.f_bfree) * (float) buf.f_bsize;
    avail = buf.f_bavail * (float) buf.f_bsize;
# endif

# if defined IRIX
/* Float fix by [email protected] */
    used = (buf.f_blocks - buf.f_bfree) * (float) buf.f_bsize;
    avail = buf.f_bfree * (float) buf.f_bsize;
# endif

    capacity = (double) (avail) / (double) (avail + used) * 100;

    CfDebug("GetDiskUsage(%s) = %jd/%jd\n", file, (intmax_t) avail, (intmax_t) capacity);

    if (type == cfabs)
    {
        return avail;
    }
    else
    {
        return capacity;
    }
}
Ejemplo n.º 13
0
int parse_mounts(const glightui *gui,const char *fn){
	char *mnt,*dev,*ops,*fs;
	off_t len,idx;
	char *map;
	int fd;

	if((map = map_virt_file(fn,&fd,&len)) == MAP_FAILED){
		return -1;
	}
	idx = 0;
	dev = mnt = fs = ops = NULL;
	while(idx < len){
		char buf[PATH_MAX + 1];
		struct statvfs vfs;
		struct stat st;
		device *d;
		char *rp;
		int r;

		free(dev); free(mnt); free(fs); free(ops);
		if((r = parse_mount(map + idx,len - idx,&dev,&mnt,&fs,&ops)) < 0){
			goto err;
		}
		idx += r;
		if(statvfs(mnt,&vfs)){
			int skip = 0;

			// We might have mounted a new target atop or above an
			// already existing one, in which case we'll need
			// possibly recreate the directory structure on the
			// newly-mounted filesystem.
			if(growlight_target){
				if(strncmp(mnt,growlight_target,strlen(growlight_target)) == 0){
					if(make_parent_directories(mnt) == 0){
						skip = 1;
					} // FIXME else remount? otherwise writes
					// go to new filesystem rather than old...?
				}
			}
			if(!skip){
				diag("Couldn't stat fs %s (%s?)\n",mnt,strerror(errno));
				r = -1;
				continue;
			}
		}
		if(*dev != '/'){ // have to get zfs's etc
			if(fstype_virt_p(fs)){
				continue;
			}
			if((d = lookup_device(dev)) == NULL){
				verbf("virtfs %s at %s\n",fs,mnt);
				continue;
			}
		}else{
			rp = dev;
			if(lstat(rp,&st) == 0){
				if(S_ISLNK(st.st_mode)){
					if((r = readlink(dev,buf,sizeof(buf))) < 0){
						diag("Couldn't deref %s (%s?)\n",dev,strerror(errno));
						continue;
					}
					if((size_t)r >= sizeof(buf)){
						diag("Name too long for %s (%d?)\n",dev,r);
						continue;
					}
					buf[r] = '\0';
					rp = buf;
				}
			}
			if((d = lookup_device(rp)) == NULL){
				continue;
			}
		}
		free(dev);
		dev = NULL;
		if(d->mnttype && strcmp(d->mnttype,fs)){
			diag("Already had mounttype for %s: %s (got %s)\n",
					d->name,d->mnttype,fs);
			free(d->mnttype);
			d->mnttype = NULL;
			free_stringlist(&d->mntops);
			free_stringlist(&d->mnt);
			d->mnttype = fs;
		}else{
			free(fs);
		}
		fs = NULL;
		if(add_string(&d->mnt,mnt)){
			goto err;
		}
		if(add_string(&d->mntops,ops)){
			goto err;
		}
		d->mntsize = (uintmax_t)vfs.f_bsize * vfs.f_blocks;
		if(d->layout == LAYOUT_PARTITION){
			d = d->partdev.parent;
		}
		d->uistate = gui->block_event(d,d->uistate);
		if(growlight_target){
			if(strcmp(mnt,growlight_target) == 0){
				mount_target();
			}
		}
	}
	free(mnt); free(fs); free(ops);
	mnt = fs = ops = NULL;
	munmap_virt(map,len);
	close(fd);
	return 0;

err:
	free(dev); free(mnt); free(fs); free(ops);
	munmap_virt(map,len);
	close(fd);
	return -1;
}
Ejemplo n.º 14
0
static int collect_item(probe_ctx *ctx, oval_version_t over, struct mntent *mnt_ent)
#endif
{
        SEXP_t *item;
        char   *uuid = "", *tok, *save = NULL, **mnt_opts = NULL;
        uint8_t mnt_ocnt;
        struct statvfs stvfs;

        /*
         * Get FS stats
         */
        if (statvfs(mnt_ent->mnt_dir, &stvfs) != 0)
                return (-1);

        /*
         * Get UUID
         */
#if defined(HAVE_BLKID_GET_TAG_VALUE)
        uuid = blkid_get_tag_value(blkcache, "UUID", mnt_ent->mnt_fsname);
        if (uuid == NULL) {
	        uuid = "";
        }
#endif
        /*
         * Create a NULL-terminated array from the mount options
         */
        mnt_ocnt = 0;

        tok = strtok_r(mnt_ent->mnt_opts, ",", &save);

        do {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, tok);
        } while ((tok = strtok_r(NULL, ",", &save)) != NULL);

        /*
         * Check for "remount", "bind" and "move" mount options
         * These options can't be found in /proc/mounts,
         * we must use flags got by statvfs().
         */
        if (stvfs.f_flag & MS_REMOUNT) {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, "remount");
        }
        if (stvfs.f_flag & MS_BIND) {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, "bind");
        }
        if (stvfs.f_flag & MS_MOVE) {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, "move");
        }

        dI("mnt_ocnt = %d, mnt_opts[mnt_ocnt]=%p\n", mnt_ocnt, mnt_opts[mnt_ocnt]);

	/*
	 * "Correct" the type (this won't be (hopefully) needed in a later version
	 * of OVAL)
	 */
        if (oval_version_cmp(over, OVAL_VERSION(5.10)) < 0)
	        mnt_ent->mnt_type = (char *)correct_fstype(mnt_ent->mnt_type);

        /*
         * Create the item
         */
        item = probe_item_create(OVAL_LINUX_PARTITION, NULL,
                                 "mount_point",   OVAL_DATATYPE_STRING,   mnt_ent->mnt_dir,
                                 "device",        OVAL_DATATYPE_STRING,   mnt_ent->mnt_fsname,
                                 "uuid",          OVAL_DATATYPE_STRING,   uuid,
                                 "fs_type",       OVAL_DATATYPE_STRING,   mnt_ent->mnt_type,
                                 "mount_options", OVAL_DATATYPE_STRING_M, mnt_opts,
                                 "total_space",   OVAL_DATATYPE_INTEGER, (int64_t)stvfs.f_blocks,
                                 "space_used",    OVAL_DATATYPE_INTEGER, (int64_t)(stvfs.f_blocks - stvfs.f_bfree),
                                 "space_left",    OVAL_DATATYPE_INTEGER, (int64_t)stvfs.f_bfree,
                                 NULL);

#if defined(HAVE_BLKID_GET_TAG_VALUE)
        /*
         * If the partition doesn't have an UUID assigned, set the uuid entity status to
         * "does not exist" which means that the value was collected but does not exist
         * on the system.
         */
        if (strcmp(uuid, "") == 0) {
	        probe_itement_setstatus(item, "uuid", 1, SYSCHAR_STATUS_DOES_NOT_EXIST);
        }
#else
	/* Compiled without blkid library, we don't collect UUID */
	probe_itement_setstatus(item, "uuid", 1, SYSCHAR_STATUS_NOT_COLLECTED);
#endif /* HAVE_BLKID_GET_TAG_VALUE */

        probe_item_collect(ctx, item);
        oscap_free(mnt_opts);

        return (0);
}
Ejemplo n.º 15
0
/** Estimate the potential payload capacity of a file address.
    @param path  The address of the file to be examined. If it does not
                 exist yet, then the directory will be inquired.
    @param bytes This value gets modified if an estimation is possible
    @return      -2 = cannot perform necessary operations on file object
                 -1 = neither path nor dirname of path exist
                  0 = could not estimate size capacity of file object
                  1 = estimation has been made, bytes was set
*/
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{
	struct stat stbuf;
	struct statvfs vfsbuf;
	char *testpath = NULL, *cpt;
	off_t add_size = 0;
	int fd, ret;

	BURN_ALLOC_MEM(testpath, char, 4096);
	testpath[0] = 0;
	if (stat(path, &stbuf) == -1) {
		strcpy(testpath, path);
		cpt = strrchr(testpath, '/');
		if(cpt == NULL)
			strcpy(testpath, ".");
		else if(cpt == testpath)
			testpath[1] = 0;
		else
			*cpt = 0;
		if (stat(testpath, &stbuf) == -1)
			{ret = -1; goto ex;}

#ifdef Libburn_if_this_was_linuX

	} else if(S_ISBLK(stbuf.st_mode)) {
		int open_mode = O_RDWR, fd, ret;
		long blocks;

		blocks = *bytes / 512;
		if(burn_sg_open_o_excl)
			open_mode |= O_EXCL;
		fd = open(path, open_mode);
		if (fd == -1)
			{ret = -2; goto ex;}
		ret = ioctl(fd, BLKGETSIZE, &blocks);
		close(fd);
		if (ret == -1)
			{ret = -2; goto ex;}
		*bytes = ((off_t) blocks) * (off_t) 512;

#endif /* Libburn_if_this_was_linuX */


	} else if(S_ISCHR(stbuf.st_mode)) {
		fd = open(path, O_RDONLY);
		if (fd == -1)
			{ret = -2; goto ex;}
		ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
		close(fd);
		if (ret == -1)
			{ret = -2; goto ex;}
		*bytes = add_size;
	} else if(S_ISREG(stbuf.st_mode)) {
		add_size = burn_sparse_file_addsize(write_start, &stbuf);
		strcpy(testpath, path);
	} else
		{ret = 0; goto ex;}

	if (testpath[0]) {	
		if (statvfs(testpath, &vfsbuf) == -1)
			{ret = -2; goto ex;}
		*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
						(off_t) vfsbuf.f_bavail;
	}
	ret = 1;
ex:
	BURN_FREE_MEM(testpath);
	return ret;
}
Ejemplo n.º 16
0
unsigned char *var_extensible_disk(struct variable *vp,
				   oid *name,
				   int *length,
				   int exact,
				   int *var_len,
				   WriteMethod **write_method)
{

  int percent, iserror, disknum=0;
#if !defined(HAVE_SYS_STATVFS_H) && !defined(HAVE_STATFS)
  double totalblks, free, used, avail, availblks;
#else
  static long avail;
#endif
  static long long_ret;
  static char errmsg[300];

#if defined(HAVE_STATVFS) || defined(HAVE_STATFS)
#ifdef STAT_STATFS_FS_DATA
  struct fs_data fsd;
  struct {
    u_int f_blocks, f_bfree, f_bavail;
  } vfs;
#else
  struct statvfs vfs;
#endif
#else
#if HAVE_FSTAB_H
  int file;
  union {
     struct fs iu_fs;
     char dummy[SBSIZE];
  } sb;
#define filesys sb.iu_fs
#endif
#endif
  
  if (header_simple_table(vp,name,length,exact,var_len,write_method,numdisks))
    return(NULL);
  disknum = name[*length - 1] - 1;
  switch (vp->magic) {
    case MIBINDEX:
      long_ret = disknum+1;
      return((u_char *) (&long_ret));
    case ERRORNAME:       /* DISKPATH */
      *var_len = strlen(disks[disknum].path);
      return((u_char *) disks[disknum].path);
    case DISKDEVICE:
      *var_len = strlen(disks[disknum].device);
      return((u_char *) disks[disknum].device);
    case DISKMINIMUM:
      long_ret = disks[disknum].minimumspace;
      return((u_char *) (&long_ret));
    case DISKMINPERCENT:
      long_ret = disks[disknum].minpercent;
      return((u_char *) (&long_ret));
  }
#if defined(HAVE_SYS_STATVFS_H) || defined(HAVE_STATFS)
#ifdef STAT_STATFS_FS_DATA
  if (statvfs (disks[disknum].path, &fsd) == -1) {
#else
  if (statvfs (disks[disknum].path, &vfs) == -1) {
#endif
    fprintf(stderr,"Couldn't open device %s\n",disks[disknum].device);
    setPerrorstatus("statvfs dev/disk");
    return NULL;
  }
#ifdef STAT_STATFS_FS_DATA
  vfs.f_blocks = fsd.fd_btot;
  vfs.f_bfree  = fsd.fd_bfree;
  vfs.f_bavail = fsd.fd_bfreen;
#endif
#if defined(HAVE_ODS)
  vfs.f_blocks = vfs.f_spare[0];
  vfs.f_bfree  = vfs.f_spare[1];
  vfs.f_bavail = vfs.f_spare[2];
#endif
  percent = vfs.f_bavail <= 0 ? 100 :
    (int) ((double) (vfs.f_blocks - vfs.f_bfree) /
           (double) (vfs.f_blocks - (vfs.f_bfree - vfs.f_bavail)) * 100.0 + 0.5);
  avail = vfs.f_bavail;
#ifdef STRUCT_STATVFS_HAS_F_FRSIZE
  if (vfs.f_frsize > 255)
    avail = avail * (vfs.f_frsize / 1024);
#endif
  iserror = (disks[disknum].minimumspace >= 0 ?
             avail < disks[disknum].minimumspace :
             100-percent <= disks[disknum].minpercent) ? 1 : 0;
  switch (vp->magic) {
    case DISKTOTAL:
      long_ret = vfs.f_blocks;
#ifdef STRUCT_STATVFS_HAS_F_FRSIZE
      if (vfs.f_frsize > 255)
        long_ret = long_ret * (vfs.f_frsize / 1024);
#endif
      return((u_char *) (&long_ret));
    case DISKAVAIL:
      return((u_char *) (&avail));
    case DISKUSED:
      long_ret = (vfs.f_blocks - vfs.f_bfree);
#ifdef STRUCT_STATVFS_HAS_F_FRSIZE
      if (vfs.f_frsize > 255)
        long_ret = long_ret * (vfs.f_frsize / 1024);
#endif
      return((u_char *) (&long_ret));
    case DISKPERCENT:
      long_ret = percent;
      return ((u_char *) (&long_ret));
    case ERRORFLAG:
      long_ret = iserror;
      return((u_char *) (&long_ret));
    case ERRORMSG:
      if (iserror)
      {
	if (disks[disknum].minimumspace >= 0)
	  sprintf(errmsg,"%s: less than %d free (= %d)",disks[disknum].path,
                  disks[disknum].minimumspace, (int) avail);
	else
	  sprintf(errmsg,"%s: less than %d%% free (= %d%%)",disks[disknum].path,
		  disks[disknum].minpercent, percent);
      }
      else
        errmsg[0] = 0;
      *var_len = strlen(errmsg);
      return((u_char *) (errmsg));
  }
#else
#if HAVE_FSTAB_H
  /* read the disk information */
  if ((file = open(disks[disknum].device,0)) < 0) {
    fprintf(stderr,"Couldn't open device %s\n",disks[disknum].device);
    setPerrorstatus("open dev/disk");
    return(NULL);
  }
  lseek(file, (long) (SBLOCK * DEV_BSIZE), 0);
  if (read(file,(char *) &filesys, SBSIZE) != SBSIZE) {
    setPerrorstatus("open dev/disk");
    fprintf(stderr,"Error reading device %s\n",disks[disknum].device);
    close(file);
    return(NULL);
  }
  close(file);
  totalblks = filesys.fs_dsize;
  free = filesys.fs_cstotal.cs_nbfree * filesys.fs_frag +
    filesys.fs_cstotal.cs_nffree;
  used = totalblks - free;
  availblks = totalblks * (100 - filesys.fs_minfree) / 100;
  avail = availblks > used ? availblks - used : 0;
  percent = availblks == 0 ? 100 : (int) ((double) used / (double) totalblks * 100.0 + 0.5);
  iserror = (disks[disknum].minimumspace >= 0 ? avail * filesys.fs_fsize / 1024 <
	    disks[disknum].minimumspace : 100-percent <= disks[disknum].minpercent) ? 1 : 0;
  switch (vp->magic) {
    case DISKTOTAL:
      long_ret = (totalblks * filesys.fs_fsize / 1024);
      return((u_char *) (&long_ret));
    case DISKAVAIL:
      long_ret = avail * filesys.fs_fsize/1024;
      return((u_char *) (&long_ret));
    case DISKUSED:
      long_ret = used * filesys.fs_fsize/1024;
      return((u_char *) (&long_ret));
    case DISKPERCENT:
      long_ret = percent;
      return ((u_char *) (&long_ret));
    case ERRORFLAG:
      long_ret = iserror;
      return((u_char *) (&long_ret));
    case ERRORMSG:
      if (iserror)
	if (disks[disknum].minimumspace >= 0)
          sprintf(errmsg,"%s: less than %d free (= %d)",disks[disknum].path,
                  disks[disknum].minimumspace, avail * filesys.fs_fsize/1024);
	else
	  sprintf(errmsg,"%s: less than %d%% free (= %d%%)",disks[disknum].path,
		  disks[disknum].minpercent, percent);
      else
        errmsg[0] = 0;
      *var_len = strlen(errmsg);
      return((u_char *) (errmsg));
  }
#endif
#endif
  return NULL;
}
Ejemplo n.º 17
0
int main(int argc, char *argv[]) {

   int ret=1;

   if (argc < 2) {
      printf("Usage: fstype <directory>\n");
      return 1;
   } else {
#if defined(LINUX)
   struct statfs buf;
   FILE *fd = NULL;
   char buffer[BUF_SIZE];
   ret = statfs(argv[1], &buf);
#elif defined(DARWIN) || defined(FREEBSD) || (defined(NETBSD) && !defined(ST_RDONLY))
   struct statfs buf;
   ret = statfs(argv[1], &buf);
#elif defined(INTERIX)
   struct statvfs buf;
   ret = wl_statvfs(argv[1], &buf);
#elif defined(SOLARIS)
   struct statvfs buf;
   struct mntinfo_kstat mnt_info;
   minor_t fsid;
   kstat_ctl_t    *kc = NULL;
   kstat_t        *ksp;
   kstat_named_t  *knp;

   ret = statvfs(argv[1], &buf);
   /*
      statfs returns dev_t (32bit - 14bit major + 18bit minor number)
      the kstat_instance is the minor number
   */
   fsid = (minor_t)(buf.f_fsid & 0x3ffff);

   if (strcmp(buf.f_basetype, "nfs") == 0) {
            kc = kstat_open();
            for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
               if (ksp->ks_type != KSTAT_TYPE_RAW)
			         continue;
		         if (strcmp(ksp->ks_module, "nfs") != 0)
			         continue;
		         if (strcmp(ksp->ks_name, "mntinfo") != 0)
			         continue;
               if (kstat_read(kc, ksp, &mnt_info) == -1) {
                  kstat_close(kc);
                  printf("error\n");
                  return 2;
               }
               if (fsid  == ksp->ks_instance) {
                  if ( mnt_info.mik_vers >= 4 ) {
                     sprintf(buf.f_basetype, "%s%i", buf.f_basetype, mnt_info.mik_vers);
                  }
                  break;
               }
            }
            ret = kstat_close(kc);
   }
#else
   struct statvfs buf;
   ret = statvfs(argv[1], &buf);
#endif

   if(ret!=0) {
      printf("Error: %s\n", strerror(errno));
      return 2;
   }

#if defined (DARWIN) || defined(FREEBSD) || defined(NETBSD)
   printf("%s\n", buf.f_fstypename);
#elif defined(LINUX)
   /* 0x6969 is NFS_SUPER_MAGIC (see statfs(2) man page) */
   if (buf.f_type == 0x6969) {
      /*
       * Linux is not able to detect the right nfs version form the statfs struct.
       * f_type always returns nfs, even when it's a nfs4. We are looking into
       * the /etc/mtab file until we found a better solution to do this.
       */
      fd = fopen("/etc/mtab", "r");
      if (fd == NULL) {
         fprintf(stderr, "file system type could not be detected\n");
         printf("unknown fs\n");
         return 1;
      } else {
         bool found_line = false;
         sge_strip_white_space_at_eol(argv[1]);
         sge_strip_slash_at_eol(argv[1]);

         while (fgets(buffer, sizeof(buffer), fd) != NULL) {
            char* export = NULL; /* where is the nfs exported*/
            char* mountpoint = NULL; /*where is it mounted to */
            char* fstype = NULL; /*type of exported file system */

            export = sge_strtok(buffer, " \t");
            mountpoint = sge_strtok(NULL, " \t");
            fstype = sge_strtok(NULL, " \t");

            /* search only in valid lines that contain NFS4 mounts */
            if (mountpoint != NULL && fstype != NULL && strcmp(fstype, "nfs4") == 0) {
               /* search mountpoint in given path */
               char *pos = strstr(argv[1], mountpoint);
               if (pos == argv[1]) {
                  /* we found the mountpoint at the start of the given path, this is it! */
                  found_line = true;
                  printf ("%s\n", fstype);
                  break;
               }
            }
         }

         fclose(fd);
         if (found_line == false) { /*if type could not be detected via /etc/mtab, then we have to print out "nfs"*/
            printf("nfs\n");
         }
      }
   } else {
Ejemplo n.º 18
0
int
main(int argc, char **argv)
{
    int			sts;
    struct statvfs	vbuf;
    struct statfs	buf;

    while (--argc > 0) {
	printf("%s N (statfs) [N (statvfs)]:\n", argv[1]);
#if defined(IS_SOLARIS)
	sts = statfs(argv[1], &buf, 0, 0);
#else
	sts = statfs(argv[1], &buf);
#endif
	if (sts < 0) {
	    printf("Error: statfs: %s\n", strerror(errno));
	    argv++;
	    continue;
	}
	sts = statvfs(argv[1], &vbuf);
	if (sts < 0) {
	    printf("Error: statvfs: %s\n", strerror(errno));
	    argv++;
	    continue;
	}
	else {
	    printf("f_bsize=%lu [%lu] ", (unsigned long)buf.f_bsize, (unsigned long)vbuf.f_bsize);
#if defined(HAVE_SYS_STATFS_H)
	    printf("f_frsize=%lu [%lu] ", (unsigned long)buf.f_frsize, (unsigned long)vbuf.f_frsize);
#else
	    printf("f_frsize=[%lu] ", (unsigned long)vbuf.f_frsize);
#endif
	    putchar('\n');
	    printf("f_blocks=%llu [%llu] ", (unsigned long long)buf.f_blocks, (unsigned long long)vbuf.f_blocks);
	    printf("f_bfree=%llu [%llu] ", (unsigned long long)buf.f_bfree, (unsigned long long)vbuf.f_bfree);
#if !defined(IS_SOLARIS)
	    printf("f_bavail=%llu [%llu] ", (unsigned long long)buf.f_bavail, (unsigned long long)vbuf.f_bavail);
#endif
	    putchar('\n');
	    printf("f_files=%llu [%llu] ", (unsigned long long)buf.f_files, (unsigned long long)vbuf.f_files);
	    printf("f_ffree=%llu [%llu] ", (unsigned long long)buf.f_ffree, (unsigned long long)vbuf.f_ffree);
#if !defined(IS_SOLARIS)
	    printf("f_favail=[%llu] ", (unsigned long long)vbuf.f_favail);
#endif
	    putchar('\n');
#if defined(IS_SOLARIS)
	    /* no f_fsid field */
#elif defined(HAVE_SYS_STATFS_H)
	    printf("f_fsid={%d,%d} [%lu] ", buf.f_fsid.__val[0], buf.f_fsid.__val[1], (unsigned long)vbuf.f_fsid);
#else
	    printf("f_fsid=[%lu] ", (unsigned long)vbuf.f_fsid);
#endif
	    putchar('\n');
	    printf("f_flag=[%lu] ", vbuf.f_flag);
#if defined(IS_SOLARIS)
	    /* no f_name[len,max] fields */
#elif defined(HAVE_SYS_STATFS_H)
	    printf("f_namelen[f_namemax]=%lu [%lu] ", (unsigned long)buf.f_namelen, (unsigned long)vbuf.f_namemax);
#else
	    printf("f_namemax=[%lu] ", (unsigned long)vbuf.f_namemax);
#endif
	    putchar('\n');
	}
	argv++;
    }

    return(0);
}
Ejemplo n.º 19
0
/* Fill in the fields of FSP with information about space usage for
   the filesystem on which PATH resides.
   DISK is the device on which PATH is mounted, for space-getting
   methods that need to know it.
   Return 0 if successful, -1 if not.  When returning -1, ensure that
   ERRNO is either a system error value, or zero if DISK is NULL
   on a system that requires a non-NULL value.  */
int
get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp)
{
#ifdef STAT_STATFS3_OSF1

  struct statfs fsd;

  if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);

#endif /* STAT_STATFS3_OSF1 */

#ifdef STAT_STATFS2_FS_DATA	/* Ultrix */

  struct fs_data fsd;

  if (statfs (path, &fsd) != 1)
    return -1;

  fsp->fsu_blocksize = 1024;
  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.fd_req.btot);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.fd_req.bfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.fd_req.bfreen);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.fd_req.bfreen) != 0;
  fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.fd_req.gtot);
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.fd_req.gfree);

#endif /* STAT_STATFS2_FS_DATA */

#ifdef STAT_READ_FILSYS		/* SVR2 */
# ifndef SUPERBOFF
#  define SUPERBOFF (SUPERB * 512)
# endif

  struct filsys fsd;
  int fd;

  if (! disk)
    {
      errno = 0;
      return -1;
    }

  fd = open (disk, O_RDONLY);
  if (fd < 0)
    return -1;
  lseek (fd, (off_t) SUPERBOFF, 0);
  if (full_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd)
    {
      close (fd);
      return -1;
    }
  close (fd);

  fsp->fsu_blocksize = (fsd.s_type == Fs2b ? 1024 : 512);
  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.s_fsize);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.s_tfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0;
  fsp->fsu_files = (fsd.s_isize == -1
		    ? UINTMAX_MAX
		    : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1));
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode);

#endif /* STAT_READ_FILSYS */

#ifdef STAT_STATFS2_BSIZE	/* 4.3BSD, SunOS 4, HP-UX, AIX */

  struct statfs fsd;

  if (statfs (path, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);

# ifdef STATFS_TRUNCATES_BLOCK_COUNTS

  /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
     struct statfs are truncated to 2GB.  These conditions detect that
     truncation, presumably without botching the 4.1.1 case, in which
     the values are not truncated.  The correct counts are stored in
     undocumented spare fields.  */
  if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0)
    {
      fsd.f_blocks = fsd.f_spare[0];
      fsd.f_bfree = fsd.f_spare[1];
      fsd.f_bavail = fsd.f_spare[2];
    }
# endif /* STATFS_TRUNCATES_BLOCK_COUNTS */

#endif /* STAT_STATFS2_BSIZE */

#ifdef STAT_STATFS2_FSIZE	/* 4.4BSD */

  struct statfs fsd;

  if (statfs (path, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);

#endif /* STAT_STATFS2_FSIZE */

#ifdef STAT_STATFS4		/* SVR3, Dynix, Irix, AIX */

# if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN
#  define f_bavail f_bfree
# endif

  struct statfs fsd;

  if (statfs (path, &fsd, sizeof fsd, 0) < 0)
    return -1;

  /* Empirically, the block counts on most SVR3 and SVR3-derived
     systems seem to always be in terms of 512-byte blocks,
     no matter what value f_bsize has.  */
# if _AIX || defined _CRAY
   fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);
# else
   fsp->fsu_blocksize = 512;
# endif

#endif /* STAT_STATFS4 */

#ifdef STAT_STATVFS		/* SVR4 */

  struct statvfs fsd;

  if (statvfs (path, &fsd) < 0)
    return -1;

  /* f_frsize isn't guaranteed to be supported.  */
  fsp->fsu_blocksize = (fsd.f_frsize
			? PROPAGATE_ALL_ONES (fsd.f_frsize)
			: PROPAGATE_ALL_ONES (fsd.f_bsize));

#endif /* STAT_STATVFS */

#if !defined STAT_STATFS2_FS_DATA && !defined STAT_READ_FILSYS
				/* !Ultrix && !SVR2 */

  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.f_bavail);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0;
  fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files);
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree);

#endif /* not STAT_STATFS2_FS_DATA && not STAT_READ_FILSYS */

  return 0;
}
Ejemplo n.º 20
0
Archivo: fs.c Proyecto: alex-tools/nad
int main(int argc, char **argv) {
  struct extmnttab mnt;
  FILE *fp;

  fp = fopen("/etc/mnttab", "r");
  if(!fp) {
    perror("fopen");
    exit(-1);
  }

  while(getextmntent(fp, &mnt, sizeof (struct extmnttab)) == 0) {
    struct statvfs buf;
    int i;

    for(i=0;suppress_fstype[i] != NULL;i++)
      if(!strcmp(mnt.mnt_fstype, suppress_fstype[i])) break;

    if (suppress_fstype[i] == NULL && statvfs(mnt.mnt_mountp, &buf) == 0) {
      if(!strcmp(mnt.mnt_fstype, "zfs")) {
        uint64_t used, avail;
        uint64_t *space_used = NULL, *space_avail = NULL;
        libzfs_handle_t *zfsh = libzfs_init();
        zfs_handle_t *handle = zfs_path_to_zhandle(zfsh, (char *)mnt.mnt_mountp, ZFS_TYPE_FILESYSTEM);
        if(handle) {
          char source[ZFS_MAXNAMELEN];
          zprop_source_t srctype;
          int rv;
#define ZFS_PULL_N_PRINT(prop, name, T, F, expr) do { \
  uint64_t datum; \
  if(zfs_prop_get_numeric(handle, prop, \
                          &datum, &srctype, source, sizeof(source)) == 0) { \
      printf("zfs`%s`" name "\t" T" \t" F "\n", mnt.mnt_mountp, expr); \
  } \
} while(0)

          uint64_t used = -1, avail = -1;
          if(zfs_prop_get_numeric(handle, ZFS_PROP_USEDDS,
                                  &used, &srctype,
                                  source, sizeof(source)) == 0) {
            printf("zfs`%s`used\tL\t%llu\n", mnt.mnt_mountp, used);
          }
          if(zfs_prop_get_numeric(handle, ZFS_PROP_AVAILABLE,
                                  &avail, &srctype,
                                  source, sizeof(source)) == 0) {
            printf("zfs`%s`avail\tL\t%llu\n", mnt.mnt_mountp, avail);
          }
          if(used != -1 && avail != -1) {
            printf("zfs`%s`used_percent\tn\t%f\n", mnt.mnt_mountp, 100.0 * (used / (double)(used + avail)));
          }

          ZFS_PULL_N_PRINT(ZFS_PROP_USEDCHILD, "used_children", "L", "%llu", datum);
          ZFS_PULL_N_PRINT(ZFS_PROP_USEDSNAP, "used_snapshot", "L", "%llu", datum);
          ZFS_PULL_N_PRINT(ZFS_PROP_REFERENCED, "referenced", "L", "%llu", datum);
          ZFS_PULL_N_PRINT(ZFS_PROP_RECORDSIZE, "record_size", "L", "%llu", datum);
          ZFS_PULL_N_PRINT(ZFS_PROP_QUOTA, "quota", "L", "%llu", datum);
          ZFS_PULL_N_PRINT(ZFS_PROP_RESERVATION, "reservation", "L", "%llu", datum);
          ZFS_PULL_N_PRINT(ZFS_PROP_REFRESERVATION, "ref_reservation", "L", "%llu", datum);
          ZFS_PULL_N_PRINT(ZFS_PROP_USEDREFRESERV, "ref_reservation_used", "L", "%llu", datum);
#ifdef HAVE_LOGICAL_USED
  ZFS_PULL_N_PRINT(ZFS_PROP_LOGICALUSED, "logical_used", "L", "%llu", datum);
  ZFS_PULL_N_PRINT(ZFS_PROP_LOGICALREFERENCED, "logical_referenced", "L", "%llu", datum);
#endif
          ZFS_PULL_N_PRINT(ZFS_PROP_COMPRESSRATIO, "compress_ratio", "n", "%f", (double)datum/100.0);
          zfs_close(handle);
        }
        libzfs_fini(zfsh);
      }
      else {
        printf("fs`%s`f_bsize\tL\t%llu\n", mnt.mnt_mountp, buf.f_bsize);
        printf("fs`%s`f_frsize\tL\t%llu\n", mnt.mnt_mountp, buf.f_frsize);
        printf("fs`%s`f_blocks\tL\t%llu\n", mnt.mnt_mountp, buf.f_blocks);
        printf("fs`%s`f_bfree\tL\t%llu\n", mnt.mnt_mountp, buf.f_bfree);
        printf("fs`%s`f_bavail\tL\t%llu\n", mnt.mnt_mountp, buf.f_bavail);
        printf("fs`%s`f_files\tL\t%llu\n", mnt.mnt_mountp, buf.f_blocks);
        printf("fs`%s`f_ffree\tL\t%llu\n", mnt.mnt_mountp, buf.f_ffree);
        printf("fs`%s`f_favail\tL\t%llu\n", mnt.mnt_mountp, buf.f_favail);
      }
    }
  }
  exit(0);
}
Ejemplo n.º 21
0
void FiosGetDrives(FileList &file_list)
{
    uint disk, disk2, save, total;

#ifndef __INNOTEK_LIBC__
    _dos_getdrive(&save); // save original drive
#else
    save = _getdrive(); // save original drive
    char wd[MAX_PATH];
    getcwd(wd, MAX_PATH);
    total = 'z';
#endif

    /* get an available drive letter */
#ifndef __INNOTEK_LIBC__
    for (disk = 1;; disk++) {
        _dos_setdrive(disk, &total);
#else
    for (disk = 'A';; disk++) {
        _chdrive(disk);
#endif
        if (disk >= total)  break;

#ifndef __INNOTEK_LIBC__
        _dos_getdrive(&disk2);
#else
        disk2 = _getdrive();
#endif

        if (disk == disk2) {
            FiosItem *fios = file_list.Append();
            fios->type = FIOS_TYPE_DRIVE;
            fios->mtime = 0;
#ifndef __INNOTEK_LIBC__
            snprintf(fios->name, lengthof(fios->name),  "%c:", 'A' + disk - 1);
#else
            snprintf(fios->name, lengthof(fios->name),  "%c:", disk);
#endif
            strecpy(fios->title, fios->name, lastof(fios->title));
        }
    }

    /* Restore the original drive */
#ifndef __INNOTEK_LIBC__
    _dos_setdrive(save, &total);
#else
    chdir(wd);
#endif
}

bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
{
#ifndef __INNOTEK_LIBC__
    struct diskfree_t free;
    char drive = path[0] - 'A' + 1;

    if (tot != NULL && _getdiskfree(drive, &free) == 0) {
        *tot = free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector;
        return true;
    }

    return false;
#else
    uint64 free = 0;

#ifdef HAS_STATVFS
    {
        struct statvfs s;

        if (statvfs(path, &s) != 0) return false;
        free = (uint64)s.f_frsize * s.f_bavail;
    }
#endif
    if (tot != NULL) *tot = free;
    return true;
#endif
}

bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)
{
    char filename[MAX_PATH];

    snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, ent->d_name);
    return stat(filename, sb) == 0;
}
Ejemplo n.º 22
0
bool opal_path_nfs(char *fname, char **ret_fstype)
{
    int i;
    int fsrc = -1;
    int vfsrc = -1;
    int trials;
    char * file = strdup (fname);
#if defined(USE_STATFS)
    struct statfs fsbuf;
#endif
#if defined(HAVE_STATVFS)
    struct statvfs vfsbuf;
#endif
    /*
     * Be sure to update the test (test/util/opal_path_nfs.c)
     * while adding a new Network/Cluster Filesystem here
     */
    static struct fs_types_t {
        unsigned long long f_fsid;
        unsigned long long f_mask;
        const char * f_fsname;
    } fs_types[] = {
        {LL_SUPER_MAGIC,                   MASK4, "lustre"},
        {NFS_SUPER_MAGIC,                  MASK2, "nfs"},
        {AUTOFS_SUPER_MAGIC,               MASK2, "autofs"},
        {PAN_KERNEL_FS_CLIENT_SUPER_MAGIC, MASK4, "panfs"},
        {GPFS_SUPER_MAGIC,                 MASK4, "gpfs"},
        {PVFS2_SUPER_MAGIC,                MASK4, "pvfs2"}
    };
#define FS_TYPES_NUM (int)(sizeof (fs_types)/sizeof (fs_types[0]))

    /*
     * First, get the OS-dependent struct stat(v)fs buf.  This may
     * return the ESTALE error on NFS, if the underlying file/path has
     * changed.
     */
again:
#if defined(USE_STATFS)
    trials = 5;
    do {
        fsrc = statfs(file, &fsbuf);
    } while (-1 == fsrc && ESTALE == errno && (0 < --trials));
#endif
#if defined(HAVE_STATVFS)
    trials = 5;
    do {
        vfsrc = statvfs(file, &vfsbuf);
    } while (-1 == vfsrc && ESTALE == errno && (0 < --trials));
#endif

    /* In case some error with the current filename, try the parent
       directory */
    if (-1 == fsrc && -1 == vfsrc) {
        char * last_sep;

        OPAL_OUTPUT_VERBOSE((10, 0, "opal_path_nfs: stat(v)fs on file:%s failed errno:%d directory:%s\n",
                             fname, errno, file));
        if (EPERM == errno) {
            free(file);
            if ( NULL != ret_fstype ) {
                *ret_fstype = NULL;
            }
            return false;
        }

        last_sep = strrchr(file, OPAL_PATH_SEP[0]);
        /* Stop the search, when we have searched past root '/' */
        if (NULL == last_sep || (1 == strlen(last_sep) &&
            OPAL_PATH_SEP[0] == *last_sep)) {
            free (file);
            if ( NULL != ret_fstype ) {
                *ret_fstype=NULL;
            }
            return false;
        }
        *last_sep = '\0';

        goto again;
    }

    /* Next, extract the magic value */
    for (i = 0; i < FS_TYPES_NUM; i++) {
#if defined(USE_STATFS)
        /* These are uses of struct statfs */
#    if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME)
        if (0 == fsrc &&
            0 == strncasecmp(fs_types[i].f_fsname, fsbuf.f_fstypename,
                             sizeof(fsbuf.f_fstypename))) {
            goto found;
        }
#    endif
#    if defined(HAVE_STRUCT_STATFS_F_TYPE)
        if (0 == fsrc &&
            fs_types[i].f_fsid == (fsbuf.f_type & fs_types[i].f_mask)) {
            goto found;
        }
#    endif
#endif

#if defined(HAVE_STATVFS)
        /* These are uses of struct statvfs */
#    if defined(HAVE_STRUCT_STATVFS_F_BASETYPE)
        if (0 == vfsrc &&
            0 == strncasecmp(fs_types[i].f_fsname, vfsbuf.f_basetype,
                             sizeof(vfsbuf.f_basetype))) {
            goto found;
        }
#    endif
#    if defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)
        if (0 == vfsrc &&
            0 == strncasecmp(fs_types[i].f_fsname, vfsbuf.f_fstypename,
                             sizeof(vfsbuf.f_fstypename))) {
            goto found;
        }
#    endif
#endif
    }

    free (file);
    if ( NULL != ret_fstype ) {
        *ret_fstype=NULL;
    }
    return false;

found:

    free (file);
    if (AUTOFS_SUPER_MAGIC == fs_types[i].f_fsid) {
        char *fs_type = opal_check_mtab(fname);
        int x;
        if (NULL != fs_type) {
            for (x = 0; x < FS_TYPES_NUM; x++) {
                if (AUTOFS_SUPER_MAGIC == fs_types[x].f_fsid) {
                    continue;
                }
                if (0 == strcasecmp(fs_types[x].f_fsname, fs_type)) {
                    OPAL_OUTPUT_VERBOSE((10, 0, "opal_path_nfs: file:%s on fs:%s\n", fname, fs_type));
                    free(fs_type);
                    if ( NULL != ret_fstype ) {
                        *ret_fstype = strdup(fs_types[x].f_fsname);
                    }
                    return true;
                }
            }
            free(fs_type);
            if ( NULL != ret_fstype ) {
                *ret_fstype=NULL;
            }
            return false;
        }
    }

    OPAL_OUTPUT_VERBOSE((10, 0, "opal_path_nfs: file:%s on fs:%s\n",
                fname, fs_types[i].f_fsname));
    if ( NULL != ret_fstype ) {
        *ret_fstype = strdup (fs_types[i].f_fsname);
    }
    return true;

#undef FS_TYPES_NUM
}
Ejemplo n.º 23
0
static int l_sleep (lua_State *L) {
  unsigned int t = lua_tonumber(L, 1);
  struct timespec st = {.tv_sec = t / 1000000, .tv_nsec = (t % 1000000) * 1000};
  nanosleep(&st, NULL);
  return 0;
}

/* Filesystem methods */
static int l_fs_exists (lua_State *L) {
  const char* fname = lua_tostring(L, 1);
  if( access( fname, F_OK ) != -1 ) {
    lua_pushboolean(L, 1);
  } else {
    lua_pushboolean(L, 0);
  }
  return 1;
}

static int l_fs_mkdir (lua_State *L) {
  const char* fname = lua_tostring(L, 1);
#ifndef _WIN32
  if( mkdir( fname, 0755 ) != -1 ) {
#else
    if( mkdir( fname ) != -1 ) {
#endif
    lua_pushboolean(L, 1);
  } else {
    lua_pushboolean(L, 0);
  }
  return 1;
}

static int l_fs_isdir (lua_State *L) {
  const char* fname = lua_tostring(L, 1);
  struct stat s;
  int err = stat(fname, &s);
  if(-1 == err) {
    lua_pushboolean(L, 0);
  } else {
    if(S_ISDIR(s.st_mode)) {
      lua_pushboolean(L, 1);
    } else {
      lua_pushboolean(L, 0);
    }
  }
  return 1;
}

static int l_fs_spaceUsed (lua_State *L) {
  const char* fname = lua_tostring(L, 1);
#ifndef _WIN32
  struct statvfs s;
  if( statvfs(fname, &s) != -1 ) {
    lua_pushnumber(L, s.f_bsize * s.f_bfree);
  } else {
    lua_pushnumber(L, -1);
  }
#else
  lua_pushnumber(L, -1);
#endif
  return 1;
}

static int l_fs_open (lua_State *L) {
  const char* fname = lua_tostring(L, 1);
  const char* mode = lua_tostring(L, 2);
  logm("Open file: ");
  logn(fname);
  int m = 0;
  if(mode[0] == 'r') m = O_RDONLY;
  else if(mode[0] == 'w') m = O_WRONLY | O_CREAT /*| O_DIRECT*/;
  else if(mode[0] == 'a') m = O_WRONLY | O_APPEND | O_CREAT /*| O_DIRECT*/;
  else return 0;
  int fd = open(fname, m, 0644);

  if(fd == -1) return 0;
  logm("FD ");
  logi(fd);
  logm(" for ");
  logn(fname);
  lua_pushnumber(L, fd);
  return 1;
}

static int l_fs_seek (lua_State *L) {
  int fd = lua_tonumber(L, 1);
  int whence = lua_tonumber(L, 2);
  long offset = lua_tonumber(L, 3);

  int w = 0;
  if(whence == 0) w = SEEK_CUR;
  else if(whence == 1) w = SEEK_SET;
  else if(whence == 2) w = SEEK_END;
  else return 0;
  int res = lseek(fd, w, offset);
  lua_pushnumber(L, res);
  return 1;
}

static int l_fs_write (lua_State *L) {
  int fd = lua_tonumber(L, 1);
  size_t len = 0;
  const char* data = lua_tolstring(L, 2, &len);

  /* TODO: May not all data be written? */
  if(write(fd, data, len) == -1) {
    lua_pushboolean(L, 0);
  } else {
    lua_pushboolean(L, 1);
  }
  return 1;
}
Ejemplo n.º 24
0
void dt_mipmap_cache_deallocate_dynamic(void *data, dt_cache_entry_t *entry)
{
  dt_mipmap_cache_t *cache = (dt_mipmap_cache_t *)data;
  const dt_mipmap_size_t mip = get_size(entry->key);
  if(mip < DT_MIPMAP_F)
  {
    struct dt_mipmap_buffer_dsc *dsc = (struct dt_mipmap_buffer_dsc *)entry->data;
    // don't write skulls:
    if(dsc->width > 8 && dsc->height > 8)
    {
      if(dsc->flags & DT_MIPMAP_BUFFER_DSC_FLAG_INVALIDATE)
      {
        // also remove jpg backing (always try to do that, in case user just temporarily switched it off,
        // to avoid inconsistencies.
        // if(dt_conf_get_bool("cache_disk_backend"))
        if(cache->cachedir[0])
        {
          char filename[PATH_MAX] = {0};
          snprintf(filename, sizeof(filename), "%s.d/%d/%d.jpg", cache->cachedir, mip, get_imgid(entry->key));
          g_unlink(filename);
        }
      }
      else if(cache->cachedir[0] && dt_conf_get_bool("cache_disk_backend"))
      {
        // serialize to disk
        char filename[PATH_MAX] = {0};
        snprintf(filename, sizeof(filename), "%s.d/%d", cache->cachedir, mip);
        int mkd = g_mkdir_with_parents(filename, 0750);
        if(!mkd)
        {
          snprintf(filename, sizeof(filename), "%s.d/%d/%d.jpg", cache->cachedir, mip, get_imgid(entry->key));
          // Don't write existing files as both performance and quality (lossy jpg) suffer
          FILE *f = NULL;
          if (!g_file_test(filename, G_FILE_TEST_EXISTS) && (f = fopen(filename, "wb")))
          {
            // first check the disk isn't full
            struct statvfs vfsbuf;
            if (!statvfs(filename, &vfsbuf))
            {
              int64_t free_mb = ((vfsbuf.f_frsize * vfsbuf.f_bavail) >> 20);
              if (free_mb < 100)
              {
                fprintf(stderr, "Aborting image write as only %" PRId64 " MB free to write %s\n", free_mb, filename);
                goto write_error;
              }
            }
            else
            {
              fprintf(stderr, "Aborting image write since couldn't determine free space available to write %s\n", filename);
              goto write_error;
            }

            const int cache_quality = dt_conf_get_int("database_cache_quality");
            const uint8_t *exif = NULL;
            int exif_len = 0;
            if(dsc->color_space == DT_COLORSPACE_SRGB)
            {
              exif = dt_mipmap_cache_exif_data_srgb;
              exif_len = dt_mipmap_cache_exif_data_srgb_length;
            }
            else if(dsc->color_space == DT_COLORSPACE_ADOBERGB)
            {
              exif = dt_mipmap_cache_exif_data_adobergb;
              exif_len = dt_mipmap_cache_exif_data_adobergb_length;
            }
            if(dt_imageio_jpeg_write(filename, entry->data + sizeof(*dsc), dsc->width, dsc->height, MIN(100, MAX(10, cache_quality)), exif, exif_len))
            {
write_error:
              g_unlink(filename);
            }
          }
          if(f) fclose(f);
        }
Ejemplo n.º 25
0
int
main(int argc, char **argv)
{
	struct stat stbuf;
	struct statfs statfsbuf, *mntbuf;
	struct statvfs statvfsbuf, *mntvbuf;
	struct maxwidths maxwidths;
	const char *fstype;
	char *mntpath, *mntpt, **vfslist;
	long mntsize;
	int ch, i, rv;

	fstype = "ufs";

	vfslist = NULL;
	while ((ch = getopt(argc, argv, "abgHhiklmnPt:T")) != -1)
		switch (ch) {
		case 'a':
			aflag = 1;
			break;
		case 'b':
				/* FALLTHROUGH */
		case 'P':
			if (setenv("BLOCKSIZE", "512", 1) != 0)
				warn("setenv: cannot set BLOCKSIZE=512");
			hflag = 0;
			break;
		case 'g':
			if (setenv("BLOCKSIZE", "1g", 1) != 0)
				warn("setenv: cannot set BLOCKSIZE=1g");
			hflag = 0;
			break;
		case 'H':
			hflag = UNITS_SI;
			break;
		case 'h':
			hflag = UNITS_2;
			break;
		case 'i':
			iflag = 1;
			break;
		case 'k':
			if (setenv("BLOCKSIZE", "1k", 1) != 0)
				warn("setenv: cannot set BLOCKSIZE=1k");
			hflag = 0;
			break;
		case 'l':
			if (vfslist != NULL)
				errx(1, "-l and -t are mutually exclusive.");
			vfslist = makevfslist(makenetvfslist());
			break;
		case 'm':
			if (setenv("BLOCKSIZE", "1m", 1) != 0)
				warn("setenv: cannot set BLOCKSIZE=1m");
			hflag = 0;
			break;
		case 'n':
			nflag = 1;
			break;
		case 't':
			if (vfslist != NULL)
				errx(1, "only one -t option may be specified");
			fstype = optarg;
			vfslist = makevfslist(optarg);
			break;
		case 'T':
			Tflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	mntsize = getmntvinfo(&mntbuf, &mntvbuf, MNT_NOWAIT);
	bzero(&maxwidths, sizeof(maxwidths));
	for (i = 0; i < mntsize; i++)
		update_maxwidths(&maxwidths, &mntbuf[i], &mntvbuf[i]);

	rv = 0;
	if (!*argv) {
		mntsize = regetmntinfo(&mntbuf, &mntvbuf, mntsize, vfslist);
		bzero(&maxwidths, sizeof(maxwidths));
		for (i = 0; i < mntsize; i++)
			update_maxwidths(&maxwidths, &mntbuf[i], &mntvbuf[i]);
		for (i = 0; i < mntsize; i++) {
			if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
				prtstat(&mntbuf[i], &mntvbuf[i], &maxwidths);
		}
		exit(rv);
	}

	for (; *argv; argv++) {
		if (stat(*argv, &stbuf) < 0) {
			if ((mntpt = getmntpt(*argv)) == NULL) {
				warn("%s", *argv);
				rv = 1;
				continue;
			}
		} else if (S_ISCHR(stbuf.st_mode)) {
			if ((mntpt = getmntpt(*argv)) == NULL) {
				mdev.fspec = *argv;
				mntpath = strdup("/tmp/df.XXXXXX");
				if (mntpath == NULL) {
					warn("strdup failed");
					rv = 1;
					continue;
				}
				mntpt = mkdtemp(mntpath);
				if (mntpt == NULL) {
					warn("mkdtemp(\"%s\") failed", mntpath);
					rv = 1;
					free(mntpath);
					continue;
				}
				if (mount(fstype, mntpt, MNT_RDONLY,
				    &mdev) != 0) {
					rv = ufs_df(*argv, &maxwidths) || rv;
					rmdir(mntpt);
					free(mntpath);
					continue;
				} else if (statfs(mntpt, &statfsbuf) == 0 &&
					   statvfs(mntpt, &statvfsbuf) == 0) {
					statfsbuf.f_mntonname[0] = '\0';
					prtstat(&statfsbuf, &statvfsbuf, &maxwidths);
				} else {
					warn("%s", *argv);
					rv = 1;
				}
				unmount(mntpt, 0);
				rmdir(mntpt);
				free(mntpath);
				continue;
			}
		} else
			mntpt = *argv;
		/*
		 * Statfs does not take a `wait' flag, so we cannot
		 * implement nflag here.
		 */
		if (statfs(mntpt, &statfsbuf) < 0) {
			warn("%s", mntpt);
			rv = 1;
			continue;
		}
		if (statvfs(mntpt, &statvfsbuf) < 0) {
			warn("%s", mntpt);
			rv = 1;
			continue;
		}
		/*
		 * Check to make sure the arguments we've been given are
		 * satisfied. Return an error if we have been asked to
		 * list a mount point that does not match the other args
		 * we've been given (-l, -t, etc.).
		 */
		if (checkvfsname(statfsbuf.f_fstypename, vfslist)) {
			rv = 1;
			continue;
		}

		if (argc == 1) {
			bzero(&maxwidths, sizeof(maxwidths));
			update_maxwidths(&maxwidths, &statfsbuf, &statvfsbuf);
		}
		prtstat(&statfsbuf, &statvfsbuf, &maxwidths);
	}
	return (rv);
}
Ejemplo n.º 26
0
static gboolean
ldsm_check_all_mounts (gpointer data)
{
        GList *mounts;
        GList *l;
        GList *check_mounts = NULL;
        GList *full_mounts = NULL;
        guint number_of_mounts;
        guint number_of_full_mounts;
        gboolean multiple_volumes = FALSE;
        gboolean other_usable_volumes = FALSE;

        /* We iterate through the static mounts in /etc/fstab first, seeing if
         * they're mounted by checking if the GUnixMountPoint has a corresponding GUnixMountEntry.
         * Iterating through the static mounts means we automatically ignore dynamically mounted media.
         */
        mounts = g_unix_mount_points_get (time_read);

        for (l = mounts; l != NULL; l = l->next) {
                GUnixMountPoint *mount_point = l->data;
                GUnixMountEntry *mount;
                LdsmMountInfo *mount_info;
                const gchar *path;

                path = g_unix_mount_point_get_mount_path (mount_point);
                mount = g_unix_mount_at (path, time_read);
                g_unix_mount_point_free (mount_point);
                if (mount == NULL) {
                        /* The GUnixMountPoint is not mounted */
                        continue;
                }

                mount_info = g_new0 (LdsmMountInfo, 1);
                mount_info->mount = mount;

                path = g_unix_mount_get_mount_path (mount);

                if (g_unix_mount_is_readonly (mount)) {
                        ldsm_free_mount_info (mount_info);
                        continue;
                }

                if (ldsm_mount_should_ignore (mount)) {
                        ldsm_free_mount_info (mount_info);
                        continue;
                }

                if (statvfs (path, &mount_info->buf) != 0) {
                        ldsm_free_mount_info (mount_info);
                        continue;
                }

                if (ldsm_mount_is_virtual (mount_info)) {
                        ldsm_free_mount_info (mount_info);
                        continue;
                }

                check_mounts = g_list_prepend (check_mounts, mount_info);
        }
        g_list_free (mounts);

        number_of_mounts = g_list_length (check_mounts);
        if (number_of_mounts > 1)
                multiple_volumes = TRUE;

        for (l = check_mounts; l != NULL; l = l->next) {
                LdsmMountInfo *mount_info = l->data;

                if (!ldsm_mount_has_space (mount_info)) {
                        full_mounts = g_list_prepend (full_mounts, mount_info);
                } else {
                        g_hash_table_remove (ldsm_notified_hash, g_unix_mount_get_mount_path (mount_info->mount));
                        ldsm_free_mount_info (mount_info);
                }
        }

        number_of_full_mounts = g_list_length (full_mounts);
        if (number_of_mounts > number_of_full_mounts)
                other_usable_volumes = TRUE;

        ldsm_maybe_warn_mounts (full_mounts, multiple_volumes,
                                other_usable_volumes);

        g_list_free (check_mounts);
        g_list_free (full_mounts);

        return TRUE;
}
Ejemplo n.º 27
0
static ssd_cachedev_info_t *
ssd_create_cachedev(char *path, int64_t size, log_ctx_t *ctx)
{
    ssd_cachedev_info_t *cachedev = NULL;
    int ret = -1;
    pid_t pid;
    char command[COMMAND_LEN] = { '\0' };
    int status;
    char *mntpnt_name = NULL;
    struct statvfs vfs;

    if (NULL == path || size < 0)
        return NULL;

    // NOTE:
    // This command is tuned for cache file size of 64KiB (128 blocks)
    // and journal size of 64 MiB
    sprintf(command, "/sbin/mkfs.ext4 -i 128 -J size=64 %s %"PRId64"",
            path, size);
    // Create file system on the device

    ret = system(command);
    if (ret == -1) {
        sfs_log(ctx, SFS_ERR, "%s: execve failed with error %d \n",
                __FUNCTION__, errno);

        return NULL;
    }

    // mkfs succeeded.

    mntpnt_name = mkdtemp("/tmp/SSDXXXXXX");
    if (NULL == mntpnt_name) {
        sfs_log(ctx, SFS_ERR, "%s: mkdtemp failed with errno %d \n",
                __FUNCTION__, errno);

        return NULL;
    }

    // Mount the file system on SSD on mntpnt_name
    sprintf(command, "mount -t ext4 %s %s", path, mntpnt_name);
    ret = system(command);
    if (ret == -1) {
        sfs_log(ctx, SFS_ERR, "%s: mount of %s on %s failed. Error = %d\n",
                __FUNCTION__, path, mntpnt_name, errno);

        return NULL;
    }
    cachedev = (ssd_cachedev_info_t *) calloc(sizeof(ssd_cachedev_info_t),
               1);
    if (NULL == cachedev) {
        sfs_log(ctx, SFS_ERR, "%s: Memory allocation failed \n",
                __FUNCTION__);

        return NULL;
    }

    strcpy(cachedev->mntpnt, mntpnt_name);
    ret = statvfs(mntpnt_name, &vfs);
    // Assume statvfs succeeded
    cachedev->num_cachelines = (uint64_t) vfs.f_files;

    return cachedev;
}
Ejemplo n.º 28
0
/* Fill in the fields of FSP with information about space usage for
   the file system on which FILE resides.
   DISK is the device on which FILE is mounted, for space-getting
   methods that need to know it.
   Return 0 if successful, -1 if not.  When returning -1, ensure that
   ERRNO is either a system error value, or zero if DISK is NULL
   on a system that requires a non-NULL value.  */
int
get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
{
#ifdef STAT_STATVFS     /* POSIX, except pre-2.6.36 glibc/Linux */

  if (statvfs_works ())
    {
      struct statvfs vfsd;

      if (statvfs (file, &vfsd) < 0)
        return -1;

      /* f_frsize isn't guaranteed to be supported.  */
      fsp->fsu_blocksize = (vfsd.f_frsize
                            ? PROPAGATE_ALL_ONES (vfsd.f_frsize)
                            : PROPAGATE_ALL_ONES (vfsd.f_bsize));

      fsp->fsu_blocks = PROPAGATE_ALL_ONES (vfsd.f_blocks);
      fsp->fsu_bfree = PROPAGATE_ALL_ONES (vfsd.f_bfree);
      fsp->fsu_bavail = PROPAGATE_TOP_BIT (vfsd.f_bavail);
      fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (vfsd.f_bavail) != 0;
      fsp->fsu_files = PROPAGATE_ALL_ONES (vfsd.f_files);
      fsp->fsu_ffree = PROPAGATE_ALL_ONES (vfsd.f_ffree);
      return 0;
    }

#endif

#if defined STAT_STATVFS64            /* AIX */

  struct statvfs64 fsd;

  if (statvfs64 (file, &fsd) < 0)
    return -1;

  /* f_frsize isn't guaranteed to be supported.  */
  fsp->fsu_blocksize = (fsd.f_frsize
                        ? PROPAGATE_ALL_ONES (fsd.f_frsize)
                        : PROPAGATE_ALL_ONES (fsd.f_bsize));

#elif defined STAT_STATFS2_FS_DATA      /* Ultrix */

  struct fs_data fsd;

  if (statfs (file, &fsd) != 1)
    return -1;

  fsp->fsu_blocksize = 1024;
  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.fd_req.btot);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.fd_req.bfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.fd_req.bfreen);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.fd_req.bfreen) != 0;
  fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.fd_req.gtot);
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.fd_req.gfree);

#elif defined STAT_READ_FILSYS          /* SVR2 */
# ifndef SUPERBOFF
#  define SUPERBOFF (SUPERB * 512)
# endif

  struct filsys fsd;
  int fd;

  if (! disk)
    {
      errno = 0;
      return -1;
    }

  fd = open (disk, O_RDONLY);
  if (fd < 0)
    return -1;
  lseek (fd, (off_t) SUPERBOFF, 0);
  if (full_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd)
    {
      close (fd);
      return -1;
    }
  close (fd);

  fsp->fsu_blocksize = (fsd.s_type == Fs2b ? 1024 : 512);
  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.s_fsize);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.s_tfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0;
  fsp->fsu_files = (fsd.s_isize == -1
                    ? UINTMAX_MAX
                    : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1));
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode);

#elif defined STAT_STATFS3_OSF1         /* OSF/1 */

  struct statfs fsd;

  if (statfs (file, &fsd, sizeof (struct statfs)) != 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);

#elif defined STAT_STATFS2_FRSIZE        /* 2.6 < glibc/Linux < 2.6.36 */

  struct statfs fsd;

  if (statfs (file, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_frsize);

#elif defined STAT_STATFS2_BSIZE        /* glibc/Linux < 2.6, 4.3BSD, SunOS 4, \
                                           Mac OS X < 10.4, FreeBSD < 5.0, \
                                           NetBSD < 3.0, OpenBSD < 4.4 */

  struct statfs fsd;

  if (statfs (file, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);

# ifdef STATFS_TRUNCATES_BLOCK_COUNTS

  /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
     struct statfs are truncated to 2GB.  These conditions detect that
     truncation, presumably without botching the 4.1.1 case, in which
     the values are not truncated.  The correct counts are stored in
     undocumented spare fields.  */
  if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0)
    {
      fsd.f_blocks = fsd.f_spare[0];
      fsd.f_bfree = fsd.f_spare[1];
      fsd.f_bavail = fsd.f_spare[2];
    }
# endif /* STATFS_TRUNCATES_BLOCK_COUNTS */

#elif defined STAT_STATFS2_FSIZE        /* 4.4BSD and older NetBSD */

  struct statfs fsd;

  if (statfs (file, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);

#elif defined STAT_STATFS4              /* SVR3, Dynix, old Irix, old AIX, \
                                           Dolphin */

# if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN
#  define f_bavail f_bfree
# endif

  struct statfs fsd;

  if (statfs (file, &fsd, sizeof fsd, 0) < 0)
    return -1;

  /* Empirically, the block counts on most SVR3 and SVR3-derived
     systems seem to always be in terms of 512-byte blocks,
     no matter what value f_bsize has.  */
# if _AIX || defined _CRAY
   fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);
# else
   fsp->fsu_blocksize = 512;
# endif

#endif

#if (defined STAT_STATVFS64 || defined STAT_STATFS3_OSF1                \
     || defined STAT_STATFS2_FRSIZE || defined STAT_STATFS2_BSIZE       \
     || defined STAT_STATFS2_FSIZE || defined STAT_STATFS4)

  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.f_bavail);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0;
  fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files);
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree);

#endif

  (void) disk;  /* avoid argument-unused warning */
  return 0;
}
Ejemplo n.º 29
0
static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
    const char *family = mi->mount_point;
    const char *disk = mi->persistent_id;

    static SIMPLE_PATTERN *excluded_mountpoints = NULL;
    static SIMPLE_PATTERN *excluded_filesystems = NULL;
    int do_space, do_inodes;

    if(unlikely(!dict_mountpoints)) {
        SIMPLE_PREFIX_MODE mode = SIMPLE_PATTERN_EXACT;

        if(config_move("plugin:proc:/proc/diskstats", "exclude space metrics on paths", CONFIG_SECTION_DISKSPACE, "exclude space metrics on paths") != -1) {
            // old configuration, enable backwards compatibility
            mode = SIMPLE_PATTERN_PREFIX;
        }

        excluded_mountpoints = simple_pattern_create(
                config_get(CONFIG_SECTION_DISKSPACE, "exclude space metrics on paths", DELAULT_EXCLUDED_PATHS)
                , NULL
                , mode
        );

        excluded_filesystems = simple_pattern_create(
                config_get(CONFIG_SECTION_DISKSPACE, "exclude space metrics on filesystems", DEFAULT_EXCLUDED_FILESYSTEMS)
                , NULL
                , SIMPLE_PATTERN_EXACT
        );

        dict_mountpoints = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
    }

    struct mount_point_metadata *m = dictionary_get(dict_mountpoints, mi->mount_point);
    if(unlikely(!m)) {
        char var_name[4096 + 1];
        snprintfz(var_name, 4096, "plugin:proc:diskspace:%s", mi->mount_point);

        int def_space = config_get_boolean_ondemand(CONFIG_SECTION_DISKSPACE, "space usage for all disks", CONFIG_BOOLEAN_AUTO);
        int def_inodes = config_get_boolean_ondemand(CONFIG_SECTION_DISKSPACE, "inodes usage for all disks", CONFIG_BOOLEAN_AUTO);

        if(unlikely(simple_pattern_matches(excluded_mountpoints, mi->mount_point))) {
            def_space = CONFIG_BOOLEAN_NO;
            def_inodes = CONFIG_BOOLEAN_NO;
        }

        if(unlikely(simple_pattern_matches(excluded_filesystems, mi->filesystem))) {
            def_space = CONFIG_BOOLEAN_NO;
            def_inodes = CONFIG_BOOLEAN_NO;
        }

        // check if the mount point is a directory #2407
        {
            struct stat bs;
            if(stat(mi->mount_point, &bs) == -1) {
                error("DISKSPACE: Cannot stat() mount point '%s' (disk '%s', filesystem '%s', root '%s')."
                      , mi->mount_point
                      , disk
                      , mi->filesystem?mi->filesystem:""
                      , mi->root?mi->root:""
                );
                def_space = CONFIG_BOOLEAN_NO;
                def_inodes = CONFIG_BOOLEAN_NO;
            }
            else {
                if((bs.st_mode & S_IFMT) != S_IFDIR) {
                    error("DISKSPACE: Mount point '%s' (disk '%s', filesystem '%s', root '%s') is not a directory."
                          , mi->mount_point
                          , disk
                          , mi->filesystem?mi->filesystem:""
                          , mi->root?mi->root:""
                    );
                    def_space = CONFIG_BOOLEAN_NO;
                    def_inodes = CONFIG_BOOLEAN_NO;
                }
            }
        }

        do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
        do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);

        struct mount_point_metadata mp = {
                .do_space = do_space,
                .do_inodes = do_inodes,
                .shown_error = 0,
                .updated = 0,

                .collected = 0,

                .st_space = NULL,
                .rd_space_avail = NULL,
                .rd_space_used = NULL,
                .rd_space_reserved = NULL,

                .st_inodes = NULL,
                .rd_inodes_avail = NULL,
                .rd_inodes_used = NULL,
                .rd_inodes_reserved = NULL
        };

        m = dictionary_set(dict_mountpoints, mi->mount_point, &mp, sizeof(struct mount_point_metadata));
    }

    m->updated = 1;

    if(unlikely(m->do_space == CONFIG_BOOLEAN_NO && m->do_inodes == CONFIG_BOOLEAN_NO))
        return;

    if(unlikely(mi->flags & MOUNTINFO_READONLY && !m->collected))
        return;

    struct statvfs buff_statvfs;
    if (statvfs(mi->mount_point, &buff_statvfs) < 0) {
        if(!m->shown_error) {
            error("DISKSPACE: failed to statvfs() mount point '%s' (disk '%s', filesystem '%s', root '%s')"
                  , mi->mount_point
                  , disk
                  , mi->filesystem?mi->filesystem:""
                  , mi->root?mi->root:""
            );
            m->shown_error = 1;
        }
        return;
    }
    m->shown_error = 0;

    // logic found at get_fs_usage() in coreutils
    unsigned long bsize = (buff_statvfs.f_frsize) ? buff_statvfs.f_frsize : buff_statvfs.f_bsize;

    fsblkcnt_t bavail         = buff_statvfs.f_bavail;
    fsblkcnt_t btotal         = buff_statvfs.f_blocks;
    fsblkcnt_t bavail_root    = buff_statvfs.f_bfree;
    fsblkcnt_t breserved_root = bavail_root - bavail;
    fsblkcnt_t bused;
    if(likely(btotal >= bavail_root))
        bused = btotal - bavail_root;
    else
        bused = bavail_root - btotal;

#ifdef NETDATA_INTERNAL_CHECKS
    if(unlikely(btotal != bavail + breserved_root + bused))
        error("DISKSPACE: disk block statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)btotal, (unsigned long long)bavail, (unsigned long long)breserved_root, (unsigned long long)bused);
#endif

    // --------------------------------------------------------------------------

    fsfilcnt_t favail         = buff_statvfs.f_favail;
    fsfilcnt_t ftotal         = buff_statvfs.f_files;
    fsfilcnt_t favail_root    = buff_statvfs.f_ffree;
    fsfilcnt_t freserved_root = favail_root - favail;
    fsfilcnt_t fused          = ftotal - favail_root;

    if(m->do_inodes == CONFIG_BOOLEAN_AUTO && favail == (fsfilcnt_t)-1) {
        // this file system does not support inodes reporting
        // eg. cephfs
        m->do_inodes = CONFIG_BOOLEAN_NO;
    }

#ifdef NETDATA_INTERNAL_CHECKS
    if(unlikely(btotal != bavail + breserved_root + bused))
        error("DISKSPACE: disk inode statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)ftotal, (unsigned long long)favail, (unsigned long long)freserved_root, (unsigned long long)fused);
#endif

    // --------------------------------------------------------------------------

    int rendered = 0;

    if(m->do_space == CONFIG_BOOLEAN_YES || (m->do_space == CONFIG_BOOLEAN_AUTO && (bavail || breserved_root || bused))) {
        if(unlikely(!m->st_space)) {
            m->do_space = CONFIG_BOOLEAN_YES;
            m->st_space = rrdset_find_bytype_localhost("disk_space", disk);
            if(unlikely(!m->st_space)) {
                char title[4096 + 1];
                snprintfz(title, 4096, "Disk Space Usage for %s [%s]", family, mi->mount_source);
                m->st_space = rrdset_create_localhost(
                        "disk_space"
                        , disk
                        , NULL
                        , family
                        , "disk.space"
                        , title
                        , "GB"
                        , "diskspace"
                        , NULL
                        , 2023
                        , update_every
                        , RRDSET_TYPE_STACKED
                );
            }

            m->rd_space_avail    = rrddim_add(m->st_space, "avail", NULL, (collected_number)bsize, 1024 * 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
            m->rd_space_used     = rrddim_add(m->st_space, "used", NULL, (collected_number)bsize, 1024 * 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
            m->rd_space_reserved = rrddim_add(m->st_space, "reserved_for_root", "reserved for root", (collected_number)bsize, 1024 * 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
        }
        else
            rrdset_next(m->st_space);

        rrddim_set_by_pointer(m->st_space, m->rd_space_avail,    (collected_number)bavail);
        rrddim_set_by_pointer(m->st_space, m->rd_space_used,     (collected_number)bused);
        rrddim_set_by_pointer(m->st_space, m->rd_space_reserved, (collected_number)breserved_root);
        rrdset_done(m->st_space);

        rendered++;
    }

    // --------------------------------------------------------------------------

    if(m->do_inodes == CONFIG_BOOLEAN_YES || (m->do_inodes == CONFIG_BOOLEAN_AUTO && (favail || freserved_root || fused))) {
        if(unlikely(!m->st_inodes)) {
            m->do_inodes = CONFIG_BOOLEAN_YES;
            m->st_inodes = rrdset_find_bytype_localhost("disk_inodes", disk);
            if(unlikely(!m->st_inodes)) {
                char title[4096 + 1];
                snprintfz(title, 4096, "Disk Files (inodes) Usage for %s [%s]", family, mi->mount_source);
                m->st_inodes = rrdset_create_localhost(
                        "disk_inodes"
                        , disk
                        , NULL
                        , family
                        , "disk.inodes"
                        , title
                        , "Inodes"
                        , "diskspace"
                        , NULL
                        , 2024
                        , update_every
                        , RRDSET_TYPE_STACKED
                );
            }

            m->rd_inodes_avail    = rrddim_add(m->st_inodes, "avail", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
            m->rd_inodes_used     = rrddim_add(m->st_inodes, "used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
            m->rd_inodes_reserved = rrddim_add(m->st_inodes, "reserved_for_root", "reserved for root", 1, 1, RRD_ALGORITHM_ABSOLUTE);
        }
        else
            rrdset_next(m->st_inodes);

        rrddim_set_by_pointer(m->st_inodes, m->rd_inodes_avail,    (collected_number)favail);
        rrddim_set_by_pointer(m->st_inodes, m->rd_inodes_used,     (collected_number)fused);
        rrddim_set_by_pointer(m->st_inodes, m->rd_inodes_reserved, (collected_number)freserved_root);
        rrdset_done(m->st_inodes);

        rendered++;
    }

    // --------------------------------------------------------------------------

    if(likely(rendered))
        m->collected++;
}
Ejemplo n.º 30
0
int main(void) {
    /* dummy variables to prevent null warnings */
    char path[] = "";
    char mode[] = "";
    char buf[1];
    struct stat st;
    struct statfs stfs;
    struct statvfs stvfs;
    fpos_t fpos;
    off_t off;
    struct rlimit rlim;
    glob_t glb;
    int result;
    DIR* dir;
    struct dirent direntry;
    struct dirent* pdirentry;
    struct dirent** ppdirentry;
    const struct dirent *pconstdirentry;
    dir = 0;
    result = alphasort(&pconstdirentry, &pconstdirentry);
    creat(path, 0);
    fgetpos(0, &fpos);
    fopen(path, mode);
    freopen(path, mode, 0);
    fseeko(0, 0, 0);
    fsetpos(0, &fpos);
    fstat(0, &st);
    fstatat(0, path, &st, 0);
    fstatfs(0, &stfs);
    fstatvfs(0, &stvfs);
    ftello(0);
    ftruncate(0, 0);
    ftw(path, ftw_stub, 0);
    getdirentries(0, buf, 0, &off);
    getrlimit(0, &rlim);
    glob(path, 0, glob_stub, &glb);
    lockf(0, 0, 0);
    lseek(0, 0, 0);
    lstat(path, &st);
    mkostemp(path, 0);
    mkstemp(path);
    mmap(buf, 0, 0, 0, 0, 0);
    nftw(path, nftw_stub, 0, 0);
    open(path, 0);
    open(path, 0, 0);
    openat(0, path, 0);
    openat(0, path, 0, 0);
    posix_fadvise(0, 0, 0, 0);
    posix_fallocate(0, 0, 0);
    pread(0, buf, 0, 0);
    pwrite(0, buf, 0, 0);
    readdir(dir);
    readdir_r(dir, &direntry, &pdirentry);
    scandir(path, &ppdirentry, scandir_filter_stub, scandir_compare_stub);
    sendfile(0, 0, &off, 0);
    setrlimit(0, &rlim);
    stat(path, &st);
    statfs(path, &stfs);
    statvfs(path, &stvfs);
    tmpfile();
    truncate(path, 0);
    result = versionsort(&pconstdirentry, &pconstdirentry);
    return result;
}