ceph_async/admin_sockets.rs
1// Copyright 2017 LambdaStack All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![cfg(unix)]
16
17use byteorder::{BigEndian, ReadBytesExt};
18
19use crate::error::{RadosError, RadosResult};
20use std::io::{Cursor, Read, Write};
21use std::net::Shutdown;
22use std::os::unix::net::UnixStream;
23use std::str;
24
25/// This is a helper function that builds a raw command from the actual
26/// command. You just pass
27/// in a command like "help". The returned `String` will be a JSON String.
28pub fn admin_socket_command(cmd: &str, socket: &str) -> RadosResult<String> {
29 let raw_cmd = json!({
30 "prefix": cmd,
31 });
32 admin_socket_raw_command(&raw_cmd.to_string(), socket)
33}
34
35/// This function supports a raw command in the format of something like:
36/// `{"prefix": "help"}`.
37/// The returned `String` will be a JSON String.
38#[allow(unused_variables)]
39pub fn admin_socket_raw_command(cmd: &str, socket: &str) -> RadosResult<String> {
40 let mut buffer = vec![0; 4]; // Should return 4 bytes with size or indicator.
41 let cmd = &format!("{}\0", cmd); // Terminator so don't add one to commands.
42
43 let mut stream = UnixStream::connect(socket)?;
44 let wb = stream.write(cmd.as_bytes())?;
45 let ret_val = stream.read(&mut buffer)?;
46 if ret_val < 4 {
47 stream.shutdown(Shutdown::Both)?;
48 return Err(RadosError::new(
49 "Admin socket: Invalid command or socket did not return any data".to_string(),
50 ));
51 }
52 // The first 4 bytes are Big Endian unsigned int
53 let mut rdr = Cursor::new(buffer);
54 let len = rdr.read_u32::<BigEndian>()?;
55 let mut output_buffer = vec![0; len as usize];
56 stream.read_exact(&mut output_buffer)?;
57 stream.shutdown(Shutdown::Both)?;
58
59 Ok(String::from_utf8_lossy(&output_buffer).into_owned())
60}