임시파일생성 소프트링크에서 하드링크로 변경
This commit is contained in:
@@ -18,7 +18,7 @@ public class TmpDatasetService {
|
|||||||
|
|
||||||
public String buildTmpDatasetSymlink(String uid, List<String> datasetUids) throws IOException {
|
public String buildTmpDatasetSymlink(String uid, List<String> datasetUids) throws IOException {
|
||||||
|
|
||||||
log.info("========== buildTmpDatasetSymlink START ==========");
|
log.info("========== buildTmpDatasetHardlink START ==========");
|
||||||
log.info("uid={}", uid);
|
log.info("uid={}", uid);
|
||||||
log.info("datasetUids={}", datasetUids);
|
log.info("datasetUids={}", datasetUids);
|
||||||
log.info("requestDir(raw)={}", requestDir);
|
log.info("requestDir(raw)={}", requestDir);
|
||||||
@@ -30,8 +30,9 @@ public class TmpDatasetService {
|
|||||||
log.info("BASE exists? {}", Files.isDirectory(BASE));
|
log.info("BASE exists? {}", Files.isDirectory(BASE));
|
||||||
log.info("tmp={}", tmp);
|
log.info("tmp={}", tmp);
|
||||||
|
|
||||||
long noDir = 0, scannedDirs = 0, regularFiles = 0, symlinksMade = 0;
|
long noDir = 0, scannedDirs = 0, regularFiles = 0, hardlinksMade = 0;
|
||||||
|
|
||||||
|
// tmp 디렉토리 준비
|
||||||
for (String type : List.of("train", "val")) {
|
for (String type : List.of("train", "val")) {
|
||||||
for (String part : List.of("input1", "input2", "label")) {
|
for (String part : List.of("input1", "input2", "label")) {
|
||||||
Path dir = tmp.resolve(type).resolve(part);
|
Path dir = tmp.resolve(type).resolve(part);
|
||||||
@@ -40,6 +41,27 @@ public class TmpDatasetService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 하드링크는 "같은 파일시스템"에서만 가능하므로 BASE/tmp가 같은 FS인지 미리 확인(권장)
|
||||||
|
try {
|
||||||
|
var baseStore = Files.getFileStore(BASE);
|
||||||
|
var tmpStore = Files.getFileStore(tmp.getParent()); // BASE/tmp
|
||||||
|
if (!baseStore.name().equals(tmpStore.name()) || !baseStore.type().equals(tmpStore.type())) {
|
||||||
|
throw new IOException(
|
||||||
|
"Hardlink requires same filesystem. baseStore="
|
||||||
|
+ baseStore.name()
|
||||||
|
+ "("
|
||||||
|
+ baseStore.type()
|
||||||
|
+ "), tmpStore="
|
||||||
|
+ tmpStore.name()
|
||||||
|
+ "("
|
||||||
|
+ tmpStore.type()
|
||||||
|
+ ")");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// FileStore 비교가 환경마다 애매할 수 있어서, 여기서는 경고만 주고 실제 createLink에서 최종 판단하게 둘 수도 있음.
|
||||||
|
log.warn("FileStore check skipped/failed (will rely on createLink): {}", e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
for (String id : datasetUids) {
|
for (String id : datasetUids) {
|
||||||
Path srcRoot = BASE.resolve(id);
|
Path srcRoot = BASE.resolve(id);
|
||||||
log.info("---- dataset id={} srcRoot={} exists? {}", id, srcRoot, Files.isDirectory(srcRoot));
|
log.info("---- dataset id={} srcRoot={} exists? {}", id, srcRoot, Files.isDirectory(srcRoot));
|
||||||
@@ -70,18 +92,21 @@ public class TmpDatasetService {
|
|||||||
String dstName = id + "__" + f.getFileName();
|
String dstName = id + "__" + f.getFileName();
|
||||||
Path dst = tmp.resolve(type).resolve(part).resolve(dstName);
|
Path dst = tmp.resolve(type).resolve(part).resolve(dstName);
|
||||||
|
|
||||||
|
// dst가 남아있으면 삭제(심볼릭링크든 파일이든)
|
||||||
|
if (Files.exists(dst) || Files.isSymbolicLink(dst)) {
|
||||||
|
Files.delete(dst);
|
||||||
|
log.debug("deleted existing: {}", dst);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Files.exists(dst) || Files.isSymbolicLink(dst)) {
|
// 하드링크 생성 (dst가 새 파일로 생기지만 inode는 f와 동일)
|
||||||
Files.delete(dst);
|
Files.createLink(dst, f);
|
||||||
log.debug("deleted existing: {}", dst);
|
hardlinksMade++;
|
||||||
}
|
log.debug("created hardlink: {} => {}", dst, f);
|
||||||
|
} catch (IOException e) {
|
||||||
Files.createSymbolicLink(dst, f.toAbsolutePath());
|
// 여기서 바로 실패시키면 “tmp는 만들었는데 내용은 0개” 같은 상태를 방지할 수 있음
|
||||||
symlinksMade++;
|
log.error("FAILED create hardlink: {} => {}", dst, f, e);
|
||||||
log.debug("created symlink: {} -> {}", dst, f.toAbsolutePath());
|
throw e;
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("FAILED create symlink: {} -> {}", dst, f.toAbsolutePath(), e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,13 +114,23 @@ public class TmpDatasetService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hardlinksMade == 0) {
|
||||||
|
throw new IOException(
|
||||||
|
"No hardlinks created. regularFiles="
|
||||||
|
+ regularFiles
|
||||||
|
+ ", scannedDirs="
|
||||||
|
+ scannedDirs
|
||||||
|
+ ", noDir="
|
||||||
|
+ noDir);
|
||||||
|
}
|
||||||
|
|
||||||
log.info("tmp dataset created: {}", tmp);
|
log.info("tmp dataset created: {}", tmp);
|
||||||
log.info(
|
log.info(
|
||||||
"summary: scannedDirs={}, noDir={}, regularFiles={}, symlinksMade={}",
|
"summary: scannedDirs={}, noDir={}, regularFiles={}, hardlinksMade={}",
|
||||||
scannedDirs,
|
scannedDirs,
|
||||||
noDir,
|
noDir,
|
||||||
regularFiles,
|
regularFiles,
|
||||||
symlinksMade);
|
hardlinksMade);
|
||||||
|
|
||||||
return uid;
|
return uid;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user