Skip to content

Commit

Permalink
Device number parsing: Handle decimal/hexadecimal representations
Browse files Browse the repository at this point in the history
The device number (major:minor) is being represented in different bases across different sources:
- procfs `maps`: hexadecimal
- procfs `mountinfo`: decimal
- sysfs `block/dev`: decimal

This commit handles parsing of these different representations.

Changes:
- Explicitly setting the wanted base for each parsing flow
- Added UT case to cover the new functionality
  • Loading branch information
chenBenjamin97 authored and dtrugman committed Mar 14, 2024
1 parent d299549 commit a671429
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 16 deletions.
3 changes: 2 additions & 1 deletion include/pfs/parsers/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
#include <string>

#include "pfs/types.hpp"
#include "pfs/utils.hpp"

namespace pfs {
namespace impl {
namespace parsers {

dev_t parse_device(const std::string& device_str);
dev_t parse_device(const std::string& device_str, utils::base base);

task_state parse_task_state(char state_char);

Expand Down
2 changes: 1 addition & 1 deletion src/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ dev_t block::get_dev() const
auto path = _block_root + DEV_FILE;

auto line = utils::readline(path);
return parsers::parse_device(line);
return parsers::parse_device(line, utils::base::decimal);
}

block_stat block::get_stat() const
Expand Down
6 changes: 3 additions & 3 deletions src/parsers/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace pfs {
namespace impl {
namespace parsers {

dev_t parse_device(const std::string& device_str)
dev_t parse_device(const std::string& device_str, utils::base base)
{
// Device format must be '<major>:<minor>'

Expand All @@ -47,10 +47,10 @@ dev_t parse_device(const std::string& device_str)
try
{
int major;
utils::stot(tokens[MAJOR], major, utils::base::hex);
utils::stot(tokens[MAJOR], major, base);

int minor;
utils::stot(tokens[MINOR], minor, utils::base::hex);
utils::stot(tokens[MINOR], minor, base);

return MKDEV(major, minor);
}
Expand Down
2 changes: 1 addition & 1 deletion src/parsers/maps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ mem_region parse_maps_line(const std::string& line)

region.offset = parse_mem_region_offset(tokens[OFFSET]);

region.device = parse_device(tokens[DEVICE]);
region.device = parse_device(tokens[DEVICE], utils::base::hex);

region.inode = parse_mem_region_inode(tokens[INODE]);

Expand Down
2 changes: 1 addition & 1 deletion src/parsers/mountinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ mount parse_mountinfo_line(const std::string& line)
utils::stot(tokens[MOUNT_ID], mnt.id);
utils::stot(tokens[PARENT_ID], mnt.parent_id);

mnt.device = parse_device(tokens[DEVICE]);
mnt.device = parse_device(tokens[DEVICE], utils::base::decimal);

mnt.root = tokens[ROOT];
mnt.point = tokens[MOUNT_POINT];
Expand Down
14 changes: 11 additions & 3 deletions test/test_common.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include <sys/sysmacros.h>

#include "catch.hpp"
#include "test_utils.hpp"

#include "pfs/utils.hpp"
#include "pfs/parser_error.hpp"
#include "pfs/parsers/common.hpp"

Expand All @@ -25,16 +28,21 @@ TEST_CASE("Parse task state", "[common][state]")

TEST_CASE("Parse device", "[common][device]")
{
using base = pfs::impl::utils::base;

dev_t dev;

SECTION("Zero") { dev = 0x00; }

SECTION("Random") { dev = generate_random<uint16_t>(); }

auto device_str = build_device_string(dev);
INFO(device_str);
auto device_hex_str = build_hex_device_string(major(dev), minor(dev));
INFO("Device (hexadecimal representation): " << device_hex_str);
REQUIRE(parse_device(device_hex_str, base::hex) == dev);

REQUIRE(parse_device(device_str) == dev);
auto device_dec_str = build_dec_device_string(major(dev), minor(dev));
INFO("Device (decimal representation): " << device_dec_str);
REQUIRE(parse_device(device_dec_str, base::decimal) == dev);
}

TEST_CASE("Parse uid_map", "[common][uid_map]")
Expand Down
2 changes: 1 addition & 1 deletion test/test_maps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ TEST_CASE("Parse maps", "[task][maps]")
out << (is_private ? 'p' : 's');
out << " ";
out << std::setfill('0') << std::setw(8) << offset << " ";
out << build_device_string(dev_major, dev_minor) << " ";
out << build_hex_device_string(dev_major, dev_minor) << " ";
out << inode << " ";
while (out.tellp() == 73)
out << " ";
Expand Down
4 changes: 2 additions & 2 deletions test/test_mountinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ TEST_CASE("Parse mountinfo", "[task][mountinfo]")

expected.id = 27;
expected.parent_id = 0;
expected.device = MKDEV(0x253, 0x00);
expected.device = MKDEV(253, 0);
expected.root = "/";
expected.point = "/";
expected.options = {"rw", "relatime"};
Expand All @@ -37,7 +37,7 @@ TEST_CASE("Parse mountinfo", "[task][mountinfo]")

expected.id = 46;
expected.parent_id = 22;
expected.device = MKDEV(0x00, 0x41);
expected.device = MKDEV(0, 41);
expected.root = "/";
expected.point = "/proc/sys/fs/binfmt_misc";
expected.options = {"rw", "relatime"};
Expand Down
8 changes: 5 additions & 3 deletions test/test_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,18 @@ inline T generate_random()
return dist(rd);
}

inline std::string build_device_string(dev_t dev_major, dev_t dev_minor)
inline std::string build_hex_device_string(dev_t dev_major, dev_t dev_minor)
{
std::ostringstream out;
out << std::hex << dev_major << ":" << dev_minor;
return out.str();
}

inline std::string build_device_string(dev_t dev)
inline std::string build_dec_device_string(dev_t dev_major, dev_t dev_minor)
{
return build_device_string(MAJOR(dev), MINOR(dev));
std::ostringstream out;
out << dev_major << ":" << dev_minor;
return out.str();
}

inline std::string create_temp_file(const std::vector<std::string>& lines)
Expand Down

0 comments on commit a671429

Please sign in to comment.