Merge pull request #123406 from SataQiu/fix-20240221
kubeadm: fix the invalid cross-device link bug during upgrade
This commit is contained in:
		| @@ -123,7 +123,7 @@ func NewKubeStaticPodPathManagerUsingTempDirs(kubernetesDir, patchesDir string, | ||||
|  | ||||
| // MoveFile should move a file from oldPath to newPath | ||||
| func (spm *KubeStaticPodPathManager) MoveFile(oldPath, newPath string) error { | ||||
| 	return os.Rename(oldPath, newPath) | ||||
| 	return kubeadmutil.MoveFile(oldPath, newPath) | ||||
| } | ||||
|  | ||||
| // KubernetesDir should point to the directory Kubernetes owns for storing various configuration files | ||||
|   | ||||
| @@ -17,19 +17,56 @@ limitations under the License. | ||||
| package util | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
|  | ||||
| 	"k8s.io/klog/v2" | ||||
| ) | ||||
|  | ||||
| // CopyFile copies a file from src to dest. | ||||
| func CopyFile(src, dest string) error { | ||||
| 	fileInfo, err := os.Stat(src) | ||||
| 	sourceFileInfo, err := os.Stat(src) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	contents, err := os.ReadFile(src) | ||||
|  | ||||
| 	sourceFile, err := os.Open(src) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = os.WriteFile(dest, contents, fileInfo.Mode()) | ||||
| 	defer func() { | ||||
| 		_ = sourceFile.Close() | ||||
| 	}() | ||||
|  | ||||
| 	destFile, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, sourceFileInfo.Mode()) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer func() { | ||||
| 		_ = destFile.Close() | ||||
| 	}() | ||||
|  | ||||
| 	_, err = io.Copy(destFile, sourceFile) | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // MoveFile moves a file from src to dest. | ||||
| func MoveFile(src, dest string) error { | ||||
| 	err := os.Rename(src, dest) | ||||
| 	if err != nil && strings.Contains(err.Error(), "invalid cross-device link") { | ||||
| 		// When calling os.Rename(), an "invalid cross-device link" error may occur | ||||
| 		// if the source and destination files are on different file systems. | ||||
| 		// In this case, the file is moved by copying and then deleting the source file, | ||||
| 		// although it is less efficient than os.Rename(). | ||||
| 		klog.V(4).Infof("cannot rename %v to %v due to %v, attempting an alternative method", src, dest, err) | ||||
| 		if err := CopyFile(src, dest); err != nil { | ||||
| 			return errors.Wrapf(err, "failed to copy file %v to %v", src, dest) | ||||
| 		} | ||||
| 		return os.Remove(src) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Prow Robot
					Kubernetes Prow Robot