From 2500954602ac751329854cfc7f3e280492737a76 Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Tue, 15 Oct 2024 14:25:06 +0000 Subject: [PATCH 1/3] Remove some old debug output Signed-off-by: Adrian Reber --- test/checkpointctl.bats | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/checkpointctl.bats b/test/checkpointctl.bats index d50e7d65..ab364b37 100644 --- a/test/checkpointctl.bats +++ b/test/checkpointctl.bats @@ -20,9 +20,8 @@ function setup() { } function teardown() { - #[ "$TEST_TMP_DIR1" != "" ] && rm -rf "$TEST_TMP_DIR1" - #[ "$TEST_TMP_DIR2" != "" ] && rm -rf "$TEST_TMP_DIR2" - echo hu + [ "$TEST_TMP_DIR1" != "" ] && rm -rf "$TEST_TMP_DIR1" + [ "$TEST_TMP_DIR2" != "" ] && rm -rf "$TEST_TMP_DIR2" } @test "Run checkpointctl" { From d2475aad2ee9d37172178706bdd613670fe41d2f Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Tue, 15 Oct 2024 14:26:07 +0000 Subject: [PATCH 2/3] Fix location of Open Files in tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this patch the output used to look something like this │ └── [1] bash │ ├── Environment variables │ ├── [8] /usr/bin/coreutils │ │ ├── Environment variables │ │ └── Open files │ │ └── [root] / │ ├── [7] /usr/bin/python3 │ │ ├── Environment variables │ │ ├── Open files │ │ │ └── [root] / │ │ └── Open sockets │ │ └── [TCP (LISTEN)] 0.0.0.0:8088 -> 0.0.0.0:0 (↑ 16.0 KB ↓ 128.0 KB) │ └── Open files │ └── [root] / Which is wrong as the list of open files (and sockets) for the first process is after the child processes. With this change the order is now correct: │ └── [1] bash │ ├── Environment variables │ ├── Open files │ │ └── [root] / │ ├── [7] /usr/bin/python3 │ │ ├── Environment variables │ │ ├── Open files │ │ │ └── [root] / │ │ └── Open sockets │ │ └── [TCP (LISTEN)] 0.0.0.0:8088 -> 0.0.0.0:0 (↑ 16.0 KB ↓ 128.0 KB) │ └── [8] /usr/bin/coreutils │ ├── Environment variables │ └── Open files │ └── [root] / Each process has its own "Open files" and "Open sockets". It was always correct for "Environment variables". Signed-off-by: Adrian Reber --- internal/tree.go | 102 +++++++++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 35 deletions(-) diff --git a/internal/tree.go b/internal/tree.go index 30bef7a8..74fb544a 100644 --- a/internal/tree.go +++ b/internal/tree.go @@ -44,29 +44,39 @@ func RenderTreeView(tasks []Task) error { } } - if err = addPsTreeToTree(tree, psTree, task.OutputDir); err != nil { - return fmt.Errorf("failed to get process tree: %w", err) - } - } - - if Files { - c := crit.New(nil, nil, filepath.Join(task.OutputDir, "checkpoint"), false, false) - fds, err := c.ExploreFds() + fds, err := func() ([]*crit.Fd, error) { + if !Files { + return nil, nil + } + c := crit.New(nil, nil, filepath.Join(task.OutputDir, "checkpoint"), false, false) + fds, err := c.ExploreFds() + if err != nil { + return nil, fmt.Errorf("failed to get file descriptors: %w", err) + } + return fds, nil + }() if err != nil { - return fmt.Errorf("failed to get file descriptors: %w", err) + return err } - addFdsToTree(tree, fds) - } - - if Sockets { - c := crit.New(nil, nil, filepath.Join(task.OutputDir, "checkpoint"), false, false) - fds, err := c.ExploreSk() + sks, err := func() ([]*crit.Sk, error) { + if !Sockets { + return nil, nil + } + c := crit.New(nil, nil, filepath.Join(task.OutputDir, "checkpoint"), false, false) + sks, err := c.ExploreSk() + if err != nil { + return nil, fmt.Errorf("failed to get sockets: %w", err) + } + return sks, nil + }() if err != nil { - return fmt.Errorf("failed to get sockets: %w", err) + return err } - addSkToTree(tree, fds) + if err = addPsTreeToTree(tree, psTree, fds, sks, task.OutputDir); err != nil { + return fmt.Errorf("failed to get process tree: %w", err) + } } if Mounts { @@ -138,7 +148,13 @@ func addDumpStatsToTree(tree treeprint.Tree, dumpStats *stats_pb.DumpStatsEntry) statsTree.AddBranch(fmt.Sprintf("Pages written: %d", dumpStats.GetPagesWritten())) } -func addPsTreeToTree(tree treeprint.Tree, psTree *crit.PsTree, checkpointOutputDir string) error { +func addPsTreeToTree( + tree treeprint.Tree, + psTree *crit.PsTree, + fds []*crit.Fd, + sks []*crit.Sk, + checkpointOutputDir string, +) error { psRoot := psTree if PID != 0 { ps := psTree.FindPs(PID) @@ -168,6 +184,15 @@ func addPsTreeToTree(tree treeprint.Tree, psTree *crit.PsTree, checkpointOutputD } } } + + if err := showFiles(fds, node, root); err != nil { + return err + } + + if err := showSockets(sks, node, root); err != nil { + return err + } + for _, child := range root.Children { if err := processNodes(node, child); err != nil { return err @@ -180,35 +205,41 @@ func addPsTreeToTree(tree treeprint.Tree, psTree *crit.PsTree, checkpointOutputD return processNodes(psTreeNode, psRoot) } -func addFdsToTree(tree treeprint.Tree, fds []*crit.Fd) { - var node treeprint.Tree +func showFiles(fds []*crit.Fd, node treeprint.Tree, root *crit.PsTree) error { + if !Files { + return nil + } + if fds == nil { + return fmt.Errorf("failed to get file descriptors") + } for _, fd := range fds { - node = tree.FindByMeta(fd.PId) - // If FindByMeta returns nil, then the node with - // the PID has been pruned while building the tree. - // Hence, skip all associated file descriptors. - if node == nil { + var nodeSubtree treeprint.Tree + if fd.PId != root.PID { continue + } else { + nodeSubtree = node.AddBranch("Open files") } - nodeSubtree := node.AddBranch("Open files") for _, file := range fd.Files { nodeSubtree.AddMetaBranch(strings.TrimSpace(file.Type+" "+file.Fd), file.Path) } } + return nil } -func addSkToTree(tree treeprint.Tree, sks []*crit.Sk) { - var node treeprint.Tree +func showSockets(sks []*crit.Sk, node treeprint.Tree, root *crit.PsTree) error { + if !Sockets { + return nil + } + if sks == nil { + return fmt.Errorf("failed to get sockets") + } for _, sk := range sks { - node = tree.FindByMeta(sk.PId) - // If FindByMeta returns nil, then the node with - // the PID has been pruned while building the tree. - // Hence, skip all associated sockets. - if node == nil { + var nodeSubtree treeprint.Tree + if sk.PId != root.PID { continue + } else { + nodeSubtree = node.AddBranch("Open sockets") } - - nodeSubtree := node.AddBranch("Open sockets") var data string var protocol string for _, socket := range sk.Sockets { @@ -243,6 +274,7 @@ func addSkToTree(tree treeprint.Tree, sks []*crit.Sk) { nodeSubtree.AddMetaBranch(protocol, data) } } + return nil } // Recursively updates the Comm field of the psTree struct with the command line arguments From b2f5b23608f474505f17e0ef8813b7fe3dbc3584 Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Tue, 15 Oct 2024 14:30:07 +0000 Subject: [PATCH 3/3] Adapt tests to new tree layout Signed-off-by: Adrian Reber --- test/checkpointctl.bats | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/checkpointctl.bats b/test/checkpointctl.bats index ab364b37..da8df16d 100644 --- a/test/checkpointctl.bats +++ b/test/checkpointctl.bats @@ -359,7 +359,7 @@ function teardown() { ( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . ) checkpointctl inspect "$TEST_TMP_DIR2"/test.tar --files [ "$status" -eq 0 ] - [[ ${lines[24]} == *"[REG 0]"* ]] + [[ ${lines[11]} == *"[REG 0]"* ]] [[ ${lines[25]} == *"[cwd]"* ]] [[ ${lines[26]} == *"[root]"* ]] } @@ -766,4 +766,4 @@ function teardown() { [[ "${lines[4]}" == *"| checkpoint-valid-config-modified.tar |"* ]] [[ "${lines[6]}" == *"| default | pod-name | container-name | CRI-O |"* ]] [[ "${lines[6]}" == *"| checkpoint-valid-config.tar |"* ]] -} \ No newline at end of file +}