Как получить информацию об оборудовании в Linux с помощью C ++ - PullRequest
9 голосов
/ 04 марта 2011

Мне нужно получить спецификации жесткого диска на машинах Win и * nix. Я использовал <hdreg.h> в Linux так:

   static struct hd_driveid hd;
   int device;
   if ((device = open("/dev/sda", O_RDONLY | O_NONBLOCK)) < 0)
   {
      cerr << "ERROR: Cannot open device /dev/sda \n";
      exit(1);
   }

   if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
   {
      cout << hd.model << endl;
      cout << hd.serial_no << endl;
      cout << hd.heads << endl;
   }

Мне нужно hd_driveid, чтобы сообщить мне больше информации о диске. Я хочу знать:

  • Количество разделов
  • Характеристики каждого раздела (формат, метка, флаги, размер, начальная точка, количество дорожек и т. Д.)
  • Количество дорожек на цилиндр
  • Общее количество треков
  • Максимальный размер блока
  • Минимальный размер блока
  • Размер блока по умолчанию
  • Общий размер устройства

Мои вопросы:

  1. Есть ли общее (независимый от платформы) способ подключить оборудование? Я хотел бы использовать один и тот же код для win и * nix. (даже если не было другого пути, кроме встраивание ассемблерного кода в cpp)
  2. Если нет, как я могу получить вышеуказанную информацию в * nix?

Ответы [ 5 ]

9 голосов
/ 04 марта 2011

Почти все в вашем списке не имеет ничего общего с "спецификациями жесткого диска":

  • Количество разделов зависит от чтения таблицы разделов, и, если у вас есть какие-либо расширенные разделы, разделтаблицы этих разделов.ОС обычно делает этот бит за вас при загрузке драйвера устройства.
  • Информация о разделе (а именно метка тома) обычно недоступна в таблице разделов.Вам нужно угадать тип файловой системы и проанализировать заголовок файловой системы.Единственная вещь в таблице разделов - это байт «type», который не так уж много говорит вам, и старт / размер.
  • Жесткие диски не дадут вам «реальной» информации CHS.Кроме того, информация CHS, которую предоставляет привод, является «неверной» с точки зрения BIOS (BIOS выполняет свою собственную обманку).
  • Жесткие диски имеют фиксированный размер сектора, который вы можете получить с помощью hd_driveid.sector_bytes (обычно 512, но некоторые современные накопители используют 4096).Я не знаю о максимальном «размере блока», который является свойством файловой системы.Я также не уверен, почему это полезно.
  • Общий размер в секторах указан в hd_driveid.lba_capacity_2.Кроме того, размер в байтах, вероятно, можно получить с помощью чего-то вроде

    #define _FILE_OFFSET_BITS 64
    #include <sys/types.h>
    #include <unistd.h>
    
    ...
    off_t size_in_bytes = lseek(device, 0, SEEK_END);
    if (size_in_bytes == (off_t)-1) { ... error, error code in ERRNO ... }
    

    . Обратите внимание, что в обоих случаях он, вероятно, будет на несколько мегабайт больше размеров, рассчитанных по C × H × S.

Может помочь, если вы скажете нам, зачем вам нужна эта информация ...

3 голосов
/ 04 марта 2011

Нет, не существует независимого от платформы способа. Там даже нет * nix пути. Есть только способ Linux.

В Linux вся соответствующая информация доступна в различных файлах в файловой системе /proc. /proc/devices сообщит вам, какие существуют устройства (файлы в /dev/ могут существовать, даже если устройства недоступны, хотя открыть их в этом случае не удастся), /proc/partitions сообщит вам, какие разделы доступны на каждом диск, а затем вам придется искать в различных подкаталогах информацию. Просто посмотрите на какую-нибудь систему Linux, где есть то, что вам нужно.

2 голосов
/ 20 сентября 2016
//-------------------------------------------------
// Without Boost LIB usage
//-------------------------------------------------
#include <sys/statvfs.h>
#include <sys/sysinfo.h>
//-------------------------------------------------
stringstream   strStream;
unsigned long  hdd_size;
unsigned long  hdd_free;
ostringstream  strConvert;
//---
struct sysinfo info;
sysinfo( &info );   
//---
struct statvfs fsinfo;
statvfs("/", &fsinfo);
//---
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
strStream << cpu_freq.rdbuf();
std::string  cpufrequency = strStream.str();
//---
strStream.str("");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
strStream << cpu_temp.rdbuf();
strConvert<< fixed << setprecision(2) << std::stof(strStream.str());
std::string cputemp = strConvert.str();
//---
std::string   mem_size = to_string( (size_t)info.totalram *     (size_t)info.mem_unit );
//---
hdd_size = fsinfo.f_frsize * fsinfo.f_blocks;
hdd_free = fsinfo.f_bsize * fsinfo.f_bfree;  
//---                                                
std::cout << "CPU core number           ==" << num_cpu       << endl;
std::cout << "CPU core speed            ==" << cpufrequency  << endl;
std::cout << "CPU temperature (C)       ==" << cputemp       << endl;
//---
std::cout << "Memory size               ==" << mem_size      << endl;
//---
std::cout << "Disk, filesystem size     ==" << hdd_size      << endl;
std::cout << "Disk free space           ==" << hdd_free      << endl;
//---
2 голосов
/ 04 марта 2011

Для GNU / Linux посмотрите на это: получение метаданных жесткого диска

1 голос
/ 16 сентября 2016
//Piece of code working for me with Boost LIB usage
//-----------------------------------------------------
#include <sys/sysinfo.h>
#include <boost/filesystem.hpp>
//---    
using namespace boost::filesystem;
//---
struct sysinfo info;
sysinfo( &info );
//---
space_info si = space(".");
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream  cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
//---
std::string cpunumber = to_string(num_cpu);
std::string cpufrequency = cpu_freq.str();
std::string cputemp = cpu_temp.str();
std::string mem_size = to_string( (size_t)info.totalram *     (size_t)info.mem_unit );
std::string disk_available = to_string(si.available);
std::string fslevel = to_string( (si.available/si.capacity)*100 );
//---
...