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
* 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

View File

@ -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<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,
const int size, int *count)
{
@ -213,10 +254,6 @@ int get_mounted_filesystems(struct fast_statfs *stats,
char line[1024];
int result;
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;
fp = fopen(filename, "r");
@ -245,27 +282,17 @@ int get_mounted_filesystems(struct fast_statfs *stats,
mntonname = strsep(&p, " \t");
fstypename = strsep(&p, " \t");
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)
{
break;
}
}
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);
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);
for (i=0; i<*count; i++)
@ -295,7 +322,7 @@ int get_mounted_filesystems(struct fast_statfs *stats,
int i;
mnts = NULL;
*count = getmntinfo(&mnts, 0);
*count = getmntinfo(&mnts, MNT_NOWAIT);
if (*count == 0)
{
result = errno != 0 ? errno : EPERM;
@ -321,6 +348,7 @@ int get_mounted_filesystems(struct fast_statfs *stats,
SET_STATFS_FIELDS(stats[i], mnts[i]);
#ifdef HAVE_FILE_SYSTEM_ID
stats[i].f_fsid = mnts[i].f_fsid;
stats[i].device_type = fast_device_type_unkown;
#endif
SET_MNT_FIELDS(stats[i], mnts[i].f_fstypename,
mnts[i].f_mntfromname, mnts[i].f_mntonname);
@ -353,7 +381,10 @@ int get_statfs_by_path(const char *path, FastStatFS *statfs)
return result;
}
realpath(path, resolved_path);
if (realpath(path, resolved_path) == NULL)
{
return errno != 0 ? errno : ENOENT;
}
path_len = strlen(resolved_path);
matched_len = 0;
end = stats + count;
@ -380,6 +411,65 @@ int get_statfs_by_path(const char *path, FastStatFS *statfs)
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)
typedef struct fast_process_array {

View File

@ -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

View File

@ -88,17 +88,19 @@ int main(int argc, char *argv[])
printf("mounted fs count: %d\n", count);
for (i=0; i<count; i++) {
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_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)