Example #1
0
File: gc.go Project: krnowak/rkt
// deletePod cleans up files and resource associated with the pod
// pod must be under exclusive lock and be in either ExitedGarbage
// or Garbage state
func deletePod(p *pod) {
	if !p.isExitedGarbage && !p.isGarbage {
		panic(fmt.Sprintf("logic error: deletePod called with non-garbage pod %q (status %q)", p.uuid, p.getState()))
	}

	if p.isExitedGarbage {
		s, err := store.NewStore(getDataDir())
		if err != nil {
			stderr("Cannot open store: %v", err)
			return
		}
		defer s.Close()
		stage1TreeStoreID, err := p.getStage1TreeStoreID()
		if err != nil {
			stderr("Error getting stage1 treeStoreID: %v", err)
			return
		}
		stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID)

		// execute stage1's GC
		if err := stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil {
			stderr("Stage1 GC of pod %q failed: %v", p.uuid, err)
			return
		}

		if p.usesOverlay() {
			apps, err := p.getApps()
			if err != nil {
				stderr("Error retrieving app hashes from pod manifest: %v", err)
				return
			}
			for _, a := range apps {
				dest := filepath.Join(common.AppPath(p.path(), a.Name), "rootfs")
				if err := syscall.Unmount(dest, 0); err != nil {
					// machine could have been rebooted and mounts lost.
					// ignore "does not exist" and "not a mount point" errors
					if err != syscall.ENOENT && err != syscall.EINVAL {
						stderr("Error unmounting app at %v: %v", dest, err)
					}
				}
			}

			s1 := filepath.Join(common.Stage1ImagePath(p.path()), "rootfs")
			if err := syscall.Unmount(s1, 0); err != nil {
				// machine could have been rebooted and mounts lost.
				// ignore "does not exist" and "not a mount point" errors
				if err != syscall.ENOENT && err != syscall.EINVAL {
					stderr("Error unmounting stage1 at %v: %v", s1, err)
					return
				}
			}
		}
	}

	if err := os.RemoveAll(p.path()); err != nil {
		stderr("Unable to remove pod %q: %v", p.uuid, err)
	}
}
Example #2
0
File: gc.go Project: nhlfr/rkt
// deletePod cleans up files and resource associated with the pod
// pod must be under exclusive lock and be in either ExitedGarbage
// or Garbage state
func deletePod(p *pkgPod.Pod) {
	podState := p.State()
	if podState != pkgPod.ExitedGarbage && podState != pkgPod.Garbage {
		stderr.Panicf("logic error: deletePod called with non-garbage pod %q (status %q)", p.UUID, p.State())
	}

	if podState == pkgPod.ExitedGarbage {
		s, err := imagestore.NewStore(storeDir())
		if err != nil {
			stderr.PrintE("cannot open store", err)
			return
		}
		defer s.Close()

		ts, err := treestore.NewStore(treeStoreDir(), s)
		if err != nil {
			stderr.PrintE("cannot open store", err)
			return
		}

		if globalFlags.Debug {
			stage0.InitDebug()
		}

		if err := mountPodStage1(ts, p); err == nil {
			if err = stage0.GC(p.Path(), p.UUID); err != nil {
				stderr.PrintE(fmt.Sprintf("problem performing stage1 GC on %q", p.UUID), err)
			}
			// an overlay fs can be mounted over itself, let's unmount it here
			// if we mounted it before to avoid problems when running
			// stage0.MountGC
			if p.UsesOverlay() {
				stage1Mnt := common.Stage1RootfsPath(p.Path())
				if err := syscall.Unmount(stage1Mnt, 0); err != nil {
					stderr.PrintE("error unmounting stage1", err)
				}
			}
		} else {
			stderr.PrintE("skipping stage1 GC", err)
		}

		// unmount all leftover mounts
		if err := stage0.MountGC(p.Path(), p.UUID.String()); err != nil {
			stderr.PrintE(fmt.Sprintf("GC of leftover mounts for pod %q failed", p.UUID), err)
			return
		}
	}

	if err := os.RemoveAll(p.Path()); err != nil {
		stderr.PrintE(fmt.Sprintf("unable to remove pod %q", p.UUID), err)
		os.Exit(254)
	}
}
Example #3
0
// emptyExitedGarbage discards sufficiently aged pods from exitedGarbageDir()
func emptyExitedGarbage(gracePeriod time.Duration) error {
	if err := walkPods(includeExitedGarbageDir, func(p *pod) {
		gp := p.path()
		st := &syscall.Stat_t{}
		if err := syscall.Lstat(gp, st); err != nil {
			if err != syscall.ENOENT {
				stderr("Unable to stat %q, ignoring: %v", gp, err)
			}
			return
		}

		if expiration := time.Unix(st.Ctim.Unix()).Add(gracePeriod); time.Now().After(expiration) {
			if err := p.ExclusiveLock(); err != nil {
				return
			}
			stdout("Garbage collecting pod %q", p.uuid)

			s, err := store.NewStore(globalFlags.Dir)
			if err != nil {
				stderr("Cannot open store: %v", err)
				return
			}
			stage1ID, err := p.getStage1Hash()
			if err != nil {
				stderr("Error getting stage1 hash")
				return
			}
			stage1RootFS := s.GetTreeStoreRootFS(stage1ID.String())

			// execute stage1's GC
			if err := stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil {
				stderr("Stage1 GC of pod %q failed: %v", p.uuid, err)
				return
			}

			if err := os.RemoveAll(gp); err != nil {
				stderr("Unable to remove pod %q: %v", p.uuid, err)
			}
		}
	}); err != nil {
		return err
	}

	return nil
}
Example #4
0
File: gc.go Project: hwinkel/rkt
// deletePod cleans up files and resource associated with the pod
// pod must be under exclusive lock and be in either ExitedGarbage
// or Garbage state
func deletePod(p *pod) {
	if !p.isExitedGarbage && !p.isGarbage {
		stderr.Panicf("logic error: deletePod called with non-garbage pod %q (status %q)", p.uuid, p.getState())
	}

	if p.isExitedGarbage {
		s, err := store.NewStore(getDataDir())
		if err != nil {
			stderr.PrintE("cannot open store", err)
			return
		}
		defer s.Close()

		// execute stage1's GC
		stage1TreeStoreID, err := p.getStage1TreeStoreID()
		if err != nil {
			stderr.PrintE("error getting stage1 treeStoreID", err)
			stderr.Print("skipping stage1 GC")
		} else {
			if globalFlags.Debug {
				stage0.InitDebug()
			}
			stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID)
			if err = stage0.GC(p.path(), p.uuid, stage1RootFS); err != nil {
				stderr.PrintE(fmt.Sprintf("problem performing stage1 GC on %q", p.uuid), err)
			}
		}

		// unmount all leftover mounts
		if err := stage0.MountGC(p.path(), p.uuid.String()); err != nil {
			stderr.PrintE(fmt.Sprintf("GC of leftover mounts for pod %q failed", p.uuid), err)
			return
		}
	}

	if err := os.RemoveAll(p.path()); err != nil {
		stderr.PrintE(fmt.Sprintf("unable to remove pod %q", p.uuid), err)
		os.Exit(1)
	}
}
Example #5
0
File: gc.go Project: matomesc/rkt
// deletePod cleans up files and resource associated with the pod
// pod must be under exclusive lock and be in either ExitedGarbage
// or Garbage state
func deletePod(p *pod) {
	if !p.isExitedGarbage && !p.isGarbage {
		panic(fmt.Sprintf("Logic error: deletePod called with non-garbage pod %q (status %q)", p.uuid, p.getState()))
	}

	if p.isExitedGarbage {
		s, err := store.NewStore(getDataDir())
		if err != nil {
			stderr("Cannot open store: %v", err)
			return
		}
		defer s.Close()

		// execute stage1's GC
		stage1TreeStoreID, err := p.getStage1TreeStoreID()
		if err != nil {
			stderr("Error getting stage1 treeStoreID: %v", err)
			stderr("Skipping stage1 GC")
		} else {
			stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID)
			if err = stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil {
				stderr("Problem performing stage1 GC on %q: %v", p.uuid, err)
			}
		}

		// unmount all leftover mounts
		if err := stage0.MountGC(p.path(), p.uuid.String()); err != nil {
			stderr("GC of leftover mounts for pod %q failed: %v\n", p.uuid, err)
			return
		}
	}

	if err := os.RemoveAll(p.path()); err != nil {
		stderr("Unable to remove pod %q: %v", p.uuid, err)
		os.Exit(1)
	}
}
Example #6
0
File: gc.go Project: runyontr/rkt
// emptyExitedGarbage discards sufficiently aged pods from exitedGarbageDir()
func emptyExitedGarbage(gracePeriod time.Duration) error {
	if err := walkPods(includeExitedGarbageDir, func(p *pod) {
		gp := p.path()
		st := &syscall.Stat_t{}
		if err := syscall.Lstat(gp, st); err != nil {
			if err != syscall.ENOENT {
				stderr("Unable to stat %q, ignoring: %v", gp, err)
			}
			return
		}

		if expiration := time.Unix(st.Ctim.Unix()).Add(gracePeriod); time.Now().After(expiration) {
			if err := p.ExclusiveLock(); err != nil {
				return
			}
			stdout("Garbage collecting pod %q", p.uuid)

			s, err := store.NewStore(globalFlags.Dir)
			if err != nil {
				stderr("Cannot open store: %v", err)
				return
			}
			stage1ID, err := p.getStage1Hash()
			if err != nil {
				stderr("Error getting stage1 hash")
				return
			}
			stage1RootFS := s.GetTreeStoreRootFS(stage1ID.String())

			if p.usesOverlay() {
				apps, err := p.getAppsHashes()
				if err != nil {
					stderr("Error retrieving app hashes from pod manifest: %v", err)
					return
				}
				for _, a := range apps {
					dest := filepath.Join(common.AppImagePath(p.path(), a), "rootfs")
					if err := syscall.Unmount(dest, 0); err != nil {
						// machine could have been rebooted and mounts lost.
						// ignore "does not exist" and "not a mount point" errors
						if err != syscall.ENOENT && err != syscall.EINVAL {
							stderr("Error unmounting app at %v: %v", dest, err)
						}
					}
				}

				s1 := filepath.Join(common.Stage1ImagePath(p.path()), "rootfs")
				if err := syscall.Unmount(s1, 0); err != nil {
					// machine could have been rebooted and mounts lost.
					// ignore "does not exist" and "not a mount point" errors
					if err != syscall.ENOENT && err != syscall.EINVAL {
						stderr("Error unmounting stage1 at %v: %v", s1, err)
						return
					}
				}
			}

			// execute stage1's GC
			if err := stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil {
				stderr("Stage1 GC of pod %q failed: %v", p.uuid, err)
				return
			}

			if err := os.RemoveAll(gp); err != nil {
				stderr("Unable to remove pod %q: %v", p.uuid, err)
			}
		}
	}); err != nil {
		return err
	}

	return nil
}