Skip to content

Commit

Permalink
CAS-23 propagate ShareProtocol from the wire to Nexus::share (#2)
Browse files Browse the repository at this point in the history
* CAS-23 propagate ShareProtocol from the wire to Nexus::share

Once the value get to Nexus::shaere, discard it.
  • Loading branch information
blaisedias authored and chriswldenyer committed Mar 19, 2020
1 parent 123a44c commit 80b32a9
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 28 deletions.
5 changes: 2 additions & 3 deletions cli/src/mctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,9 @@ async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
&call::<_, PublishNexusReply>(
&opt.socket,
"publish_nexus",
Some(json!({
"uuid": uuid,
Some(json!({ "uuid": uuid,
"share" : ShareProtocol::Nbd as i32,
"key" : key,
"share" : ShareProtocol::None as i32,
})),
)
.await?,
Expand Down
40 changes: 40 additions & 0 deletions mayastor-test/mayastor_proto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

const path = require('path');
const protoLoader = require('@grpc/proto-loader');
// we can't use grpc-kit because we need to connect to UDS and that's currently
// possible only with grpc-uds.
const grpc = require('grpc-uds');

function getConstants() {
const pkgDef = grpc.loadPackageDefinition(
protoLoader.loadSync(
path.join(__dirname, '..', 'rpc', 'proto', 'mayastor.proto'),
{
// this is to load google/descriptor.proto
includeDirs: ['./node_modules/protobufjs'],
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
}
)
);

//FIXME: the correct way to do this is to enumerate all the members of ShareProtocol,
// ans create the map from that. This will do for now.
return {
ShareProtocol: {
NONE: pkgDef.mayastor.ShareProtocol.type.value.find(ent => ent.name == 'NONE').number,
NVMF: pkgDef.mayastor.ShareProtocol.type.value.find(ent => ent.name == 'NVMF').number,
ISCSI: pkgDef.mayastor.ShareProtocol.type.value.find(ent => ent.name == 'ISCSI').number,
NBD: pkgDef.mayastor.ShareProtocol.type.value.find(ent => ent.name == 'NBD').number,
},
};
}

module.exports = {
getConstants,
};

5 changes: 4 additions & 1 deletion mayastor-test/test_csi.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ const protoLoader = require('@grpc/proto-loader');
// possible only with grpc-uds.
const grpc = require('grpc-uds');
const common = require('./test_common');
const mayastorProto = require('./mayastor_proto');
// Without requiring wtf module the ts hangs at the end. It seems that it is
// waiting for sudo'd mayastor progress which has already exited!?
const wtfnode = require('wtfnode');
const mayastorProtoConstants = mayastorProto.getConstants();

var csiSock = common.CSI_ENDPOINT;
var endpoint = common.endpoint;
Expand Down Expand Up @@ -200,7 +202,8 @@ describe('csi', function() {
{
uuid: uuid,
key: '',
share: 3, // NBD
// TODO: repeat this test for iSCSI and Nvmf
share: mayastorProtoConstants.ShareProtocol.NBD,
},
next
);
Expand Down
14 changes: 10 additions & 4 deletions mayastor-test/test_nexus.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const { exec } = require('child_process');
const { createClient } = require('grpc-kit');
const grpc = require('grpc');
const common = require('./test_common');
const mayastorProto = require('./mayastor_proto');
// just some UUID used for nexus ID
const UUID = 'dbe4d7eb-118a-4d15-b789-a18d9af6ff21';
const UUID2 = 'dbe4d7eb-118a-4d15-b789-a18d9af6ff22';
Expand All @@ -24,6 +25,7 @@ const aioFile = '/tmp/aio-backend';
const diskSize = 64 * 1024 * 1024;
// external IP address detected by common lib
const externIp = common.getMyIp();
const mayastorProtoConstants = mayastorProto.getConstants();

// Instead of using mayastor grpc methods to create replicas we use a config
// file to create them. Advantage is that we don't depend on bugs in replica
Expand Down Expand Up @@ -344,7 +346,8 @@ describe('nexus', function() {
});

it('should publish the nexus using nbd', done => {
client.PublishNexus({ uuid: UUID }, (err, res) => {
// TODO: repeat this test for iSCSI and Nvmf
client.PublishNexus({ uuid: UUID, share: mayastorProtoConstants.ShareProtocol.NBD }, (err, res) => {
assert(res.device_path);
nbd_device = res.device_path;
done();
Expand All @@ -359,7 +362,8 @@ describe('nexus', function() {
});

it('should re-publish the nexus using NBD, and a crypto key', done => {
client.PublishNexus({ uuid: UUID, key: '0123456789123456' }, (err, res) => {
// TODO: repeat this test for iSCSI and Nvmf
client.PublishNexus({ uuid: UUID, share: mayastorProtoConstants.ShareProtocol.NBD, key: '0123456789123456' }, (err, res) => {
assert(res.device_path);
nbd_device = res.device_path;
done();
Expand Down Expand Up @@ -443,7 +447,8 @@ describe('nexus', function() {
it('should create, publish, un-publish and finally destroy the same nexus', async () => {
for (let i = 0; i < 10; i++) {
await createNexus(createArgs);
await publish({ uuid: UUID });
// TODO: repeat this test for iSCSI and Nvmf
await publish({ uuid: UUID, share: mayastorProtoConstants.ShareProtocol.NBD });
await unpublish({ uuid: UUID });
await destroyNexus({ uuid: UUID });
}
Expand All @@ -460,7 +465,8 @@ describe('nexus', function() {
it('should create, publish, and destroy but without un-publishing the same nexus', async () => {
for (let i = 0; i < 10; i++) {
await createNexus(createArgs);
await publish({ uuid: UUID });
// TODO: repeat this test for iSCSI and Nvmf
await publish({ uuid: UUID, share: mayastorProtoConstants.ShareProtocol.NBD });
await destroyNexus({ uuid: UUID });
}
});
Expand Down
49 changes: 38 additions & 11 deletions mayastor/src/bdev/nexus/nexus_bdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,49 @@ pub enum Error {
name: String,
reason: String,
},
#[snafu(display("Invalid ShareProtocol value {}", sp_value))]
InvalidShareProtocol { sp_value: i32},
}

impl RpcErrorCode for Error {
fn rpc_error_code(&self) -> Code {
match self {
Error::NexusNotFound { .. } => Code::NotFound,
Error::InvalidUuid { .. } => Code::InvalidParams,
Error::InvalidKey { .. } => Code::InvalidParams,
Error::AlreadyShared { .. } => Code::InvalidParams,
Error::NotShared { .. } => Code::InvalidParams,
Error::CreateChild { .. } => Code::InvalidParams,
Error::MixedBlockSizes { .. } => Code::InvalidParams,
Error::ChildGeometry { .. } => Code::InvalidParams,
Error::OpenChild { .. } => Code::InvalidParams,
Error::DestroyLastChild { .. } => Code::InvalidParams,
Error::ChildNotFound { .. } => Code::NotFound,
Error::NexusNotFound {
..
} => Code::NotFound,
Error::InvalidUuid {
..
} => Code::InvalidParams,
Error::InvalidKey {
..
} => Code::InvalidParams,
Error::AlreadyShared {
..
} => Code::InvalidParams,
Error::NotShared {
..
} => Code::InvalidParams,
Error::CreateChild {
..
} => Code::InvalidParams,
Error::MixedBlockSizes {
..
} => Code::InvalidParams,
Error::ChildGeometry {
..
} => Code::InvalidParams,
Error::OpenChild {
..
} => Code::InvalidParams,
Error::DestroyLastChild {
..
} => Code::InvalidParams,
Error::ChildNotFound {
..
} => Code::NotFound,
Error::InvalidShareProtocol {
..
} => Code::InvalidParams,
_ => Code::InternalError,
}
}
Expand Down
27 changes: 23 additions & 4 deletions mayastor/src/bdev/nexus/nexus_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rpc::mayastor::{
RemoveChildNexusRequest,
StartRebuildRequest,
UnpublishNexusRequest,
ShareProtocol,
};

use crate::{
Expand Down Expand Up @@ -64,6 +65,18 @@ fn name_to_uuid(name: &str) -> &str {
}
}

/// Convert share protocol value to ShareProtocol for frontend use.
/// Returns Option<ShareProtocol> or None.
fn frontend_shareprotocol_from(spv : i32) -> Option<ShareProtocol> {
match spv {
0 => None,
1 => Some(ShareProtocol::Nvmf),
2 => Some(ShareProtocol::Iscsi),
3 => Some(ShareProtocol::Nbd),
_ => None
}
}

pub(crate) fn register_rpc_methods() {
// JSON rpc method to list the nexus and their states
jsonrpc_register::<(), _, _, Error>("list_nexus", |_| {
Expand Down Expand Up @@ -133,11 +146,17 @@ pub(crate) fn register_rpc_methods() {
let key: Option<String> =
if args.key == "" { None } else { Some(args.key) };

let spv = frontend_shareprotocol_from(args.share);
if spv.is_none() {
return Err(Error::InvalidShareProtocol {sp_value: args.share});
}

let share = spv.unwrap();

let nexus = nexus_lookup(&args.uuid)?;
nexus
.share(key)
.await
.map(|device_path| PublishNexusReply { device_path })
nexus.share(share, key).await.map(|device_path| PublishNexusReply {
device_path,
})
};
fut.boxed_local()
});
Expand Down
13 changes: 13 additions & 0 deletions mayastor/src/bdev/nexus/nexus_share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ use crate::{
ffihelper::{cb_arg, done_errno_cb, errno_result_from_i32, ErrnoResult},
};

use rpc::mayastor::{
ShareProtocol,
};

/// we are using the multi buffer encryption implementation using CBC as the
/// algorithm
const CRYPTO_FLAVOUR: &str = "crypto_aesni_mb";
Expand All @@ -27,6 +31,7 @@ impl Nexus {
/// nbd device.
pub async fn share(
&mut self,
share_proto: ShareProtocol,
key: Option<String>,
) -> Result<String, Error> {
if self.nbd_disk.is_some() {
Expand All @@ -36,6 +41,14 @@ impl Nexus {
}

assert_eq!(self.share_handle, None);
let _ = match share_proto {
ShareProtocol::Nvmf => (),
ShareProtocol::Iscsi => (),
ShareProtocol::Nbd => (),
_ => return Err(Error::InvalidShareProtocol {sp_value: share_proto as i32}),
};

// TODO for now we discard and ignore share_proto

let name = if let Some(key) = key {
let name = format!("crypto-{}", self.name);
Expand Down
18 changes: 13 additions & 5 deletions mayastor/tests/mount_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ use mayastor::{
core::{mayastor_env_stop, MayastorCliArgs, MayastorEnvironment, Reactor},
};

use rpc::mayastor::{
ShareProtocol,
};

static DISKNAME1: &str = "/tmp/disk1.img";
static BDEVNAME1: &str = "aio:///tmp/disk1.img?blk_size=512";

Expand All @@ -20,7 +24,8 @@ fn mount_fs() {
create_nexus().await;
let nexus = nexus_lookup("nexus").unwrap();

let device = nexus.share(None).await.unwrap();
//TODO: repeat this test for NVMF and ISCSI
let device = nexus.share(ShareProtocol::Nbd, None).await.unwrap();
let (s, r) = unbounded();

// create an XFS filesystem on the nexus device, mount it, create a file
Expand All @@ -46,8 +51,9 @@ fn mount_fs() {
let right = nexus_lookup("right").unwrap();

// share both nexuses
let left_device = left.share(None).await.unwrap();
let right_device = right.share(None).await.unwrap();
//TODO: repeat this test for NVMF and ISCSI, and permutations?
let left_device = left.share(ShareProtocol::Nbd, None).await.unwrap();
let right_device = right.share(ShareProtocol::Nbd, None).await.unwrap();

let s1 = s.clone();
std::thread::spawn(move || {
Expand Down Expand Up @@ -92,7 +98,8 @@ fn mount_fs_1() {
create_nexus().await;
let nexus = nexus_lookup("nexus").unwrap();

let device = nexus.share(None).await.unwrap();
//TODO: repeat this test for NVMF and ISCSI
let device = nexus.share(ShareProtocol::Nbd, None).await.unwrap();

std::thread::spawn(move || {
for _i in 0 .. 10 {
Expand All @@ -113,7 +120,8 @@ fn mount_fs_2() {
create_nexus().await;
let nexus = nexus_lookup("nexus").unwrap();

let device = nexus.share(None).await.unwrap();
//TODO: repeat this test for NVMF and ISCSI
let device = nexus.share(ShareProtocol::Nbd, None).await.unwrap();
let (s, r) = unbounded::<String>();

std::thread::spawn(move || s.send(common::fio_run_verify(&device)));
Expand Down

0 comments on commit 80b32a9

Please sign in to comment.