Merge pull request #123406 from SataQiu/fix-20240221

kubeadm: fix the invalid cross-device link bug during upgrade
This commit is contained in:
Kubernetes Prow Robot 2024-02-22 06:12:58 -08:00 committed by GitHub
commit 786510947b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 41 additions and 4 deletions

View File

@ -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

View File

@ -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
}