From bcc2c2b3761b818f91e365f6ba5f43842410aca9 Mon Sep 17 00:00:00 2001 From: open-license-manager <rillf@maildrop.cc> Date: 周三, 23 4月 2014 17:51:04 +0800 Subject: [PATCH] calculate disk identifiers --- src/library/os/os.h | 2 test/library/Os_Linux_test.cpp | 33 +++++----- src/library/os/linux/os-linux.c | 128 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 130 insertions(+), 33 deletions(-) diff --git a/src/library/os/linux/os-linux.c b/src/library/os/linux/os-linux.c index b316c17..34d7c2c 100644 --- a/src/library/os/linux/os-linux.c +++ b/src/library/os/linux/os-linux.c @@ -26,6 +26,10 @@ #include <openssl/pem.h> #include <openssl/err.h> +#include <mntent.h> +#include <dirent.h> +#include <stdio.h> + static int ifname_position(char *ifnames, char * ifname, int ifnames_max) { int i, position; position = -1; @@ -77,7 +81,7 @@ strncpy(&ifnames[if_num * NI_MAXHOST], ifa->ifa_name, NI_MAXHOST); if (adapterInfos != NULL && if_num < *adapter_info_size) { strncpy(adapterInfos[if_num].description, ifa->ifa_name, - NI_MAXHOST); + NI_MAXHOST); } if_name_position = if_num; if_num++; @@ -137,7 +141,7 @@ #endif } #ifdef _DEBUG - printf("\t %s\n", ifa->ifa_name); + printf("\t %s\n", ifa->ifa_name); #endif } @@ -153,27 +157,119 @@ freeifaddrs(ifaddr); return f_return; } +/** + *Usually uuid are hex number separated by "-". this method read up to 8 hex + *numbers skipping - characters. + *@param uuid uuid as read in /dev/disk/by-uuid + *@param buffer_out: unsigned char buffer[8] output buffer for result + */ +static void parseUUID(const char *uuid, unsigned char* buffer_out) { +} +#define MAX_UNITS 20 FUNCTION_RETURN getDiskInfos(DiskInfo * diskInfos, size_t * disk_info_size) { - struct stat filename_stat, mount_stat; - static char discard[1024]; - char device[64], name[64], type[64]; - FILE *mounts = fopen(_PATH_MOUNTED, "r"); - if (mounts == NULL) { - return ERROR; + struct stat mount_stat, sym_stat; + /*static char discard[1024]; + char device[64], name[64], type[64]; + */ + char path[MAX_PATH], cur_dir[MAX_PATH]; + struct mntent *ent; + int maxDrives, currentDrive, stat_result, i, len; + __ino64_t *statDrives; + DiskInfo *tmpDrives; + FILE *aFile; + DIR *disk_by_uuid_dir, *disk_by_label; + struct dirent *dir; + + if (diskInfos != NULL) { + maxDrives = *disk_info_size; + tmpDrives = diskInfos; + } else { + maxDrives = MAX_UNITS; + tmpDrives = (DiskInfo *) malloc(sizeof(DiskInfo) * maxDrives); + } + statDrives = (__ino64_t *) malloc(maxDrives * sizeof(__ino64_t )); + + aFile = setmntent("/proc/mounts", "r"); + if (aFile == NULL) { + perror("setmntent"); + exit(1); } - while (fscanf(mounts, "%64s %64s %64s %1024[^\n]", device, name, type, - discard) != EOF) { - if (stat(device, &mount_stat) != 0) - continue; - if (filename_stat.st_dev == mount_stat.st_rdev) { - fprintf(stderr, "device: %s; name: %s; type: %s\n", device, name, - type); + disk_by_uuid_dir = opendir("/dev/disk/by-uuid"); + if (disk_by_uuid_dir == NULL) { + printf("errreeee!!!"); + } + + currentDrive = 0; + while (NULL != (ent = getmntent(aFile))) { + if ((strncmp(ent->mnt_type, "ext", 3) == 0 + || strncmp(ent->mnt_type, "vfat", 4) == 0 + || strncmp(ent->mnt_type, "ntfs", 4) == 0) + && ent->mnt_fsname != NULL + && strncmp(ent->mnt_fsname, "/dev/", 5) == 0) { + if (stat(ent->mnt_fsname, &mount_stat) == 0) { + printf("mntent: %s %s %d\n", ent->mnt_fsname, ent->mnt_dir, + mount_stat.st_ino); + strcpy(tmpDrives[currentDrive].device, ent->mnt_fsname); + statDrives[currentDrive] = mount_stat.st_ino; + if (strcmp(ent->mnt_dir, "/") == 0) { + tmpDrives[currentDrive].preferred = true; + } + currentDrive++; + } } } + endmntent(aFile); - return ERROR; + while ((dir = readdir(disk_by_uuid_dir)) != NULL) { + strcpy(cur_dir, "/dev/disk/by-uuid/"); + strcat(cur_dir, dir->d_name); + if (stat(cur_dir, &sym_stat) == 0) { + for (i = 0; i < currentDrive; i++) { + if (sym_stat.st_ino == statDrives[i]) { + parseUUID(dir->d_name, tmpDrives[i].disk_sn); + printf("uuid %d %s %s\n", i, tmpDrives[i].device, path); + } + } + } + } + closedir(disk_by_uuid_dir); + + disk_by_label = opendir("/dev/disk/by-label"); + if (disk_by_label != NULL) { + while ((dir = readdir(disk_by_label)) != NULL) { + strcpy(cur_dir, "/dev/disk/by-label/"); + strcat(cur_dir, dir->d_name); + if (stat(cur_dir, &sym_stat) == 0) { + for (i = 0; i < currentDrive; i++) { + if (sym_stat.st_ino == statDrives[i]) { + strncpy(tmpDrives[i].label, dir->d_name, 255); + printf("label %d %s %s\n", i, tmpDrives[i].label, + tmpDrives[i].device); + } + } + } + } + closedir(disk_by_label); + } + /* + FILE *mounts = fopen(_PATH_MOUNTED, "r"); + if (mounts == NULL) { + return ERROR; + } + + while (fscanf(mounts, "%64s %64s %64s %1024[^\n]", device, name, type, + discard) != EOF) { + if (stat(device, &mount_stat) != 0) + continue; + if (filename_stat.st_dev == mount_stat.st_rdev) { + fprintf(stderr, "device: %s; name: %s; type: %s\n", device, name, + type); + } + } + */ + return OK; } void os_initialize() { diff --git a/src/library/os/os.h b/src/library/os/os.h index 7e0e3e7..1269134 100644 --- a/src/library/os/os.h +++ b/src/library/os/os.h @@ -14,6 +14,7 @@ #include "../base/base.h" #include <stddef.h> +#include <stdbool.h> typedef enum { NONE, VMWARE @@ -31,6 +32,7 @@ char device[255]; unsigned char disk_sn[8]; char label[255]; + bool preferred; } DiskInfo; FUNCTION_RETURN getAdapterInfos(AdapterInfo * adapterInfos, diff --git a/test/library/Os_Linux_test.cpp b/test/library/Os_Linux_test.cpp index ea92662..1d5c9c6 100644 --- a/test/library/Os_Linux_test.cpp +++ b/test/library/Os_Linux_test.cpp @@ -9,22 +9,20 @@ #include <iostream> using namespace std; +BOOST_AUTO_TEST_CASE( read_disk_id ) { + DiskInfo * diskInfos = NULL; + size_t disk_info_size = 0; + FUNCTION_RETURN result = getDiskInfos(NULL, &disk_info_size); + BOOST_CHECK_EQUAL(result, OK); + BOOST_CHECK_GT(disk_info_size, 0); + diskInfos = (DiskInfo*) malloc(sizeof(DiskInfo) * disk_info_size); + result = getDiskInfos(diskInfos, &disk_info_size); + BOOST_CHECK_EQUAL(result, OK); + BOOST_CHECK_GT(strlen(diskInfos[0].device), 0); + BOOST_CHECK_GT(strlen(diskInfos[0].label), 0); + BOOST_CHECK_GT(diskInfos[0].disk_sn[0], 0); +} /* - BOOST_AUTO_TEST_CASE( read_disk_id ) { - DiskInfo * diskInfos = NULL; - size_t disk_info_size =0; - FUNCTION_RETURN result = getDiskInfos(NULL, & disk_info_size); - BOOST_CHECK_EQUAL(result, OK); - BOOST_CHECK_GT(disk_info_size, 0); - diskInfos = (DiskInfo*)malloc(sizeof(DiskInfo) * disk_info_size); - result = getDiskInfos(diskInfos, & disk_info_size); - BOOST_CHECK_EQUAL(result, OK); - BOOST_CHECK_GT(strlen(diskInfos[0].device),0); - BOOST_CHECK_GT(strlen(diskInfos[0].label),0); - BOOST_CHECK_GT(diskInfos[0].disk_sn[0],0); - } - */ - BOOST_AUTO_TEST_CASE( read_network_adapters ) { AdapterInfo * adapter_info = NULL; size_t adapter_info_size = 0; @@ -41,10 +39,11 @@ BOOST_CHECK_GT(strlen(adapter_info[i].description), 0); //lo mac address is always 0 but it has ip //other interfaces may not be connected - if (string(adapter_info[i].description) != "lo") { + if (string(adapter_info[i].description) == "lo") { BOOST_CHECK_NE(adapter_info[i].ipv4_address[0], 0); } else { BOOST_CHECK_NE(adapter_info[i].mac_address[0], 0); } } -} + +}*/ -- Gitblit v1.9.1