]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs: provide additional volume details on Windows
authorLucian Petrut <lpetrut@cloudbasesolutions.com>
Mon, 8 Mar 2021 14:25:25 +0000 (14:25 +0000)
committerLucian Petrut <lpetrut@cloudbasesolutions.com>
Tue, 20 Apr 2021 15:39:11 +0000 (15:39 +0000)
At the moment, the Windows volume name and serial number are hardcoded.

This change makes the volume name configurable, defaulting to "Ceph"
or "Ceph - <fs_name>". 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 <lpetrut@cloudbasesolutions.com>
(cherry picked from commit 8a190816947b414366f5e1c6fac36ce0954f80d8)

src/dokan/ceph_dokan.cc
src/dokan/ceph_dokan.h
src/dokan/options.cc

index d16e81957799e916642025943b3270d476ec4087..90320e662c3a3c1536a2342cfecfe5f8b092b5ea 100644 (file)
@@ -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<string>("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;
index f4323e4ba01ce9bfbeb0444a014c52662e3c127d..9675a15af56d9fb2936f2af738c42e417d1b1580 100644 (file)
@@ -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;
index 21c5d4d6dbe4e498e91601060e38fef8441f410f..160ca8cdd9bba2b3190896cc0ca8dfebfbc9db24 100644 (file)
@@ -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 - <fs_name>.
 
 Unmap options:
   -l [ --mountpoint ] arg     mountpoint (path or drive letter) (e.g -l x).
@@ -82,6 +83,7 @@ int parse_args(
   std::vector<const char*>::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,