From f29fbea082f949d0a9b2937ced5afbe491280275 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Mon, 8 Mar 2021 14:25:25 +0000 Subject: [PATCH] cephfs: provide additional volume details on Windows At the moment, the Windows volume name and serial number are hardcoded. This change makes the volume name configurable, defaulting to "Ceph" or "Ceph - ". This makes it easier to identify Ceph mounts. At the same time, we're going to retrieve the Ceph filesystem identifier instead of using the hardcoded value. Fixes: https://tracker.ceph.com/issues/49662 Signed-off-by: Lucian Petrut (cherry picked from commit 8a190816947b414366f5e1c6fac36ce0954f80d8) --- src/dokan/ceph_dokan.cc | 48 +++++++++++++++++++++++++++++++++++++---- src/dokan/ceph_dokan.h | 3 +++ src/dokan/options.cc | 5 +++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/dokan/ceph_dokan.cc b/src/dokan/ceph_dokan.cc index d16e81957799e..90320e662c3a3 100644 --- a/src/dokan/ceph_dokan.cc +++ b/src/dokan/ceph_dokan.cc @@ -38,6 +38,8 @@ #include "global/global_init.h" +#include "include/uuid.h" + #include "dbg.h" #include "utils.h" @@ -784,10 +786,9 @@ static NTSTATUS WinCephGetVolumeInformation( DWORD FileSystemNameSize, PDOKAN_FILE_INFO DokanFileInfo) { - // TODO: configurable volume name and serial number. - // We should also support having multiple mounts. - wcscpy(VolumeNameBuffer, L"Ceph"); - *VolumeSerialNumber = 0x19831116; + g_cfg->win_vol_name.copy(VolumeNameBuffer, VolumeNameSize); + *VolumeSerialNumber = g_cfg->win_vol_serial; + *MaximumComponentLength = 256; *FileSystemFlags = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | @@ -865,6 +866,30 @@ static void unmount_atexit(void) cleanup_mount(); } +NTSTATUS get_volume_serial(PDWORD serial) { + int64_t fs_cid = ceph_get_fs_cid(cmount); + + char fsid_str[64] = { 0 }; + int ret = ceph_getxattr(cmount, "/", "ceph.cluster_fsid", + fsid_str, sizeof(fsid_str)); + if (ret < 0) { + dout(2) << "Coudln't retrieve the cluster fsid. Error: " << ret << dendl; + return cephfs_errno_to_ntsatus(ret); + } + + uuid_d fsid; + if (!fsid.parse(fsid_str)) { + dout(2) << "Couldn't parse cluster fsid" << dendl; + return STATUS_INTERNAL_ERROR; + } + + // We're generating a volume serial number by concatenating the last 16 bits + // of the filesystem id and the cluster fsid. + *serial = ((*(uint16_t*) fsid.bytes() & 0xffff) << 16) | (fs_cid & 0xffff); + + return 0; +} + int do_map() { PDOKAN_OPERATIONS dokan_operations = (PDOKAN_OPERATIONS) malloc(sizeof(DOKAN_OPERATIONS)); @@ -909,6 +934,21 @@ int do_map() { return cephfs_errno_to_ntsatus(r); } + if (g_cfg->win_vol_name.empty()) { + string ceph_fs_name = g_conf().get_val("client_fs"); + + g_cfg->win_vol_name = L"Ceph"; + if (!ceph_fs_name.empty()) { + g_cfg->win_vol_name += L" - " + to_wstring(ceph_fs_name); + } + } + + if (!g_cfg->win_vol_serial) { + if (get_volume_serial(&g_cfg->win_vol_serial)) { + return -EINVAL; + } + } + atexit(unmount_atexit); dout(0) << "Mounted cephfs directory: " << ceph_getcwd(cmount) <<". Mountpoint: " << to_string(g_cfg->mountpoint) << dendl; diff --git a/src/dokan/ceph_dokan.h b/src/dokan/ceph_dokan.h index f4323e4ba01ce..9675a15af56d9 100644 --- a/src/dokan/ceph_dokan.h +++ b/src/dokan/ceph_dokan.h @@ -32,6 +32,9 @@ struct Config { std::wstring mountpoint = L""; std::string root_path = ""; + + std::wstring win_vol_name = L""; + unsigned long win_vol_serial = 0; }; extern Config *g_cfg; diff --git a/src/dokan/options.cc b/src/dokan/options.cc index 21c5d4d6dbe4e..160ca8cdd9bba 100644 --- a/src/dokan/options.cc +++ b/src/dokan/options.cc @@ -39,6 +39,7 @@ Map options: -o [ --win-mount-mgr] use the Windows mount manager --current-session-only expose the mount only to the current user session -m [ --removable ] use a removable drive + --win-vol-name arg The Windows volume name. Default: Ceph - . Unmap options: -l [ --mountpoint ] arg mountpoint (path or drive letter) (e.g -l x). @@ -82,6 +83,7 @@ int parse_args( std::vector::iterator i; std::ostringstream err; std::string mountpoint; + std::string win_vol_name; for (i = args.begin(); i != args.end(); ) { if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) { @@ -104,6 +106,9 @@ int parse_args( cfg->removable = true; } else if (ceph_argparse_flag(args, i, "--win-mount-mgr", "-o", (char *)NULL)) { cfg->use_win_mount_mgr = true; + } else if (ceph_argparse_witharg(args, i, &win_vol_name, + "--win-vol-name", (char *)NULL)) { + cfg->win_vol_name = to_wstring(win_vol_name); } else if (ceph_argparse_flag(args, i, "--current-session-only", (char *)NULL)) { cfg->current_session_only = true; } else if (ceph_argparse_witharg(args, i, (int*)&cfg->thread_count, -- 2.39.5