Skip to content

Commit c536151

Browse files
mayastor-borsAbhinandan-Purkait
mayastor-bors
andcommitted
chore(bors): merge pull request #913
913: refactor(csi-driver): use tokio process command for findmnt and add path prefix r=Abhinandan-Purkait a=Abhinandan-Purkait - Use tokio async process for findmnt - Use the kubelet path as prefix in exhaustive mount path search during cleanup Co-authored-by: Abhinandan Purkait <[email protected]>
2 parents f6e0654 + 264e3f3 commit c536151

File tree

7 files changed

+56
-23
lines changed

7 files changed

+56
-23
lines changed

control-plane/csi-driver/src/bin/node/block_vol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub(crate) async fn publish_block_volume(msg: &NodePublishVolumeRequest) -> Resu
5555
//target exists and is a special file
5656

5757
// Idempotency, if we have done this already just return success.
58-
match findmnt::get_devicepath(target_path) {
58+
match findmnt::get_devicepath(target_path).await {
5959
Ok(findmnt_dev) => {
6060
if let Some(fm_devpath) = findmnt_dev {
6161
if fm_devpath == device_path {

control-plane/csi-driver/src/bin/node/filesystem_ops.rs

+1
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ impl FileSystemOps for Ext4Fs {
230230
let dev_path = match dev_path {
231231
Some(path) => path,
232232
None => get_devicepath(mount_path)
233+
.await
233234
.map_err(|error| {
234235
format!("failed to get dev path for mountpoint {mount_path}: {error}")
235236
})?

control-plane/csi-driver/src/bin/node/findmnt.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::{error::DeviceError, filesystem_ops::FileSystem};
22
use csi_driver::filesystem::FileSystem as Fs;
3+
use utils::csi_plugin_name;
34

45
use serde_json::Value;
5-
use std::{collections::HashMap, process::Command, str::FromStr, string::String, vec::Vec};
6+
use std::{collections::HashMap, str::FromStr, string::String, vec::Vec};
67
use tracing::{error, warn};
7-
use utils::csi_plugin_name;
88

99
// Keys of interest we expect to find in the JSON output generated
1010
// by findmnt.
@@ -145,8 +145,12 @@ const FIND_MNT_ARGS: [&str; 3] = ["-J", "-o", "SOURCE,TARGET,FSTYPE"];
145145

146146
/// Execute the Linux utility findmnt, collect the json output,
147147
/// invoke the filter function and return the filtered results.
148-
fn findmnt(params: Filter) -> Result<Vec<HashMap<String, String>>, DeviceError> {
149-
let output = Command::new(FIND_MNT).args(FIND_MNT_ARGS).output()?;
148+
async fn findmnt(params: Filter<'_>) -> Result<Vec<HashMap<String, String>>, DeviceError> {
149+
let output = tokio::process::Command::new(FIND_MNT)
150+
.args(FIND_MNT_ARGS)
151+
.output()
152+
.await?;
153+
150154
if output.status.success() {
151155
let json_str = String::from_utf8(output.stdout)?;
152156
let json: Value = serde_json::from_str(&json_str)?;
@@ -161,12 +165,12 @@ fn findmnt(params: Filter) -> Result<Vec<HashMap<String, String>>, DeviceError>
161165
/// Use the Linux utility findmnt to find the name of the device mounted at a
162166
/// directory or block special file, if any.
163167
/// mount_path is the path a device is mounted on.
164-
pub(crate) fn get_devicepath(mount_path: &str) -> Result<Option<String>, DeviceError> {
168+
pub(crate) async fn get_devicepath(mount_path: &str) -> Result<Option<String>, DeviceError> {
165169
let tgt_filter = Filter {
166170
key: TARGET_KEY,
167171
value: mount_path,
168172
};
169-
let sources = findmnt(tgt_filter)?;
173+
let sources = findmnt(tgt_filter).await?;
170174
{
171175
match sources.len() {
172176
0 => Ok(None),
@@ -194,12 +198,12 @@ pub(crate) fn get_devicepath(mount_path: &str) -> Result<Option<String>, DeviceE
194198
/// Use the Linux utility findmnt to find the mount paths for a block device,
195199
/// if any.
196200
/// device_path is the path to the device for example "/dev/sda1"
197-
pub(crate) fn get_mountpaths(device_path: &str) -> Result<Vec<DeviceMount>, DeviceError> {
201+
pub(crate) async fn get_mountpaths(device_path: &str) -> Result<Vec<DeviceMount>, DeviceError> {
198202
let dev_filter = Filter {
199203
key: SOURCE_KEY,
200204
value: device_path,
201205
};
202-
match findmnt(dev_filter) {
206+
match findmnt(dev_filter).await {
203207
Ok(results) => {
204208
let mut mountpaths: Vec<DeviceMount> = Vec::new();
205209
for entry in results {
@@ -249,8 +253,18 @@ struct FilterCsiMounts<'a> {
249253
}
250254

251255
/// Finds CSI mount points using `findmnt` and filters based on the given criteria.
252-
fn find_csi_mount(filter: FilterCsiMounts) -> Result<Vec<HashMap<String, String>>, DeviceError> {
253-
let output = Command::new(FIND_MNT).args(FIND_MNT_ARGS).output()?;
256+
async fn find_csi_mount(
257+
filter: FilterCsiMounts<'_>,
258+
path_prefix: Option<&str>,
259+
) -> Result<Vec<HashMap<String, String>>, DeviceError> {
260+
let mut command = tokio::process::Command::new(FIND_MNT);
261+
command.args(FIND_MNT_ARGS);
262+
263+
if let Some(path_prefix) = path_prefix {
264+
command.args(["-R", path_prefix]);
265+
}
266+
267+
let output = command.output().await?;
254268

255269
if !output.status.success() {
256270
return Err(DeviceError::new(String::from_utf8(output.stderr)?.as_str()));
@@ -321,14 +335,17 @@ fn read_vol_data_json(path: &str) -> Result<serde_json::Map<String, Value>, Devi
321335
}
322336

323337
/// Retrieves mount paths for a given CSI volume ID by parsing the metadata file.
324-
pub(crate) async fn get_csi_mountpaths(volume_id: &str) -> Result<Vec<DeviceMount>, DeviceError> {
338+
pub(crate) async fn get_csi_mountpaths(
339+
volume_id: &str,
340+
path_prefix: Option<&str>,
341+
) -> Result<Vec<DeviceMount>, DeviceError> {
325342
let filter = FilterCsiMounts {
326343
driver: &csi_plugin_name(),
327344
volume_id,
328345
file_name: METADATA_FILE,
329346
device_pattern: DEVICE_PATTERN,
330347
};
331-
match find_csi_mount(filter) {
348+
match find_csi_mount(filter, path_prefix).await {
332349
Ok(results) => {
333350
let mut mountpaths: Vec<DeviceMount> = Vec::new();
334351
for entry in results {

control-plane/csi-driver/src/bin/node/fsfreeze/bin/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ pub(crate) async fn fsfreeze(volume_id: &str, command: FsFreezeOpt) -> Result<()
6767
// Use findmnt to work out if volume is mounted as a raw
6868
// block, i.e. we get some matches, and return the
6969
// BlockDeviceMount error.
70-
let mountpaths = findmnt::get_mountpaths(&device_path).map_err(|error| {
71-
FsfreezeError::InternalFailure {
70+
let mountpaths = findmnt::get_mountpaths(&device_path)
71+
.await
72+
.map_err(|error| FsfreezeError::InternalFailure {
7273
source: error,
7374
volume_id: volume_id.to_string(),
74-
}
75-
})?;
75+
})?;
7676
if !mountpaths.is_empty() {
7777
return Err(FsfreezeError::BlockDeviceMount {
7878
volume_id: volume_id.to_string(),

control-plane/csi-driver/src/bin/node/main_.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ pub(super) async fn main() -> anyhow::Result<()> {
185185
even though volume target is rdma capable."
186186
)
187187
)
188+
.arg(
189+
Arg::new("kubelet-path")
190+
.long("kubelet-path")
191+
.default_value("/var/lib/kubelet")
192+
.help("Kubelet path on the host system")
193+
)
188194
.subcommand(
189195
clap::Command::new("fs-freeze")
190196
.arg(
@@ -346,12 +352,14 @@ pub(super) async fn main() -> anyhow::Result<()> {
346352
// Parse instance and grpc endpoints from the command line arguments and validate.
347353
let grpc_sock_addr = validate_endpoints(&matches, registration_enabled)?;
348354

355+
let kubelet_path = matches.get_one::<String>("kubelet-path").unwrap();
356+
349357
// Start the CSI server, node plugin grpc server and registration loop if registration is
350358
// enabled.
351359
*crate::config::config().nvme_as_mut() = TryFrom::try_from(&matches)?;
352360
let (csi, grpc, registration) = tokio::join!(
353361
CsiServer::run(csi_socket, &matches)?,
354-
NodePluginGrpcServer::run(grpc_sock_addr),
362+
NodePluginGrpcServer::run(grpc_sock_addr, kubelet_path.to_owned()),
355363
run_registration_loop(
356364
node_name.clone(),
357365
grpc_sock_addr.to_string(),

control-plane/csi-driver/src/bin/node/nodeplugin_grpc.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ use tracing::{debug, error, info};
3131
use uuid::Uuid;
3232

3333
#[derive(Debug, Default)]
34-
pub(crate) struct NodePluginSvc {}
34+
pub(crate) struct NodePluginSvc {
35+
kubelet_path: String,
36+
}
3537

3638
#[tonic::async_trait]
3739
impl NodePlugin for NodePluginSvc {
@@ -105,7 +107,7 @@ impl NodePlugin for NodePluginSvc {
105107
})?;
106108

107109
if let Ok(Some(device)) = Device::lookup(&uuid).await {
108-
let mountpaths = findmnt::get_mountpaths(&device.devname())?;
110+
let mountpaths = findmnt::get_mountpaths(&device.devname()).await?;
109111
debug!(
110112
"Device: {} found, with mount paths: {}, issuing unmount",
111113
device.devname(),
@@ -117,7 +119,8 @@ impl NodePlugin for NodePluginSvc {
117119
);
118120
lazy_unmount_mountpaths(&mountpaths).await?;
119121
} else {
120-
let mountpaths = findmnt::get_csi_mountpaths(&volume_id).await?;
122+
let mountpaths =
123+
findmnt::get_csi_mountpaths(&volume_id, Some(&self.kubelet_path)).await?;
121124
debug!(
122125
"Device was not found, detected mount paths: {}, issuing unmount",
123126
mountpaths
@@ -149,13 +152,16 @@ pub(crate) struct NodePluginGrpcServer {}
149152

150153
impl NodePluginGrpcServer {
151154
/// Run `Self` as a tonic server.
152-
pub(crate) async fn run(endpoint: std::net::SocketAddr) -> anyhow::Result<()> {
155+
pub(crate) async fn run(
156+
endpoint: std::net::SocketAddr,
157+
kubelet_path: String,
158+
) -> anyhow::Result<()> {
153159
info!(
154160
"node plugin gRPC server configured at address {:?}",
155161
endpoint
156162
);
157163
Server::builder()
158-
.add_service(NodePluginServer::new(NodePluginSvc {}))
164+
.add_service(NodePluginServer::new(NodePluginSvc { kubelet_path }))
159165
.serve_with_shutdown(endpoint, Shutdown::wait())
160166
.await
161167
.map_err(|error| {

control-plane/csi-driver/src/bin/node/nodeplugin_svc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub(crate) async fn find_mount(
3838
) -> Result<Option<TypeOfMount>, tonic::Status> {
3939
let device_path = device.devname();
4040
let mountpaths = findmnt::get_mountpaths(&device_path)
41+
.await
4142
.map_err(|error| tonic::Status::internal(error.to_string()))?;
4243
debug!(
4344
volume.uuid = volume_id,

0 commit comments

Comments
 (0)