]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Copyright (C) 2021 SUSE LINUX GmbH | |
3 | * | |
4 | * This is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Lesser General Public | |
6 | * License version 2.1, as published by the Free Software | |
7 | * Foundation. See file COPYING. | |
8 | * | |
9 | */ | |
10 | ||
11 | #include "include/compat.h" | |
12 | #include "include/cephfs/libcephfs.h" | |
13 | ||
14 | #include "ceph_dokan.h" | |
15 | #include "utils.h" | |
16 | ||
17 | #include "common/ceph_argparse.h" | |
18 | #include "common/config.h" | |
19 | ||
20 | #include "global/global_init.h" | |
21 | ||
22 | void print_usage() { | |
23 | const char* usage_str = R"( | |
24 | Usage: ceph-dokan.exe -l <mountpoint> | |
25 | map -l <mountpoint> Map a CephFS filesystem | |
26 | unmap -l <mountpoint> Unmap a CephFS filesystem | |
27 | ||
28 | Map options: | |
29 | -l [ --mountpoint ] arg mountpoint (path or drive letter) (e.g -l x) | |
30 | -x [ --root-path ] arg mount a Ceph filesystem subdirectory | |
31 | ||
32 | -t [ --thread-count] arg thread count | |
33 | --operation-timeout arg Dokan operation timeout. Default: 120s. | |
34 | ||
35 | --debug enable debug output | |
36 | --dokan-stderr enable stderr Dokan logging | |
37 | ||
38 | --read-only read-only mount | |
39 | -o [ --win-mount-mgr] use the Windows mount manager | |
40 | --current-session-only expose the mount only to the current user session | |
41 | --removable use a removable drive | |
42 | --win-vol-name arg The Windows volume name. Default: Ceph - <fs_name>. | |
43 | ||
44 | Unmap options: | |
45 | -l [ --mountpoint ] arg mountpoint (path or drive letter) (e.g -l x). | |
46 | It has to be the exact same mountpoint that was | |
47 | used when the mapping was created. | |
48 | ||
49 | Common Options: | |
50 | )"; | |
51 | ||
52 | std::cout << usage_str; | |
53 | generic_client_usage(); | |
54 | } | |
55 | ||
56 | ||
57 | int parse_args( | |
58 | std::vector<const char*>& args, | |
59 | std::ostream *err_msg, | |
60 | Command *command, Config *cfg) | |
61 | { | |
62 | if (args.empty()) { | |
63 | std::cout << "ceph-dokan: -h or --help for usage" << std::endl; | |
64 | return -EINVAL; | |
65 | } | |
66 | ||
67 | std::string conf_file_list; | |
68 | std::string cluster; | |
69 | CephInitParameters iparams = ceph_argparse_early_args( | |
70 | args, CEPH_ENTITY_TYPE_CLIENT, &cluster, &conf_file_list); | |
71 | ||
72 | ConfigProxy config{false}; | |
73 | config->name = iparams.name; | |
74 | config->cluster = cluster; | |
75 | if (!conf_file_list.empty()) { | |
76 | config.parse_config_files(conf_file_list.c_str(), nullptr, 0); | |
77 | } else { | |
78 | config.parse_config_files(nullptr, nullptr, 0); | |
79 | } | |
80 | config.parse_env(CEPH_ENTITY_TYPE_CLIENT); | |
81 | config.parse_argv(args); | |
82 | ||
83 | std::vector<const char*>::iterator i; | |
84 | std::ostringstream err; | |
85 | std::string mountpoint; | |
86 | std::string win_vol_name; | |
87 | ||
88 | for (i = args.begin(); i != args.end(); ) { | |
89 | if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) { | |
90 | *command = Command::Help; | |
91 | return 0; | |
92 | } else if (ceph_argparse_flag(args, i, "-v", "--version", (char*)NULL)) { | |
93 | *command = Command::Version; | |
94 | } else if (ceph_argparse_witharg(args, i, &mountpoint, | |
95 | "--mountpoint", "-l", (char *)NULL)) { | |
96 | cfg->mountpoint = to_wstring(mountpoint); | |
97 | } else if (ceph_argparse_witharg(args, i, &cfg->root_path, | |
98 | "--root-path", "-x", (char *)NULL)) { | |
99 | } else if (ceph_argparse_flag(args, i, "--debug", (char *)NULL)) { | |
100 | cfg->debug = true; | |
101 | } else if (ceph_argparse_flag(args, i, "--dokan-stderr", (char *)NULL)) { | |
102 | cfg->dokan_stderr = true; | |
103 | } else if (ceph_argparse_flag(args, i, "--read-only", (char *)NULL)) { | |
104 | cfg->readonly = true; | |
105 | } else if (ceph_argparse_flag(args, i, "--removable", (char *)NULL)) { | |
106 | cfg->removable = true; | |
107 | } else if (ceph_argparse_flag(args, i, "--win-mount-mgr", "-o", (char *)NULL)) { | |
108 | cfg->use_win_mount_mgr = true; | |
109 | } else if (ceph_argparse_witharg(args, i, &win_vol_name, | |
110 | "--win-vol-name", (char *)NULL)) { | |
111 | cfg->win_vol_name = to_wstring(win_vol_name); | |
112 | } else if (ceph_argparse_flag(args, i, "--current-session-only", (char *)NULL)) { | |
113 | cfg->current_session_only = true; | |
114 | } else if (ceph_argparse_witharg(args, i, (int*)&cfg->thread_count, | |
115 | err, "--thread-count", "-t", (char *)NULL)) { | |
116 | if (!err.str().empty()) { | |
117 | *err_msg << "ceph-dokan: " << err.str(); | |
118 | return -EINVAL; | |
119 | } | |
120 | if (cfg->thread_count < 0) { | |
121 | *err_msg << "ceph-dokan: Invalid argument for thread-count"; | |
122 | return -EINVAL; | |
123 | } | |
124 | } else if (ceph_argparse_witharg(args, i, (int*)&cfg->operation_timeout, | |
125 | err, "--operation-timeout", (char *)NULL)) { | |
126 | if (!err.str().empty()) { | |
127 | *err_msg << "ceph-dokan: " << err.str(); | |
128 | return -EINVAL; | |
129 | } | |
130 | if (cfg->operation_timeout < 0) { | |
131 | *err_msg << "ceph-dokan: Invalid argument for operation-timeout"; | |
132 | return -EINVAL; | |
133 | } | |
134 | } else { | |
135 | ++i; | |
136 | } | |
137 | } | |
138 | ||
139 | if (cfg->use_win_mount_mgr && cfg->current_session_only) { | |
140 | *err_msg << "ceph-dokan: The mount manager always mounts the drive " | |
141 | << "for all user sessions."; | |
142 | return -EINVAL; | |
143 | } | |
144 | ||
145 | Command cmd = Command::None; | |
146 | if (args.begin() != args.end()) { | |
147 | if (strcmp(*args.begin(), "help") == 0) { | |
148 | cmd = Command::Help; | |
149 | } else if (strcmp(*args.begin(), "version") == 0) { | |
150 | cmd = Command::Version; | |
151 | } else if (strcmp(*args.begin(), "map") == 0) { | |
152 | cmd = Command::Map; | |
153 | } else if (strcmp(*args.begin(), "unmap") == 0) { | |
154 | cmd = Command::Unmap; | |
155 | } else { | |
156 | *err_msg << "ceph-dokan: unknown command: " << *args.begin(); | |
157 | return -EINVAL; | |
158 | } | |
159 | args.erase(args.begin()); | |
160 | } | |
161 | if (cmd == Command::None) { | |
162 | // The default command. | |
163 | cmd = Command::Map; | |
164 | } | |
165 | ||
166 | switch (cmd) { | |
167 | case Command::Map: | |
168 | case Command::Unmap: | |
169 | if (cfg->mountpoint.empty()) { | |
170 | *err_msg << "ceph-dokan: missing mountpoint."; | |
171 | return -EINVAL; | |
172 | } | |
173 | break; | |
174 | default: | |
175 | break; | |
176 | } | |
177 | ||
178 | if (args.begin() != args.end()) { | |
179 | *err_msg << "ceph-dokan: unknown args: " << *args.begin(); | |
180 | return -EINVAL; | |
181 | } | |
182 | ||
183 | *command = cmd; | |
184 | return 0; | |
185 | } | |
186 | ||
187 | int set_dokan_options(Config *cfg, PDOKAN_OPTIONS dokan_options) { | |
188 | ZeroMemory(dokan_options, sizeof(DOKAN_OPTIONS)); | |
189 | dokan_options->Version = DOKAN_VERSION; | |
190 | dokan_options->ThreadCount = cfg->thread_count; | |
191 | dokan_options->MountPoint = cfg->mountpoint.c_str(); | |
192 | dokan_options->Timeout = cfg->operation_timeout * 1000; | |
193 | ||
194 | if (cfg->removable) | |
195 | dokan_options->Options |= DOKAN_OPTION_REMOVABLE; | |
196 | if (cfg->use_win_mount_mgr) | |
197 | dokan_options->Options |= DOKAN_OPTION_MOUNT_MANAGER; | |
198 | if (cfg->current_session_only) | |
199 | dokan_options->Options |= DOKAN_OPTION_CURRENT_SESSION; | |
200 | if (cfg->readonly) | |
201 | dokan_options->Options |= DOKAN_OPTION_WRITE_PROTECT; | |
202 | if (cfg->debug) | |
203 | dokan_options->Options |= DOKAN_OPTION_DEBUG; | |
204 | if (cfg->dokan_stderr) | |
205 | dokan_options->Options |= DOKAN_OPTION_STDERR; | |
206 | ||
207 | return 0; | |
208 | } |