summaryrefslogtreecommitdiffstats
path: root/runtime/docs/html/relay-app_8h-source.html
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/docs/html/relay-app_8h-source.html')
-rw-r--r--runtime/docs/html/relay-app_8h-source.html542
1 files changed, 0 insertions, 542 deletions
diff --git a/runtime/docs/html/relay-app_8h-source.html b/runtime/docs/html/relay-app_8h-source.html
deleted file mode 100644
index 16feefe0..00000000
--- a/runtime/docs/html/relay-app_8h-source.html
+++ /dev/null
@@ -1,542 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
-<title>SystemTap: relay-app.h Source File</title>
-<link href="doxygen.css" rel="stylesheet" type="text/css">
-</head><body>
-<!-- Generated by Doxygen 1.4.1 -->
-<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
-<h1>relay-app.h</h1><div class="fragment"><pre class="fragment">00001 <span class="comment">/*</span>
-00002 <span class="comment"> * relay-app.h - kernel 'library' functions for typical relayfs applications</span>
-00003 <span class="comment"> *</span>
-00004 <span class="comment"> * This program is free software; you can redistribute it and/or modify</span>
-00005 <span class="comment"> * it under the terms of the GNU General Public License as published by</span>
-00006 <span class="comment"> * the Free Software Foundation; either version 2 of the License, or</span>
-00007 <span class="comment"> * (at your option) any later version.</span>
-00008 <span class="comment"> *</span>
-00009 <span class="comment"> * This program is distributed in the hope that it will be useful,</span>
-00010 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
-00011 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
-00012 <span class="comment"> * GNU General Public License for more details.</span>
-00013 <span class="comment"> *</span>
-00014 <span class="comment"> * You should have received a copy of the GNU General Public License</span>
-00015 <span class="comment"> * along with this program; if not, write to the Free Software</span>
-00016 <span class="comment"> * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.</span>
-00017 <span class="comment"> *</span>
-00018 <span class="comment"> * Copyright (C) IBM Corporation, 2005</span>
-00019 <span class="comment"> *</span>
-00020 <span class="comment"> * 2005-Feb Created by Tom Zanussi &lt;zanussi@us.ibm.com&gt;</span>
-00021 <span class="comment"> *</span>
-00022 <span class="comment"> * This header file encapsulates the details of channel setup and</span>
-00023 <span class="comment"> * teardown and communication between the kernel and user parts of a</span>
-00024 <span class="comment"> * typical and common type of relayfs application, which is that</span>
-00025 <span class="comment"> * kernel logging is kicked off when a userspace data collection</span>
-00026 <span class="comment"> * application starts and stopped when the collection app exits, and</span>
-00027 <span class="comment"> * data is automatically logged to disk in-between. Channels are</span>
-00028 <span class="comment"> * created when the collection app is started and destroyed when it</span>
-00029 <span class="comment"> * exits, not when the kernel module is inserted, so different channel</span>
-00030 <span class="comment"> * buffer sizes can be specified for each separate run via</span>
-00031 <span class="comment"> * command-line options for instance.</span>
-00032 <span class="comment"> *</span>
-00033 <span class="comment"> * Writing to the channel is done using 2 macros, relayapp_write() and</span>
-00034 <span class="comment"> * _relayapp_write(), which are just wrappers around relay_write() and</span>
-00035 <span class="comment"> * _relay_write() but without the channel param. You can safely call</span>
-00036 <span class="comment"> * these at any time - if there's no channel yet, they'll just be</span>
-00037 <span class="comment"> * ignored.</span>
-00038 <span class="comment"> *</span>
-00039 <span class="comment"> * To create a relay-app application, do the following:</span>
-00040 <span class="comment"> *</span>
-00041 <span class="comment"> * In your kernel module:</span>
-00042 <span class="comment"> *</span>
-00043 <span class="comment"> * - #include "relay-app.h"</span>
-00044 <span class="comment"> *</span>
-00045 <span class="comment"> * - Call init_relay_app() in your module_init function, with the</span>
-00046 <span class="comment"> * names of the directory to create relayfs files in and the base name</span>
-00047 <span class="comment"> * of the per-cpu relayfs files e.g. to have /mnt/relay/myapp/cpuXXX</span>
-00048 <span class="comment"> * created call init_relay_app("myapp", "cpu", callbacks).</span>
-00049 <span class="comment"> *</span>
-00050 <span class="comment"> * NOTE: The callbacks are entirely optional - pass NULL if you</span>
-00051 <span class="comment"> * don't want to define any. If you want to define some but not</span>
-00052 <span class="comment"> * others, just set the ones you want, and ignore or NULL out the</span>
-00053 <span class="comment"> * others.</span>
-00054 <span class="comment"> *</span>
-00055 <span class="comment"> * NOTE: This won't actually create the relayfs files - that will</span>
-00056 <span class="comment"> * happen when the userspace application starts (i.e. you can supply</span>
-00057 <span class="comment"> * the buffer sizes on the application command-line for each new run</span>
-00058 <span class="comment"> * of your program).</span>
-00059 <span class="comment"> *</span>
-00060 <span class="comment"> * NOTE: If you pass in NULL for the directory name, the relay files</span>
-00061 <span class="comment"> * will be created in the root directory of the relayfs filesystem.</span>
-00062 <span class="comment"> *</span>
-00063 <span class="comment"> * - Call close_relay_app() in your module_exit function - this cleans</span>
-00064 <span class="comment"> * up the control channel and the relay files from the previous run,</span>
-00065 <span class="comment"> * if any.</span>
-00066 <span class="comment"> *</span>
-00067 <span class="comment"> * - relay-apps use a control channel to communicate initialization</span>
-00068 <span class="comment"> * and status information between the kernel module and user space</span>
-00069 <span class="comment"> * program. This is hidden beneath the API so you normally don't need</span>
-00070 <span class="comment"> * to know anything about it, but if you want you can also use it to</span>
-00071 <span class="comment"> * send user-defined commands from your user space application. To do</span>
-00072 <span class="comment"> * this, you need to define a definition for the user_command()</span>
-00073 <span class="comment"> * callback and in the callback sort out and handle handle the</span>
-00074 <span class="comment"> * commands you send from user space (via send_request()). The</span>
-00075 <span class="comment"> * callback must return 1 if the command was handled, or 0 if not</span>
-00076 <span class="comment"> * (which will result in a send_error in the user space program,</span>
-00077 <span class="comment"> * alerting you to the fact that you're sending something bogus).</span>
-00078 <span class="comment"> *</span>
-00079 <span class="comment"> * NOTE: Currently commands can only be sent before the user space</span>
-00080 <span class="comment"> * application enters relay_app_main_loop() i.e. for initialization</span>
-00081 <span class="comment"> * purposes only.</span>
-00082 <span class="comment"> *</span>
-00083 <span class="comment"> * - the app_started() and app_stopped() callbacks provide an</span>
-00084 <span class="comment"> * opportunity for your kernel module to perform app-specific</span>
-00085 <span class="comment"> * initialization and cleanup, if desired. They are purely</span>
-00086 <span class="comment"> * informational. app_started() is called when the user space</span>
-00087 <span class="comment"> * application has started and app_stopped() is called when the user</span>
-00088 <span class="comment"> * space application has stopped.</span>
-00089 <span class="comment"> *</span>
-00090 <span class="comment"> * In your user space application do the following:</span>
-00091 <span class="comment"> *</span>
-00092 <span class="comment"> * - Call init_relay_app() with the names of the relayfs file base</span>
-00093 <span class="comment"> * name and the base filename of the output files that will be</span>
-00094 <span class="comment"> * created, as well as the sub-buffer size and count for the current</span>
-00095 <span class="comment"> * run (which can be passed in on the command-line if you want). This</span>
-00096 <span class="comment"> * will create the channel and set up the ouptut files and buffer</span>
-00097 <span class="comment"> * mappings. e.g. to set up reading from the relayfs files specified in the</span>
-00098 <span class="comment"> * above example and write them to a set of per-cpu output files named</span>
-00099 <span class="comment"> * myoutputXXX:</span>
-00100 <span class="comment"> * </span>
-00101 <span class="comment"> * init_relay_app("/mnt/relay/myapp/cpu", "myoutput",</span>
-00102 <span class="comment"> * subbuf_size_opt, n_subbufs_opt, 1);</span>
-00103 <span class="comment"> *</span>
-00104 <span class="comment"> * (the last parameter just specifies whether or not to print out a</span>
-00105 <span class="comment"> * summary of the number of buffers processed, and the maximum backlog</span>
-00106 <span class="comment"> * of sub-buffers encountered e.g. if you have 4 sub-buffers, a</span>
-00107 <span class="comment"> * maximum backlog of 3 would mean that you came close to having a</span>
-00108 <span class="comment"> * full buffer, so you might want to use more or bigger sub-buffers</span>
-00109 <span class="comment"> * next time. Of course, if the buffers actually filled up, the</span>
-00110 <span class="comment"> * maximum backlog would be 4 and you'd have lost data).</span>
-00111 <span class="comment"> *</span>
-00112 <span class="comment"> * - Call relay_app_main_loop(). This will set up an infinite loop</span>
-00113 <span class="comment"> * (press Control-C to break out and finalize the data) which</span>
-00114 <span class="comment"> * automatically reads the data from the relayfs buffers as it becomes</span>
-00115 <span class="comment"> * available and and writes it out to per-cpu output files.</span>
-00116 <span class="comment"> *</span>
-00117 <span class="comment"> * NOTE: The control channel is implemented as a netlink socket.</span>
-00118 <span class="comment"> * relay-app defaults to using NETLINK_USERSOCK for all</span>
-00119 <span class="comment"> * applications, which means that you can't have more than 1</span>
-00120 <span class="comment"> * relay-app in use at a time, unless you use different netlink</span>
-00121 <span class="comment"> * 'units' for each one. If you want to have more than one</span>
-00122 <span class="comment"> * relay-app in use at a time, you can specify a different netlink</span>
-00123 <span class="comment"> * 'unit' by using the _init_relay_app() versions of the</span>
-00124 <span class="comment"> * init_relay_app() functions, on both the kernel and user sides,</span>
-00125 <span class="comment"> * which are the same as the init_relay_app() functions but add a</span>
-00126 <span class="comment"> * netlink unit param. See netlink.h for the currently unused</span>
-00127 <span class="comment"> * numbers.</span>
-00128 <span class="comment"> */</span>
-00129
-00130 <span class="preprocessor">#include &lt;linux/inet.h&gt;</span>
-00131 <span class="preprocessor">#include &lt;linux/ip.h&gt;</span>
-00132 <span class="preprocessor">#include &lt;linux/netlink.h&gt;</span>
-00133 <span class="preprocessor">#include &lt;linux/relayfs_fs.h&gt;</span>
-00134
-00135 <span class="comment">/* relay-app pseudo-API */</span>
-00136
-00137 <span class="comment">/*</span>
-00138 <span class="comment"> * relay-app callbacks</span>
-00139 <span class="comment"> */</span>
-00140 <span class="keyword">struct </span>relay_app_callbacks
-00141 {
-00142 <span class="comment">/*</span>
-00143 <span class="comment"> * user_command - app-specific command callback</span>
-00144 <span class="comment"> * @command: user-defined command id</span>
-00145 <span class="comment"> * @data: user-defined data associated with the command</span>
-00146 <span class="comment"> *</span>
-00147 <span class="comment"> * Return value: 1 if this callback handled it, 0 if not</span>
-00148 <span class="comment"> *</span>
-00149 <span class="comment"> * define this callback to handle user-defined commands sent</span>
-00150 <span class="comment"> * from the user space application via send_request()</span>
-00151 <span class="comment"> *</span>
-00152 <span class="comment"> * NOTE: user commands must be &gt;= RELAY_APP_USERCMD_START</span>
-00153 <span class="comment"> */</span>
-00154 int (*user_command) (<span class="keywordtype">int</span> command, <span class="keywordtype">void</span> *data);
-00155
-00156 <span class="comment">/*</span>
-00157 <span class="comment"> * app_started - the user-space application has started</span>
-00158 <span class="comment"> *</span>
-00159 <span class="comment"> * Do app-specific initializations now, if desired</span>
-00160 <span class="comment"> */</span>
-00161 void (*app_started) (void);
-00162
-00163 <span class="comment">/*</span>
-00164 <span class="comment"> * app_stopped - the user-space application has stopped</span>
-00165 <span class="comment"> *</span>
-00166 <span class="comment"> * Do app-specific cleanup now, if desired</span>
-00167 <span class="comment"> */</span>
-00168 void (*app_stopped) (void);
-00169 };
-00170
-00171 <span class="comment">/*</span>
-00172 <span class="comment"> * relay-app API functions</span>
-00173 <span class="comment"> */</span>
-00174 <span class="keyword">static</span> <span class="keywordtype">int</span> init_relay_app(<span class="keyword">const</span> <span class="keywordtype">char</span> *dirname,
-00175 <span class="keyword">const</span> <span class="keywordtype">char</span> *file_basename,
-00176 <span class="keyword">struct</span> relay_app_callbacks *callbacks);
-00177 <span class="keyword">static</span> <span class="keywordtype">void</span> close_relay_app(<span class="keywordtype">void</span>);
-00178
-00179 <span class="comment">/*</span>
-00180 <span class="comment"> * relay-app write wrapper macros - use these instead of directly</span>
-00181 <span class="comment"> * using relay_write() and _relay_write() relayfs functions.</span>
-00182 <span class="comment"> */</span>
-00183 <span class="preprocessor">#define relayapp_write(data, len) \</span>
-00184 <span class="preprocessor"> if (app.logging) relay_write(app.chan, data, len)</span>
-00185 <span class="preprocessor"></span>
-00186 <span class="preprocessor">#define _relayapp_write(data, len) \</span>
-00187 <span class="preprocessor"> if (app.logging) _relay_write(app.chan, data, len)</span>
-00188 <span class="preprocessor"></span>
-00189 <span class="comment">/* relay-app control channel command values */</span>
-00190 <span class="keyword">enum</span>
-00191 {
-00192 RELAY_APP_BUF_INFO = 1,
-00193 RELAY_APP_SUBBUFS_CONSUMED,
-00194 RELAY_APP_START,
-00195 RELAY_APP_STOP,
-00196 RELAY_APP_CHAN_CREATE,
-00197 RELAY_APP_CHAN_DESTROY,
-00198 RELAY_APP_USERCMD_START = 32
-00199 };
-00200
-00201 <span class="comment">/* SystemTap extensions */</span>
-00202 <span class="keyword">enum</span>
-00203 {
-00204 STP_REALTIME_DATA = RELAY_APP_USERCMD_START,
-00205 STP_EXIT,
-00206 STP_DONE
-00207 };
-00208
-00209 <span class="comment">/* internal stuff below here */</span>
-00210
-00211 <span class="comment">/* netlink control channel */</span>
-00212 <span class="keyword">static</span> <span class="keyword">struct </span>sock *control;
-00213 <span class="keyword">static</span> <span class="keywordtype">int</span> seq;
-00214 <span class="keyword">static</span> <span class="keywordtype">int</span> stpd_pid = 0;
-00215
-00216 <span class="comment">/* info for this application */</span>
-00217 <span class="keyword">static</span> <span class="keyword">struct </span>relay_app
-00218 {
-00219 <span class="keywordtype">char</span> dirname[1024];
-00220 <span class="keywordtype">char</span> file_basename[1024];
-00221 <span class="keyword">struct </span>relay_app_callbacks *cb;
-00222 <span class="keyword">struct </span>rchan *chan;
-00223 <span class="keyword">struct </span>dentry *dir;
-00224 <span class="keywordtype">int</span> logging;
-00225 <span class="keywordtype">int</span> mappings;
-00226 } app;
-00227
-00228 <span class="comment">/*</span>
-00229 <span class="comment"> * subbuf_start() relayfs callback.</span>
-00230 <span class="comment"> */</span>
-00231 <span class="keyword">static</span> <span class="keywordtype">int</span> relay_app_subbuf_start(<span class="keyword">struct</span> rchan_buf *buf,
-00232 <span class="keywordtype">void</span> *subbuf,
-00233 <span class="keywordtype">unsigned</span> prev_subbuf_idx,
-00234 <span class="keywordtype">void</span> *prev_subbuf)
-00235 {
-00236 <span class="keywordtype">unsigned</span> padding = buf-&gt;padding[prev_subbuf_idx];
-00237 <span class="keywordflow">if</span> (prev_subbuf)
-00238 *((<span class="keywordtype">unsigned</span> *)prev_subbuf) = padding;
-00239
-00240 <span class="keywordflow">return</span> <span class="keyword">sizeof</span>(padding); <span class="comment">/* reserve space for padding */</span>
-00241 }
-00242
-00243 <span class="comment">/*</span>
-00244 <span class="comment"> * buf_full() relayfs callback.</span>
-00245 <span class="comment"> */</span>
-00246 <span class="keyword">static</span> <span class="keywordtype">void</span> relay_app_buf_full(<span class="keyword">struct</span> rchan_buf *buf,
-00247 <span class="keywordtype">unsigned</span> subbuf_idx,
-00248 <span class="keywordtype">void</span> *subbuf)
-00249 {
-00250 <span class="keywordtype">unsigned</span> padding = buf-&gt;padding[subbuf_idx];
-00251 *((<span class="keywordtype">unsigned</span> *)subbuf) = padding;
-00252 }
-00253
-00254 <span class="keyword">static</span> <span class="keywordtype">void</span> relay_app_buf_mapped(<span class="keyword">struct</span> rchan_buf *buf, <span class="keyword">struct</span> file *filp)
-00255 {
-00256 <span class="keywordflow">if</span> (app.cb &amp;&amp; app.cb-&gt;app_started &amp;&amp; !app.mappings++)
-00257 app.cb-&gt;app_started();
-00258 }
-00259
-00260 static <span class="keywordtype">void</span> relay_app_buf_unmapped(struct rchan_buf *buf, struct file *filp)
-00261 {
-00262 <span class="keywordflow">if</span> (app.cb &amp;&amp; app.cb-&gt;app_started &amp;&amp; !--app.mappings)
-00263 app.cb-&gt;app_stopped();
-00264 }
-00265
-00266 static struct rchan_callbacks app_rchan_callbacks =
-00267 {
-00268 .subbuf_start = relay_app_subbuf_start,
-00269 .buf_full = relay_app_buf_full,
-00270 .buf_mapped = relay_app_buf_mapped,
-00271 .buf_unmapped = relay_app_buf_unmapped
-00272 };
-00273 <span class="comment"></span>
-00274 <span class="comment">/**</span>
-00275 <span class="comment"> * create_app_chan - creates channel /mnt/relay/dirname/filebaseXXX</span>
-00276 <span class="comment"> *</span>
-00277 <span class="comment"> * Returns channel on success, NULL otherwise.</span>
-00278 <span class="comment"> */</span>
-00279 <span class="keyword">static</span> <span class="keyword">struct </span>rchan *create_app_chan(<span class="keywordtype">unsigned</span> subbuf_size,
-00280 <span class="keywordtype">unsigned</span> n_subbufs)
-00281 {
-00282 <span class="keyword">struct </span>rchan *chan;
-00283
-00284 <span class="keywordflow">if</span> (strlen(app.dirname)) {
-00285 app.dir = relayfs_create_dir(app.dirname, NULL);
-00286 <span class="keywordflow">if</span> (!app.dir) {
-00287 printk(<span class="stringliteral">"Couldn't create relayfs app directory %s.\n"</span>, app.dirname);
-00288 <span class="keywordflow">return</span> NULL;
-00289 }
-00290 }
-00291
-00292 chan = relay_open(app.file_basename, app.dir, subbuf_size,
-00293 n_subbufs, 0, &amp;app_rchan_callbacks);
-00294
-00295 <span class="keywordflow">if</span> (!chan) {
-00296 printk(<span class="stringliteral">"relay app channel creation failed\n"</span>);
-00297 <span class="keywordflow">if</span> (app.dir)
-00298 relayfs_remove_dir(app.dir);
-00299 return NULL;
-00300 }
-00301
-00302 return chan;
-00303 }
-00304 <span class="comment"></span>
-00305 <span class="comment">/**</span>
-00306 <span class="comment"> * destroy_app_chan - destroys channel /mnt/relay/dirname/filebaseXXX</span>
-00307 <span class="comment"> */</span>
-00308 static <span class="keywordtype">void</span> destroy_app_chan(struct rchan *chan)
-00309 {
-00310 <span class="keywordflow">if</span> (chan)
-00311 relay_close(chan);
-00312 if (app.dir)
-00313 relayfs_remove_dir(app.dir);
-00314
-00315 app.chan = NULL;
-00316 app.dir = NULL;
-00317 }
-00318
-00319 <span class="comment">/* netlink control channel communication with userspace */</span>
-00320
-00321 struct buf_info
-00322 {
-00323 <span class="keywordtype">int</span> cpu;
-00324 <span class="keywordtype">unsigned</span> produced;
-00325 <span class="keywordtype">unsigned</span> consumed;
-00326 };
-00327
-00328 <span class="keyword">struct </span>consumed_info
-00329 {
-00330 <span class="keywordtype">int</span> cpu;
-00331 <span class="keywordtype">unsigned</span> consumed;
-00332 };
-00333
-00334 <span class="keyword">struct </span>channel_create_info
-00335 {
-00336 <span class="keywordtype">unsigned</span> subbuf_size;
-00337 <span class="keywordtype">unsigned</span> n_subbufs;
-00338 };
-00339
-00340 <span class="comment">/*</span>
-00341 <span class="comment"> * send_reply - send reply to userspace over netlink control channel</span>
-00342 <span class="comment"> */</span>
-00343 <span class="keyword">static</span> <span class="keywordtype">int</span> send_reply(<span class="keywordtype">int</span> type, <span class="keywordtype">void</span> *reply, <span class="keywordtype">int</span> len, <span class="keywordtype">int</span> pid)
-00344 {
-00345 <span class="keyword">struct </span>sk_buff *skb;
-00346 <span class="keyword">struct </span>nlmsghdr *nlh;
-00347 <span class="keywordtype">void</span> *data;
-00348 <span class="keywordtype">int</span> size;
-00349 <span class="keywordtype">int</span> err;
-00350
-00351 size = NLMSG_SPACE(len);
-00352 skb = alloc_skb(size, GFP_ATOMIC);
-00353 <span class="keywordflow">if</span> (!skb)
-00354 return -1;
-00355 nlh = NLMSG_PUT(skb, pid, seq++, type, size - sizeof(*nlh));
-00356 nlh-&gt;nlmsg_flags = 0;
-00357 data = NLMSG_DATA(nlh);
-00358 memcpy(data, reply, len);
-00359 err = netlink_unicast(control, skb, pid, MSG_DONTWAIT);
-00360
-00361 return 0;
-00362
-00363 nlmsg_failure:
-00364 if (skb)
-00365 kfree_skb(skb);
-00366
-00367 return -1;
-00368 }
-00369
-00370 static <span class="keywordtype">void</span> handle_buf_info(struct buf_info *in, <span class="keywordtype">int</span> pid)
-00371 {
-00372 <span class="keyword">struct </span>buf_info out;
-00373
-00374 <span class="keywordflow">if</span> (!app.chan)
-00375 return;
-00376
-00377 out.cpu = in-&gt;cpu;
-00378 out.produced = atomic_read(&amp;app.chan-&gt;buf[in-&gt;cpu]-&gt;subbufs_produced);
-00379 out.consumed = atomic_read(&amp;app.chan-&gt;buf[in-&gt;cpu]-&gt;subbufs_consumed);
-00380
-00381 send_reply(RELAY_APP_BUF_INFO, &amp;out, sizeof(out), pid);
-00382 }
-00383
-00384 static inline <span class="keywordtype">void</span> handle_subbufs_consumed(struct consumed_info *info)
-00385 {
-00386 <span class="keywordflow">if</span> (!app.chan)
-00387 return;
-00388
-00389 relay_subbufs_consumed(app.chan, info-&gt;cpu, info-&gt;consumed);
-00390 }
-00391
-00392 static inline <span class="keywordtype">void</span> handle_create(struct channel_create_info *info)
-00393 {
-00394 destroy_app_chan(app.chan);
-00395 app.chan = create_app_chan(info-&gt;subbuf_size, info-&gt;n_subbufs);
-00396 <span class="keywordflow">if</span>(!app.chan)
-00397 <span class="keywordflow">return</span>;
-00398 app.mappings = 0;
-00399 }
-00400
-00401 <span class="comment">/*</span>
-00402 <span class="comment"> * msg_rcv_skb - dispatch userspace requests from netlink control channel</span>
-00403 <span class="comment"> */</span>
-00404 <span class="keyword">static</span> <span class="keywordtype">void</span> msg_rcv_skb(<span class="keyword">struct</span> sk_buff *skb)
-00405 {
-00406 <span class="keyword">struct </span>nlmsghdr *nlh = NULL;
-00407 <span class="keywordtype">int</span> pid, flags;
-00408 <span class="keywordtype">int</span> nlmsglen, skblen;
-00409 <span class="keywordtype">void</span> *data;
-00410
-00411 skblen = skb-&gt;len;
-00412
-00413 <span class="keywordflow">if</span> (skblen &lt; <span class="keyword">sizeof</span> (*nlh))
-00414 return;
-00415
-00416 nlh = (struct nlmsghdr *)skb-&gt;data;
-00417 nlmsglen = nlh-&gt;nlmsg_len;
-00418
-00419 if (nlmsglen &lt; sizeof(*nlh) || skblen &lt; nlmsglen)
-00420 return;
-00421
-00422 stpd_pid = pid = nlh-&gt;nlmsg_pid;
-00423 flags = nlh-&gt;nlmsg_flags;
-00424
-00425 if (pid &lt;= 0 || !(flags &amp; NLM_F_REQUEST)) {
-00426 netlink_ack(skb, nlh, -EINVAL);
-00427 <span class="keywordflow">return</span>;
-00428 }
-00429
-00430 <span class="keywordflow">if</span> (flags &amp; MSG_TRUNC) {
-00431 netlink_ack(skb, nlh, -ECOMM);
-00432 <span class="keywordflow">return</span>;
-00433 }
-00434
-00435 data = NLMSG_DATA(nlh);
-00436
-00437 <span class="keywordflow">switch</span> (nlh-&gt;nlmsg_type) {
-00438 <span class="keywordflow">case</span> RELAY_APP_CHAN_CREATE:
-00439 handle_create(data);
-00440 <span class="keywordflow">break</span>;
-00441 <span class="keywordflow">case</span> RELAY_APP_CHAN_DESTROY:
-00442 destroy_app_chan(app.chan);
-00443 <span class="keywordflow">break</span>;
-00444 <span class="keywordflow">case</span> RELAY_APP_START:
-00445 app.logging = 1;
-00446 <span class="keywordflow">break</span>;
-00447 <span class="keywordflow">case</span> RELAY_APP_STOP:
-00448 app.logging = 0;
-00449 relay_flush(app.chan);
-00450 <span class="keywordflow">break</span>;
-00451 <span class="keywordflow">case</span> RELAY_APP_BUF_INFO:
-00452 handle_buf_info(data, pid);
-00453 <span class="keywordflow">break</span>;
-00454 <span class="keywordflow">case</span> RELAY_APP_SUBBUFS_CONSUMED:
-00455 handle_subbufs_consumed(data);
-00456 <span class="keywordflow">break</span>;
-00457 <span class="keywordflow">default</span>:
-00458 <span class="keywordflow">if</span> (!app.cb || !app.cb-&gt;user_command ||
-00459 !app.cb-&gt;user_command(nlh-&gt;nlmsg_type, data))
-00460 netlink_ack(skb, nlh, -EINVAL);
-00461 <span class="keywordflow">return</span>;
-00462 }
-00463
-00464 <span class="keywordflow">if</span> (flags &amp; NLM_F_ACK)
-00465 netlink_ack(skb, nlh, 0);
-00466 }
-00467
-00468 <span class="comment">/*</span>
-00469 <span class="comment"> * msg_rcv - handle netlink control channel requests</span>
-00470 <span class="comment"> */</span>
-00471 static <span class="keywordtype">void</span> msg_rcv(struct sock *sk, <span class="keywordtype">int</span> len)
-00472 {
-00473 <span class="keyword">struct </span>sk_buff *skb;
-00474
-00475 <span class="keywordflow">while</span> ((skb = skb_dequeue(&amp;sk-&gt;sk_receive_queue))) {
-00476 msg_rcv_skb(skb);
-00477 kfree_skb(skb);
-00478 }
-00479 }
-00480
-00481 <span class="comment">/*</span>
-00482 <span class="comment"> * _init_relay_app - adds netlink 'unit' if other than NETLINK_USERSOCK wanted</span>
-00483 <span class="comment"> */</span>
-00484 <span class="keyword">static</span> <span class="keywordtype">int</span> _init_relay_app(<span class="keyword">const</span> <span class="keywordtype">char</span> *dirname,
-00485 <span class="keyword">const</span> <span class="keywordtype">char</span> *file_basename,
-00486 <span class="keyword">struct</span> relay_app_callbacks *callbacks,
-00487 <span class="keywordtype">int</span> unit)
-00488 {
-00489 <span class="keywordflow">if</span> (!file_basename)
-00490 return -1;
-00491
-00492 if (dirname)
-00493 strncpy(app.dirname, dirname, 1024);
-00494 strncpy(app.file_basename, file_basename, 1024);
-00495 app.cb = callbacks;
-00496
-00497 control = netlink_kernel_create(unit, msg_rcv);
-00498 if (!control) {
-00499 printk(<span class="stringliteral">"Couldn't create control channel\n"</span>);
-00500 <span class="keywordflow">return</span> -1;
-00501 }
-00502
-00503 <span class="keywordflow">return</span> 0;
-00504 }
-00505 <span class="comment"></span>
-00506 <span class="comment">/**</span>
-00507 <span class="comment"> * init_relay_app - initialize /mnt/relay/dirname/file_basenameXXX</span>
-00508 <span class="comment"> * @dirname: the directory to contain relayfs files for this app</span>
-00509 <span class="comment"> * @file_basename: the base filename of the relayfs files for this app</span>
-00510 <span class="comment"> * @callbacks: the relay_app_callbacks implemented for this app</span>
-00511 <span class="comment"> *</span>
-00512 <span class="comment"> * Returns 0 on success, -1 otherwise.</span>
-00513 <span class="comment"> *</span>
-00514 <span class="comment"> * NOTE: this doesn't create the relayfs files. That happens via the</span>
-00515 <span class="comment"> * control channel protocol.</span>
-00516 <span class="comment"> */</span>
-00517 <span class="keyword">static</span> <span class="keywordtype">int</span> init_relay_app(<span class="keyword">const</span> <span class="keywordtype">char</span> *dirname,
-00518 <span class="keyword">const</span> <span class="keywordtype">char</span> *file_basename,
-00519 <span class="keyword">struct</span> relay_app_callbacks *callbacks)
-00520 {
-00521 <span class="keywordflow">return</span> _init_relay_app(dirname, file_basename, callbacks, NETLINK_USERSOCK);
-00522 }
-00523 <span class="comment"></span>
-00524 <span class="comment">/**</span>
-00525 <span class="comment"> * close_relay_app - close netlink socket and destroy channel if it exists</span>
-00526 <span class="comment"> *</span>
-00527 <span class="comment"> * Returns 0 on success, -1 otherwise.</span>
-00528 <span class="comment"> */</span>
-00529 <span class="keyword">static</span> <span class="keywordtype">void</span> close_relay_app(<span class="keywordtype">void</span>)
-00530 {
-00531 <span class="keywordflow">if</span> (control)
-00532 sock_release(control-&gt;sk_socket);
-00533 destroy_app_chan(app.chan);
-00534 }
-</pre></div></body></html>