From 10c15228ec1811b64d01c143f68be678ba31415d Mon Sep 17 00:00:00 2001 From: yuqing Date: Tue, 12 Jan 2016 16:32:26 +0800 Subject: [PATCH] add function get_mounted_filesystems --- HISTORY | 1 + src/system_info.c | 130 ++++++++++++++++++++++++++++++++++++++-- src/system_info.h | 34 +++++++++++ src/tests/test_mblock.c | 15 ++++- 4 files changed, 173 insertions(+), 7 deletions(-) diff --git a/HISTORY b/HISTORY index 681b0bb..6f59f2c 100644 --- a/HISTORY +++ b/HISTORY @@ -5,6 +5,7 @@ Version 1.24 2016-01-12 * make.sh: use sed to replace perl * support get local mac addresses * add system_info.h and system_info.c + * add function get_mounted_filesystems Version 1.23 2015-11-16 * sched_thread.c: task can execute in a new thread diff --git a/src/system_info.c b/src/system_info.c index 4c8a4cd..c21f7a3 100644 --- a/src/system_info.c +++ b/src/system_info.c @@ -19,14 +19,17 @@ #include #include #include +#include #include "logger.h" #include "system_info.h" #ifdef OS_LINUX #include +#include #else #ifdef OS_FREEBSD #include +#include #endif #endif @@ -82,9 +85,9 @@ int get_uptime(time_t *uptime) struct sysinfo si; if (sysinfo(&si) != 0) { - logError("file: "__FILE__", line: %d, " \ - "call sysinfo fail, " \ - "errno: %d, error info: %s", \ + logError("file: "__FILE__", line: %d, " + "call sysinfo fail, " + "errno: %d, error info: %s", __LINE__, errno, STRERROR(errno)); return errno != 0 ? errno : EPERM; } @@ -108,9 +111,9 @@ int get_uptime(time_t *uptime) else { *uptime = 0; - logError("file: "__FILE__", line: %d, " \ - "call sysctl fail, " \ - "errno: %d, error info: %s", \ + logError("file: "__FILE__", line: %d, " + "call sysctl fail, " + "errno: %d, error info: %s", __LINE__, errno, STRERROR(errno)); return errno != 0 ? errno : EPERM; } @@ -120,3 +123,118 @@ int get_uptime(time_t *uptime) #endif } +#define SET_STATFS_FIELDS(left, right) \ + do { \ + left.f_type = right.f_type; \ + left.f_bsize = right.f_bsize; \ + left.f_blocks = right.f_blocks; \ + left.f_bfree = right.f_bfree; \ + left.f_bavail = right.f_bavail; \ + left.f_files = right.f_files; \ + left.f_ffree = right.f_ffree; \ + left.f_fsid = right.f_fsid; \ + } while (0) + +#define SET_MNT_FIELDS(left, fstypename, mntfromname, mntonname) \ + do { \ + snprintf(left.f_fstypename, sizeof(left.f_fstypename), "%s", fstypename); \ + snprintf(left.f_mntfromname, sizeof(left.f_mntfromname), "%s", mntfromname); \ + snprintf(left.f_mntonname, sizeof(left.f_mntonname), "%s", mntonname); \ + } while (0) + +int get_mounted_filesystems(struct fast_statfs *stats, const int size, int *count) +{ +#ifdef OS_LINUX + const char *filename = "/proc/mounts"; + FILE *fp; + struct mntent *mnt; + struct statfs buf; + int result; + int i; + + *count = 0; + fp = setmntent(filename, "r"); + if (fp == NULL) + { + result = errno != 0 ? errno : ENOENT; + logError("file: "__FILE__", line: %d, " + "call setmntent fail, " + "errno: %d, error info: %s", + __LINE__, errno, STRERROR(errno)); + return result; + } + + memset(stats, 0, sizeof(struct fast_statfs) * size); + result = 0; + while ((mnt=getmntent(fp)) != NULL) + { + if (*count >= size) + { + result = ENOSPC; + break; + } + + SET_MNT_FIELDS(stats[*count], mnt->mnt_type, + mnt->mnt_fsname, mnt->mnt_dir); + + (*count)++; + } + endmntent(fp); + + for (i=0; i<*count; i++) + { + if (statfs(stats[i].f_mntonname, &buf) == 0) + { + SET_STATFS_FIELDS(stats[i], buf); + } + else + { + logWarning("file: "__FILE__", line: %d, " + "call statfs fail, " + "errno: %d, error info: %s", + __LINE__, errno, STRERROR(errno)); + } + } + + return result; +#else +#ifdef OS_FREEBSD + struct statfs *mnts; + int result; + int i; + + mnts = NULL; + *count = getmntinfo(&mnts, 0); + if (*count == 0) + { + result = errno != 0 ? errno : EPERM; + logError("file: "__FILE__", line: %d, " + "call getmntinfo fail, " + "errno: %d, error info: %s", + __LINE__, errno, STRERROR(errno)); + return result; + } + + if (*count <= size) + { + result = 0; + } + else + { + *count = size; + result = ENOSPC; + } + + for (i=0; i<*count; i++) + { + SET_STATFS_FIELDS(stats[i], mnts[i]); + SET_MNT_FIELDS(stats[i], mnts[i].f_fstypename, + mnts[i].f_mntfromname, mnts[i].f_mntonname); + } + return result; +#else +#error port me! +#endif +#endif +} + diff --git a/src/system_info.h b/src/system_info.h index d4f54b9..22b8385 100644 --- a/src/system_info.h +++ b/src/system_info.h @@ -15,12 +15,37 @@ #include #include #include +#include +#include #include "common_define.h" #ifdef __cplusplus extern "C" { #endif +#ifndef MFSNAMELEN +#define MFSNAMELEN 16 +#endif + +#ifndef MNAMELEN +#define MNAMELEN 128 +#endif + + typedef struct fast_statfs { + long f_type; /* type of file system (see below) */ + long f_bsize; /* optimal transfer block size */ + long f_blocks; /* total data blocks in file system */ + long f_bfree; /* free blocks in fs */ + long f_bavail; /* free blocks avail to non-superuser */ + long f_files; /* total file nodes in file system */ + long f_ffree; /* free file nodes in fs */ + fsid_t f_fsid; /* file system id */ + + char f_fstypename[MFSNAMELEN]; /* fs type name */ + char f_mntfromname[MNAMELEN]; /* mounted file system */ + char f_mntonname[MNAMELEN]; /* directory on which mounted */ + } FastStatFS; + /** get system total memory size * parameters: * mem_size: return the total memory size @@ -42,6 +67,15 @@ int get_sys_cpu_count(); */ int get_uptime(time_t *uptime); +/** get mounted file systems + * parameters: + * stats: the stat array + * size: max size of the array + * count: return the count of the array + * return: error no , 0 success, != 0 fail +*/ +int get_mounted_filesystems(struct fast_statfs *stats, const int size, int *count); + #ifdef __cplusplus } #endif diff --git a/src/tests/test_mblock.c b/src/tests/test_mblock.c index 3a0b1aa..9e07ca2 100644 --- a/src/tests/test_mblock.c +++ b/src/tests/test_mblock.c @@ -11,6 +11,7 @@ #include "ini_file_reader.h" #include "fast_mblock.h" #include "sockopt.h" +#include "system_info.h" struct my_struct { struct fast_mblock_man *mblock; @@ -47,6 +48,7 @@ int main(int argc, char *argv[]) ScheduleEntry scheduleEntries[1]; volatile bool continue_flag = true; FastIFConfig if_configs[32]; + struct fast_statfs stats[32]; if (argc > 1) { filename = argv[1]; @@ -65,13 +67,24 @@ int main(int argc, char *argv[]) return result; } - getifconfigs(if_configs, 32, &count); + getifconfigs(if_configs, sizeof(if_configs) / sizeof(if_configs[0]), &count); + printf("ifconfig count: %d\n", count); for (i=0; i