add function is_rotational_device_by_path

use_iouring
YuQing 2024-11-01 11:31:46 +08:00
parent 21366a4a2e
commit 83f757672b
4 changed files with 159 additions and 34 deletions

View File

@ -1,7 +1,8 @@
Version 1.76 2024-10-31 Version 1.76 2024-11-01
* get_mounted_filesystems act as program df * get_mounted_filesystems act as program df
* add function get_statfs_by_path * add function get_statfs_by_path
* add function is_rotational_device_by_path
Version 1.75 2024-09-22 Version 1.75 2024-09-22
* task init callback support extra argument * task init callback support extra argument

View File

@ -199,6 +199,47 @@ int get_boot_time(struct timeval *boot_time)
snprintf(left.f_mntonname, sizeof(left.f_mntonname), "%s", mntonname); \ snprintf(left.f_mntonname, sizeof(left.f_mntonname), "%s", mntonname); \
} while (0) } 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<disk_ftype_count; i++)
{
if (strcmp(type_name, disk_ftypes[i]) == 0)
{
*device_type = fast_device_type_disk;
return 0;
}
}
if (strcmp(type_name, "tmpfs") == 0 || strcmp(type_name, "devtmpfs") == 0)
{
*device_type = fast_device_type_memory;
return 0;
}
if (strcmp(type_name, "nfs") == 0 || strcmp(type_name, "smb") == 0 ||
strcmp(type_name, "cifs") == 0 || strcmp(type_name, "afp") == 0)
{
*device_type = fast_device_type_network;
return 0;
}
if (strcmp(type_name, "fuse") == 0)
{
*device_type = fast_device_type_fuse;
return 0;
}
return ENOENT;
}
#endif
int get_mounted_filesystems(struct fast_statfs *stats, int get_mounted_filesystems(struct fast_statfs *stats,
const int size, int *count) const int size, int *count)
{ {
@ -213,10 +254,6 @@ int get_mounted_filesystems(struct fast_statfs *stats,
char line[1024]; char line[1024];
int result; int result;
int i; int i;
char *ftypes[] = {"ext3", "ext4", "xfs", "btrfs", "f2fs", "jfs",
"reiserfs", "nilfs", "zfs", "ufs", "ntfs", "vfat", "udf",
"tmpfs", "devtmpfs", "nfs", "smb", "cifs", "fuse"};
const int ftype_count = sizeof(ftypes) / sizeof(char *);
*count = 0; *count = 0;
fp = fopen(filename, "r"); fp = fopen(filename, "r");
@ -245,26 +282,16 @@ int get_mounted_filesystems(struct fast_statfs *stats,
mntonname = strsep(&p, " \t"); mntonname = strsep(&p, " \t");
fstypename = strsep(&p, " \t"); fstypename = strsep(&p, " \t");
toLowercase(fstypename); toLowercase(fstypename);
for (i=0; i<ftype_count; i++) if (get_device_type(fstypename, &stats[*count].device_type) == 0)
{ {
if (strcmp(fstypename, ftypes[i]) == 0) snprintf(stats[*count].f_mntfromname, sizeof(stats[*count].
{ f_mntfromname), "%s", mntfromname);
break; snprintf(stats[*count].f_mntonname, sizeof(stats[*count].
} f_mntonname), "%s", mntonname);
snprintf(stats[*count].f_fstypename, sizeof(stats[*count].
f_fstypename), "%s", fstypename);
(*count)++;
} }
if (i == ftype_count) //not found
{
continue;
}
snprintf(stats[*count].f_mntfromname,
sizeof(stats[*count].f_mntfromname), "%s", mntfromname);
snprintf(stats[*count].f_mntonname,
sizeof(stats[*count].f_mntonname), "%s", mntonname);
snprintf(stats[*count].f_fstypename,
sizeof(stats[*count].f_fstypename), "%s", fstypename);
(*count)++;
} }
fclose(fp); fclose(fp);
@ -295,7 +322,7 @@ int get_mounted_filesystems(struct fast_statfs *stats,
int i; int i;
mnts = NULL; mnts = NULL;
*count = getmntinfo(&mnts, 0); *count = getmntinfo(&mnts, MNT_NOWAIT);
if (*count == 0) if (*count == 0)
{ {
result = errno != 0 ? errno : EPERM; result = errno != 0 ? errno : EPERM;
@ -321,6 +348,7 @@ int get_mounted_filesystems(struct fast_statfs *stats,
SET_STATFS_FIELDS(stats[i], mnts[i]); SET_STATFS_FIELDS(stats[i], mnts[i]);
#ifdef HAVE_FILE_SYSTEM_ID #ifdef HAVE_FILE_SYSTEM_ID
stats[i].f_fsid = mnts[i].f_fsid; stats[i].f_fsid = mnts[i].f_fsid;
stats[i].device_type = fast_device_type_unkown;
#endif #endif
SET_MNT_FIELDS(stats[i], mnts[i].f_fstypename, SET_MNT_FIELDS(stats[i], mnts[i].f_fstypename,
mnts[i].f_mntfromname, mnts[i].f_mntonname); mnts[i].f_mntfromname, mnts[i].f_mntonname);
@ -353,7 +381,10 @@ int get_statfs_by_path(const char *path, FastStatFS *statfs)
return result; return result;
} }
realpath(path, resolved_path); if (realpath(path, resolved_path) == NULL)
{
return errno != 0 ? errno : ENOENT;
}
path_len = strlen(resolved_path); path_len = strlen(resolved_path);
matched_len = 0; matched_len = 0;
end = stats + count; end = stats + count;
@ -380,6 +411,65 @@ int get_statfs_by_path(const char *path, FastStatFS *statfs)
return (matched_len > 0 ? 0 : ENOENT); return (matched_len > 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) #if defined(OS_LINUX) || defined(OS_FREEBSD)
typedef struct fast_process_array { typedef struct fast_process_array {
@ -679,7 +769,7 @@ int get_processes(struct fast_process_info **processes, int *count)
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
mib[1] = KERN_PROC; mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ALL; mib[2] = KERN_PROC_ALL;
mib[3] = 0; mib[3] = 0;
size = 0; size = 0;
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
{ {

View File

@ -42,6 +42,14 @@ extern "C" {
#define MNAMELEN 128 #define MNAMELEN 128
#endif #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 { typedef struct fast_statfs {
long f_type; /* type of file system (see below) */ long f_type; /* type of file system (see below) */
long f_bsize; /* optimal transfer block size */ long f_bsize; /* optimal transfer block size */
@ -56,6 +64,7 @@ extern "C" {
char f_fstypename[MFSNAMELEN]; /* fs type name */ char f_fstypename[MFSNAMELEN]; /* fs type name */
char f_mntfromname[MNAMELEN]; /* mounted file system */ char f_mntfromname[MNAMELEN]; /* mounted file system */
char f_mntonname[MNAMELEN]; /* directory on which mounted */ char f_mntonname[MNAMELEN]; /* directory on which mounted */
FastDeviceType device_type;
} FastStatFS; } FastStatFS;
#if defined(OS_LINUX) || defined(OS_FREEBSD) #if defined(OS_LINUX) || defined(OS_FREEBSD)
@ -120,6 +129,23 @@ extern "C" {
} FastProcessInfo; } FastProcessInfo;
#endif #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 /** get system total memory size
* parameters: * parameters:
* mem_size: return the total memory size * 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); 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) #if defined(OS_LINUX) || defined(OS_FREEBSD)
/** get processes /** get processes

View File

@ -88,17 +88,19 @@ int main(int argc, char *argv[])
printf("mounted fs count: %d\n", count); printf("mounted fs count: %d\n", count);
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
printf("%s => %s %s %ld %ld %ld %ld %ld %ld %ld\n", printf("%s => %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_mntfromname, stats[i].f_mntonname,
stats[i].f_type, stats[i].f_bsize, stats[i].f_blocks, stats[i].f_fstypename, stats[i].f_type, stats[i].f_bsize,
stats[i].f_bfree, stats[i].f_bavail, stats[i].f_files, stats[i].f_blocks, stats[i].f_bfree, stats[i].f_bavail,
stats[i].f_ffree); stats[i].f_files, stats[i].f_ffree);
} }
path = "/root"; path = "/";
if (get_statfs_by_path(path, &statfs) == 0) { if (get_statfs_by_path(path, &statfs) == 0) {
printf("\ninput path: %s, %s => %s, type: %s\n\n", path, printf("\ninput path: %s, %s => %s, type: %s, category: %s, "
statfs.f_mntfromname, statfs.f_mntonname, "rotational: %d\n\n", path, statfs.f_mntfromname,
statfs.f_fstypename); 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) #if defined(OS_LINUX) || defined(OS_FREEBSD)