diff options
Diffstat (limited to 'runtime/docs/html/relay-app_8h-source.html')
-rw-r--r-- | runtime/docs/html/relay-app_8h-source.html | 542 |
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 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 List</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related 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 <zanussi@us.ibm.com></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 <linux/inet.h></span> -00131 <span class="preprocessor">#include <linux/ip.h></span> -00132 <span class="preprocessor">#include <linux/netlink.h></span> -00133 <span class="preprocessor">#include <linux/relayfs_fs.h></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 >= 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->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->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 && app.cb->app_started && !app.mappings++) -00257 app.cb->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 && app.cb->app_started && !--app.mappings) -00263 app.cb->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, &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->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->cpu; -00378 out.produced = atomic_read(&app.chan->buf[in->cpu]->subbufs_produced); -00379 out.consumed = atomic_read(&app.chan->buf[in->cpu]->subbufs_consumed); -00380 -00381 send_reply(RELAY_APP_BUF_INFO, &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->cpu, info->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->subbuf_size, info->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->len; -00412 -00413 <span class="keywordflow">if</span> (skblen < <span class="keyword">sizeof</span> (*nlh)) -00414 return; -00415 -00416 nlh = (struct nlmsghdr *)skb->data; -00417 nlmsglen = nlh->nlmsg_len; -00418 -00419 if (nlmsglen < sizeof(*nlh) || skblen < nlmsglen) -00420 return; -00421 -00422 stpd_pid = pid = nlh->nlmsg_pid; -00423 flags = nlh->nlmsg_flags; -00424 -00425 if (pid <= 0 || !(flags & NLM_F_REQUEST)) { -00426 netlink_ack(skb, nlh, -EINVAL); -00427 <span class="keywordflow">return</span>; -00428 } -00429 -00430 <span class="keywordflow">if</span> (flags & 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->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->user_command || -00459 !app.cb->user_command(nlh->nlmsg_type, data)) -00460 netlink_ack(skb, nlh, -EINVAL); -00461 <span class="keywordflow">return</span>; -00462 } -00463 -00464 <span class="keywordflow">if</span> (flags & 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(&sk->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->sk_socket); -00533 destroy_app_chan(app.chan); -00534 } -</pre></div></body></html> |