Handle attaching loop devices instead of handing it to mount
* So that we can pass extra loop options like Direct I/O * To workaround an issue with loop device files not getting automatically created
This commit is contained in:
parent
c500df8ca2
commit
dcc2210b3c
@ -4,6 +4,7 @@ from google.protobuf.wrappers_pb2 import BoolValue
|
|||||||
import rawfile_util
|
import rawfile_util
|
||||||
from csi import csi_pb2, csi_pb2_grpc
|
from csi import csi_pb2, csi_pb2_grpc
|
||||||
from orchestrator.k8s import volume_to_node, run_on_node
|
from orchestrator.k8s import volume_to_node, run_on_node
|
||||||
|
from rawfile_util import attach_loop
|
||||||
from remote import init_rawfile, scrub
|
from remote import init_rawfile, scrub
|
||||||
from util import log_grpc_request, run
|
from util import log_grpc_request, run
|
||||||
|
|
||||||
@ -48,7 +49,8 @@ class RawFileNodeServicer(csi_pb2_grpc.NodeServicer):
|
|||||||
def NodePublishVolume(self, request, context):
|
def NodePublishVolume(self, request, context):
|
||||||
mount_path = request.target_path
|
mount_path = request.target_path
|
||||||
img_file = rawfile_util.img_file(request.volume_id)
|
img_file = rawfile_util.img_file(request.volume_id)
|
||||||
run(f"mount {img_file} {mount_path}")
|
loop_file = attach_loop(img_file)
|
||||||
|
run(f"mount {loop_file} {mount_path}")
|
||||||
return csi_pb2.NodePublishVolumeResponse()
|
return csi_pb2.NodePublishVolumeResponse()
|
||||||
|
|
||||||
@log_grpc_request
|
@log_grpc_request
|
||||||
|
@ -2,6 +2,7 @@ import json
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from consts import DATA_DIR
|
from consts import DATA_DIR
|
||||||
|
from util import run, run_out
|
||||||
|
|
||||||
|
|
||||||
def img_dir(volume_id):
|
def img_dir(volume_id):
|
||||||
@ -28,3 +29,27 @@ def patch_metadata(volume_id, obj):
|
|||||||
new_data = {**old_data, **obj}
|
new_data = {**old_data, **obj}
|
||||||
meta_file(volume_id).write_text(json.dumps(new_data))
|
meta_file(volume_id).write_text(json.dumps(new_data))
|
||||||
return new_data
|
return new_data
|
||||||
|
|
||||||
|
|
||||||
|
def attached_loops(file: str) -> [str]:
|
||||||
|
out = run_out(f"losetup -j {file}").stdout.decode()
|
||||||
|
lines = out.splitlines()
|
||||||
|
devs = [line.split(":", 1)[0] for line in lines]
|
||||||
|
return devs
|
||||||
|
|
||||||
|
|
||||||
|
def attach_loop(file) -> str:
|
||||||
|
def next_loop():
|
||||||
|
loop_file = run_out(f"losetup -f").stdout.decode().strip()
|
||||||
|
if not Path(loop_file).exists():
|
||||||
|
pfx_len = len("/dev/loop")
|
||||||
|
loop_dev_id = loop_file[pfx_len:]
|
||||||
|
run(f"mknod {loop_file} b 7 {loop_dev_id}")
|
||||||
|
return loop_file
|
||||||
|
|
||||||
|
while True:
|
||||||
|
devs = attached_loops(file)
|
||||||
|
if len(devs) > 0:
|
||||||
|
return devs[0]
|
||||||
|
next_loop()
|
||||||
|
run(f"losetup -f {file}")
|
||||||
|
5
util.py
5
util.py
@ -39,6 +39,11 @@ def run(cmd):
|
|||||||
return subprocess.run(cmd, shell=True, check=True)
|
return subprocess.run(cmd, shell=True, check=True)
|
||||||
|
|
||||||
|
|
||||||
|
def run_out(cmd: str):
|
||||||
|
p = subprocess.run(cmd, shell=True, capture_output=True)
|
||||||
|
return p
|
||||||
|
|
||||||
|
|
||||||
class remote_fn(object):
|
class remote_fn(object):
|
||||||
def __init__(self, fn):
|
def __init__(self, fn):
|
||||||
self.fn = fn
|
self.fn = fn
|
||||||
|
Loading…
Reference in New Issue
Block a user