Annotation of src/usr.bin/systat/nfs.c, Revision 1.2
1.2 ! jasper 1: /* $OpenBSD: nfs.c,v 1.1 2009/06/19 07:48:45 jasper Exp $ */
1.1 jasper 2:
3: /*
4: * Copyright (c) 2009 Jasper Lievisse Adriaanse <jasper@openbsd.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: *
18: */
19:
20: #include <sys/param.h>
21: #include <sys/mount.h>
22: #include <sys/sysctl.h>
23: #include <sys/types.h>
24: #include <nfs/rpcv2.h>
25: #include <nfs/nfsproto.h>
26: #include <nfs/nfs.h>
27:
28: #include <err.h>
29: #include <errno.h>
30: #include <stdio.h>
31: #include <stdlib.h>
32: #include <string.h>
33:
34: #include "systat.h"
35:
36: int check_nfs(void);
37: int select_client(void);
38: int select_server(void);
39: int read_nfs(void);
40: void print_client(void);
41: void print_server(void);
42:
43: struct nfsstats nfsstats;
44: int num_client = 0;
45: int num_server = 0;
46:
47: field_def fields_nfs[] = {
48: /* Client */
1.2 ! jasper 49: {"RPC COUNTS", 10, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.1 jasper 50: {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
1.2 ! jasper 51: {"RPC INFO", 14, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.1 jasper 52: {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
1.2 ! jasper 53: {"CACHE INFO", 10, 12, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
1.1 jasper 54: {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
55:
56: /* Server */
1.2 ! jasper 57: {"RPC COUNTS", 10, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.1 jasper 58: {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
1.2 ! jasper 59: {"CACHE STATS", 14, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.1 jasper 60: {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
1.2 ! jasper 61: {"WRITES", 10, 12, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
1.1 jasper 62: {"", 12, 14, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
63: };
64:
65: /* _V suffixed fields indicate a value column. */
66: #define FIELD_ADDR(x) (&fields_nfs[x])
67:
68: /* Client */
69: #define FLD_NFS_C_RPC_COUNTS FIELD_ADDR(0)
70: #define FLD_NFS_C_RPC_COUNTS_V FIELD_ADDR(1)
71: #define FLD_NFS_C_RPC_INFO FIELD_ADDR(2)
72: #define FLD_NFS_C_RPC_INFO_V FIELD_ADDR(3)
73: #define FLD_NFS_C_CACHE_INFO FIELD_ADDR(4)
74: #define FLD_NFS_C_CACHE_V FIELD_ADDR(5)
75:
76: /* Server */
77: #define FLD_NFS_S_RPC_COUNTS FIELD_ADDR(6)
78: #define FLD_NFS_S_RPC_COUNTS_V FIELD_ADDR(7)
79: #define FLD_NFS_S_CACHE_STATS FIELD_ADDR(8)
80: #define FLD_NFS_S_CACHE_STATS_V FIELD_ADDR(9)
81: #define FLD_NFS_S_WRITES FIELD_ADDR(10)
82: #define FLD_NFS_S_WRITES_V FIELD_ADDR(11)
83:
84: /* Define views */
85: field_def *view_nfs_0[] = {
86: FLD_NFS_C_RPC_COUNTS, FLD_NFS_C_RPC_COUNTS_V, FLD_NFS_C_RPC_INFO,
87: FLD_NFS_C_RPC_INFO_V, FLD_NFS_C_CACHE_INFO, FLD_NFS_C_CACHE_V ,NULL
88: };
89:
90: field_def *view_nfs_1[] = {
91: FLD_NFS_S_RPC_COUNTS, FLD_NFS_S_RPC_COUNTS_V, FLD_NFS_S_CACHE_STATS,
92: FLD_NFS_S_CACHE_STATS_V, FLD_NFS_S_WRITES, FLD_NFS_S_WRITES_V, NULL
93: };
94:
95: /* Define view managers */
96: struct view_manager nfs_client_mgr = {
97: "Client", select_client, read_nfs, NULL, print_header,
98: print_client, keyboard_callback, NULL, NULL
99: };
100:
101: struct view_manager nfs_server_mgr = {
102: "Server", select_server, read_nfs, NULL, print_header,
103: print_server, keyboard_callback, NULL, NULL
104: };
105:
106: field_view views_nfs[] = {
107: {view_nfs_0, "nfsclient", '8', &nfs_client_mgr},
108: {view_nfs_1, "nfsserver", '9', &nfs_server_mgr},
109: {NULL, NULL, 0, NULL}
110: };
111:
112: int
113: select_client(void)
114: {
115: num_disp = num_client;
116: return(0);
117: }
118:
119: int
120: select_server(void)
121: {
122: num_disp = num_server;
123: return(0);
124: }
125:
126: int
127: initnfs(void)
128: {
129: field_view *v;
130:
131: for (v = views_nfs; v->name != NULL; v++)
132: add_view(v);
133:
134: read_nfs();
135:
136: return(0);
137: }
138:
139: /*
140: * We get all the information in one go and don't care about
141: * server or client fields (those will be '0' if not applicable.
142: */
143: int
144: read_nfs(void)
145: {
146: struct nfsstats *p = &nfsstats;
147: int mib[3];
148: size_t len = sizeof(*p);
149:
150: mib[0] = CTL_VFS;
151: mib[1] = 2; /* NETDEV */
152: mib[2] = NFS_NFSSTATS;
153:
154: if (sysctl(mib, 3, p, &len, NULL, 0) < 0)
155: return(-1);
156: else
157: return(0);
158: }
159:
160:
161: /*
162: * As we want a view with multiple columns, mixed with labels and values,
163: * we can't use the regular dance and have to use our own (looong) dance
164: * to build the layout.
165: */
166: void
167: print_client(void)
168: {
169: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Getattr");
170: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
171: nfsstats.rpccnt[NFSPROC_GETATTR]);
172: print_fld_str(FLD_NFS_C_RPC_INFO, "TimedOut");
173: print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpctimeouts);
174: print_fld_str(FLD_NFS_C_CACHE_INFO, "Attr Hits ");
175: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.attrcache_hits);
176: end_line();
177:
178: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Setattr");
179: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
180: nfsstats.rpccnt[NFSPROC_SETATTR]);
181: print_fld_str(FLD_NFS_C_RPC_INFO, "Invalid");
182: print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcinvalid);
183: print_fld_str(FLD_NFS_C_CACHE_INFO, "Attr Misses");
184: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.attrcache_misses);
185: end_line();
186:
187: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Lookup");
188: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
189: nfsstats.rpccnt[NFSPROC_LOOKUP]);
190: print_fld_str(FLD_NFS_C_RPC_INFO, "X Replies");
191: print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcunexpected);
192: print_fld_str(FLD_NFS_C_CACHE_INFO, "Lkup Hits ");
193: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.lookupcache_hits);
194: end_line();
195:
196: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Readlink");
197: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
198: nfsstats.rpccnt[NFSPROC_READLINK]);
199: print_fld_str(FLD_NFS_C_RPC_INFO, "Retries");
200: print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcretries);
201: print_fld_str(FLD_NFS_C_CACHE_INFO, "Lkup Misses ");
202: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.lookupcache_misses);
203: end_line();
204:
205: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Read");
206: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
207: nfsstats.rpccnt[NFSPROC_READ]);
208: print_fld_str(FLD_NFS_C_RPC_INFO, "Requests");
209: print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.rpcrequests);
210: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioR Hits ");
211: print_fld_ssize(FLD_NFS_C_CACHE_V,
212: nfsstats.biocache_reads-nfsstats.read_bios);
213: end_line();
214:
215: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Write");
216: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_WRITE]);
217: print_fld_str(FLD_NFS_C_RPC_INFO, "FrcSync");
218: print_fld_ssize(FLD_NFS_C_RPC_INFO_V, nfsstats.forcedsync);
219: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioR Misses");
220: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.read_bios);
221: end_line();
222:
223: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Create");
224: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
225: nfsstats.rpccnt[NFSPROC_CREATE]);
226: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioW Hits ");
227: print_fld_ssize(FLD_NFS_C_CACHE_V,
228: nfsstats.biocache_writes-nfsstats.write_bios);
229: end_line();
230:
231: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Remove");
232: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
233: nfsstats.rpccnt[NFSPROC_REMOVE]);
234: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioW Misses");
235: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.write_bios);
236: end_line();
237:
238: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Rename");
239: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
240: nfsstats.rpccnt[NFSPROC_RENAME]);
241: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioRL Hits ");
242: print_fld_ssize(FLD_NFS_C_CACHE_V,
243: nfsstats.biocache_readlinks-nfsstats.readlink_bios);
244: end_line();
245:
246: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Link");
247: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_LINK]);
248: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioRL Misses");
249: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.readlink_bios);
250: end_line();
251:
252: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Symlink");
253: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
254: nfsstats.rpccnt[NFSPROC_SYMLINK]);
255: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioD Hits ");
256: print_fld_ssize(FLD_NFS_C_CACHE_V,
257: nfsstats.biocache_readdirs-nfsstats.readdir_bios);
258: end_line();
259:
260: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Mkdir");
261: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_MKDIR]);
262: print_fld_str(FLD_NFS_C_CACHE_INFO, "BioD Misses");
263: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.readdir_bios);
264: end_line();
265:
266: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Rmdir");
267: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_RMDIR]);
268: print_fld_str(FLD_NFS_C_CACHE_INFO, "DirE Hits ");
269: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.direofcache_hits);
270: end_line();
271:
272: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Readdir");
273: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
274: nfsstats.rpccnt[NFSPROC_READDIR]);
275: print_fld_str(FLD_NFS_C_CACHE_INFO, "DirE Misses");
276: print_fld_ssize(FLD_NFS_C_CACHE_V, nfsstats.direofcache_misses);
277: end_line();
278:
279: print_fld_str(FLD_NFS_C_RPC_COUNTS, "RdirPlus");
280: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
281: nfsstats.rpccnt[NFSPROC_READDIRPLUS]);
282: end_line();
283:
284: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Access");
285: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
286: nfsstats.rpccnt[NFSPROC_ACCESS]);
287: end_line();
288:
289: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Mknod");
290: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V, nfsstats.rpccnt[NFSPROC_MKNOD]);
291: end_line();
292:
293: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Fsstat");
294: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
295: nfsstats.rpccnt[NFSPROC_FSSTAT]);
296: end_line();
297:
298: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Fsinfo");
299: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
300: nfsstats.rpccnt[NFSPROC_FSINFO]);
301: end_line();
302:
303: print_fld_str(FLD_NFS_C_RPC_COUNTS, "PathConf");
304: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
305: nfsstats.rpccnt[NFSPROC_PATHCONF]);
306: end_line();
307:
308: print_fld_str(FLD_NFS_C_RPC_COUNTS, "Commit");
309: print_fld_ssize(FLD_NFS_C_RPC_COUNTS_V,
310: nfsstats.rpccnt[NFSPROC_COMMIT]);
311: end_line();
312: }
313:
314: void
315: print_server(void)
316: {
317: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Getattr");
318: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
319: nfsstats.srvrpccnt[NFSPROC_GETATTR]);
320: print_fld_str(FLD_NFS_S_CACHE_STATS, "Inprog");
321: print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, nfsstats.srvcache_inproghits);
322: print_fld_str(FLD_NFS_S_WRITES, "WriteOps");
323: print_fld_ssize(FLD_NFS_S_WRITES_V, nfsstats.srvvop_writes);
324: end_line();
325:
326: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Setattr");
327: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
328: nfsstats.srvrpccnt[NFSPROC_SETATTR]);
329: print_fld_str(FLD_NFS_S_CACHE_STATS, "Idem");
330: print_fld_ssize(FLD_NFS_S_CACHE_STATS_V,
331: nfsstats.srvcache_idemdonehits);
332: print_fld_str(FLD_NFS_S_WRITES, "WriteRPC");
333: print_fld_ssize(FLD_NFS_S_WRITES_V, nfsstats.srvrpccnt[NFSPROC_WRITE]);
334: end_line();
335:
336: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Lookup");
337: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
338: nfsstats.srvrpccnt[NFSPROC_LOOKUP]);
339: print_fld_str(FLD_NFS_S_CACHE_STATS, "Non-idem");
340: print_fld_ssize(FLD_NFS_S_CACHE_STATS_V,
341: nfsstats.srvcache_nonidemdonehits);
342: print_fld_str(FLD_NFS_S_WRITES, "Opsaved");
343: print_fld_ssize(FLD_NFS_S_WRITES_V,
344: nfsstats.srvrpccnt[NFSPROC_WRITE] - nfsstats.srvvop_writes);
345: end_line();
346:
347: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Readlink");
348: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
349: nfsstats.srvrpccnt[NFSPROC_READLINK]);
350: print_fld_str(FLD_NFS_S_CACHE_STATS, "Misses");
351: print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, nfsstats.srvcache_misses);
352: end_line();
353:
354: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Read");
355: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
356: nfsstats.srvrpccnt[NFSPROC_READ]);
357: end_line();
358:
359: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Write");
360: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
361: nfsstats.srvrpccnt[NFSPROC_WRITE]);
362: end_line();
363:
364: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Create");
365: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
366: nfsstats.srvrpccnt[NFSPROC_CREATE]);
367: end_line();
368:
369: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Remove");
370: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
371: nfsstats.srvrpccnt[NFSPROC_REMOVE]);
372: end_line();
373:
374: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Rename");
375: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
376: nfsstats.srvrpccnt[NFSPROC_RENAME]);
377: end_line();
378:
379: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Link");
380: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
381: nfsstats.srvrpccnt[NFSPROC_LINK]);
382: end_line();
383:
384: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Symlink");
385: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
386: nfsstats.srvrpccnt[NFSPROC_SYMLINK]);
387: end_line();
388:
389: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Mkdir");
390: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
391: nfsstats.srvrpccnt[NFSPROC_MKDIR]);
392: end_line();
393:
394: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Rmdir");
395: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
396: nfsstats.srvrpccnt[NFSPROC_RMDIR]);
397: end_line();
398:
399: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Readdir");
400: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
401: nfsstats.srvrpccnt[NFSPROC_READDIR]);
402: end_line();
403:
404: print_fld_str(FLD_NFS_S_RPC_COUNTS, "RdirPlus");
405: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
406: nfsstats.srvrpccnt[NFSPROC_READDIRPLUS]);
407: end_line();
408:
409: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Access");
410: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
411: nfsstats.srvrpccnt[NFSPROC_ACCESS]);
412: end_line();
413:
414: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Mknod");
415: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
416: nfsstats.srvrpccnt[NFSPROC_MKNOD]);
417: end_line();
418:
419: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Fsstat");
420: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
421: nfsstats.srvrpccnt[NFSPROC_FSSTAT]);
422: end_line();
423:
424: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Fsinfo");
425: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
426: nfsstats.srvrpccnt[NFSPROC_FSINFO]);
427: end_line();
428:
429: print_fld_str(FLD_NFS_S_RPC_COUNTS, "PathConf");
430: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
431: nfsstats.srvrpccnt[NFSPROC_PATHCONF]);
432: end_line();
433:
434: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Commit");
435: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V,
436: nfsstats.srvrpccnt[NFSPROC_COMMIT]);
437: end_line();
438:
439: /* The following end_line() creates two seperate blocks on the screen */
440: end_line();
441:
442: print_fld_str(FLD_NFS_S_RPC_COUNTS, "Ret-Failed");
443: print_fld_ssize(FLD_NFS_S_RPC_COUNTS_V, nfsstats.srvrpc_errs);
444: print_fld_str(FLD_NFS_S_CACHE_STATS, "Faults");
445: print_fld_ssize(FLD_NFS_S_CACHE_STATS_V, nfsstats.srv_errs);
446: end_line();
447: }