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.
This commit is contained in:
Christian Hergert
2021-02-24 17:50:36 -08:00
parent ff22417de9
commit 4758fb42ce
8 changed files with 138 additions and 2 deletions

View File

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

View File

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

View File

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

View File

@ -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");

View File

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

View File

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

View File

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

View File

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