mirror of
https://codeberg.org/icewind/cube.git
synced 2026-06-03 12:04:10 +02:00
fix block devices getting reported as 0 size
This commit is contained in:
parent
7c2db32507
commit
7d7c252eea
5 changed files with 94 additions and 43 deletions
8
flake.lock
generated
8
flake.lock
generated
|
|
@ -17,16 +17,16 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1685043448,
|
"lastModified": 1686237827,
|
||||||
"narHash": "sha256-U3BwyDc2OzBcZ8tD09qXibyivgOtOQFTFCVgFyJ+6MM=",
|
"narHash": "sha256-fAZB+Zkcmc+qlauiFnIH9+2qgwM0NO/ru5pWEw3tDow=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9886352ec9ab3945896ee8a4185e961fe29df209",
|
"rev": "81ed90058a851eb73be835c770e062c6938c8a9e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"id": "nixpkgs",
|
"id": "nixpkgs",
|
||||||
"ref": "nixos-22.11",
|
"ref": "nixos-23.05",
|
||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
70
flake.nix
70
flake.nix
|
|
@ -1,41 +1,33 @@
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
nixpkgs.url = "nixpkgs/nixos-22.11";
|
nixpkgs.url = "nixpkgs/nixos-23.05";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }: let
|
outputs = {
|
||||||
buildCube = pkgs: pkgs.rustPlatform.buildRustPackage rec {
|
self,
|
||||||
version = "0.1.0";
|
nixpkgs,
|
||||||
pname = "cube";
|
flake-utils,
|
||||||
|
}:
|
||||||
src = ./.;
|
flake-utils.lib.eachDefaultSystem (
|
||||||
|
|
||||||
cargoSha256 = "sha256-tHcIwMQrGIRC6W0/B476QT5nOUY/5KkzEeJKbg3sFUA=";
|
|
||||||
|
|
||||||
meta = with pkgs.lib; {
|
|
||||||
description = "A basic NBD block server with a single gimmick";
|
|
||||||
homepage = "https://github.com/icewind1991/cube";
|
|
||||||
license = licenses.mit;
|
|
||||||
platforms = platforms.linux;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in flake-utils.lib.eachDefaultSystem (
|
|
||||||
system: let
|
system: let
|
||||||
pkgs = nixpkgs.legacyPackages."${system}";
|
pkgs = (import nixpkgs) {
|
||||||
in
|
inherit system;
|
||||||
rec {
|
};
|
||||||
# `nix build`
|
in rec {
|
||||||
packages.cube = buildCube pkgs;
|
# `nix build`
|
||||||
defaultPackage = packages.cube;
|
packages = rec {
|
||||||
defaultApp = packages.cube;
|
cube = pkgs.callPackage (import ./package.nix) {};
|
||||||
|
default = cube;
|
||||||
|
};
|
||||||
|
|
||||||
# `nix develop`
|
# `nix develop`
|
||||||
devShell = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
nativeBuildInputs = with pkgs; [ rustc cargo bacon cargo-edit cargo-outdated ];
|
nativeBuildInputs = with pkgs; [rustc cargo bacon cargo-edit cargo-outdated];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
) // {
|
)
|
||||||
|
// {
|
||||||
nixosModule = {
|
nixosModule = {
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
|
|
@ -43,16 +35,18 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
cube = buildCube pkgs;
|
cube = pkgs.callPackage (import ./package.nix) {};
|
||||||
cfg = config.services.cube;
|
cfg = config.services.cube;
|
||||||
format = pkgs.formats.toml {};
|
format = pkgs.formats.toml {};
|
||||||
configFile = format.generate "cube.toml" ({
|
configFile = format.generate "cube.toml" {
|
||||||
inherit (cfg) listen;
|
inherit (cfg) listen;
|
||||||
exports = mapAttrs (_: export: {
|
exports =
|
||||||
inherit (export) path;
|
mapAttrs (_: export: {
|
||||||
read_only = export.readOnly;
|
inherit (export) path;
|
||||||
}) cfg.exports;
|
read_only = export.readOnly;
|
||||||
});
|
})
|
||||||
|
cfg.exports;
|
||||||
|
};
|
||||||
pkg = self.defaultPackage.${pkgs.system};
|
pkg = self.defaultPackage.${pkgs.system};
|
||||||
in {
|
in {
|
||||||
options.services.cube = {
|
options.services.cube = {
|
||||||
|
|
|
||||||
23
package.nix
Normal file
23
package.nix
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
rustPlatform,
|
||||||
|
lib,
|
||||||
|
}: let
|
||||||
|
src = lib.sources.sourceByRegex (lib.cleanSource ./.) ["Cargo.*" "(src)(/.*)?"];
|
||||||
|
in
|
||||||
|
rustPlatform.buildRustPackage rec {
|
||||||
|
version = "0.1.0";
|
||||||
|
pname = "cube";
|
||||||
|
|
||||||
|
inherit src;
|
||||||
|
|
||||||
|
cargoLock = {
|
||||||
|
lockFile = ./Cargo.lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "A basic NBD block server with a single gimmick";
|
||||||
|
homepage = "https://github.com/icewind1991/cube";
|
||||||
|
license = licenses.mit;
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ use std::fs::{read_to_string, File, OpenOptions};
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use tracing::{debug, info};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
|
@ -103,6 +104,19 @@ impl ExportConfig {
|
||||||
err: e,
|
err: e,
|
||||||
path: self.path.clone(),
|
path: self.path.clone(),
|
||||||
})?;
|
})?;
|
||||||
|
let size = match meta.len() {
|
||||||
|
0 => {
|
||||||
|
let path = self.path.canonicalize().map_err(|e| HandshakeError::Open {
|
||||||
|
err: e,
|
||||||
|
path: self.path.clone(),
|
||||||
|
})?;
|
||||||
|
if path != self.path {
|
||||||
|
debug!(path = ?self.path, canonicalized = ?path, "path is configured in non canonicalized form");
|
||||||
|
}
|
||||||
|
get_block_size(&path).ok_or_else(|| HandshakeError::UnknownSize(path))?
|
||||||
|
}
|
||||||
|
size => size,
|
||||||
|
};
|
||||||
|
|
||||||
let readonly = self.readonly || meta.permissions().readonly();
|
let readonly = self.readonly || meta.permissions().readonly();
|
||||||
let mut opt = OpenOptions::new();
|
let mut opt = OpenOptions::new();
|
||||||
|
|
@ -116,9 +130,11 @@ impl ExportConfig {
|
||||||
path: self.path.clone(),
|
path: self.path.clone(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
info!(readonly, size, "go export meta");
|
||||||
|
|
||||||
Ok(Export {
|
Ok(Export {
|
||||||
readonly,
|
readonly,
|
||||||
size: meta.len(),
|
size,
|
||||||
data: file,
|
data: file,
|
||||||
resizeable: false,
|
resizeable: false,
|
||||||
rotational: false,
|
rotational: false,
|
||||||
|
|
@ -128,6 +144,18 @@ impl ExportConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument]
|
||||||
|
fn get_block_size(path: &Path) -> Option<u64> {
|
||||||
|
let device = path.strip_prefix("/dev").ok()?;
|
||||||
|
let mut sys_path = PathBuf::from("/sys/class/block");
|
||||||
|
sys_path.push(device);
|
||||||
|
sys_path.push("size");
|
||||||
|
debug!(sysfs_path = ?sys_path, "getting block size");
|
||||||
|
let size_str = read_to_string(sys_path).ok()?;
|
||||||
|
debug!(block_count = size_str, "got size");
|
||||||
|
size_str.trim().parse().ok().map(|blocks: u64| blocks * 512)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
#[serde(from = "HashMap<String, ExportConfig>")]
|
#[serde(from = "HashMap<String, ExportConfig>")]
|
||||||
pub struct Exports {
|
pub struct Exports {
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ pub enum HandshakeError {
|
||||||
UnknownExport(String),
|
UnknownExport(String),
|
||||||
#[error("Failed to open {path}")]
|
#[error("Failed to open {path}")]
|
||||||
Open { path: PathBuf, err: IoError },
|
Open { path: PathBuf, err: IoError },
|
||||||
|
#[error("Failed to determine size of source {0:?}")]
|
||||||
|
UnknownSize(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<HandshakeError> for IoError {
|
impl From<HandshakeError> for IoError {
|
||||||
|
|
@ -62,6 +64,10 @@ impl From<HandshakeError> for IoError {
|
||||||
HandshakeError::UnknownExport(export) => {
|
HandshakeError::UnknownExport(export) => {
|
||||||
IoError::new(ErrorKind::InvalidData, format!("Unknown export: {export}"))
|
IoError::new(ErrorKind::InvalidData, format!("Unknown export: {export}"))
|
||||||
}
|
}
|
||||||
|
HandshakeError::UnknownSize(path) => IoError::new(
|
||||||
|
ErrorKind::InvalidData,
|
||||||
|
format!("Failed to get size of: {path:?}"),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue