From 83f757672b639b02f45dad9c1a6ba2af58ba92bf Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Fri, 1 Nov 2024 11:31:46 +0800 Subject: [PATCH] add function is_rotational_device_by_path --- HISTORY | 3 +- src/system_info.c | 140 +++++++++++++++++++++++++++++++++------- src/system_info.h | 32 +++++++++ src/tests/test_mblock.c | 18 +++--- 4 files changed, 159 insertions(+), 34 deletions(-) diff --git a/HISTORY b/HISTORY index 81fe791..52cb95f 100644 --- a/HISTORY +++ b/HISTORY @@ -1,7 +1,8 @@ -Version 1.76 2024-10-31 +Version 1.76 2024-11-01 * get_mounted_filesystems act as program df * add function get_statfs_by_path + * add function is_rotational_device_by_path Version 1.75 2024-09-22 * task init callback support extra argument diff --git a/src/system_info.c b/src/system_info.c index ee5eb67..76e1bf1 100644 --- a/src/system_info.c +++ b/src/system_info.c @@ -199,6 +199,47 @@ int get_boot_time(struct timeval *boot_time) snprintf(left.f_mntonname, sizeof(left.f_mntonname), "%s", mntonname); \ } while (0) +#ifdef OS_LINUX +static int get_device_type(const char *type_name, FastDeviceType *device_type) +{ + int i; + const char *disk_ftypes[] = {"ext2", "ext3", "ext4", "xfs", + "btrfs", "f2fs", "jfs", "reiserfs", "nilfs", "zfs", + "ufs", "ntfs", "vfat", "udf", "romfs", "squashfs"}; + const int disk_ftype_count = sizeof(disk_ftypes) / sizeof(char *); + + for (i=0; i 0 ? 0 : ENOENT); } +bool is_rotational_device_by_path(const char *path) +{ +#if defined(OS_LINUX) +#define DEV_PATH_PREFIX_STR "/dev/" +#define DEV_PATH_PREFIX_LEN (sizeof(DEV_PATH_PREFIX_STR) - 1) + + int result; + int fd; + int len; + FastStatFS statfs; + char resolved_path[PATH_MAX]; + char filename[PATH_MAX]; + char buff[8]; + char *device_name; + + if ((result=get_statfs_by_path(path, &statfs)) != 0) { + return true; + } + + if (statfs.device_type == fast_device_type_memory) { + return false; + } + + if (!(statfs.device_type == fast_device_type_disk && + strncmp(statfs.f_mntfromname, DEV_PATH_PREFIX_STR, + DEV_PATH_PREFIX_LEN) == 0)) + { + return true; + } + + if (realpath(statfs.f_mntfromname, resolved_path) == NULL) { + return true; + } + if (strncmp(resolved_path, DEV_PATH_PREFIX_STR, + DEV_PATH_PREFIX_LEN) != 0) + { + return true; + } + device_name = resolved_path + DEV_PATH_PREFIX_LEN; + sprintf(filename, "/sys/class/block/%s/queue/rotational", device_name); + if ((fd=open(filename, O_RDONLY)) < 0) { + sprintf(filename, "/sys/class/block/%s/../queue/rotational", device_name); + if ((fd=open(filename, O_RDONLY)) < 0) { + return true; + } + } + + len = read(fd, buff, sizeof(buff)); + close(fd); + if (len == 1 || len == 2) { + return (buff[0] != '0'); + } else { + return true; + } +#else + return true; +#endif +} + #if defined(OS_LINUX) || defined(OS_FREEBSD) typedef struct fast_process_array { @@ -679,7 +769,7 @@ int get_processes(struct fast_process_info **processes, int *count) mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_ALL; - mib[3] = 0; + mib[3] = 0; size = 0; if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) { diff --git a/src/system_info.h b/src/system_info.h index 4e3a07b..a6d0de7 100644 --- a/src/system_info.h +++ b/src/system_info.h @@ -42,6 +42,14 @@ extern "C" { #define MNAMELEN 128 #endif + typedef enum fast_device_type { + fast_device_type_unkown = 0, + fast_device_type_disk, + fast_device_type_memory, + fast_device_type_fuse, + fast_device_type_network + } FastDeviceType; + typedef struct fast_statfs { long f_type; /* type of file system (see below) */ long f_bsize; /* optimal transfer block size */ @@ -56,6 +64,7 @@ extern "C" { char f_fstypename[MFSNAMELEN]; /* fs type name */ char f_mntfromname[MNAMELEN]; /* mounted file system */ char f_mntonname[MNAMELEN]; /* directory on which mounted */ + FastDeviceType device_type; } FastStatFS; #if defined(OS_LINUX) || defined(OS_FREEBSD) @@ -120,6 +129,23 @@ extern "C" { } FastProcessInfo; #endif + static inline const char *get_device_type_caption( + const FastDeviceType device_type) + { + switch (device_type) { + case fast_device_type_disk: + return "disk"; + case fast_device_type_memory: + return "memory"; + case fast_device_type_fuse: + return "fuse"; + case fast_device_type_network: + return "network"; + default: + return "unkown"; + } + } + /** get system total memory size * parameters: * mem_size: return the total memory size @@ -159,6 +185,12 @@ int get_mounted_filesystems(struct fast_statfs *stats, */ int get_statfs_by_path(const char *path, FastStatFS *statfs); +/** is rotational device by path + * parameters: + * path: the path + * return: true for rotational device, otherwise false +*/ +bool is_rotational_device_by_path(const char *path); #if defined(OS_LINUX) || defined(OS_FREEBSD) /** get processes diff --git a/src/tests/test_mblock.c b/src/tests/test_mblock.c index d7431e0..970ab6d 100644 --- a/src/tests/test_mblock.c +++ b/src/tests/test_mblock.c @@ -88,17 +88,19 @@ int main(int argc, char *argv[]) printf("mounted fs count: %d\n", count); for (i=0; i %s %s %ld %ld %ld %ld %ld %ld %ld\n", - stats[i].f_mntfromname, stats[i].f_mntonname, stats[i].f_fstypename, - stats[i].f_type, stats[i].f_bsize, stats[i].f_blocks, - stats[i].f_bfree, stats[i].f_bavail, stats[i].f_files, - stats[i].f_ffree); + stats[i].f_mntfromname, stats[i].f_mntonname, + stats[i].f_fstypename, stats[i].f_type, stats[i].f_bsize, + stats[i].f_blocks, stats[i].f_bfree, stats[i].f_bavail, + stats[i].f_files, stats[i].f_ffree); } - path = "/root"; + path = "/"; if (get_statfs_by_path(path, &statfs) == 0) { - printf("\ninput path: %s, %s => %s, type: %s\n\n", path, - statfs.f_mntfromname, statfs.f_mntonname, - statfs.f_fstypename); + printf("\ninput path: %s, %s => %s, type: %s, category: %s, " + "rotational: %d\n\n", path, statfs.f_mntfromname, + statfs.f_mntonname, statfs.f_fstypename, + get_device_type_caption(statfs.device_type), + is_rotational_device_by_path(path)); } #if defined(OS_LINUX) || defined(OS_FREEBSD)