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; }
// 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; }
/* * 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; }
void getDisk() { struct statvfs root; statvfs("/", &root); remaining = root.f_bfree * root.f_bsize; getSizeUnit(); }
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); }
/* * 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); }
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; }
/* * 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; }
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; }
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 }
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); }
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; } }
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; }
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); }
/** 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; }
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; }
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 {
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); }
/* 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; }
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); }
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; }
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 }
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; }
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); }
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); }
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; }
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; }
/* 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; }
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++; }
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; }