From a205aca6d272fa1cd070da6dc2d21008555bc8a5 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Sun, 8 May 2016 22:45:34 +0530 Subject: [PATCH] init: Cleanup .minio/tmp directories recursively. Also takes care of cleaning up of parts directory during abortMultipartUpload. (#1532) --- fs-objects-multipart.go | 2 +- object-common-multipart.go | 21 +++------------------ object-common.go | 31 ++++++++++++++++++++++++++++++- object-utils.go | 9 +++++++-- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/fs-objects-multipart.go b/fs-objects-multipart.go index f358a0477..0c042c84b 100644 --- a/fs-objects-multipart.go +++ b/fs-objects-multipart.go @@ -123,7 +123,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload } // Cleanup all the parts if everything else has been safely committed. - if err = cleanupUploadedParts(fs.storage, mpartMetaPrefix, bucket, object, uploadID); err != nil { + if err = cleanupUploadedParts(fs.storage, bucket, object, uploadID); err != nil { return "", err } diff --git a/object-common-multipart.go b/object-common-multipart.go index 4f85512a1..e408abbf5 100644 --- a/object-common-multipart.go +++ b/object-common-multipart.go @@ -215,25 +215,10 @@ func putObjectPartCommon(storage StorageAPI, bucket string, object string, uploa return newMD5Hex, nil } -// Cleanup all temp entries inside tmpMetaPrefix directory, upon server initialization. -func cleanupAllTmpEntries(storage StorageAPI) error { - return cleanupUploadedParts(storage, tmpMetaPrefix, "", "", "") -} - // Wrapper to which removes all the uploaded parts after a successful // complete multipart upload. -func cleanupUploadedParts(storage StorageAPI, prefix, bucket, object, uploadID string) error { - multipartDir := path.Join(prefix, bucket, object, uploadID) - entries, err := storage.ListDir(minioMetaBucket, multipartDir) - if err != nil { - return err - } - for _, entry := range entries { - if err = storage.DeleteFile(minioMetaBucket, path.Join(multipartDir, entry)); err != nil { - return err - } - } - return nil +func cleanupUploadedParts(storage StorageAPI, bucket, object, uploadID string) error { + return cleanupDir(storage, minioMetaBucket, path.Join(mpartMetaPrefix, bucket, object, uploadID)) } // abortMultipartUploadCommon - aborts a multipart upload, common @@ -253,7 +238,7 @@ func abortMultipartUploadCommon(storage StorageAPI, bucket, object, uploadID str if !isUploadIDExists(storage, bucket, object, uploadID) { return InvalidUploadID{UploadID: uploadID} } - return cleanupUploadedParts(storage, mpartMetaPrefix, bucket, object, uploadID) + return cleanupUploadedParts(storage, bucket, object, uploadID) } // isIncompleteMultipart - is object incomplete multipart. diff --git a/object-common.go b/object-common.go index 22f83bd13..e437ed34c 100644 --- a/object-common.go +++ b/object-common.go @@ -38,13 +38,42 @@ func initObjectLayer(storage StorageAPI) error { } } // Cleanup all temp entries upon start. - err := cleanupAllTmpEntries(storage) + err := cleanupDir(storage, minioMetaBucket, tmpMetaPrefix) if err != nil { return toObjectErr(err, minioMetaBucket, tmpMetaPrefix) } return nil } +// Cleanup a directory recursively. +func cleanupDir(storage StorageAPI, volume, dirPath string) error { + var delFunc func(string) error + // Function to delete entries recursively. + delFunc = func(entryPath string) error { + if !strings.HasSuffix(entryPath, slashSeparator) { + // No trailing "/" means that this is a file which can be deleted. + return storage.DeleteFile(volume, entryPath) + } + // If it's a directory, list and call delFunc() for each entry. + entries, err := storage.ListDir(volume, entryPath) + if err != nil { + if err == errFileNotFound { + // if dirPath prefix never existed. + return nil + } + return err + } + for _, entry := range entries { + err = delFunc(pathJoin(entryPath, entry)) + if err != nil { + return err + } + } + return nil + } + return delFunc(retainSlash(dirPath)) +} + /// Common object layer functions. // makeBucket - create a bucket, is a common function for both object layers. diff --git a/object-utils.go b/object-utils.go index 583fca34c..9370c3161 100644 --- a/object-utils.go +++ b/object-utils.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "io" + "path" "regexp" "strings" "unicode/utf8" @@ -103,9 +104,13 @@ func retainSlash(s string) string { return strings.TrimSuffix(s, slashSeparator) + slashSeparator } -// pathJoin - path join. +// pathJoin - like path.Join() but retains trailing "/" of the last element func pathJoin(s1 string, s2 string) string { - return retainSlash(s1) + s2 + trailingSlash := "" + if strings.HasSuffix(s2, slashSeparator) { + trailingSlash = "/" + } + return path.Join(s1, s2) + trailingSlash } // Create an s3 compatible MD5sum for complete multipart transaction.