From 1af37106c0cbc5c30958c10e907db9c8a39322e1 Mon Sep 17 00:00:00 2001 From: Travis Glenn Hansen Date: Sun, 24 Apr 2022 22:34:20 -0600 Subject: [PATCH] more robust ntfs support on linux Signed-off-by: Travis Glenn Hansen --- src/driver/index.js | 56 ++++++++++++++++++++++++--------- src/utils/filesystem.js | 70 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 17 deletions(-) diff --git a/src/driver/index.js b/src/driver/index.js index 0141aa2..3c4281e 100644 --- a/src/driver/index.js +++ b/src/driver/index.js @@ -304,6 +304,13 @@ class CsiBaseDriver { // throw new Error(`failed to retrieve volume_context for ${volume_id}`); //} + if (!volume_context) { + volume_context = _.get( + driver.options, + `_private.volume_context.${volume_id}` + ); + } + driver.ctx.logger.debug( "retrived derived volume_context %j", volume_context @@ -979,21 +986,42 @@ class CsiBaseDriver { fs_type = "ext4"; } + let partition_count = + await filesystem.getBlockDevicePartitionCount(device); + if (partition_count > 0) { + // data partion MUST be the last partition on the drive + // to properly support expand/resize operations + device = await filesystem.getBlockDeviceLastPartition(device); + driver.ctx.logger.debug( + `device has partitions, mount device is: ${device}` + ); + + await filesystem.expandPartition(device); + } + 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" - ); + if (partition_count < 1) { + // dos is what csi-proxy uses by default + let ntfs_partition_label = "dos"; + switch (ntfs_partition_label.toLowerCase()) { + case "dos": + // partion dos + await filesystem.partitionDevice(device, "dos", "07"); + break; + case "gpt": + // partion gpt + await filesystem.partitionDevice( + device, + "gpt", + "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" + ); + break; + default: + throw new GrpcError( + grpc.status.INVALID_ARGUMENT, + `unknown/unsupported ntfs_partition_label: ${ntfs_partition_label}` + ); + } device = await filesystem.getBlockDeviceLargestPartition( device ); diff --git a/src/utils/filesystem.js b/src/utils/filesystem.js index 26f28b8..284c713 100644 --- a/src/utils/filesystem.js +++ b/src/utils/filesystem.js @@ -341,6 +341,33 @@ class Filesystem { } } + /** + * + * @param {*} device + * @returns + */ + async getBlockDeviceLastPartition(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 { + let minor = child["maj:min"].split(":")[1]; + let minor_i = child_i["maj:min"].split(":")[1]; + if (minor_i > minor) { + child = child_i; + } + } + } + } + return `${child.path}`; + } + } + /** * * @param {*} device @@ -360,10 +387,22 @@ class Filesystem { return count; } + async getBlockDeviceHasParitionTable(device) { + const filesystem = this; + let block_device_info = await filesystem.getBlockDevice(device); + + return block_device_info.pttype ? true : false; + } + /** - * type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 = linux - * type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 = ntfs - * type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B = EFI + * DOS + * - type=83 = Linux + * - type=07 = HPFS/NTFS/exFAT + * + * GPT + * - 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 @@ -534,6 +573,31 @@ class Filesystem { } } + async expandPartition(device) { + const filesystem = this; + const command = "growpart"; + const args = []; + + let block_device_info = await filesystem.getBlockDevice(device); + let device_fs_info = await filesystem.getDeviceFilesystemInfo(device); + let growpart_partition = device_fs_info["part_entry_number"]; + let parent_block_device = await filesystem.getBlockDeviceParent(device); + + args.push(parent_block_device.path, growpart_partition); + + try { + await filesystem.exec(command, args); + } catch (err) { + if ( + err.code == 1 && + err.stdout && + err.stdout.includes("could only be grown by") + ) { + return; + } + } + } + /** * expand a given filesystem *