|
|
3 months ago | |
|---|---|---|
| examples | 3 months ago | |
| include | 3 months ago | |
| modules | 3 months ago | |
| src | 3 months ago | |
| .gitignore | 3 months ago | |
| LICENSE | 3 months ago | |
| Makefile | 3 months ago | |
| README.md | 3 months ago | |
README.md
bsdiskinfo
A lightweight, modular, and dependency-free FreeBSD C library along with high-performance native Lua bindings for extracting precise hardware disk identity properties, active filesystem mounts, and raw S.M.A.R.T. metrics.
The architecture strictly separates the system-level extraction engine from execution layers, allowing easy integration with multiple runtime environments (Lua, Python, Go, etc.) without inflating overhead or calling external binaries.
Features
- Advanced Identity Verification: Direct hardware query via
libcamtaskfiles. Successfully bypasses standard USB bridge constraints using SCSI SAT ATA PASS-THROUGH (16) to pull authentic models, serial numbers, firmware versions, WWN identifiers, and native sector geometry configs. - Granular Type Classification: Employs robust heuristics to accurately
identify target media storage profiles (
ssd,hdd,nvme,sdcard, or standardusbdrive tokens). - Fast Mount Traversal: Scans active filesystem topologies directly via
kernel
getfsstatwrappers with non-blocking configurations, safely mitigating hung network storage paths. - Isolated S.M.A.R.T. Matrix Layout: Exposes full 30-slot attribute maps to user space, eliminating raw hex-parsing complexities inside scripting architectures.
Repository Structure
bsdiskinfo
├── examples
│ ├── tree_view.lua # Complex hardware tree mapping layout example
│ └── tree_view.pl
├── include
│ └── bsdiskinfo.h # Public standalone C API header
├── modules
│ ├── lua
│ │ ├── lua_bsdiskinfo.c # High-performance C-to-Lua binding translator
│ │ └── Makefile # Dynamic Lua module build configurations
│ └── perl
│ ├── lib
│ │ └── bsdiskinfo.pm # Public Perl module interface and POD docs
│ ├── bsdiskinfo.xs # Core C-to-Perl XS translator bridge
│ └── Makefile.PL # Perl ExtUtils::MakeMaker build script
├── src
│ ├── cli.c # POSIX-compliant administrative CLI testbed
│ ├── libbsdiskinfo.c # Core library implementation layers
│ └── smart.h # Shared structural S.M.A.R.T. hardware definitions
├── LICENSE # BSD 2-Clause Simplified License
└── Makefile # Native FreeBSD root pmake script
Building and Installation
The build workflow utilizes native FreeBSD bmake engines and standard
pkg-config routines to automatically discover installed platform toolchains.
Build Everything (Library + CLI + Lua Module)
make
Build Library Only (Headless C Environment)
make WITHOUT_CLI=1 WITHOUT_LUA=1
Build Targeting a Specific Lua Environment
make LUA_VER=5.1
Build without Perl XS module bindings
make WITHOUT_PERL=1
Build targeting a specific custom Perl layout
cd modules/perl && perl Makefile.PL PREFIX=/my/path && make
Standard System Deployment
sudo make install
Installs components under /usr/local/ paths (lib/, include/, sbin/,
and corresponding Lua runtime folders).
Installation via FreeBSD Ports (Custom Overlay)
The project is packaged for FreeBSD through a dedicated, standalone ports
repository overlay. If you manage a local ports overlay or want to build a
clean native package via poudriere/bmake, add the port definition from
the tracking tree repository:
- Ports Overlay Repository: https://git.dc365.ru/digital-freak/ports
To build and install the toolkit from the overlay manually:
# Navigate to the port directory inside your overlay tree
cd /usr/ports/devel/bsdiskinfo
# Configure, build, and install with selected bindings (Lua/Perl)
sudo make config
sudo make install clean
Usage Profiles
Binary CLI Diagnostic Tool
You can invoke the isolated diagnostics executable directly via administrative
flags (-i identity, -m mounts, -s S.M.A.R.T.):
# Print identity and active storage mount points for a block device node
./bsdiskinfo-cli -im ada0
Lua Scripting Layer Integration
A production-ready implementation mapping out the whole physical ecosystem
using devel/lua-sysctl looks like this:
local bsdiskinfo = require("bsdiskinfo")
local sysctl = require("sysctl")
local disks_str = sysctl.get("kern.disks") or ""
for disk in disks_str:gmatch("%S+") do
local props = bsdiskinfo.get_properties(disk)
if props then
print(string.format("Drive: /dev/%s [Model: %s, Serial: %s, Type: %s]",
disk, props.model, props.serial, props.type))
-- Process mount objects safely
local mounts = bsdiskinfo.get_mounts(disk) or {}
for _, mnt in ipairs(mounts) do
print(string.format(" └─ Mounted partition %s at %s", mnt.device, mnt.path))
end
end
end
(See more extensive processing inside examples/tree_view.lua).
Perl5 Scripting Layer Integration
A production-ready Perl 5 execution layer maps out the storage ecosystem
using high-performance native XS structures. For direct kernel MIB tree
traversal without spawning shell processes, the sysutils/p5-BSD-Sysctl
port is highly recommended as a companion dependency.
The integration utilizes standard UTF-8 stream handling to seamlessly draw complex nested topology layouts:
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use open qw/:std :encoding(utf8)/; # Ensures proper UTF-8 printing bounds
use bsdiskinfo;
use BSD::Sysctl; # Native FreeBSD kernel MIB traversal bindings
# Query available physical drives straight from the kernel tree
my $disks_str = BSD::Sysctl::sysctl('kern.disks') || "";
for my $disk (sort (split /\s+/,$disks_str)) {
# Protect routing logic by verifying character device existence
next unless bsdiskinfo::exists($disk);
my $props = get_properties($disk);
if ($props) {
print "Drive: /dev/$disk [Model: $props->{model}, Type: $props->{type}]\n";
# Traverse active slices and mounted partitions
my $mounts = get_mounts($disk) || [];
for my $mnt (@$mounts) {
print " └─ Partition $mnt->{device} mounted at $mnt->{path} ($mnt->{fstype})\n";
}
}
}
(See examples/tree_view.pl for an expanded implementation containing full
raw S.M.A.R.T. matrix unpacking).
Device Access & Permissions
By default, raw character device nodes under /dev/ (e.g., /dev/ada*,
/dev/da*) are strictly accessible only by the root user in FreeBSD.
Running the binary CLI tool or calling the Lua module as an unprivileged user
will fail during transport library initialization (Permission denied).
To safely grant a specific non-root user or daemon group (e.g., operator)
execution rights to query hardware parameters without escalating system-wide
privileges, configure the native FreeBSD devfs rules subsystem.
1. Append Rules to /etc/devfs.rules
Create or modify the local rulesets configuration file to assign proper ownership and read/write accessibility maps to storage targets:
[local_devices=10]
add path 'ada*' mode 0660 group operator
add path 'da*' mode 0660 group operator
add path 'nvme*' mode 0660 group operator
2. Enable the Ruleset inside /etc/rc.conf
Instruct the kernel subsystem init profiles to mount the default active /dev
structure bound strictly against your custom ruleset index sequence:
devfs_system_ruleset="local_devices"
3. Apply Changes Immediately
Restart the system-wide device filesystem management daemon wrapper layer to evaluate state mutations on the fly:
sudo service devfs restart
Ensure your unprivileged target runtime user account belongs to the configured
destination group mapping bounds (e.g., pw groupmod operator -m myuser).
License
This project is licensed under the terms of the
BSD 2-Clause Simplified License. See LICENSE for details.