From 08cdeb3bcf977067dd0a31d65bf43ce6b534db72 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 12 Oct 2024 13:29:58 +0800 Subject: [PATCH] PhysicalDisk (Linux): simplify code --- .../physicaldisk/physicaldisk_linux.c | 267 +++++++++--------- 1 file changed, 130 insertions(+), 137 deletions(-) diff --git a/src/detection/physicaldisk/physicaldisk_linux.c b/src/detection/physicaldisk/physicaldisk_linux.c index 1b12d70fb..266a37218 100644 --- a/src/detection/physicaldisk/physicaldisk_linux.c +++ b/src/detection/physicaldisk/physicaldisk_linux.c @@ -5,19 +5,18 @@ #include #include +#include +#include -static double detectNvmeTemp(const char* devName) +static double detectNvmeTemp(int devfd) { - char pathSysBlock[PATH_MAX]; - int index = snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/hwmon$/temp1_input", devName); - if (index <= 0) return FF_PHYSICALDISK_TEMP_UNSET; - index -= (int) sizeof("/temp1_input"); + char pathHwmon[] = "hwmon$/temp1_input"; for (char c = '0'; c <= '9'; c++) // hopefully there's only one digit { - pathSysBlock[index] = c; + pathHwmon[strlen("hwmon")] = c; char buffer[64]; - ssize_t size = ffReadFileData(pathSysBlock, sizeof(buffer), buffer); + ssize_t size = ffReadFileDataRelative(devfd, pathHwmon, sizeof(buffer), buffer); if (size > 0) { buffer[size] = '\0'; @@ -29,6 +28,126 @@ static double detectNvmeTemp(const char* devName) return FF_PHYSICALDISK_TEMP_UNSET; } +static void parsePhysicalDisk(int dfd, const char* devName, const char* pathSysDeviceReal, FFPhysicalDiskOptions* options, FFlist* result) +{ + int devfd = openat(dfd, "device", O_RDONLY | O_CLOEXEC); + if (devfd < 0) return; + + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); + + { + if (ffAppendFileBufferRelative(devfd, "vendor", &name)) + { + ffStrbufTrimRightSpace(&name); + if (name.length > 0) + ffStrbufAppendC(&name, ' '); + } + + ffAppendFileBufferRelative(devfd, "model", &name); + ffStrbufTrimRightSpace(&name); + + if (name.length == 0) + ffStrbufSetS(&name, devName); + + if (ffStrStartsWith(devName, "nvme")) + { + int devid, nsid; + if (sscanf(devName, "nvme%dn%d", &devid, &nsid) == 2) + { + bool multiNs = nsid > 1; + if (!multiNs) + { + char pathSysBlock[32]; + snprintf(pathSysBlock, sizeof(pathSysBlock), "/dev/nvme%dn2", devid); + multiNs = access(pathSysBlock, F_OK) == 0; + } + if (multiNs) + { + // In Asahi Linux, there are multiple namespaces for the same NVMe drive. + ffStrbufAppendF(&name, " - %d", nsid); + } + } + } + + if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) + return; + } + + FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result); + device->type = FF_PHYSICALDISK_TYPE_NONE; + ffStrbufInitMove(&device->name, &name); + ffStrbufInitF(&device->devPath, "/dev/%s", devName); + + { + ffStrbufInit(&device->interconnect); + if (strstr(pathSysDeviceReal, "/usb") != NULL) + ffStrbufSetS(&device->interconnect, "USB"); + else if (strstr(pathSysDeviceReal, "/nvme") != NULL) + ffStrbufSetS(&device->interconnect, "NVMe"); + else if (strstr(pathSysDeviceReal, "/ata") != NULL) + ffStrbufSetS(&device->interconnect, "ATA"); + else if (strstr(pathSysDeviceReal, "/scsi") != NULL) + ffStrbufSetS(&device->interconnect, "SCSI"); + else + { + if (ffAppendFileBufferRelative(devfd, "transport", &device->interconnect)) + ffStrbufTrimRightSpace(&device->interconnect); + } + } + + { + char isRotationalChar = '1'; + if (ffReadFileDataRelative(dfd, "queue/rotational", 1, &isRotationalChar) > 0) + device->type |= isRotationalChar == '1' ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD; + } + + { + char blkSize[32]; + ssize_t fileSize = ffReadFileDataRelative(dfd, "size", sizeof(blkSize) - 1, blkSize); + if (fileSize > 0) + { + blkSize[fileSize] = 0; + device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512; + } + else + device->size = 0; + } + + { + char removableChar = '0'; + if (ffReadFileDataRelative(dfd, "removable", 1, &removableChar) > 0) + device->type |= removableChar == '1' ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED; + } + + { + char roChar = '0'; + if (ffReadFileDataRelative(dfd, "ro", 1, &roChar) > 0) + device->type |= roChar == '1' ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE; + } + + { + ffStrbufInit(&device->serial); + if (ffReadFileBufferRelative(devfd, "serial", &device->serial)) + ffStrbufTrimRightSpace(&device->serial); + } + + { + ffStrbufInit(&device->revision); + if (ffReadFileBufferRelative(devfd, "firmware_rev", &device->revision)) + ffStrbufTrimRightSpace(&device->revision); + else + { + if (ffReadFileBufferRelative(devfd, "rev", &device->revision)) + ffStrbufTrimRightSpace(&device->revision); + } + } + + if (options->temp) + device->temperature = detectNvmeTemp(devfd); + else + device->temperature = FF_PHYSICALDISK_TEMP_UNSET; +} + const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) { FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/"); @@ -43,8 +162,8 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) if (devName[0] == '.') continue; - char pathSysBlock[PATH_MAX]; - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName); + char pathSysBlock[sizeof("/sys/block/") + sizeof(sysBlockEntry->d_name)]; + snprintf(pathSysBlock, sizeof(pathSysBlock), "/sys/block/%s", devName); char pathSysDeviceReal[PATH_MAX]; ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1); @@ -55,134 +174,8 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device continue; - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName); - if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY)) - continue; - - FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result); - device->type = FF_PHYSICALDISK_TYPE_NONE; - ffStrbufInit(&device->name); - - { - 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)) - { - ffStrbufDestroy(&device->name); - result->length--; - continue; - } - } - - ffStrbufInitF(&device->devPath, "/dev/%s", devName); - - { - ffStrbufInit(&device->interconnect); - if (strstr(pathSysDeviceReal, "/usb") != NULL) - ffStrbufSetS(&device->interconnect, "USB"); - else if (strstr(pathSysDeviceReal, "/nvme") != NULL) - ffStrbufSetS(&device->interconnect, "NVMe"); - else if (strstr(pathSysDeviceReal, "/ata") != NULL) - ffStrbufSetS(&device->interconnect, "ATA"); - else if (strstr(pathSysDeviceReal, "/scsi") != NULL) - ffStrbufSetS(&device->interconnect, "SCSI"); - else - { - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName); - if (ffAppendFileBuffer(pathSysBlock, &device->interconnect)) - ffStrbufTrimRightSpace(&device->interconnect); - } - } - - { - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName); - char isRotationalChar = '1'; - if (ffReadFileData(pathSysBlock, 1, &isRotationalChar) > 0) - device->type |= isRotationalChar == '1' ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD; - } - - { - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName); - char blkSize[32]; - ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blkSize) - 1, blkSize); - if (fileSize > 0) - { - blkSize[fileSize] = 0; - device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512; - } - else - device->size = 0; - } - - { - char removableChar = '0'; - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/removable", devName); - if (ffReadFileData(pathSysBlock, 1, &removableChar) > 0) - device->type |= removableChar == '1' ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED; - } - - { - char roChar = '0'; - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/ro", devName); - if (ffReadFileData(pathSysBlock, 1, &roChar) > 0) - device->type |= roChar == '1' ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE; - } - - { - ffStrbufInit(&device->serial); - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName); - if (ffReadFileBuffer(pathSysBlock, &device->serial)) - ffStrbufTrimRightSpace(&device->serial); - } - - { - ffStrbufInit(&device->revision); - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/firmware_rev", devName); - if (ffReadFileBuffer(pathSysBlock, &device->revision)) - ffStrbufTrimRightSpace(&device->revision); - else - { - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/rev", devName); - if (ffReadFileBuffer(pathSysBlock, &device->revision)) - ffStrbufTrimRightSpace(&device->revision); - } - } - - if (options->temp) - device->temperature = detectNvmeTemp(devName); - else - device->temperature = FF_PHYSICALDISK_TEMP_UNSET; + int dfd = openat(dirfd(sysBlockDirp), devName, O_RDONLY | O_CLOEXEC); + if (dfd > 0) parsePhysicalDisk(dfd, devName, pathSysDeviceReal, options, result); } return NULL;