}
+#include "common/blkdev.h"
+
#ifdef __linux__
#include <libudev.h>
#include <linux/fs.h>
static const char *sandbox_dir = "";
-static std::string get_block_device_string_property_wrap(const std::string &devname, const std::string &property);
+static std::string get_block_device_string_property_wrap(const std::string &devname,
+ blkdev_prop_t property);
+
+static const char *blkdev_props2strings[] = {
+ [BLKDEV_PROP_DEV] = "dev",
+ [BLKDEV_PROP_DISCARD_GRANULARITY] = "queue/discard_granularity",
+ [BLKDEV_PROP_MODEL] = "device/model",
+ [BLKDEV_PROP_ROTATIONAL] = "queue/rotational",
+ [BLKDEV_PROP_SERIAL] = "device/serial",
+ [BLKDEV_PROP_VENDOR] = "device/vendor",
+};
void set_block_device_sandbox_dir(const char *dir)
{
* return negative error on error
*/
int64_t get_block_device_string_property(const char *devname,
- const char *property,
+ blkdev_prop_t prop,
char *val, size_t maxlen)
{
char filename[PATH_MAX];
+ const char *propstr;
+
+ assert(prop < BLKDEV_PROP_NUMPROPS);
+ propstr = blkdev_props2strings[prop];
snprintf(filename, sizeof(filename),
- "%s/sys/block/%s/%s", sandbox_dir, devname, property);
+ "%s/sys/block/%s/%s", sandbox_dir, devname, propstr);
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
* return the value (we assume it is positive)
* return negative error on error
*/
-int64_t get_block_device_int_property(const char *devname, const char *property)
+int64_t get_block_device_int_property(const char *devname, blkdev_prop_t prop)
{
char buff[256] = {0};
- int r = get_block_device_string_property(devname, property, buff, sizeof(buff));
+ int r = get_block_device_string_property(devname, prop, buff, sizeof(buff));
if (r < 0)
return r;
// take only digits
bool block_device_support_discard(const char *devname)
{
- return get_block_device_int_property(devname, "queue/discard_granularity") > 0;
+ return get_block_device_int_property(devname, BLKDEV_PROP_DISCARD_GRANULARITY) > 0;
}
int block_device_discard(int fd, int64_t offset, int64_t len)
bool block_device_is_rotational(const char *devname)
{
- return get_block_device_int_property(devname, "queue/rotational") > 0;
+ return get_block_device_int_property(devname, BLKDEV_PROP_ROTATIONAL) > 0;
}
int block_device_vendor(const char *devname, char *vendor, size_t max)
{
- return get_block_device_string_property(devname, "device/vendor", vendor, max);
+ return get_block_device_string_property(devname, BLKDEV_PROP_VENDOR, vendor, max);
}
int block_device_model(const char *devname, char *model, size_t max)
{
- return get_block_device_string_property(devname, "device/model", model, max);
+ return get_block_device_string_property(devname, BLKDEV_PROP_MODEL, model,
+ max);
}
int block_device_serial(const char *devname, char *serial, size_t max)
{
- return get_block_device_string_property(devname, "device/serial", serial, max);
+ return get_block_device_string_property(devname, BLKDEV_PROP_SERIAL, serial, max);
}
int get_device_by_fd(int fd, char *partition, char *device, size_t max)
// returned nothing; trying to read from files. note that the 'vendor'
// file rarely contains the actual vendor; it's usually 'ATA'.
std::string model, serial;
- model = get_block_device_string_property_wrap(devname, "device/model");
- serial = get_block_device_string_property_wrap(devname, "device/serial");
+ model = get_block_device_string_property_wrap(devname, BLKDEV_PROP_MODEL);
+ serial = get_block_device_string_property_wrap(devname, BLKDEV_PROP_MODEL);
if (!model.size() || serial.size()) {
return {};
}
std::string get_block_device_string_property_wrap(const std::string &devname,
- const std::string &property)
+ blkdev_prop_t prop)
{
char buff[1024] = {0};
std::string prop_val;
- int ret = get_block_device_string_property(devname.c_str(), property.c_str(), buff, sizeof(buff));
+ int ret = get_block_device_string_property(devname.c_str(), prop, buff, sizeof(buff));
if (ret < 0) {
return {};
}
#include <set>
#include <string>
+enum blkdev_prop_t {
+ BLKDEV_PROP_DEV,
+ BLKDEV_PROP_DISCARD_GRANULARITY,
+ BLKDEV_PROP_MODEL,
+ BLKDEV_PROP_ROTATIONAL,
+ BLKDEV_PROP_SERIAL,
+ BLKDEV_PROP_VENDOR,
+ BLKDEV_PROP_NUMPROPS
+};
+
/* for testing purposes */
extern void set_block_device_sandbox_dir(const char *dir);
// from a device (e.g., "sdb")
extern int64_t get_block_device_int_property(
- const char *devname, const char *property);
+ const char *devname, blkdev_prop_t prop);
extern int64_t get_block_device_string_property(
- const char *devname, const char *property,
+ const char *devname, blkdev_prop_t prop,
char *val, size_t maxlen);
extern bool block_device_support_discard(const char *devname);
extern bool block_device_is_rotational(const char *devname);
path.clear();
}
-static string get_dev_property(const char *dev, const char *property)
+static string get_dev_property(const char *dev, blkdev_prop_t property)
{
char val[1024] = {0};
get_block_device_string_property(dev, property, val, sizeof(val));
{
(*pm)[prefix + "partition_path"] = string(partition_path);
(*pm)[prefix + "dev_node"] = string(dev_node);
- (*pm)[prefix + "model"] = get_dev_property(dev_node, "device/model");
- (*pm)[prefix + "dev"] = get_dev_property(dev_node, "dev");
+ (*pm)[prefix + "model"] = get_dev_property(dev_node, BLKDEV_PROP_MODEL);
+ (*pm)[prefix + "dev"] = get_dev_property(dev_node, BLKDEV_PROP_DEV);
// nvme exposes a serial number
- string serial = get_dev_property(dev_node, "device/serial");
+ string serial = get_dev_property(dev_node, BLKDEV_PROP_SERIAL);
if (serial.length()) {
(*pm)[prefix + "serial"] = serial;
}
// nvme has a device/device/* structure; infer from that. there
// is probably a better way?
- string nvme_vendor = get_dev_property(dev_node, "device/device/vendor");
+ string nvme_vendor = get_dev_property(dev_node, BLKDEV_PROP_VENDOR);
if (nvme_vendor.length()) {
(*pm)[prefix + "type"] = "nvme";
}
path.clear();
}
-static string get_dev_property(const char *dev, const char *property)
+static string get_dev_property(const char *dev, blkdev_prop_t property)
{
char val[1024] = {0};
get_block_device_string_property(dev, property, val, sizeof(val));
{
(*pm)[prefix + "partition_path"] = string(partition_path);
(*pm)[prefix + "dev_node"] = string(dev_node);
- (*pm)[prefix + "model"] = get_dev_property(dev_node, "device/model");
- (*pm)[prefix + "dev"] = get_dev_property(dev_node, "dev");
+ (*pm)[prefix + "model"] = get_dev_property(dev_node, BLKDEV_PROP_MODEL);
+ (*pm)[prefix + "dev"] = get_dev_property(dev_node, BLKDEV_PROP_DEV);
// nvme exposes a serial number
- string serial = get_dev_property(dev_node, "device/serial");
+ string serial = get_dev_property(dev_node, BLKDEV_PROP_SERIAL);
if (serial.length()) {
(*pm)[prefix + "serial"] = serial;
}
// nvme has a device/device/* structure; infer from that. there
// is probably a better way?
- string nvme_vendor = get_dev_property(dev_node, "device/device/vendor");
+ string nvme_vendor = get_dev_property(dev_node, BLKDEV_PROP_VENDOR);
if (nvme_vendor.length()) {
(*pm)[prefix + "type"] = "nvme";
}
printf(" got '%s' expected '%s'\n", buf3, de->d_name);
ASSERT_EQ(0, strcmp(de->d_name, buf3));
printf(" discard granularity = %lld .. supported = %d\n",
- (long long)get_block_device_int_property(base, "queue/discard_granularity"),
+ (long long)get_block_device_int_property(base, BLKDEV_PROP_DISCARD_GRANULARITY),
(int)block_device_support_discard(base));
char subdirfn[PATH_MAX];
printf(" got '%s' expected '%s'\n", buf3, de->d_name);
ASSERT_EQ(0, strcmp(buf3, de->d_name));
printf(" discard granularity = %lld .. supported = %d\n",
- (long long)get_block_device_int_property(part, "queue/discard_granularity"),
+ (long long)get_block_device_int_property(part, BLKDEV_PROP_DISCARD_GRANULARITY),
(int)block_device_support_discard(part));
}
set_block_device_sandbox_dir(root.c_str());
char val[1000] = {0};
- int rc = get_block_device_string_property("sda", "device/model",
+ int rc = get_block_device_string_property("sda", BLKDEV_PROP_MODEL,
val, sizeof(val));
ASSERT_EQ(0, rc);
printf("val '%s'\n", val);