github-actions[bot] commented on code in PR #65987:
URL: https://github.com/apache/doris/pull/65987#discussion_r3643057704
##########
fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java:
##########
@@ -304,28 +306,94 @@ public static String getFullDriverUrl(String driverUrl)
throws IllegalArgumentEx
+ "file://xxx.jar, http://xxx.jar, https://xxx.jar, or
xxx.jar (without prefix).");
}
+ URI uri;
try {
- URI uri = new URI(driverUrl);
- String schema = uri.getScheme();
- checkCloudWhiteList(driverUrl);
- if (schema == null && !driverUrl.startsWith("/")) {
- return checkAndReturnDefaultDriverUrl(driverUrl);
- }
+ uri = new URI(driverUrl);
+ } catch (URISyntaxException e) {
+ // Fail closed: an unparsable URL must never be silently accepted,
otherwise the
+ // allowed-path check below could be bypassed by a malformed URL.
+ LOG.warn("invalid jdbc driver url: {}", driverUrl, e);
+ throw new IllegalArgumentException("Invalid driver URL: " +
driverUrl);
+ }
- if ("*".equals(Config.jdbc_driver_secure_path)) {
- return driverUrl;
- }
+ String schema = uri.getScheme();
+ checkCloudWhiteList(driverUrl);
+ if (schema == null && !driverUrl.startsWith("/")) {
+ return checkAndReturnDefaultDriverUrl(driverUrl);
+ }
- boolean isAllowed =
Arrays.stream(Config.jdbc_driver_secure_path.split(";"))
- .anyMatch(allowedPath ->
driverUrl.startsWith(allowedPath.trim()));
- if (!isAllowed) {
- throw new IllegalArgumentException("Driver URL does not match
any allowed paths: " + driverUrl);
- }
+ if ("*".equals(Config.jdbc_driver_secure_path)) {
return driverUrl;
+ }
+
+ if (!isDriverUrlAllowed(driverUrl, uri)) {
+ throw new IllegalArgumentException("Driver URL does not match any
allowed paths: " + driverUrl);
+ }
+ return driverUrl;
+ }
+
+ /**
+ * Check whether {@code driverUrl} falls under one of the
semicolon-separated prefixes configured in
+ * {@link Config#jdbc_driver_secure_path}. Matching is structural
(component-based) rather than a raw string
+ * prefix, so that neither prefix confusion ({@code /opt/drivers} vs
{@code /opt/drivers-evil}) nor path
+ * traversal ({@code /opt/drivers/../etc}) can slip a driver outside the
allowed location.
+ */
+ private static boolean isDriverUrlAllowed(String driverUrl, URI uri) {
+ String scheme = uri.getScheme();
+ List<String> allowedPaths = new ArrayList<>();
+ for (String p : Config.jdbc_driver_secure_path.split(";")) {
+ String trimmed = p.trim();
+ if (!trimmed.isEmpty()) {
+ allowedPaths.add(trimmed);
+ }
+ }
+ if ("http".equalsIgnoreCase(scheme) ||
"https".equalsIgnoreCase(scheme)) {
+ URI candidate = uri.normalize();
+ return allowedPaths.stream().anyMatch(allowed ->
remoteUrlMatches(candidate, allowed));
+ }
+ // Only file:// reaches here; bare absolute paths and bare "*.jar" are
handled earlier.
+ Path candidate = toLocalPath(driverUrl).normalize();
+ return allowedPaths.stream()
+ .map(allowed -> toLocalPath(allowed).normalize())
+ .anyMatch(candidate::startsWith);
+ }
+
+ /**
+ * Turn a {@code file://} URL or a plain filesystem path into a {@link
Path} for structural comparison.
+ */
+ private static Path toLocalPath(String pathOrUrl) {
+ String path = pathOrUrl;
+ if (path.startsWith("file://")) {
+ path = path.substring("file://".length());
+ }
+ return Paths.get(path);
+ }
+
+ /**
+ * Structural match for remote (http/https) driver URLs: scheme, host and
port must be equal, and the
+ * candidate path must sit under the allowed path (component-based). A
bare path prefix (no scheme) can
+ * never authorize a remote URL.
+ */
+ private static boolean remoteUrlMatches(URI candidate, String allowedPath)
{
+ URI base;
+ try {
+ base = new URI(allowedPath).normalize();
} catch (URISyntaxException e) {
- LOG.warn("invalid jdbc driver url: " + driverUrl);
- return driverUrl;
+ return false;
}
+ if (base.getScheme() == null) {
+ return false;
+ }
+ return base.getScheme().equalsIgnoreCase(candidate.getScheme())
+ && base.getHost() != null &&
base.getHost().equalsIgnoreCase(candidate.getHost())
+ && base.getPort() == candidate.getPort()
+ && pathIsUnder(candidate.getPath(), base.getPath());
Review Comment:
[P1] Preserve resource-selecting URI components
This comparison ignores query and user-info even though the checksum and
classloaders consume the complete original URL. With
`jdbc_driver_secure_path=https://good.example/download?id=approved`, the
candidate `https://good.example/download?id=evil` now matches because both
paths are `/download`; the previous prefix check rejected it. User-info is
broadened similarly. Please define the full remote-URI contract and either
compare these components when present or reject such entries/driver URLs, with
negative tests for query- and user-info-bearing URLs.
##########
fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/JdbcDorisConnector.java:
##########
@@ -125,11 +126,52 @@ public ConnectorScanPlanProvider getScanPlanProvider() {
return scanPlanProvider;
}
+ // A scheme-less driver_url must be a plain jar file name: letters,
digits, dot, underscore, hyphen.
+ // This intentionally forbids any path separator, so it can never escape
jdbc_drivers_dir.
+ private static final Pattern SAFE_DRIVER_FILE_NAME =
Pattern.compile("^[A-Za-z0-9._-]+\\.jar$");
+
+ /**
+ * Mandatory, non-configurable driver_url security rule. It is invoked from
+ * {@link #preCreateValidation} only, which the engine runs exclusively on
the user-facing
+ * create path (CatalogFactory calls {@code checkWhenCreating()} only when
{@code !isReplay}).
+ * Therefore this rule never runs during metadata/edit-log replay nor at
query time, so existing
+ * catalogs are unaffected and FE startup / follower replay can never be
blocked by it.
+ *
+ * <p>The rule cannot be turned off:
+ * <ul>
+ * <li>any {@code ..} path-traversal segment is rejected, for {@code
file://} and {@code http(s)} alike;</li>
+ * <li>a scheme-less driver_url must be a bare jar file name matching
{@code [A-Za-z0-9._-]+.jar}
+ * (no directories, no special characters), which is then resolved
under {@code jdbc_drivers_dir}.</li>
+ * </ul>
+ * Whether a remote/absolute URL is allowed at all remains governed by the
fe.conf-only
+ * {@code jdbc_driver_secure_path} / {@code jdbc_driver_url_white_list}
configs; this rule only
+ * forbids traversal and enforces the bare-name charset.
+ */
+ // package-private for unit testing; conceptually private.
+ static void checkDriverUrlSecurityRule(String driverUrl) {
+ String probe = driverUrl.replace('\\', '/');
+ for (String segment : probe.split("/")) {
+ if ("..".equals(segment)) {
+ throw new DorisConnectorException(
+ "Invalid driver_url: path traversal ('..') is not
allowed: " + driverUrl);
+ }
+ }
+ if (!driverUrl.contains("://")) {
+ if (!SAFE_DRIVER_FILE_NAME.matcher(driverUrl).matches()) {
+ throw new DorisConnectorException(
+ "Invalid driver_url: a driver file name must match
[A-Za-z0-9._-]+.jar (got: "
+ + driverUrl + ")");
+ }
+ }
+ }
+
@Override
public void preCreateValidation(ConnectorValidationContext context) throws
Exception {
// 1. Validate/resolve JDBC driver — format, whitelist, secure_path,
file existence.
String driverUrl = properties.get(JdbcConnectorProperties.DRIVER_URL);
if (driverUrl != null && !driverUrl.isEmpty()) {
+ // Mandatory, non-configurable security rule, enforced on catalog
creation only.
+ checkDriverUrlSecurityRule(driverUrl);
Review Comment:
[P1] Enforce this rule when `driver_url` is altered
This call is reached only from `checkWhenCreating()`. `ALTER CATALOG ... SET
PROPERTIES("driver_url"=...)` instead goes through
`CatalogMgr.replayAlterCatalogProps(..., false)` and
`PluginDrivenExternalCatalog.checkProperties()`, where the JDBC provider
validates only property shape. The update is then journaled, the catalog is
reset, and the recreated connector passes the replacement URL directly to
`URLClassLoader`; the old checksum is not recomputed or checked by FE. A user
with catalog `ALTER` can therefore create with an allowed URL and then replace
it with a traversal/out-of-policy URL. Validate the replacement and
recompute/verify its checksum before mutation/journaling (without doing the I/O
under the catalog write lock), and add an ALTER-path test.
##########
fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/UploadAction.java:
##########
@@ -1,318 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.httpv2.rest;
-
-import org.apache.doris.common.Config;
-import org.apache.doris.httpv2.entity.ResponseEntityBuilder;
-import org.apache.doris.httpv2.util.LoadSubmitter;
-import org.apache.doris.httpv2.util.TmpFileMgr;
-import org.apache.doris.mysql.privilege.PrivPredicate;
-import org.apache.doris.qe.ConnectContext;
-import org.apache.doris.system.SystemInfoService;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-/**
- * Upload file
- */
-@RestController
-public class UploadAction extends RestBaseController {
- private static final Logger LOG = LogManager.getLogger(UploadAction.class);
- private static TmpFileMgr fileMgr = new TmpFileMgr(Config.tmp_dir);
- private static LoadSubmitter loadSubmitter = new LoadSubmitter();
-
- private static final String PARAM_COLUMN_SEPARATOR = "column_separator";
- private static final String PARAM_PREVIEW = "preview";
- private static final String PARAM_FILE_ID = "file_id";
- private static final String PARAM_FILE_UUID = "file_uuid";
-
- /**
- * Upload the file
- * @param ns
- * @param dbName
- * @param tblName
- * @param file
- * @param request
- * @param response
- * @return
- */
- @RequestMapping(path = "/api/{" + NS_KEY + "}/{" + DB_KEY + "}/{" +
TABLE_KEY + "}/upload",
Review Comment:
[P2] Retire the Web UI caller with this endpoint
The shipped UI still exposes the Data Import tab and routes it to
`DataImport` (`ui/src/pages/playground/content/content-structure.tsx` and
`ui/src/router/index.ts`). That component and `ui/src/api/api.ts` still issue
POST/PUT/GET/DELETE requests to this exact route. With no API handler, GET/POST
may be swallowed by the SPA fallback and return HTML while PUT/DELETE cannot
run, so upload/list/preview/submit/delete cannot complete. Remove the tab,
route, component, and API helpers in this PR, or migrate them to a supported
import flow, so the product does not advertise a guaranteed-broken action.
##########
fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java:
##########
@@ -304,28 +306,94 @@ public static String getFullDriverUrl(String driverUrl)
throws IllegalArgumentEx
+ "file://xxx.jar, http://xxx.jar, https://xxx.jar, or
xxx.jar (without prefix).");
}
+ URI uri;
try {
- URI uri = new URI(driverUrl);
- String schema = uri.getScheme();
- checkCloudWhiteList(driverUrl);
- if (schema == null && !driverUrl.startsWith("/")) {
- return checkAndReturnDefaultDriverUrl(driverUrl);
- }
+ uri = new URI(driverUrl);
+ } catch (URISyntaxException e) {
+ // Fail closed: an unparsable URL must never be silently accepted,
otherwise the
+ // allowed-path check below could be bypassed by a malformed URL.
+ LOG.warn("invalid jdbc driver url: {}", driverUrl, e);
+ throw new IllegalArgumentException("Invalid driver URL: " +
driverUrl);
+ }
- if ("*".equals(Config.jdbc_driver_secure_path)) {
- return driverUrl;
- }
+ String schema = uri.getScheme();
+ checkCloudWhiteList(driverUrl);
+ if (schema == null && !driverUrl.startsWith("/")) {
+ return checkAndReturnDefaultDriverUrl(driverUrl);
+ }
- boolean isAllowed =
Arrays.stream(Config.jdbc_driver_secure_path.split(";"))
- .anyMatch(allowedPath ->
driverUrl.startsWith(allowedPath.trim()));
- if (!isAllowed) {
- throw new IllegalArgumentException("Driver URL does not match
any allowed paths: " + driverUrl);
- }
+ if ("*".equals(Config.jdbc_driver_secure_path)) {
return driverUrl;
+ }
+
+ if (!isDriverUrlAllowed(driverUrl, uri)) {
+ throw new IllegalArgumentException("Driver URL does not match any
allowed paths: " + driverUrl);
+ }
+ return driverUrl;
+ }
+
+ /**
+ * Check whether {@code driverUrl} falls under one of the
semicolon-separated prefixes configured in
+ * {@link Config#jdbc_driver_secure_path}. Matching is structural
(component-based) rather than a raw string
+ * prefix, so that neither prefix confusion ({@code /opt/drivers} vs
{@code /opt/drivers-evil}) nor path
+ * traversal ({@code /opt/drivers/../etc}) can slip a driver outside the
allowed location.
+ */
+ private static boolean isDriverUrlAllowed(String driverUrl, URI uri) {
+ String scheme = uri.getScheme();
+ List<String> allowedPaths = new ArrayList<>();
+ for (String p : Config.jdbc_driver_secure_path.split(";")) {
+ String trimmed = p.trim();
+ if (!trimmed.isEmpty()) {
Review Comment:
[P2] Update the empty-value config contract
Dropping empty entries makes `jdbc_driver_secure_path=""` deny every
scheme-qualified URL, but the operator-visible `Config.jdbc_driver_secure_path`
description still says an empty value means allow-all. That leaves `SHOW
FRONTEND CONFIG`/the source contract directly opposite to runtime behavior.
Update the declaration in this PR and add an empty-value test so the
intentional compatibility change is unambiguous.
##########
fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java:
##########
@@ -304,28 +306,94 @@ public static String getFullDriverUrl(String driverUrl)
throws IllegalArgumentEx
+ "file://xxx.jar, http://xxx.jar, https://xxx.jar, or
xxx.jar (without prefix).");
}
+ URI uri;
try {
- URI uri = new URI(driverUrl);
- String schema = uri.getScheme();
- checkCloudWhiteList(driverUrl);
- if (schema == null && !driverUrl.startsWith("/")) {
- return checkAndReturnDefaultDriverUrl(driverUrl);
- }
+ uri = new URI(driverUrl);
+ } catch (URISyntaxException e) {
+ // Fail closed: an unparsable URL must never be silently accepted,
otherwise the
+ // allowed-path check below could be bypassed by a malformed URL.
+ LOG.warn("invalid jdbc driver url: {}", driverUrl, e);
+ throw new IllegalArgumentException("Invalid driver URL: " +
driverUrl);
+ }
- if ("*".equals(Config.jdbc_driver_secure_path)) {
- return driverUrl;
- }
+ String schema = uri.getScheme();
+ checkCloudWhiteList(driverUrl);
+ if (schema == null && !driverUrl.startsWith("/")) {
+ return checkAndReturnDefaultDriverUrl(driverUrl);
+ }
- boolean isAllowed =
Arrays.stream(Config.jdbc_driver_secure_path.split(";"))
- .anyMatch(allowedPath ->
driverUrl.startsWith(allowedPath.trim()));
- if (!isAllowed) {
- throw new IllegalArgumentException("Driver URL does not match
any allowed paths: " + driverUrl);
- }
+ if ("*".equals(Config.jdbc_driver_secure_path)) {
return driverUrl;
+ }
+
+ if (!isDriverUrlAllowed(driverUrl, uri)) {
+ throw new IllegalArgumentException("Driver URL does not match any
allowed paths: " + driverUrl);
+ }
+ return driverUrl;
+ }
+
+ /**
+ * Check whether {@code driverUrl} falls under one of the
semicolon-separated prefixes configured in
+ * {@link Config#jdbc_driver_secure_path}. Matching is structural
(component-based) rather than a raw string
+ * prefix, so that neither prefix confusion ({@code /opt/drivers} vs
{@code /opt/drivers-evil}) nor path
+ * traversal ({@code /opt/drivers/../etc}) can slip a driver outside the
allowed location.
+ */
+ private static boolean isDriverUrlAllowed(String driverUrl, URI uri) {
+ String scheme = uri.getScheme();
+ List<String> allowedPaths = new ArrayList<>();
+ for (String p : Config.jdbc_driver_secure_path.split(";")) {
+ String trimmed = p.trim();
+ if (!trimmed.isEmpty()) {
+ allowedPaths.add(trimmed);
+ }
+ }
+ if ("http".equalsIgnoreCase(scheme) ||
"https".equalsIgnoreCase(scheme)) {
+ URI candidate = uri.normalize();
+ return allowedPaths.stream().anyMatch(allowed ->
remoteUrlMatches(candidate, allowed));
+ }
+ // Only file:// reaches here; bare absolute paths and bare "*.jar" are
handled earlier.
+ Path candidate = toLocalPath(driverUrl).normalize();
Review Comment:
[P1] Decode file URIs before checking containment
`toLocalPath()` strips the raw `file://` prefix, so an encoded parent
segment remains a literal `%2e%2e` path component and passes `startsWith`. The
checksum/classloading consumers then URL-decode it. For example, with the
allowed directory `file:///home/runner/work/doris/doris/fe`,
`file:///home/runner/work/doris/doris/fe/%2e%2e/README.md` passes this
comparison but `URL.openStream()` resolves and reads the repository-root file.
The connector's raw segment check misses the same representation. Build the
local path from the parsed URI (decoded exactly once), normalize/compare
allowed paths in the same representation used by consumers, and add an
encoded-traversal test that opens the result.
##########
fe/fe-core/src/main/java/org/apache/doris/httpv2/util/LoadSubmitter.java:
##########
@@ -1,178 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.httpv2.util;
-
-import org.apache.doris.catalog.Env;
-import org.apache.doris.common.Config;
-import org.apache.doris.common.LoadException;
-import org.apache.doris.common.ThreadPoolManager;
-import org.apache.doris.common.util.NetUtils;
-import org.apache.doris.httpv2.rest.UploadAction;
-import org.apache.doris.system.Backend;
-import org.apache.doris.system.BeSelectionPolicy;
-import org.apache.doris.system.SystemInfoService;
-
-import com.google.common.base.Strings;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.Type;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadPoolExecutor;
-
-public class LoadSubmitter {
- private static final Logger LOG =
LogManager.getLogger(LoadSubmitter.class);
-
- private ThreadPoolExecutor executor =
ThreadPoolManager.newDaemonCacheThreadPoolThrowException(
- Config.http_load_submitter_max_worker_threads,
"load-submitter", true);
Review Comment:
[P2] Retire the upload-submitter config too
This executor is the only consumer of
`Config.http_load_submitter_max_worker_threads`, but the annotated field
remains accepted and exposed with the description “maximum number of worker
threads for the HTTP upload submitter.” After this deletion the setting can
never affect runtime behavior. Remove it so old `fe.conf` entries receive the
existing unknown-key warning, or explicitly retain and describe it as a
deprecated no-op.
##########
fe/fe-core/src/main/java/org/apache/doris/httpv2/util/TmpFileMgr.java:
##########
@@ -1,307 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.httpv2.util;
-
-import org.apache.doris.common.util.Util;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
-
-/**
- * Manager the file uploaded.
- * This file manager is currently only used to manage files
- * uploaded through the Upload RESTFul API.
- * And limit the number and size of the maximum upload file.
- * It can also browse or delete files through the RESTFul API.
- */
-public class TmpFileMgr {
- public static final Logger LOG = LogManager.getLogger(TmpFileMgr.class);
-
- private static final long MAX_TOTAL_FILE_SIZE_BYTES = 1 * 1024 * 1024 *
1024L; // 1GB
- private static final long MAX_TOTAL_FILE_NUM = 100;
- public static final long MAX_SINGLE_FILE_SIZE = 100 * 1024 * 1024L; //
100MB
- private static final String UPLOAD_DIR = "_doris_upload";
-
- private AtomicLong fileIdGenerator = new AtomicLong(0);
- private String rootDir;
- private Map<Long, TmpFile> fileMap = Maps.newConcurrentMap();
-
- private long totalFileSize = 0;
-
- public TmpFileMgr(String dir) {
- this.rootDir = dir + "/" + UPLOAD_DIR;
- init();
- }
-
- private void init() {
Review Comment:
[P2] Preserve cleanup of pre-upgrade upload files
This `init()` call was the only startup path that deleted
`Config.tmp_dir/_doris_upload`. If an FE running the previous version stops
with uploaded files present, the first start after this deletion no longer
loads the manager, and no other current code cleans that directory; up to the
old 1 GiB limit can remain indefinitely. Keep a startup migration that removes
the legacy directory without re-registering the endpoint, and cover the upgrade
case by seeding the directory before initialization.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]