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
|
#ifndef _TRANSPORT_RELAYFS_C_ /* -*- linux-c -*- */
#define _TRANSPORT_RELAYFS_C_
/*
* relayfs.c - stp relayfs-related transport functions
*
* Copyright (C) IBM Corporation, 2005
* Copyright (C) Redhat Inc, 2005
*
* This file is released under the GPL.
*/
/** @file relayfs.c
* @brief Systemtap relayfs-related transport functions
*/
/** @addtogroup transport Transport Functions
* @{
*/
#include "relayfs.h"
/**
* _stp_subbuf_start - subbuf_start() relayfs callback implementation
*/
static int _stp_subbuf_start(struct rchan_buf *buf,
void *subbuf,
unsigned prev_subbuf_idx,
void *prev_subbuf)
{
unsigned padding = buf->padding[prev_subbuf_idx];
if (prev_subbuf)
*((unsigned *)prev_subbuf) = padding;
return sizeof(padding); /* reserve space for padding */
}
/**
* _stp_buf_full - buf_full() relayfs callback implementation
*/
static void _stp_buf_full(struct rchan_buf *buf,
unsigned subbuf_idx,
void *subbuf)
{
unsigned padding = buf->padding[subbuf_idx];
*((unsigned *)subbuf) = padding;
}
/* relayfs callback functions */
static struct rchan_callbacks stp_rchan_callbacks =
{
.subbuf_start = _stp_subbuf_start,
.buf_full = _stp_buf_full,
};
/**
* _stp_relayfs_close - destroys relayfs channel
* @chan: the relayfs channel
* @dir: the directory containing the relayfs files
*/
void _stp_relayfs_close(struct rchan *chan, struct dentry *dir)
{
if (!chan)
return;
relay_close(chan);
if (dir)
relayfs_remove_dir(dir);
}
/**
* _stp_relayfs_open - create relayfs channel
* @n_subbufs: number of relayfs sub-buffers
* @subbuf_size: size of relayfs sub-buffers
* @pid: daemon pid
* @outdir: receives directory dentry
*
* Returns relay channel, NULL on failure
*
* Creates relayfs files as /systemtap/pid/cpuX in relayfs root
*/
struct rchan *_stp_relayfs_open(unsigned n_subbufs,
unsigned subbuf_size,
int pid,
struct dentry **outdir)
{
char dirname[16];
struct rchan *chan;
struct dentry* dir = NULL;
sprintf(dirname, "%d", pid);
/* TODO: need to create systemtap dir */
dir = relayfs_create_dir(dirname, NULL);
if (!dir) {
printk("STP: couldn't create relayfs dir %s.\n", dirname);
return NULL;
}
chan = relay_open("cpu", dir, subbuf_size,
n_subbufs, 0, &stp_rchan_callbacks);
if (!chan) {
printk("STP: couldn't create relayfs channel.\n");
if (dir)
relayfs_remove_dir(dir);
}
*outdir = dir;
return chan;
}
#endif /* _TRANSPORT_RELAYFS_C_ */
|