support ntfs, more robust detection of device formatting, more robust logic for iscsi device detection
Signed-off-by: Travis Glenn Hansen <travisghansen@yahoo.com>
This commit is contained in:
parent
68022bb4e5
commit
78d50b4836
|
|
@ -550,6 +550,7 @@ class CsiBaseDriver {
|
|||
const iscsi = driver.getDefaultISCSIInstance();
|
||||
let result;
|
||||
let device;
|
||||
let block_device_info;
|
||||
|
||||
const volume_id = call.request.volume_id;
|
||||
if (!volume_id) {
|
||||
|
|
@ -978,6 +979,27 @@ class CsiBaseDriver {
|
|||
fs_type = "ext4";
|
||||
}
|
||||
|
||||
if (fs_type == "ntfs") {
|
||||
block_device_info = await filesystem.getBlockDevice(device);
|
||||
let partition_count =
|
||||
await filesystem.getBlockDevicePartitionCount(device);
|
||||
if (partition_count > 0) {
|
||||
device = await filesystem.getBlockDeviceLargestPartition(
|
||||
device
|
||||
);
|
||||
} else {
|
||||
// partion/gpt
|
||||
await filesystem.partitionDevice(
|
||||
device,
|
||||
"gpt",
|
||||
"EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"
|
||||
);
|
||||
device = await filesystem.getBlockDeviceLargestPartition(
|
||||
device
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (await filesystem.isBlockDevice(device)) {
|
||||
// format
|
||||
result = await filesystem.deviceIsFormatted(device);
|
||||
|
|
@ -1043,10 +1065,39 @@ class CsiBaseDriver {
|
|||
staging_target_path
|
||||
);
|
||||
if (!result) {
|
||||
// expand fs if necessary
|
||||
if (await filesystem.isBlockDevice(device)) {
|
||||
// go ahead and expand fs (this covers cloned setups where expand is not explicitly invoked)
|
||||
switch (fs_type) {
|
||||
case "exfat":
|
||||
case "ntfs":
|
||||
case "vfat":
|
||||
//await filesystem.checkFilesystem(device, fs_info.type);
|
||||
await filesystem.expandFilesystem(device, fs_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let mount_fs_type = fs_type;
|
||||
if (mount_fs_type == "ntfs") {
|
||||
mount_fs_type = "ntfs3";
|
||||
}
|
||||
|
||||
// handle volume_mount_group where appropriate
|
||||
if (volume_mount_group) {
|
||||
switch (fs_type) {
|
||||
case "exfat":
|
||||
case "ntfs":
|
||||
case "vfat":
|
||||
mount_flags.push(`gid=${volume_mount_group}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await mount.mount(
|
||||
device,
|
||||
staging_target_path,
|
||||
["-t", fs_type].concat(["-o", mount_flags.join(",")])
|
||||
["-t", mount_fs_type].concat(["-o", mount_flags.join(",")])
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1054,8 +1105,8 @@ class CsiBaseDriver {
|
|||
if (await filesystem.isBlockDevice(device)) {
|
||||
// go ahead and expand fs (this covers cloned setups where expand is not explicitly invoked)
|
||||
switch (fs_type) {
|
||||
case "ext4":
|
||||
case "ext3":
|
||||
case "ext4":
|
||||
case "ext4dev":
|
||||
//await filesystem.checkFilesystem(device, fs_info.type);
|
||||
try {
|
||||
|
|
@ -1094,6 +1145,11 @@ class CsiBaseDriver {
|
|||
fs_type
|
||||
);
|
||||
break;
|
||||
case "exfat":
|
||||
case "ntfs":
|
||||
case "vfat":
|
||||
// noop
|
||||
break;
|
||||
default:
|
||||
// unsupported filesystem
|
||||
throw new GrpcError(
|
||||
|
|
@ -1613,7 +1669,11 @@ class CsiBaseDriver {
|
|||
|
||||
// TODO: this could be made async to detach all simultaneously
|
||||
for (const block_device_info_i of realBlockDeviceInfos) {
|
||||
if (block_device_info_i.tran == "iscsi") {
|
||||
if (await filesystem.deviceIsIscsi(block_device_info_i.path)) {
|
||||
let parent_block_device = await filesystem.getBlockDeviceParent(
|
||||
block_device_info_i.path
|
||||
);
|
||||
|
||||
// figure out which iscsi session this belongs to and logout
|
||||
// scan /dev/disk/by-path/ip-*?
|
||||
// device = `/dev/disk/by-path/ip-${volume_context.portal}-iscsi-${volume_context.iqn}-lun-${volume_context.lun}`;
|
||||
|
|
@ -1632,7 +1692,7 @@ class CsiBaseDriver {
|
|||
session.attached_scsi_devices.host.devices.some(
|
||||
(device) => {
|
||||
if (
|
||||
device.attached_scsi_disk == block_device_info_i.name
|
||||
device.attached_scsi_disk == parent_block_device.name
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2439,8 +2499,8 @@ class CsiBaseDriver {
|
|||
fs_type = fs_info.type;
|
||||
if (fs_type) {
|
||||
switch (fs_type) {
|
||||
case "ext4":
|
||||
case "ext3":
|
||||
case "ext4":
|
||||
case "ext4dev":
|
||||
//await filesystem.checkFilesystem(device, fs_info.type);
|
||||
await filesystem.expandFilesystem(device, fs_type);
|
||||
|
|
@ -2453,6 +2513,13 @@ class CsiBaseDriver {
|
|||
await filesystem.expandFilesystem(device_path, fs_type);
|
||||
}
|
||||
break;
|
||||
case "exfat":
|
||||
case "ntfs":
|
||||
case "vfat":
|
||||
// TODO: return error here, cannot be expanded while online
|
||||
//await filesystem.checkFilesystem(device, fs_info.type);
|
||||
//await filesystem.expandFilesystem(device, fs_type);
|
||||
break;
|
||||
default:
|
||||
// unsupported filesystem
|
||||
throw new GrpcError(
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ class Filesystem {
|
|||
async getBlockDevice(device) {
|
||||
const filesystem = this;
|
||||
device = await filesystem.realpath(device);
|
||||
let args = ["-a", "-b", "-l", "-J", "-O"];
|
||||
let args = ["-a", "-b", "-J", "-O"];
|
||||
args.push(device);
|
||||
let result;
|
||||
|
||||
|
|
@ -317,30 +317,121 @@ class Filesystem {
|
|||
}
|
||||
|
||||
/**
|
||||
* blkid -p -o export <device>
|
||||
*
|
||||
* @param {*} device
|
||||
* @returns
|
||||
*/
|
||||
async getBlockDeviceLargestPartition(device) {
|
||||
const filesystem = this;
|
||||
let block_device_info = await filesystem.getBlockDevice(device);
|
||||
if (block_device_info.children) {
|
||||
let child;
|
||||
for (const child_i of block_device_info.children) {
|
||||
if (child_i.type == "part") {
|
||||
if (!child) {
|
||||
child = child_i;
|
||||
} else {
|
||||
if (child_i.size > child.size) {
|
||||
child = child_i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return `${child.path}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} device
|
||||
* @returns
|
||||
*/
|
||||
async getBlockDevicePartitionCount(device) {
|
||||
const filesystem = this;
|
||||
let count = 0;
|
||||
let block_device_info = await filesystem.getBlockDevice(device);
|
||||
if (block_device_info.children) {
|
||||
for (const child_i of block_device_info.children) {
|
||||
if (child_i.type == "part") {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 = linux
|
||||
* type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 = ntfs
|
||||
* type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B = EFI
|
||||
*
|
||||
* @param {*} device
|
||||
* @param {*} label
|
||||
* @param {*} type
|
||||
*/
|
||||
async partitionDevice(
|
||||
device,
|
||||
label = "gpt",
|
||||
type = "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
|
||||
) {
|
||||
const filesystem = this;
|
||||
let args = [device];
|
||||
let result;
|
||||
|
||||
try {
|
||||
result = await filesystem.exec("sfdisk", args, {
|
||||
stdin: `label: ${label}\n`,
|
||||
});
|
||||
result = await filesystem.exec("sfdisk", args, {
|
||||
stdin: `type=${type}\n`,
|
||||
});
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} device
|
||||
*/
|
||||
async deviceIsFormatted(device) {
|
||||
const filesystem = this;
|
||||
let args = ["-p", "-o", "export", device];
|
||||
let result;
|
||||
|
||||
try {
|
||||
result = await filesystem.exec("blkid", args);
|
||||
result = await filesystem.getBlockDevice(device);
|
||||
return result.fstype ? true : false;
|
||||
} catch (err) {
|
||||
if (err.code == 2 && err.stderr.includes("No such device or address")) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (err.code == 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
async deviceIsIscsi(device) {
|
||||
const filesystem = this;
|
||||
let result;
|
||||
|
||||
do {
|
||||
if (result) {
|
||||
device = `/dev/${result.pkname}`;
|
||||
}
|
||||
result = await filesystem.getBlockDevice(device);
|
||||
} while (result.pkname);
|
||||
|
||||
return result && result.tran == "iscsi";
|
||||
}
|
||||
|
||||
async getBlockDeviceParent(device) {
|
||||
const filesystem = this;
|
||||
let result;
|
||||
|
||||
do {
|
||||
if (result) {
|
||||
device = `/dev/${result.pkname}`;
|
||||
}
|
||||
result = await filesystem.getBlockDevice(device);
|
||||
} while (result.pkname);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -463,6 +554,9 @@ class Filesystem {
|
|||
args = args.concat(["filesystem", "resize", "max"]);
|
||||
args.push(device); // in this case should be a mounted path
|
||||
break;
|
||||
case "exfat":
|
||||
// https://github.com/exfatprogs/exfatprogs/issues/134
|
||||
return;
|
||||
case "ext4":
|
||||
case "ext3":
|
||||
case "ext4dev":
|
||||
|
|
@ -470,6 +564,13 @@ class Filesystem {
|
|||
args = args.concat(options);
|
||||
args.push(device);
|
||||
break;
|
||||
case "ntfs":
|
||||
// must be unmounted
|
||||
command = "ntfsresize";
|
||||
args = args.concat(options);
|
||||
//args = args.concat(["-s", "max"]);
|
||||
args.push(device);
|
||||
break;
|
||||
case "xfs":
|
||||
command = "xfs_growfs";
|
||||
args = args.concat(options);
|
||||
|
|
@ -526,6 +627,14 @@ class Filesystem {
|
|||
args.push("-f");
|
||||
args.push("-p");
|
||||
break;
|
||||
case "ntfs":
|
||||
/**
|
||||
* -b, --clear-bad-sectors Clear the bad sector list
|
||||
* -d, --clear-dirty Clear the volume dirty flag
|
||||
*/
|
||||
command = "ntfsfix";
|
||||
args.push(device);
|
||||
break;
|
||||
case "xfs":
|
||||
command = "xfs_repair";
|
||||
args = args.concat(["-o", "force_geometry"]);
|
||||
|
|
@ -612,6 +721,12 @@ class Filesystem {
|
|||
//options.timeout = DEFAULT_TIMEOUT;
|
||||
}
|
||||
|
||||
let stdin;
|
||||
if (options.stdin) {
|
||||
stdin = options.stdin;
|
||||
delete options.stdin;
|
||||
}
|
||||
|
||||
const filesystem = this;
|
||||
args = args || [];
|
||||
|
||||
|
|
@ -619,13 +734,27 @@ class Filesystem {
|
|||
args.unshift(command);
|
||||
command = filesystem.options.paths.sudo;
|
||||
}
|
||||
console.log("executing filesystem command: %s %s", command, args.join(" "));
|
||||
let command_log = `${command} ${args.join(" ")}`.trim();
|
||||
if (stdin) {
|
||||
command_log = `echo '${stdin}' | ${command_log}`
|
||||
.trim()
|
||||
.replace(/\n/, "\\n");
|
||||
}
|
||||
console.log("executing filesystem command: %s", command_log);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = filesystem.options.executor.spawn(command, args, options);
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
|
||||
child.on("spawn", function () {
|
||||
if (stdin) {
|
||||
child.stdin.setEncoding("utf-8");
|
||||
child.stdin.write(stdin);
|
||||
child.stdin.end();
|
||||
}
|
||||
});
|
||||
|
||||
child.stdout.on("data", function (data) {
|
||||
stdout = stdout + data;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ function stringify(value) {
|
|||
}
|
||||
|
||||
function default_supported_block_filesystems() {
|
||||
return ["btrfs", "ext3", "ext4", "ext4dev", "xfs", "ntfs"];
|
||||
return ["btrfs", "exfat", "ext3", "ext4", "ext4dev", "ntfs", "vfat", "xfs"];
|
||||
}
|
||||
|
||||
function default_supported_file_filesystems() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue