[sysprof] capture: add pid-root frame type



commit 4758fb42ce97d4d0af34dfc9ee96e8de2fe564da
Author: Christian Hergert <chergert redhat com>
Date:   Wed Feb 24 17:50:36 2021 -0800

    capture: add pid-root frame type
    
    While I'm not thrilled to add new frame types for every sort of thing, I
    think having this will be relatively useful so we can improve decoding
    operations.
    
    This adds SysprofCapturePidRoot which lets us specify a root directory
    on the host system for which is the real root (/) of the PID. This can
    be useful when reconstructing overlays for containers and you need to
    direct access to alternate roots.
    
    The layer gives us some ability to try to deal with overlayfs, albeit at
    a very rudimentary level. In most cases I anticipate we just deal with
    the main root and ignore overlays until necessary.

 src/libsysprof-capture/sysprof-capture-cursor.c    |  4 ++
 src/libsysprof-capture/sysprof-capture-reader.c    | 51 ++++++++++++++++++++++
 src/libsysprof-capture/sysprof-capture-reader.h    |  2 +
 src/libsysprof-capture/sysprof-capture-types.h     | 13 +++++-
 .../sysprof-capture-writer-cat.c                   | 18 +++++++-
 src/libsysprof-capture/sysprof-capture-writer.c    | 33 ++++++++++++++
 src/libsysprof-capture/sysprof-capture-writer.h    |  7 +++
 src/tools/sysprof-dump.c                           | 12 +++++
 8 files changed, 138 insertions(+), 2 deletions(-)
---
diff --git a/src/libsysprof-capture/sysprof-capture-cursor.c b/src/libsysprof-capture/sysprof-capture-cursor.c
index 6d4c83a..eab3aca 100644
--- a/src/libsysprof-capture/sysprof-capture-cursor.c
+++ b/src/libsysprof-capture/sysprof-capture-cursor.c
@@ -223,6 +223,10 @@ sysprof_capture_cursor_foreach (SysprofCaptureCursor         *self,
           delegate = READ_DELEGATE (sysprof_capture_reader_read_allocation);
           break;
 
+        case SYSPROF_CAPTURE_FRAME_PID_ROOT:
+          delegate = READ_DELEGATE (sysprof_capture_reader_read_pid_root);
+          break;
+
         default:
           if (!sysprof_capture_reader_skip (self->reader))
             return;
diff --git a/src/libsysprof-capture/sysprof-capture-reader.c b/src/libsysprof-capture/sysprof-capture-reader.c
index b07ad2d..5ba5273 100644
--- a/src/libsysprof-capture/sysprof-capture-reader.c
+++ b/src/libsysprof-capture/sysprof-capture-reader.c
@@ -353,6 +353,17 @@ sysprof_capture_reader_bswap_mark (SysprofCaptureReader *self,
     mark->duration = bswap_64 (mark->duration);
 }
 
+static inline void
+sysprof_capture_reader_bswap_pid_root (SysprofCaptureReader  *self,
+                                       SysprofCapturePidRoot *pr)
+{
+  assert (self != NULL);
+  assert (pr != NULL);
+
+  if (SYSPROF_UNLIKELY (self->endian != __BYTE_ORDER))
+    pr->layer = bswap_32 (pr->layer);
+}
+
 static inline void
 sysprof_capture_reader_bswap_jitmap (SysprofCaptureReader *self,
                                      SysprofCaptureJitmap *jitmap)
@@ -679,6 +690,46 @@ sysprof_capture_reader_read_mark (SysprofCaptureReader *self)
   return mark;
 }
 
+const SysprofCapturePidRoot *
+sysprof_capture_reader_read_pid_root (SysprofCaptureReader *self)
+{
+  SysprofCapturePidRoot *pr;
+
+  assert (self != NULL);
+  assert ((self->pos % SYSPROF_CAPTURE_ALIGN) == 0);
+  assert (self->pos <= self->bufsz);
+
+  if (!sysprof_capture_reader_ensure_space_for (self, sizeof *pr + 1))
+    return NULL;
+
+  pr = (SysprofCapturePidRoot *)(void *)&self->buf[self->pos];
+
+  sysprof_capture_reader_bswap_frame (self, &pr->frame);
+
+  if (pr->frame.type != SYSPROF_CAPTURE_FRAME_PID_ROOT)
+    return NULL;
+
+  if (pr->frame.len < (sizeof *pr + 1))
+    return NULL;
+
+  if (!sysprof_capture_reader_ensure_space_for (self, pr->frame.len))
+    return NULL;
+
+  pr = (SysprofCapturePidRoot *)(void *)&self->buf[self->pos];
+
+  sysprof_capture_reader_bswap_pid_root (self, pr);
+
+  self->pos += pr->frame.len;
+
+  if ((self->pos % SYSPROF_CAPTURE_ALIGN) != 0)
+    return NULL;
+
+  /* Ensure trailing \0 in name and message */
+  ((char *)pr)[pr->frame.len-1] = 0;
+
+  return pr;
+}
+
 const SysprofCaptureMetadata *
 sysprof_capture_reader_read_metadata (SysprofCaptureReader *self)
 {
diff --git a/src/libsysprof-capture/sysprof-capture-reader.h b/src/libsysprof-capture/sysprof-capture-reader.h
index 0fdd8b3..1d7b72a 100644
--- a/src/libsysprof-capture/sysprof-capture-reader.h
+++ b/src/libsysprof-capture/sysprof-capture-reader.h
@@ -120,6 +120,8 @@ SYSPROF_AVAILABLE_IN_ALL
 const SysprofCaptureFileChunk      *sysprof_capture_reader_read_file           (SysprofCaptureReader      
*self);
 SYSPROF_AVAILABLE_IN_3_36
 const SysprofCaptureAllocation     *sysprof_capture_reader_read_allocation     (SysprofCaptureReader      
*self);
+SYSPROF_AVAILABLE_IN_3_40
+const SysprofCapturePidRoot        *sysprof_capture_reader_read_pid_root       (SysprofCaptureReader      
*self);
 SYSPROF_AVAILABLE_IN_ALL
 bool                                sysprof_capture_reader_reset               (SysprofCaptureReader      
*self);
 SYSPROF_AVAILABLE_IN_ALL
diff --git a/src/libsysprof-capture/sysprof-capture-types.h b/src/libsysprof-capture/sysprof-capture-types.h
index 2f5b4b4..1fbcbec 100644
--- a/src/libsysprof-capture/sysprof-capture-types.h
+++ b/src/libsysprof-capture/sysprof-capture-types.h
@@ -139,10 +139,11 @@ typedef enum
   SYSPROF_CAPTURE_FRAME_LOG          = 12,
   SYSPROF_CAPTURE_FRAME_FILE_CHUNK   = 13,
   SYSPROF_CAPTURE_FRAME_ALLOCATION   = 14,
+  SYSPROF_CAPTURE_FRAME_PID_ROOT     = 15,
 } SysprofCaptureFrameType;
 
 /* Not part of ABI */
-#define SYSPROF_CAPTURE_FRAME_LAST 15
+#define SYSPROF_CAPTURE_FRAME_LAST 16
 
 SYSPROF_ALIGNED_BEGIN(1)
 typedef struct
@@ -172,6 +173,15 @@ typedef struct
 } SysprofCaptureFrame
 SYSPROF_ALIGNED_END(1);
 
+SYSPROF_ALIGNED_BEGIN(1)
+typedef struct
+{
+  SysprofCaptureFrame frame;
+  uint32_t            layer;
+  char                path[0];
+} SysprofCapturePidRoot
+SYSPROF_ALIGNED_END(1);
+
 SYSPROF_ALIGNED_BEGIN(1)
 typedef struct
 {
@@ -356,6 +366,7 @@ SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureMetadata) == 64, "SysprofCaptureMet
 SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureLog) == 64, "SysprofCaptureLog changed size");
 SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureFileChunk) == 284, "SysprofCaptureFileChunk changed size");
 SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureAllocation) == 48, "SysprofCaptureAllocation changed size");
+SYSPROF_STATIC_ASSERT (sizeof (SysprofCapturePidRoot) == 28, "SysprofCapturePidRoot changed size");
 
 SYSPROF_STATIC_ASSERT ((offsetof (SysprofCaptureAllocation, addrs) % SYSPROF_CAPTURE_ALIGN) == 0, 
"SysprofCaptureAllocation.addrs is not aligned");
 SYSPROF_STATIC_ASSERT ((offsetof (SysprofCaptureSample, addrs) % SYSPROF_CAPTURE_ALIGN) == 0, 
"SysprofCaptureSample.addrs is not aligned");
diff --git a/src/libsysprof-capture/sysprof-capture-writer-cat.c 
b/src/libsysprof-capture/sysprof-capture-writer-cat.c
index a157ed7..0cb69df 100644
--- a/src/libsysprof-capture/sysprof-capture-writer-cat.c
+++ b/src/libsysprof-capture/sysprof-capture-writer-cat.c
@@ -108,7 +108,7 @@ compare_by_src (const void *a,
     return -1;
   else if (itema->src > itemb->src)
     return 1;
-  else 
+  else
     return 0;
 }
 
@@ -532,6 +532,22 @@ sysprof_capture_writer_cat (SysprofCaptureWriter *self,
           break;
         }
 
+        case SYSPROF_CAPTURE_FRAME_PID_ROOT:
+          {
+            const SysprofCapturePidRoot *frame;
+
+            if (!(frame = sysprof_capture_reader_read_pid_root (reader)))
+              goto panic;
+
+            sysprof_capture_writer_add_pid_root (self,
+                                                 frame->frame.time,
+                                                 frame->frame.cpu,
+                                                 frame->frame.pid,
+                                                 frame->path,
+                                                 frame->layer);
+            break;
+          }
+
         default:
           /* Silently drop, which is better than looping. We could potentially
            * copy this over using the raw bytes at some point.
diff --git a/src/libsysprof-capture/sysprof-capture-writer.c b/src/libsysprof-capture/sysprof-capture-writer.c
index 8fa89d2..5a09b6a 100644
--- a/src/libsysprof-capture/sysprof-capture-writer.c
+++ b/src/libsysprof-capture/sysprof-capture-writer.c
@@ -827,6 +827,39 @@ sysprof_capture_writer_add_fork (SysprofCaptureWriter *self,
   return true;
 }
 
+bool
+sysprof_capture_writer_add_pid_root (SysprofCaptureWriter *self,
+                                     int64_t               time,
+                                     int                   cpu,
+                                     int32_t               pid,
+                                     const char           *path,
+                                     uint32_t              layer)
+{
+  SysprofCapturePidRoot *ev;
+  size_t strl = strlen (path);
+  size_t len = sizeof *ev + strl + 1;
+
+  assert (self != NULL);
+
+  ev = (SysprofCapturePidRoot *)sysprof_capture_writer_allocate (self, &len);
+  if (!ev)
+    return false;
+
+  sysprof_capture_writer_frame_init (&ev->frame,
+                                     len,
+                                     cpu,
+                                     pid,
+                                     time,
+                                     SYSPROF_CAPTURE_FRAME_PID_ROOT);
+  ev->layer = layer;
+  memcpy (ev->path, path, strl);
+  ev->path[strl] = 0;
+
+  self->stat.frame_count[SYSPROF_CAPTURE_FRAME_PID_ROOT]++;
+
+  return true;
+}
+
 bool
 sysprof_capture_writer_add_exit (SysprofCaptureWriter *self,
                                  int64_t               time,
diff --git a/src/libsysprof-capture/sysprof-capture-writer.h b/src/libsysprof-capture/sysprof-capture-writer.h
index 8a65726..2432aee 100644
--- a/src/libsysprof-capture/sysprof-capture-writer.h
+++ b/src/libsysprof-capture/sysprof-capture-writer.h
@@ -201,6 +201,13 @@ bool                  sysprof_capture_writer_add_allocation_copy             (Sy
                                                                               int64_t                        
    alloc_size,
                                                                               const SysprofCaptureAddress    
   *addrs,
                                                                               unsigned int                   
    n_addrs);
+SYSPROF_AVAILABLE_IN_3_40
+bool                  sysprof_capture_writer_add_pid_root                    (SysprofCaptureWriter           
   *self,
+                                                                              int64_t                        
    time,
+                                                                              int                            
    cpu,
+                                                                              int32_t                        
    pid,
+                                                                              const char                     
   *path,
+                                                                              uint32_t                       
    layer);
 SYSPROF_AVAILABLE_IN_ALL
 bool                  sysprof_capture_writer_flush                           (SysprofCaptureWriter           
   *self);
 SYSPROF_AVAILABLE_IN_ALL
diff --git a/src/tools/sysprof-dump.c b/src/tools/sysprof-dump.c
index 2b3936a..4875b69 100644
--- a/src/tools/sysprof-dump.c
+++ b/src/tools/sysprof-dump.c
@@ -115,6 +115,18 @@ main (gint argc,
             break;
           }
 
+        case SYSPROF_CAPTURE_FRAME_PID_ROOT:
+          {
+            const SysprofCapturePidRoot *pr = sysprof_capture_reader_read_pid_root (reader);
+
+            if (pr == NULL)
+              return EXIT_FAILURE;
+
+            g_print ("PID ROOT: pid=%d layer=%u path=%s\n", pr->frame.pid, pr->layer, pr->path);
+
+            break;
+          }
+
         case SYSPROF_CAPTURE_FRAME_JITMAP:
           {
             const SysprofCaptureJitmap *jitmap = sysprof_capture_reader_read_jitmap (reader);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]