Files
fastfetch/src/detection/diskio/diskio_linux.c
T

105 lines
3.7 KiB
C
Raw Normal View History

2023-10-07 16:21:26 +08:00
#include "diskio.h"
#include "common/io/io.h"
#include "common/properties.h"
2023-10-07 16:21:26 +08:00
#include "util/stringUtils.h"
#include <ctype.h>
#include <limits.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
2023-12-17 10:38:16 +08:00
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
if(sysBlockDirp == NULL)
return "opendir(\"/sys/block/\") == NULL";
2023-10-07 16:21:26 +08:00
2023-12-17 10:38:16 +08:00
struct dirent* sysBlockEntry;
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
2023-10-07 16:21:26 +08:00
{
2023-12-17 10:38:16 +08:00
const char* const devName = sysBlockEntry->d_name;
2023-10-07 16:21:26 +08:00
2023-12-17 10:38:16 +08:00
if (devName[0] == '.')
2023-10-07 16:21:26 +08:00
continue;
2023-12-17 10:38:16 +08:00
char pathSysBlock[PATH_MAX];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
2023-12-18 17:04:26 +09:00
char pathSysDeviceReal[PATH_MAX];
ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
if (pathLength < 0)
continue;
pathSysDeviceReal[pathLength] = '\0';
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
continue;
2023-10-07 16:21:26 +08:00
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
continue;
2023-10-07 16:21:26 +08:00
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInit(&device->name);
2023-12-17 10:38:16 +08:00
2023-10-07 16:21:26 +08:00
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
if (ffAppendFileBuffer(pathSysBlock, &device->name))
{
ffStrbufTrimRightSpace(&device->name);
if (device->name.length > 0)
ffStrbufAppendC(&device->name, ' ');
}
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
ffAppendFileBuffer(pathSysBlock, &device->name);
ffStrbufTrimRightSpace(&device->name);
if (device->name.length == 0)
ffStrbufSetS(&device->name, devName);
else if (ffStrStartsWith(devName, "nvme"))
{
int devid, nsid;
if (sscanf(devName, "nvme%dn%d", &devid, &nsid) == 2)
{
bool multiNs = nsid > 1;
if (!multiNs)
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/nvme%dn2", devName, devid);
multiNs = ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY);
}
if (multiNs)
{
// In Asahi Linux, there are multiple namespaces for the same NVMe drive.
ffStrbufAppendF(&device->name, " - %d", nsid);
}
}
}
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
2023-12-17 10:38:16 +08:00
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
2023-12-17 10:38:16 +08:00
}
2023-10-07 16:21:26 +08:00
}
2023-12-17 10:38:16 +08:00
// I/Os merges sectors ticks ...
uint64_t nRead, sectorRead, nWritten, sectorWritten;
{
char sysBlockStat[PROC_FILE_BUFFSIZ];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(sysBlockStat) - 1, sysBlockStat);
if (fileSize <= 0) continue;
sysBlockStat[fileSize] = '\0';
if (sscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, &sectorRead, &nWritten, &sectorWritten) <= 0)
continue;
}
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
2023-10-07 16:21:26 +08:00
device->bytesRead = sectorRead * 512;
device->bytesWritten = sectorWritten * 512;
device->readCount = nRead;
device->writeCount = nWritten;
}
return NULL;
}