File: common.h

package info (click to toggle)
bootchart2 0.14.4-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch, wheezy
  • size: 5,036 kB
  • sloc: ansic: 1,805; python: 1,764; sh: 155; makefile: 88
file content (172 lines) | stat: -rw-r--r-- 5,076 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
 * bootchart-common.h - shared data structures
 */
#ifndef BOOTCHART_COMMON_H
#define BOOTCHART_COMMON_H

/* get the right versions of various key functions */
#define _XOPEN_SOURCE 800
#define _FILE_OFFSET_BITS 64
#define _LARGEFILE64_SOURCE
#define _BSD_SOURCE
#define _ATFILE_SOURCE
#define _GNU_SOURCE

#include <sys/mount.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/resource.h>
#include <sys/socket.h>

#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <assert.h>
#include <dirent.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <alloca.h>
#include <pthread.h>

/* Magic path we mount our tmpfs on, inside which we do everything */
#define TMPFS_PATH "/lib/bootchart/tmpfs"
#define PROC_PATH  "/lib/bootchart/tmpfs/proc"
/* where we lurk to get move mounted into the live system */
#define MOVE_DEV_PATH "/dev/.bootchart"

/* helpers */
#undef	MAX
#undef	MIN
#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))

/* ---------------- collector.c  ---------------- */

/* it is nice to be able to parse the remote process' arguments too */
typedef struct {
	unsigned int   console_debug : 1;
	unsigned int   probe_running : 1;
	unsigned int   relative_time : 1;
	char          *dump_path;
	long	       usleep_time;
	int            hz;
} Arguments;

void arguments_set_defaults (Arguments *args);
void arguments_parse        (Arguments *args, int argc, char **argv);
void arguments_free         (Arguments *args);

/* ---------------- output.c  ---------------- */

/* Max ~ 128Mb of space for logging, should be enough */
#define CHUNK_SIZE (128 * 1024)
#define STACK_MAP_MAGIC "really-unique-stack-pointer-for-xp-detection-goodness"

typedef struct {
	char          dest_stream[60];
	unsigned long length;
	char          data[0];
} Chunk;
#define CHUNK_PAYLOAD (CHUNK_SIZE - sizeof (Chunk))

typedef struct {
	char   magic[sizeof (STACK_MAP_MAGIC)];
	Chunk *chunks[1024];
	int    max_chunk;
} StackMap;
#define STACK_MAP_INIT { STACK_MAP_MAGIC, { 0, }, 0 }

typedef struct {
	StackMap   *sm;
	const char *dest;
	Chunk      *cur;
} BufferFile;

BufferFile *buffer_file_new            (StackMap *sm, const char *output_fname);
void        buffer_file_dump           (BufferFile *file, int input_fd);
void        buffer_file_append         (BufferFile *file, const char *str, size_t len);
void        buffer_file_dump_frame_with_timestamp
                                       (BufferFile *file, int input_fd,
					const char *uptime, size_t uptimelen);

int         buffers_extract_and_dump   (const char *output_path,
					Arguments  *remote_args);
int         dump_dmsg                  (const char *output_path);
int         dump_header                (const char *output_path);
int         bootchart_find_running_pid (Arguments *opt_args);

/* ---------------- tasks.c  ---------------- */

/*
 * a big bit-field, one bit per pid.
 */
typedef struct {
	int  len;
	unsigned char *pids;
} PidMap;

typedef enum {
	PID_SCAN_EVENT_EXEC,    /* signal dump of cmdline */
	PID_SCAN_EVENT_CREATED  /* signal process creation - not reliable */
} PidScanEventType;

typedef struct {
	PidScanEventType type;
	pid_t pid;
	union {
		pid_t ppid;
	} u;
} PidScanEvent;

typedef void (*PidScanEventFn) (const PidScanEvent *event, void *user_data);

typedef struct _PidScanner PidScanner;
struct _PidScanner {
	PidMap          map;
	PidScanEventFn  event_fn;
	void           *user_data;

	int    (*free)         (PidScanner *scanner);  
	void   (*restart)      (PidScanner *scanner);  
	pid_t  (*next)         (PidScanner *scanner);
	pid_t  (*get_cur_pid)  (PidScanner *scanner);
	pid_t  (*get_cur_ppid) (PidScanner *scanner);

	void   (*get_tasks_start) (PidScanner *scanner);
	pid_t  (*get_tasks_next)  (PidScanner *scanner);
	void   (*get_tasks_stop)  (PidScanner *scanner);
};

PidScanner *pid_scanner_new_netlink     (PidScanEventFn event_cb,
					 void	     *user_data);
PidScanner *pid_scanner_new_proc	(const char *proc_path,
					 PidScanEventFn event_cb,
					 void	     *user_data);
#define	    pid_scanner_free(s)         (s)->free(s)

#define	    pid_scanner_restart(s)      (s)->restart(s)
#define	    pid_scanner_next(s)         (s)->next(s)
#define	    pid_scanner_get_cur_pid(s)  (s)->get_cur_pid(s)
#define	    pid_scanner_get_cur_ppid(s) (s)->get_cur_ppid(s)

#define	    pid_scanner_get_tasks_start(s)  (s)->get_tasks_start(s)
#define	    pid_scanner_get_tasks_next(s)   (s)->get_tasks_next(s)
#define	    pid_scanner_get_tasks_stop(s)   (s)->get_tasks_stop(s)

/* for impl. only */
PidScanner *pid_scanner_alloc           (int            derived_size,
					 PidScanEventFn event_cb,
					 void	       *user_data);
void	    pid_scanner_emit_exec       (PidScanner    *scanner,
					 pid_t          new_pid);
void	    pid_scanner_emit_paternity  (PidScanner    *scanner,
					 pid_t          new_pid,
					 pid_t          parent);

#endif /* BOOTCHART_COMMON_H */