summaryrefslogtreecommitdiffstats
path: root/runtime/transport/relayfs.c
blob: 181a130e7908e2e2669f86a74b62a1eb28bfedea (plain)
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_ */