Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions cmd/crio/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,16 @@ func main() {
logrus.Error(err)
}

// Write "$CleanShutdownFile".supported to show crio-wipe that
// we should be wiping if the CleanShutdownFile wasn't found.
// This protects us from wiping after an upgrade from a version that don't support
// CleanShutdownFile.
f, err := os.Create(config.CleanShutdownSupportedFileName())
if err != nil {
logrus.Errorf("Writing clean shutdown supported file: %v", err)
}
f.Close()

// and sync the changes to disk
if err := utils.SyncParent(config.CleanShutdownFile); err != nil {
logrus.Errorf("failed to sync parent directory of clean shutdown file: %v", err)
Expand Down
83 changes: 51 additions & 32 deletions cmd/crio/wipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/cri-o/cri-o/internal/criocli"
"github.com/cri-o/cri-o/internal/storage"
"github.com/cri-o/cri-o/internal/version"
crioconf "github.com/cri-o/cri-o/pkg/config"
json "github.com/json-iterator/go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -36,41 +37,18 @@ func crioWipe(c *cli.Context) error {
if err != nil {
return err
}
shouldWipeImages := true
shouldWipeContainers := true

// First, check if the node was rebooted.
// We know this happened because the VersionFile (which lives in a tmpfs)
// will not be there.
shouldWipeContainers, err := version.ShouldCrioWipe(config.VersionFile)
if err != nil {
logrus.Infof("checking whether cri-o should wipe containers: %v", err)
}

// Then, check whether crio has shutdown with time to sync.
// Note: this is only needed if the node rebooted.
// If there wasn't time to sync, we should clear the storage directory
if shouldWipeContainers && config.CleanShutdownFile != "" {
if _, err := os.Stat(config.CleanShutdownFile); err != nil {
logrus.Infof("file %s not found. Wiping storage directory %s because of suspected dirty shutdown", config.CleanShutdownFile, store.GraphRoot())
// If we do not do this, we may leak other resources that are not directly in the graphroot.
// Erroring here should not be fatal though, it's a best effort cleanup
if err := store.Wipe(); err != nil {
logrus.Infof("failed to wipe storage cleanly: %v", err)
}
// unmount storage or else we will fail with EBUSY
if _, err := store.Shutdown(false); err != nil {
return errors.Errorf("failed to shutdown storage before wiping: %v", err)
}
// totally remove storage, whatever is left (possibly orphaned layers)
if err := os.RemoveAll(store.GraphRoot()); err != nil {
return errors.Errorf("failed to remove storage directory: %v", err)
}
return nil
if !c.IsSet("force") {
// First, check if the node was rebooted.
// We know this happened because the VersionFile (which lives in a tmpfs)
// will not be there.
shouldWipeContainers, err = version.ShouldCrioWipe(config.VersionFile)
if err != nil {
logrus.Infof("checking whether cri-o should wipe containers: %v", err)
}
}

shouldWipeImages := true
// First, check if we need to upgrade at all
if !c.IsSet("force") {
// there are two locations we check before wiping:
// one in a temporary directory. This is to check whether the node has rebooted.
// if so, we should remove containers
Expand All @@ -82,6 +60,13 @@ func crioWipe(c *cli.Context) error {
}
}

// Then, check whether crio has shutdown with time to sync.
// Note: this is only needed if the node rebooted.
// If there wasn't time to sync, we should clear the storage directory
if shouldWipeContainers && shutdownWasUnclean(config) {
return handleCleanShutdown(config, store)
}

// if we should not wipe, exit with no error
if !shouldWipeContainers {
// we should not wipe images without wiping containers
Expand All @@ -103,6 +88,40 @@ func crioWipe(c *cli.Context) error {
return nil
}

func shutdownWasUnclean(config *crioconf.Config) bool {
// CleanShutdownFile not configured, skip
if config.CleanShutdownFile == "" {
return false
}
// CleanShutdownFile isn't supported, skip
if _, err := os.Stat(config.CleanShutdownSupportedFileName()); err != nil {
return false
}
// CleanShutdownFile is present, indicating clean shutdown
if _, err := os.Stat(config.CleanShutdownFile); err == nil {
return false
}
return true
}

func handleCleanShutdown(config *crioconf.Config, store cstorage.Store) error {
logrus.Infof("file %s not found. Wiping storage directory %s because of suspected dirty shutdown", config.CleanShutdownFile, store.GraphRoot())
// If we do not do this, we may leak other resources that are not directly in the graphroot.
// Erroring here should not be fatal though, it's a best effort cleanup
if err := store.Wipe(); err != nil {
logrus.Infof("failed to wipe storage cleanly: %v", err)
}
// unmount storage or else we will fail with EBUSY
if _, err := store.Shutdown(false); err != nil {
return errors.Errorf("failed to shutdown storage before wiping: %v", err)
}
// totally remove storage, whatever is left (possibly orphaned layers)
if err := os.RemoveAll(store.GraphRoot()); err != nil {
return errors.Errorf("failed to remove storage directory: %v", err)
}
return nil
}

type ContainerStore struct {
store cstorage.Store
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,10 @@ func (c *RootConfig) Validate(onExecution bool) error {
return nil
}

func (c *RootConfig) CleanShutdownSupportedFileName() string {
return c.CleanShutdownFile + ".supported"
}

// Validate is the main entry point for runtime configuration validation
// The parameter `onExecution` specifies if the validation should include
// execution checks. It returns an `error` on validation failure, otherwise
Expand Down
14 changes: 14 additions & 0 deletions test/crio-wipe.bats
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,17 @@ function start_crio_with_stopped_pod() {
test_crio_did_not_wipe_containers
test_crio_did_not_wipe_images
}

@test "don't clear containers if clean shutdown supported file not present" {
start_crio_with_stopped_pod
stop_crio_no_clean

rm "$CONTAINER_CLEAN_SHUTDOWN_FILE.supported"

run_crio_wipe

start_crio_no_setup

test_crio_did_not_wipe_containers
test_crio_did_not_wipe_images
}