8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / nfslog / nfslog_trans.c
blobbfab8998d46470be8b8c83d03c06d740bc259b97
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <errno.h>
31 #include <malloc.h>
32 #include <strings.h>
33 #include <stddef.h>
34 #include <search.h>
35 #include <syslog.h>
36 #include <libintl.h>
37 #include <unistd.h>
38 #include <rpc/rpc.h>
39 #include <netconfig.h>
40 #include <netdir.h>
41 #include <nfs/nfs_sec.h>
42 #include <nfs/export.h>
43 #include <rpc/auth.h>
44 #include <rpc/svc.h>
45 #include <rpc/xdr.h>
46 #include <rpc/clnt.h>
47 #include <nfs/nfs.h>
48 #include <nfs/nfs_log.h>
49 #include <assert.h>
50 #include "fhtab.h"
51 #include "nfslogd.h"
54 * How long should an entry stay in the list before being forced
55 * out and a trans log entry printed
57 #define TRANS_ENTRY_TIMEOUT 60
59 extern char *addrtoname(void *);
61 struct transentry {
62 struct transentry *next;
63 struct transentry *prev;
64 timestruc32_t starttime; /* when did transaction start? */
65 timestruc32_t lastupdate; /* last operation for this entry */
66 #define TRANS_OPER_READ 1
67 #define TRANS_OPER_WRITE 2
68 #define TRANS_OPER_SETATTR 3
69 #define TRANS_OPER_REMOVE 4
70 #define TRANS_OPER_MKDIR 5
71 #define TRANS_OPER_CREATE 6
72 #define TRANS_OPER_RMDIR 7
73 #define TRANS_OPER_RENAME 8
74 #define TRANS_OPER_MKNOD 9
75 #define TRANS_OPER_LINK 10
76 #define TRANS_OPER_SYMLINK 11
77 uchar_t optype; /* read, write, ...? */
78 #define TRANS_DATATYPE_NA /* not applicable data type */
79 #define TRANS_DATATYPE_ASCII 0 /* transfer done as ascii */
80 #define TRANS_DATATYPE_BINARY 1 /* transfer done as binary */
81 uchar_t datatype;
83 * Action taken by server before transfer was made -- noaction,
84 * compressed, tar or uncompressed.
86 #define TRANS_OPTION_NOACTION 0
87 uchar_t transoption;
88 char *pathname;
89 struct netbuf *pnb;
90 uid_t uid;
91 int nfsvers;
92 char *netid;
93 char *principal_name;
94 uint64_t totalbytes; /* total operated upon in history */
95 union {
96 fhandle_t fh;
97 nfs_fh3 fh3;
98 } fh_u;
101 struct nfslog_trans_file {
102 struct nfslog_trans_file *next; /* next file in list */
103 struct nfslog_trans_file *prev; /* next file in list */
104 int refcnt; /* number of references to this struct */
105 char *path; /* pathname of file */
106 FILE *fp; /* file pointer */
107 /* timestamp of the last transaction processed for this file */
108 timestruc32_t lasttrans_timestamp;
109 /* 'current' time that last trans was processed */
110 time_t last_trans_read;
111 uint32_t trans_to_log; /* transactions that are to be logged */
112 uint32_t trans_output_type;
113 struct transentry *te_list_v3_read;
114 struct transentry *te_list_v3_write;
115 struct transentry *te_list_v2_read;
116 struct transentry *te_list_v2_write;
119 static struct nfslog_trans_file *trans_file_head = NULL;
121 static void nfslog_print_trans_logentry(struct transentry *,
122 struct nfslog_trans_file *);
125 static struct netbuf *
126 netbufdup(struct netbuf *pnb)
128 struct netbuf *pnewnb;
129 uint32_t size;
131 size = offsetof(struct netbuf, buf);
132 size += pnb->len;
134 if ((pnewnb = (struct netbuf *)malloc(sizeof (*pnewnb))) == NULL)
135 return (NULL);
136 if ((pnewnb->buf = malloc(pnb->len)) == NULL) {
137 free(pnewnb);
138 return (NULL);
141 pnewnb->maxlen = pnb->maxlen;
142 pnewnb->len = pnb->len;
143 bcopy(pnb->buf, pnewnb->buf, pnb->len);
144 return (pnewnb);
147 static void
148 freenetbuf(struct netbuf *pnb)
150 free(pnb->buf);
151 free(pnb);
154 static struct transentry *
155 create_te()
157 struct transentry *pte;
159 if ((pte = (struct transentry *)calloc(1, sizeof (*pte))) == NULL) {
160 /* failure message or action */
161 return (NULL);
164 pte->next = pte->prev = NULL;
166 return (pte);
169 static struct transentry *
170 insert_te(
171 struct transentry *te_list,
172 struct transentry *entry)
174 struct transentry *pte;
177 * First check for any non-filehandle comparisons that may be needed.
179 switch (entry->optype) {
180 case TRANS_OPER_REMOVE:
181 case TRANS_OPER_RENAME:
182 for (pte = te_list->next; pte != te_list; pte = pte->next) {
183 /* if path names match, then return */
184 if (strcmp(pte->pathname, entry->pathname) == 0) {
185 return (pte);
188 return (NULL);
189 default:
190 break;
193 for (pte = te_list->next; pte != te_list; pte = pte->next) {
194 /* If the file handles match, then we have a hit */
195 if (entry->nfsvers == NFS_VERSION) {
196 if (bcmp(&(pte->fh_u.fh), &(entry->fh_u.fh),
197 sizeof (fhandle_t)) == 0) {
198 switch (entry->optype) {
199 case TRANS_OPER_READ:
200 case TRANS_OPER_WRITE:
201 if (pte->uid == entry->uid) {
202 return (pte);
204 break;
205 default:
206 return (pte);
209 } else {
210 if (pte->fh_u.fh3.fh3_length ==
211 entry->fh_u.fh3.fh3_length &&
212 bcmp(pte->fh_u.fh3.fh3_u.data,
213 entry->fh_u.fh3.fh3_u.data,
214 pte->fh_u.fh3.fh3_length) == 0)
215 switch (entry->optype) {
216 case TRANS_OPER_READ:
217 case TRANS_OPER_WRITE:
218 if (pte->uid == entry->uid) {
219 return (pte);
221 break;
222 default:
223 return (pte);
228 * XXX - should compare more of the information to make sure
229 * it is a match.
233 * other operation types do not generate an entry for
234 * further analysis
236 switch (entry->optype) {
237 case TRANS_OPER_READ:
238 case TRANS_OPER_WRITE:
239 break;
240 default:
241 return (NULL);
244 insque(entry, te_list);
246 return (NULL); /* NULL signifies insertion and no record found */
249 static void
250 remove_te(struct transentry *pte)
252 if (pte->next)
253 remque(pte);
255 if (pte->principal_name) free(pte->principal_name);
256 if (pte->pathname) free(pte->pathname);
257 if (pte->pnb) freenetbuf(pte->pnb);
258 if (pte->netid) free(pte->netid);
260 free(pte);
264 * nfslog_trans_file_free - frees a record
266 static void
267 nfslog_trans_file_free(struct nfslog_trans_file *transrec)
269 if (transrec == NULL)
270 return;
271 if (transrec->path != NULL) {
272 if (debug)
273 (void) printf("freeing transpath '%s'\n",
274 transrec->path);
275 free(transrec->path);
277 free(transrec);
281 * On success returns a pointer to the trans_file that matches
282 * 'path', 'output_type' and 'transtolog'. The reference count for this
283 * object is incremented as well.
284 * Returns NULL if it is not in the list.
286 static struct nfslog_trans_file *
287 nfslog_trans_file_find(
288 char *path,
289 uint32_t output_type,
290 uint32_t transtolog)
292 struct nfslog_trans_file *tfp;
294 for (tfp = trans_file_head; tfp != NULL; tfp = tfp->next) {
295 if ((strcmp(path, tfp->path) == 0) &&
296 (output_type == tfp->trans_output_type) &&
297 (transtolog == tfp->trans_to_log)) {
298 if (debug)
299 (void) printf("Found transfile '%s'\n", path);
300 (tfp->refcnt)++;
301 return (tfp);
304 return (NULL);
309 * nfslog_close_trans_file - decrements the reference count on
310 * this object. On last reference it closes transfile and
311 * frees resources
313 static void
314 nfslog_close_trans_file(struct nfslog_trans_file *tf)
316 assert(tf != NULL);
317 assert(tf->refcnt > 0);
318 if (tf->refcnt > 1) {
319 (tf->refcnt)--;
320 return;
323 if (tf->fp != NULL) {
324 (void) fsync(fileno(tf->fp));
325 (void) fclose(tf->fp);
329 * Disconnect from list
331 tf->prev->next = tf->next;
332 if (tf->next != NULL)
333 tf->next->prev = tf->prev;
336 * Adjust the head of the list if appropriate
338 if (tf == trans_file_head)
339 trans_file_head = tf->next;
341 nfslog_trans_file_free(tf);
345 * nfslog_open_trans_file - open the output trans file and mallocs.
346 * The object is then inserted at the beginning of the global
347 * transfile list.
348 * Returns 0 for success, error else.
350 * *error contains the last error encountered on this object. It can
351 * be used to avoid reporting the same error endlessly, by comparing
352 * the current error to the last error. It is reset to the current error
353 * code on return.
355 void *
356 nfslog_open_trans_file(
357 char *transpath,
358 uint32_t output_type,
359 uint32_t transtolog,
360 int *error)
362 int preverror = *error;
363 struct nfslog_trans_file *transrec;
365 transrec = nfslog_trans_file_find(transpath, output_type, transtolog);
366 if (transrec != NULL)
367 return (transrec);
369 if ((transrec = malloc(sizeof (*transrec))) == NULL) {
370 *error = errno;
371 if (*error != preverror) {
372 syslog(LOG_ERR, gettext("nfslog_open_trans_file: %s"),
373 strerror(*error));
375 return (NULL);
377 bzero(transrec, sizeof (*transrec));
379 if ((transrec->path = strdup(transpath)) == NULL) {
380 *error = errno;
381 if (*error != preverror) {
382 syslog(LOG_ERR, gettext("nfslog_open_trans_file: %s"),
383 strerror(*error));
385 nfslog_trans_file_free(transrec);
386 return (NULL);
389 if ((transrec->fp = fopen(transpath, "a")) == NULL) {
390 *error = errno;
391 if (*error != preverror) {
392 syslog(LOG_ERR, gettext("Cannot open '%s': %s"),
393 transpath, strerror(*error));
395 nfslog_trans_file_free(transrec);
396 return (NULL);
399 transrec->te_list_v3_read =
400 (struct transentry *)malloc(sizeof (struct transentry));
401 transrec->te_list_v3_write =
402 (struct transentry *)malloc(sizeof (struct transentry));
403 transrec->te_list_v2_read =
404 (struct transentry *)malloc(sizeof (struct transentry));
405 transrec->te_list_v2_write =
406 (struct transentry *)malloc(sizeof (struct transentry));
408 if (transrec->te_list_v3_read == NULL ||
409 transrec->te_list_v3_write == NULL ||
410 transrec->te_list_v2_read == NULL ||
411 transrec->te_list_v2_write == NULL) {
412 if (transrec->te_list_v3_read)
413 free(transrec->te_list_v3_read);
414 if (transrec->te_list_v3_write)
415 free(transrec->te_list_v3_write);
416 if (transrec->te_list_v2_read)
417 free(transrec->te_list_v2_read);
418 if (transrec->te_list_v2_write)
419 free(transrec->te_list_v2_write);
420 nfslog_close_trans_file(transrec);
421 return (NULL);
424 transrec->te_list_v3_read->next =
425 transrec->te_list_v3_read->prev = transrec->te_list_v3_read;
426 transrec->te_list_v3_write->next =
427 transrec->te_list_v3_write->prev = transrec->te_list_v3_write;
428 transrec->te_list_v2_read->next =
429 transrec->te_list_v2_read->prev = transrec->te_list_v2_read;
430 transrec->te_list_v2_write->next =
431 transrec->te_list_v2_write->prev = transrec->te_list_v2_write;
434 * Indicate what transaction types to log
436 transrec->trans_to_log = transtolog;
439 * Indicate whether to print 'full' or 'basic' version
440 * of the transactions
442 transrec->trans_output_type = output_type;
445 * Insert at the beginning of the list.
447 transrec->next = trans_file_head;
448 if (trans_file_head != NULL)
449 trans_file_head->prev = transrec;
450 trans_file_head = transrec->prev = transrec;
452 transrec->refcnt = 1;
454 transrec->lasttrans_timestamp.tv_sec = 0;
455 transrec->lasttrans_timestamp.tv_nsec = 0;
456 transrec->last_trans_read = time(0);
458 if (debug)
459 (void) printf("New transfile '%s'\n", transrec->path);
461 return (transrec);
464 void
465 nfslog_process_trans_timeout(
466 struct nfslog_trans_file *tf,
467 uint32_t force_flush)
469 struct transentry *pte;
470 time_t cur_time = time(0);
473 * If we have not seen a transaction on this file for
474 * a long time, then we need to flush everything out since
475 * we may not be getting anything else in for awhile.
477 if (difftime(cur_time, tf->last_trans_read) >
478 (2 * MAX(TRANS_ENTRY_TIMEOUT, idle_time)))
479 force_flush = TRUE;
481 restart1:
482 for (pte = tf->te_list_v3_read->next;
483 pte != tf->te_list_v3_read;
484 pte = pte->next) {
485 if (force_flush == TRUE ||
486 (difftime(tf->lasttrans_timestamp.tv_sec,
487 pte->lastupdate.tv_sec) >
488 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
489 nfslog_print_trans_logentry(pte, tf);
490 remove_te(pte);
491 goto restart1;
494 restart2:
495 for (pte = tf->te_list_v3_write->next;
496 pte != tf->te_list_v3_write;
497 pte = pte->next) {
498 if (force_flush == TRUE ||
499 (difftime(tf->lasttrans_timestamp.tv_sec,
500 pte->lastupdate.tv_sec) >
501 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
502 nfslog_print_trans_logentry(pte, tf);
503 remove_te(pte);
504 goto restart2;
507 restart3:
508 for (pte = tf->te_list_v2_read->next;
509 pte != tf->te_list_v2_read;
510 pte = pte->next) {
511 if (force_flush == TRUE ||
512 (difftime(tf->lasttrans_timestamp.tv_sec,
513 pte->lastupdate.tv_sec) >
514 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
515 nfslog_print_trans_logentry(pte, tf);
516 remove_te(pte);
517 goto restart3;
520 restart4:
521 for (pte = tf->te_list_v2_write->next;
522 pte != tf->te_list_v2_write;
523 pte = pte->next) {
524 if (force_flush == TRUE ||
525 (difftime(tf->lasttrans_timestamp.tv_sec,
526 pte->lastupdate.tv_sec) >
527 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
528 nfslog_print_trans_logentry(pte, tf);
529 remove_te(pte);
530 goto restart4;
534 (void) fflush(tf->fp);
538 * Flushes outstanding transactions to disk, and closes
539 * the transaction log.
541 void
542 nfslog_close_transactions(void **transcookie)
544 assert(*transcookie != NULL);
545 nfslog_process_trans_timeout(
546 (struct nfslog_trans_file *)(*transcookie), TRUE);
547 nfslog_close_trans_file((struct nfslog_trans_file *)(*transcookie));
548 *transcookie = NULL;
551 static struct transentry *
552 trans_read(
553 nfslog_request_record *logrec,
554 struct nfslog_trans_file *tf,
555 char *fhpath,
556 char *path1)
558 struct transentry *newte;
559 struct transentry *pte = NULL;
560 /* LINTED */
561 nfslog_nfsreadargs *args = (nfslog_nfsreadargs *)logrec->re_rpc_arg;
562 /* LINTED */
563 nfslog_rdresult *res = (nfslog_rdresult *)logrec->re_rpc_res;
565 if (res->r_status != NFS_OK)
566 return (NULL);
568 if ((newte = create_te()) == NULL)
569 return (NULL);
571 if (!path1) {
572 newte->pathname = nfslog_get_path(&args->ra_fhandle,
573 NULL, fhpath, "trans_read");
574 } else {
575 newte->pathname = strdup(path1);
578 /* prep the struct for insertion */
579 newte->starttime = logrec->re_header.rh_timestamp;
580 newte->lastupdate = logrec->re_header.rh_timestamp;
581 newte->optype = TRANS_OPER_READ;
582 newte->datatype = TRANS_DATATYPE_BINARY;
583 newte->transoption = TRANS_OPTION_NOACTION;
584 newte->pnb = netbufdup(&(logrec->re_ipaddr));
585 newte->uid = logrec->re_header.rh_uid;
586 newte->nfsvers = NFS_VERSION;
587 newte->netid = strdup(logrec->re_netid);
588 if (logrec->re_principal_name)
589 newte->principal_name = strdup(logrec->re_principal_name);
590 else
591 newte->principal_name = NULL;
592 newte->totalbytes = res->nfslog_rdresult_u.r_ok.rrok_count;
593 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->ra_fhandle));
595 if (res->nfslog_rdresult_u.r_ok.rrok_count <
596 res->nfslog_rdresult_u.r_ok.filesize) {
597 if (pte = insert_te(tf->te_list_v2_read, newte)) {
598 /* free this since entry was found (not inserted) */
599 remove_te(newte);
601 pte->totalbytes +=
602 res->nfslog_rdresult_u.r_ok.rrok_count;
604 if (pte->lastupdate.tv_sec <=
605 logrec->re_header.rh_timestamp.tv_sec)
606 pte->lastupdate =
607 logrec->re_header.rh_timestamp;
609 if (pte->totalbytes <
610 res->nfslog_rdresult_u.r_ok.filesize) {
611 pte = NULL; /* prevent printing of log entry */
614 } else {
615 pte = newte; /* print a log record - complete file read */
618 return (pte);
621 static struct transentry *
622 trans_write(
623 nfslog_request_record *logrec,
624 struct nfslog_trans_file *tf,
625 char *fhpath,
626 char *path1)
628 struct transentry *newte;
629 struct transentry *pte = NULL;
630 /* LINTED */
631 nfslog_writeargs *args = (nfslog_writeargs *)logrec->re_rpc_arg;
632 /* LINTED */
633 nfslog_writeresult *res = (nfslog_writeresult *)logrec->re_rpc_res;
635 if (res->wr_status != NFS_OK)
636 return (NULL);
638 if ((newte = create_te()) == NULL)
639 return (NULL);
641 if (!path1) {
642 newte->pathname = nfslog_get_path(&args->waargs_fhandle,
643 NULL, fhpath, "trans_write");
644 } else {
645 newte->pathname = strdup(path1);
648 newte->starttime = logrec->re_header.rh_timestamp;
649 newte->lastupdate = logrec->re_header.rh_timestamp;
650 newte->optype = TRANS_OPER_WRITE;
651 newte->datatype = TRANS_DATATYPE_BINARY;
652 newte->transoption = TRANS_OPTION_NOACTION;
653 newte->pnb = netbufdup(&(logrec->re_ipaddr));
654 newte->uid = logrec->re_header.rh_uid;
655 newte->nfsvers = NFS_VERSION;
656 newte->netid = strdup(logrec->re_netid);
657 if (logrec->re_principal_name)
658 newte->principal_name = strdup(logrec->re_principal_name);
659 else
660 newte->principal_name = NULL;
661 newte->totalbytes = args->waargs_totcount;
662 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->waargs_fhandle));
664 if (pte = insert_te(tf->te_list_v2_write, newte)) {
666 * if the write would have increased the total byte count
667 * over the filesize, then generate a log entry and remove
668 * the write record and insert the new one.
670 if (pte->totalbytes + args->waargs_totcount >
671 res->nfslog_writeresult_u.wr_size) {
672 nfslog_print_trans_logentry(pte, tf);
673 remove_te(pte);
674 (void) insert_te(tf->te_list_v2_write, newte);
675 pte = NULL;
676 } else {
677 /* free this since entry was found (not inserted) */
678 remove_te(newte);
680 pte->totalbytes += args->waargs_totcount;
682 if (pte->lastupdate.tv_sec <=
683 logrec->re_header.rh_timestamp.tv_sec) {
684 pte->lastupdate =
685 logrec->re_header.rh_timestamp;
687 pte = NULL; /* prevent printing of log entry */
690 return (pte);
693 static struct transentry *
694 trans_setattr(
695 nfslog_request_record *logrec,
696 struct nfslog_trans_file *tf,
697 char *fhpath,
698 char *path1)
700 struct transentry *newte;
701 struct transentry *pte = NULL;
702 /* LINTED */
703 nfslog_setattrargs *args = (nfslog_setattrargs *)logrec->re_rpc_arg;
704 /* LINTED */
705 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
707 if (*res != NFS_OK)
708 return (NULL);
710 if (args->saa_sa.sa_size == (uint32_t)-1)
711 return (NULL);
713 * should check the size of the file to see if it
714 * is being truncated below current eof. if so
715 * a record should be generated.... XXX
717 if (args->saa_sa.sa_size != 0)
718 return (NULL);
720 if ((newte = create_te()) == NULL)
721 return (NULL);
723 if (!path1) {
724 newte->pathname = nfslog_get_path(&args->saa_fh, NULL,
725 fhpath, "trans_setattr2");
726 } else {
727 newte->pathname = strdup(path1);
730 newte->starttime = logrec->re_header.rh_timestamp;
731 newte->lastupdate = logrec->re_header.rh_timestamp;
732 newte->optype = TRANS_OPER_SETATTR;
733 newte->datatype = TRANS_DATATYPE_BINARY;
734 newte->transoption = TRANS_OPTION_NOACTION;
735 newte->pnb = netbufdup(&(logrec->re_ipaddr));
736 newte->uid = logrec->re_header.rh_uid;
737 newte->nfsvers = NFS_VERSION;
738 newte->netid = strdup(logrec->re_netid);
739 if (logrec->re_principal_name)
740 newte->principal_name = strdup(logrec->re_principal_name);
741 else
742 newte->principal_name = NULL;
743 newte->totalbytes = 0;
744 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->saa_fh));
746 if (pte = insert_te(tf->te_list_v2_write, newte)) {
747 nfslog_print_trans_logentry(pte, tf);
748 remove_te(pte);
750 if (pte = insert_te(tf->te_list_v2_read, newte)) {
751 nfslog_print_trans_logentry(pte, tf);
752 remove_te(pte);
755 return (newte);
758 static struct transentry *
759 trans_create(
760 nfslog_request_record *logrec,
761 struct nfslog_trans_file *tf,
762 char *fhpath,
763 char *path1)
765 struct transentry *newte;
766 struct transentry *pte = NULL;
767 /* LINTED */
768 nfslog_createargs *args = (nfslog_createargs *)logrec->re_rpc_arg;
769 /* LINTED */
770 nfslog_diropres *res = (nfslog_diropres *)logrec->re_rpc_res;
772 if (res->dr_status != NFS_OK)
773 return (NULL);
775 if ((newte = create_te()) == NULL)
776 return (NULL);
778 if (!path1) {
779 newte->pathname =
780 nfslog_get_path(&args->ca_da.da_fhandle,
781 args->ca_da.da_name,
782 fhpath, "trans_create2");
783 } else {
784 newte->pathname = strdup(path1);
787 newte->starttime = logrec->re_header.rh_timestamp;
788 newte->lastupdate = logrec->re_header.rh_timestamp;
789 newte->optype = TRANS_OPER_CREATE;
790 newte->datatype = TRANS_DATATYPE_BINARY;
791 newte->transoption = TRANS_OPTION_NOACTION;
792 newte->pnb = netbufdup(&(logrec->re_ipaddr));
793 newte->uid = logrec->re_header.rh_uid;
794 newte->nfsvers = NFS_VERSION;
795 newte->netid = strdup(logrec->re_netid);
796 if (logrec->re_principal_name)
797 newte->principal_name = strdup(logrec->re_principal_name);
798 else
799 newte->principal_name = NULL;
801 if (args->ca_sa.sa_size == (uint32_t)-1)
802 newte->totalbytes = 0;
803 else
804 newte->totalbytes = args->ca_sa.sa_size;
806 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(
807 &res->nfslog_diropres_u.dr_ok.drok_fhandle));
810 * if the file is being truncated on create, we need to flush
811 * any outstanding read/write transactions
813 if (args->ca_sa.sa_size != (uint32_t)-1) {
814 if (pte = insert_te(tf->te_list_v2_write, newte)) {
815 nfslog_print_trans_logentry(pte, tf);
816 remove_te(pte);
818 if (pte = insert_te(tf->te_list_v2_read, newte)) {
819 nfslog_print_trans_logentry(pte, tf);
820 remove_te(pte);
824 return (newte);
827 static struct transentry *
828 trans_remove(
829 nfslog_request_record *logrec,
830 struct nfslog_trans_file *tf,
831 char *fhpath,
832 char *path1)
834 struct transentry *newte;
835 struct transentry *pte = NULL;
836 /* LINTED */
837 nfslog_diropargs *args = (nfslog_diropargs *)logrec->re_rpc_arg;
838 /* LINTED */
839 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
841 if (*res != NFS_OK)
842 return (NULL);
844 if ((newte = create_te()) == NULL)
845 return (NULL);
847 if (!path1) {
848 char *name = args->da_name;
849 fhandle_t *dfh = &args->da_fhandle;
850 newte->pathname = nfslog_get_path(dfh, name,
851 fhpath, "trans_remove2");
852 } else {
853 newte->pathname = strdup(path1);
856 newte->starttime = logrec->re_header.rh_timestamp;
857 newte->lastupdate = logrec->re_header.rh_timestamp;
858 newte->optype = TRANS_OPER_REMOVE;
859 newte->datatype = TRANS_DATATYPE_BINARY;
860 newte->transoption = TRANS_OPTION_NOACTION;
861 newte->pnb = netbufdup(&(logrec->re_ipaddr));
862 newte->uid = logrec->re_header.rh_uid;
863 newte->nfsvers = NFS_VERSION;
864 newte->netid = strdup(logrec->re_netid);
865 if (logrec->re_principal_name)
866 newte->principal_name = strdup(logrec->re_principal_name);
867 else
868 newte->principal_name = NULL;
869 newte->totalbytes = 0;
870 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->da_fhandle));
872 if (pte = insert_te(tf->te_list_v2_write, newte)) {
873 nfslog_print_trans_logentry(pte, tf);
874 remove_te(pte);
876 if (pte = insert_te(tf->te_list_v2_read, newte)) {
877 nfslog_print_trans_logentry(pte, tf);
878 remove_te(pte);
880 if (pte = insert_te(tf->te_list_v3_write, newte)) {
881 nfslog_print_trans_logentry(pte, tf);
882 remove_te(pte);
884 if (pte = insert_te(tf->te_list_v3_read, newte)) {
885 nfslog_print_trans_logentry(pte, tf);
886 remove_te(pte);
889 return (newte);
892 static struct transentry *
893 trans_mkdir(
894 nfslog_request_record *logrec,
895 char *fhpath,
896 char *path1)
898 struct transentry *newte;
899 /* LINTED */
900 nfslog_createargs *args = (nfslog_createargs *)logrec->re_rpc_arg;
901 /* LINTED */
902 nfslog_diropres *res = (nfslog_diropres *)logrec->re_rpc_res;
904 if (res->dr_status != NFS_OK)
905 return (NULL);
907 if ((newte = create_te()) == NULL)
908 return (NULL);
910 if (!path1) {
911 nfslog_diropargs *dargs = &args->ca_da;
912 char *name = dargs->da_name;
913 fhandle_t *dfh = &dargs->da_fhandle;
914 newte->pathname = nfslog_get_path(dfh, name,
915 fhpath, "trans_mkdir2");
916 } else {
917 newte->pathname = strdup(path1);
920 newte->starttime = logrec->re_header.rh_timestamp;
921 newte->lastupdate = logrec->re_header.rh_timestamp;
922 newte->optype = TRANS_OPER_MKDIR;
923 newte->datatype = TRANS_DATATYPE_BINARY;
924 newte->transoption = TRANS_OPTION_NOACTION;
925 newte->pnb = netbufdup(&(logrec->re_ipaddr));
926 newte->uid = logrec->re_header.rh_uid;
927 newte->nfsvers = NFS_VERSION;
928 newte->netid = strdup(logrec->re_netid);
929 if (logrec->re_principal_name)
930 newte->principal_name = strdup(logrec->re_principal_name);
931 else
932 newte->principal_name = NULL;
933 newte->totalbytes = 0;
934 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->ca_da.da_fhandle));
936 return (newte);
939 static struct transentry *
940 trans_rmdir(
941 nfslog_request_record *logrec,
942 char *fhpath,
943 char *path1)
945 struct transentry *newte;
946 /* LINTED */
947 nfslog_diropargs *args = (nfslog_diropargs *)logrec->re_rpc_arg;
948 /* LINTED */
949 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
951 if (*res != NFS_OK)
952 return (NULL);
954 if ((newte = create_te()) == NULL)
955 return (NULL);
957 if (!path1) {
958 char *name = args->da_name;
959 fhandle_t *dfh = &args->da_fhandle;
960 newte->pathname = nfslog_get_path(dfh, name,
961 fhpath, "trans_rmdir2");
962 } else {
963 newte->pathname = strdup(path1);
966 newte->starttime = logrec->re_header.rh_timestamp;
967 newte->lastupdate = logrec->re_header.rh_timestamp;
968 newte->optype = TRANS_OPER_RMDIR;
969 newte->datatype = TRANS_DATATYPE_BINARY;
970 newte->transoption = TRANS_OPTION_NOACTION;
971 newte->pnb = netbufdup(&(logrec->re_ipaddr));
972 newte->uid = logrec->re_header.rh_uid;
973 newte->nfsvers = NFS_VERSION;
974 newte->netid = strdup(logrec->re_netid);
975 if (logrec->re_principal_name)
976 newte->principal_name = strdup(logrec->re_principal_name);
977 else
978 newte->principal_name = NULL;
979 newte->totalbytes = 0;
980 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->da_fhandle));
982 return (newte);
985 static struct transentry *
986 trans_rename(
987 nfslog_request_record *logrec,
988 struct nfslog_trans_file *tf,
989 char *fhpath,
990 char *path1,
991 char *path2)
993 struct transentry *newte;
994 struct transentry *pte = NULL;
995 /* LINTED */
996 nfslog_rnmargs *args = (nfslog_rnmargs *)logrec->re_rpc_arg;
997 /* LINTED */
998 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
999 char *tpath1 = NULL;
1000 char *tpath2 = NULL;
1002 if (*res != NFS_OK)
1003 return (NULL);
1005 if ((newte = create_te()) == NULL)
1006 return (NULL);
1008 if (!path1) {
1009 char *from_name, *to_name;
1010 fhandle_t *from_dfh, *to_dfh;
1012 from_name = args->rna_from.da_name;
1013 from_dfh = &args->rna_from.da_fhandle;
1014 to_name = args->rna_to.da_name;
1015 to_dfh = &args->rna_to.da_fhandle;
1017 path1 = tpath1 = nfslog_get_path(from_dfh, from_name,
1018 fhpath, "trans_rename from");
1019 path2 = tpath2 = nfslog_get_path(to_dfh, to_name,
1020 fhpath, "trans_rename to");
1023 newte->pathname = path1; /* no need to strdup here */
1024 newte->starttime = logrec->re_header.rh_timestamp;
1025 newte->lastupdate = logrec->re_header.rh_timestamp;
1026 newte->optype = TRANS_OPER_RENAME;
1027 newte->datatype = TRANS_DATATYPE_BINARY;
1028 newte->transoption = TRANS_OPTION_NOACTION;
1029 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1030 newte->uid = logrec->re_header.rh_uid;
1031 newte->nfsvers = NFS_VERSION;
1032 newte->netid = strdup(logrec->re_netid);
1033 if (logrec->re_principal_name)
1034 newte->principal_name = strdup(logrec->re_principal_name);
1035 else
1036 newte->principal_name = NULL;
1037 newte->totalbytes = 0;
1038 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->rna_from.da_fhandle));
1040 /* switch path names for the file for renames */
1041 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1042 free(pte->pathname);
1043 pte->pathname = strdup(path2);
1045 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1046 free(pte->pathname);
1047 pte->pathname = strdup(path2);
1049 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1050 free(pte->pathname);
1051 pte->pathname = strdup(path2);
1053 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1054 free(pte->pathname);
1055 pte->pathname = strdup(path2);
1058 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1059 /* check for NULL malloc */
1060 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1062 if (tpath1) {
1063 free(tpath1);
1064 free(tpath2);
1067 return (newte);
1070 static struct transentry *
1071 trans_link(
1072 nfslog_request_record *logrec,
1073 char *fhpath,
1074 char *path1,
1075 char *path2)
1077 struct transentry *newte;
1078 /* LINTED */
1079 nfslog_linkargs *args = (nfslog_linkargs *)logrec->re_rpc_arg;
1080 /* LINTED */
1081 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
1082 char *tpath1 = NULL;
1083 char *tpath2 = NULL;
1085 if (*res != NFS_OK)
1086 return (NULL);
1088 if ((newte = create_te()) == NULL)
1089 return (NULL);
1091 if (!path1) {
1092 fhandle_t *fh = &args->la_from;
1093 char *name = args->la_to.da_name;
1094 fhandle_t *dfh = &args->la_to.da_fhandle;
1096 path1 = tpath1 = nfslog_get_path(fh, NULL,
1097 fhpath, "trans_link from");
1098 path2 = tpath2 = nfslog_get_path(dfh, name,
1099 fhpath, "trans_link to");
1102 newte->starttime = logrec->re_header.rh_timestamp;
1103 newte->lastupdate = logrec->re_header.rh_timestamp;
1104 newte->optype = TRANS_OPER_LINK;
1105 newte->datatype = TRANS_DATATYPE_BINARY;
1106 newte->transoption = TRANS_OPTION_NOACTION;
1107 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1108 newte->uid = logrec->re_header.rh_uid;
1109 newte->nfsvers = NFS_VERSION;
1110 newte->netid = strdup(logrec->re_netid);
1111 if (logrec->re_principal_name)
1112 newte->principal_name = strdup(logrec->re_principal_name);
1113 else
1114 newte->principal_name = NULL;
1115 newte->totalbytes = 0;
1116 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->la_from));
1118 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1119 /* check for NULL malloc */
1120 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1122 if (tpath1) {
1123 free(tpath1);
1124 free(tpath2);
1127 return (newte);
1130 static struct transentry *
1131 trans_symlink(
1132 nfslog_request_record *logrec,
1133 char *fhpath,
1134 char *path1)
1136 struct transentry *newte;
1137 /* LINTED */
1138 nfslog_symlinkargs *args = (nfslog_symlinkargs *)logrec->re_rpc_arg;
1139 /* LINTED */
1140 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
1141 char *tpath1 = NULL;
1143 if (*res != NFS_OK)
1144 return (NULL);
1146 if ((newte = create_te()) == NULL)
1147 return (NULL);
1149 if (!path1) {
1150 char *name = args->sla_from.da_name;
1151 fhandle_t *dfh = &args->sla_from.da_fhandle;
1153 path1 = tpath1 = nfslog_get_path(dfh, name,
1154 fhpath, "trans_symlink");
1157 newte->starttime = logrec->re_header.rh_timestamp;
1158 newte->lastupdate = logrec->re_header.rh_timestamp;
1159 newte->optype = TRANS_OPER_SYMLINK;
1160 newte->datatype = TRANS_DATATYPE_BINARY;
1161 newte->transoption = TRANS_OPTION_NOACTION;
1162 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1163 newte->uid = logrec->re_header.rh_uid;
1164 newte->nfsvers = NFS_VERSION;
1165 newte->netid = strdup(logrec->re_netid);
1166 if (logrec->re_principal_name)
1167 newte->principal_name = strdup(logrec->re_principal_name);
1168 else
1169 newte->principal_name = NULL;
1170 newte->totalbytes = 0;
1171 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->sla_from.da_fhandle));
1173 newte->pathname = (char *)malloc(strlen(path1) +
1174 strlen(args->sla_tnm) + 3);
1175 (void) sprintf(newte->pathname, "%s->%s", path1, args->sla_tnm);
1177 if (tpath1)
1178 free(tpath1);
1180 return (newte);
1183 static struct transentry *
1184 trans_read3(
1185 nfslog_request_record *logrec,
1186 struct nfslog_trans_file *tf,
1187 char *fhpath,
1188 char *path1)
1190 struct transentry *newte;
1191 struct transentry *pte = NULL;
1192 /* LINTED */
1193 nfslog_READ3args *args = (nfslog_READ3args *)logrec->re_rpc_arg;
1194 /* LINTED */
1195 nfslog_READ3res *res = (nfslog_READ3res *)logrec->re_rpc_res;
1197 if (res->status != NFS3_OK)
1198 return (NULL);
1200 if ((newte = create_te()) == NULL)
1201 return (NULL);
1203 if (!path1) {
1204 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->file);
1205 newte->pathname = nfslog_get_path(fh, NULL,
1206 fhpath, "trans_read3");
1207 } else {
1208 newte->pathname = strdup(path1);
1211 /* prep the struct for insertion */
1212 newte->starttime = logrec->re_header.rh_timestamp;
1213 newte->lastupdate = logrec->re_header.rh_timestamp;
1214 newte->optype = TRANS_OPER_READ;
1215 newte->datatype = TRANS_DATATYPE_BINARY;
1216 newte->transoption = TRANS_OPTION_NOACTION;
1217 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1218 newte->uid = logrec->re_header.rh_uid;
1219 newte->nfsvers = NFS_V3;
1220 newte->netid = strdup(logrec->re_netid);
1221 if (logrec->re_principal_name)
1222 newte->principal_name = strdup(logrec->re_principal_name);
1223 else
1224 newte->principal_name = NULL;
1225 newte->totalbytes = res->nfslog_READ3res_u.ok.count;
1226 newte->fh_u.fh3 = args->file;
1228 if (res->nfslog_READ3res_u.ok.count <
1229 res->nfslog_READ3res_u.ok.filesize) {
1230 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1231 /* free this since entry was found (not inserted) */
1232 remove_te(newte);
1234 pte->totalbytes += res->nfslog_READ3res_u.ok.count;
1236 if (pte->lastupdate.tv_sec <=
1237 logrec->re_header.rh_timestamp.tv_sec)
1238 pte->lastupdate =
1239 logrec->re_header.rh_timestamp;
1241 if (pte->totalbytes <
1242 res->nfslog_READ3res_u.ok.filesize) {
1243 pte = NULL; /* prevent printing of log entry */
1246 } else {
1247 pte = newte; /* print a log record - complete file read */
1250 return (pte);
1253 static struct transentry *
1254 trans_write3(
1255 nfslog_request_record *logrec,
1256 struct nfslog_trans_file *tf,
1257 char *fhpath,
1258 char *path1)
1260 struct transentry *newte;
1261 struct transentry *pte = NULL;
1262 /* LINTED */
1263 nfslog_WRITE3args *args = (nfslog_WRITE3args *)logrec->re_rpc_arg;
1264 /* LINTED */
1265 nfslog_WRITE3res *res = (nfslog_WRITE3res *)logrec->re_rpc_res;
1267 if (res->status != NFS3_OK)
1268 return (NULL);
1270 if ((newte = create_te()) == NULL)
1271 return (NULL);
1273 if (!path1) {
1274 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->file);
1275 newte->pathname = nfslog_get_path(fh, NULL,
1276 fhpath, "trans_write3");
1277 } else {
1278 newte->pathname = strdup(path1);
1281 newte->starttime = logrec->re_header.rh_timestamp;
1282 newte->lastupdate = logrec->re_header.rh_timestamp;
1283 newte->optype = TRANS_OPER_WRITE;
1284 newte->datatype = TRANS_DATATYPE_BINARY;
1285 newte->transoption = TRANS_OPTION_NOACTION;
1286 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1287 newte->uid = logrec->re_header.rh_uid;
1288 newte->nfsvers = NFS_V3;
1289 newte->netid = strdup(logrec->re_netid);
1290 if (logrec->re_principal_name)
1291 newte->principal_name = strdup(logrec->re_principal_name);
1292 else
1293 newte->principal_name = NULL;
1294 newte->totalbytes = res->nfslog_WRITE3res_u.ok.count;
1295 newte->fh_u.fh3 = args->file;
1297 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1299 * if the write would have increased the total byte count
1300 * over the filesize, then generate a log entry and remove
1301 * the write record and insert the new one.
1303 if (pte->totalbytes + res->nfslog_WRITE3res_u.ok.count >
1304 res->nfslog_WRITE3res_u.ok.filesize) {
1305 nfslog_print_trans_logentry(pte, tf);
1306 remove_te(pte);
1307 (void) insert_te(tf->te_list_v3_write, newte);
1308 pte = NULL;
1309 } else {
1310 /* free this since entry was found (not inserted) */
1311 remove_te(newte);
1313 pte->totalbytes += res->nfslog_WRITE3res_u.ok.count;
1315 if (pte->lastupdate.tv_sec <=
1316 logrec->re_header.rh_timestamp.tv_sec) {
1317 pte->lastupdate =
1318 logrec->re_header.rh_timestamp;
1320 pte = NULL; /* prevent printing of log entry */
1323 return (pte);
1326 static struct transentry *
1327 trans_setattr3(
1328 nfslog_request_record *logrec,
1329 struct nfslog_trans_file *tf,
1330 char *fhpath,
1331 char *path1)
1333 struct transentry *newte;
1334 struct transentry *pte = NULL;
1335 /* LINTED */
1336 nfslog_SETATTR3args *args = (nfslog_SETATTR3args *)logrec->re_rpc_arg;
1337 /* LINTED */
1338 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1340 if (*res != NFS3_OK)
1341 return (NULL);
1343 if (!args->size.set_it)
1344 return (NULL);
1346 * should check the size of the file to see if it
1347 * is being truncated below current eof. if so
1348 * a record should be generated.... XXX
1350 if (args->size.size != 0)
1351 return (NULL);
1353 if ((newte = create_te()) == NULL)
1354 return (NULL);
1356 if (!path1) {
1357 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->object);
1358 newte->pathname = nfslog_get_path(fh, NULL,
1359 fhpath, "trans_setattr3");
1360 } else {
1361 newte->pathname = strdup(path1);
1364 newte->starttime = logrec->re_header.rh_timestamp;
1365 newte->lastupdate = logrec->re_header.rh_timestamp;
1366 newte->optype = TRANS_OPER_SETATTR;
1367 newte->datatype = TRANS_DATATYPE_BINARY;
1368 newte->transoption = TRANS_OPTION_NOACTION;
1369 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1370 newte->uid = logrec->re_header.rh_uid;
1371 newte->nfsvers = NFS_V3;
1372 newte->netid = strdup(logrec->re_netid);
1373 if (logrec->re_principal_name)
1374 newte->principal_name = strdup(logrec->re_principal_name);
1375 else
1376 newte->principal_name = NULL;
1377 newte->totalbytes = 0;
1378 newte->fh_u.fh3 = args->object;
1380 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1381 nfslog_print_trans_logentry(pte, tf);
1382 remove_te(pte);
1384 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1385 nfslog_print_trans_logentry(pte, tf);
1386 remove_te(pte);
1389 return (newte);
1392 static struct transentry *
1393 trans_create3(
1394 nfslog_request_record *logrec,
1395 struct nfslog_trans_file *tf,
1396 char *fhpath,
1397 char *path1)
1399 struct transentry *newte;
1400 struct transentry *pte = NULL;
1401 /* LINTED */
1402 nfslog_CREATE3args *args = (nfslog_CREATE3args *)logrec->re_rpc_arg;
1403 /* LINTED */
1404 nfslog_CREATE3res *res = (nfslog_CREATE3res *)logrec->re_rpc_res;
1406 if (res->status != NFS3_OK)
1407 return (NULL);
1409 if ((newte = create_te()) == NULL)
1410 return (NULL);
1412 if (!path1) {
1413 newte->pathname =
1414 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1415 args->where.name,
1416 fhpath, "trans_create3");
1417 } else {
1418 newte->pathname = strdup(path1);
1421 newte->starttime = logrec->re_header.rh_timestamp;
1422 newte->lastupdate = logrec->re_header.rh_timestamp;
1423 newte->optype = TRANS_OPER_CREATE;
1424 newte->datatype = TRANS_DATATYPE_BINARY;
1425 newte->transoption = TRANS_OPTION_NOACTION;
1426 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1427 newte->uid = logrec->re_header.rh_uid;
1428 newte->nfsvers = NFS_V3;
1429 newte->netid = strdup(logrec->re_netid);
1430 if (logrec->re_principal_name)
1431 newte->principal_name = strdup(logrec->re_principal_name);
1432 else
1433 newte->principal_name = NULL;
1435 if (!args->how.nfslog_createhow3_u.size.set_it)
1436 newte->totalbytes = 0;
1437 else
1438 newte->totalbytes =
1439 args->how.nfslog_createhow3_u.size.size;
1441 newte->fh_u.fh3 = args->where.dir;
1443 if (args->how.nfslog_createhow3_u.size.set_it) {
1444 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1445 nfslog_print_trans_logentry(pte, tf);
1446 remove_te(pte);
1448 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1449 nfslog_print_trans_logentry(pte, tf);
1450 remove_te(pte);
1454 return (newte);
1457 static struct transentry *
1458 trans_remove3(
1459 nfslog_request_record *logrec,
1460 struct nfslog_trans_file *tf,
1461 char *fhpath,
1462 char *path1)
1464 struct transentry *newte;
1465 struct transentry *pte = NULL;
1466 /* LINTED */
1467 nfslog_REMOVE3args *args = (nfslog_REMOVE3args *)logrec->re_rpc_arg;
1468 /* LINTED */
1469 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1471 if (*res != NFS3_OK)
1472 return (NULL);
1474 if ((newte = create_te()) == NULL)
1475 return (NULL);
1477 if (!path1) {
1478 newte->pathname =
1479 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object.dir),
1480 args->object.name,
1481 fhpath, "trans_remove3");
1482 } else {
1483 newte->pathname = strdup(path1);
1486 newte->starttime = logrec->re_header.rh_timestamp;
1487 newte->lastupdate = logrec->re_header.rh_timestamp;
1488 newte->optype = TRANS_OPER_REMOVE;
1489 newte->datatype = TRANS_DATATYPE_BINARY;
1490 newte->transoption = TRANS_OPTION_NOACTION;
1491 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1492 newte->uid = logrec->re_header.rh_uid;
1493 newte->nfsvers = NFS_V3;
1494 newte->netid = strdup(logrec->re_netid);
1495 if (logrec->re_principal_name)
1496 newte->principal_name = strdup(logrec->re_principal_name);
1497 else
1498 newte->principal_name = NULL;
1499 newte->totalbytes = 0;
1500 newte->fh_u.fh3 = args->object.dir;
1502 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1503 nfslog_print_trans_logentry(pte, tf);
1504 remove_te(pte);
1506 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1507 nfslog_print_trans_logentry(pte, tf);
1508 remove_te(pte);
1510 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1511 nfslog_print_trans_logentry(pte, tf);
1512 remove_te(pte);
1514 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1515 nfslog_print_trans_logentry(pte, tf);
1516 remove_te(pte);
1519 return (newte);
1522 static struct transentry *
1523 trans_mkdir3(
1524 nfslog_request_record *logrec,
1525 char *fhpath,
1526 char *path1)
1528 struct transentry *newte;
1529 /* LINTED */
1530 nfslog_MKDIR3args *args = (nfslog_MKDIR3args *)logrec->re_rpc_arg;
1531 /* LINTED */
1532 nfslog_MKDIR3res *res = (nfslog_MKDIR3res *)logrec->re_rpc_res;
1534 if (res->status != NFS3_OK)
1535 return (NULL);
1537 if ((newte = create_te()) == NULL)
1538 return (NULL);
1540 if (!path1) {
1541 newte->pathname =
1542 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1543 args->where.name,
1544 fhpath, "trans_mkdir3");
1545 } else {
1546 newte->pathname = strdup(path1);
1549 newte->starttime = logrec->re_header.rh_timestamp;
1550 newte->lastupdate = logrec->re_header.rh_timestamp;
1551 newte->optype = TRANS_OPER_MKDIR;
1552 newte->datatype = TRANS_DATATYPE_BINARY;
1553 newte->transoption = TRANS_OPTION_NOACTION;
1554 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1555 newte->uid = logrec->re_header.rh_uid;
1556 newte->nfsvers = NFS_V3;
1557 newte->netid = strdup(logrec->re_netid);
1558 if (logrec->re_principal_name)
1559 newte->principal_name = strdup(logrec->re_principal_name);
1560 else
1561 newte->principal_name = NULL;
1562 newte->totalbytes = 0;
1563 newte->fh_u.fh3 = args->where.dir;
1565 return (newte);
1568 static struct transentry *
1569 trans_rmdir3(
1570 nfslog_request_record *logrec,
1571 char *fhpath,
1572 char *path1)
1574 struct transentry *newte;
1575 /* LINTED */
1576 nfslog_RMDIR3args *args = (nfslog_RMDIR3args *)logrec->re_rpc_arg;
1577 /* LINTED */
1578 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1580 if (*res != NFS3_OK)
1581 return (NULL);
1583 if ((newte = create_te()) == NULL)
1584 return (NULL);
1586 if (!path1) {
1587 newte->pathname =
1588 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object.dir),
1589 args->object.name,
1590 fhpath, "trans_rmdir3");
1591 } else {
1592 newte->pathname = strdup(path1);
1595 newte->starttime = logrec->re_header.rh_timestamp;
1596 newte->lastupdate = logrec->re_header.rh_timestamp;
1597 newte->optype = TRANS_OPER_RMDIR;
1598 newte->datatype = TRANS_DATATYPE_BINARY;
1599 newte->transoption = TRANS_OPTION_NOACTION;
1600 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1601 newte->uid = logrec->re_header.rh_uid;
1602 newte->nfsvers = NFS_V3;
1603 newte->netid = strdup(logrec->re_netid);
1604 if (logrec->re_principal_name)
1605 newte->principal_name = strdup(logrec->re_principal_name);
1606 else
1607 newte->principal_name = NULL;
1608 newte->totalbytes = 0;
1609 newte->fh_u.fh3 = args->object.dir;
1611 return (newte);
1614 static struct transentry *
1615 trans_rename3(
1616 nfslog_request_record *logrec,
1617 struct nfslog_trans_file *tf,
1618 char *fhpath,
1619 char *path1,
1620 char *path2)
1622 struct transentry *newte;
1623 struct transentry *pte = NULL;
1624 /* LINTED */
1625 nfslog_RENAME3args *args = (nfslog_RENAME3args *)logrec->re_rpc_arg;
1626 /* LINTED */
1627 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1628 char *tpath1 = NULL;
1629 char *tpath2 = NULL;
1631 if (*res != NFS3_OK)
1632 return (NULL);
1634 if ((newte = create_te()) == NULL)
1635 return (NULL);
1637 if (!path1) {
1638 path1 = tpath1 =
1639 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->from.dir),
1640 args->from.name, fhpath, "trans_rename3 from");
1641 path2 = tpath2 =
1642 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->to.dir),
1643 args->to.name, fhpath, "trans_rename3 to");
1646 newte->pathname = path1; /* no need to strdup here */
1647 newte->starttime = logrec->re_header.rh_timestamp;
1648 newte->lastupdate = logrec->re_header.rh_timestamp;
1649 newte->optype = TRANS_OPER_RENAME;
1650 newte->datatype = TRANS_DATATYPE_BINARY;
1651 newte->transoption = TRANS_OPTION_NOACTION;
1652 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1653 newte->uid = logrec->re_header.rh_uid;
1654 newte->nfsvers = NFS_V3;
1655 newte->netid = strdup(logrec->re_netid);
1656 if (logrec->re_principal_name)
1657 newte->principal_name = strdup(logrec->re_principal_name);
1658 else
1659 newte->principal_name = NULL;
1660 newte->totalbytes = 0;
1661 newte->fh_u.fh3 = args->from.dir;
1663 /* switch path names for the file for renames */
1664 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1665 free(pte->pathname);
1666 pte->pathname = strdup(path2);
1668 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1669 free(pte->pathname);
1670 pte->pathname = strdup(path2);
1672 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1673 free(pte->pathname);
1674 pte->pathname = strdup(path2);
1676 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1677 free(pte->pathname);
1678 pte->pathname = strdup(path2);
1681 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1682 /* check for NULL malloc */
1683 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1685 if (tpath1) {
1686 free(tpath1);
1687 free(tpath2);
1690 return (newte);
1693 static struct transentry *
1694 trans_mknod3(
1695 nfslog_request_record *logrec,
1696 char *fhpath,
1697 char *path1)
1699 struct transentry *newte;
1700 /* LINTED */
1701 nfslog_MKNOD3args *args = (nfslog_MKNOD3args *)logrec->re_rpc_arg;
1702 /* LINTED */
1703 nfslog_MKNOD3res *res = (nfslog_MKNOD3res *)logrec->re_rpc_res;
1705 if (res->status != NFS3_OK)
1706 return (NULL);
1708 if ((newte = create_te()) == NULL)
1709 return (NULL);
1711 if (!path1) {
1712 newte->pathname =
1713 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1714 args->where.name,
1715 fhpath, "trans_mknod3");
1716 } else {
1717 newte->pathname = strdup(path1);
1720 newte->starttime = logrec->re_header.rh_timestamp;
1721 newte->lastupdate = logrec->re_header.rh_timestamp;
1722 newte->optype = TRANS_OPER_MKNOD;
1723 newte->datatype = TRANS_DATATYPE_BINARY;
1724 newte->transoption = TRANS_OPTION_NOACTION;
1725 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1726 newte->uid = logrec->re_header.rh_uid;
1727 newte->nfsvers = NFS_V3;
1728 newte->netid = strdup(logrec->re_netid);
1729 if (logrec->re_principal_name)
1730 newte->principal_name = strdup(logrec->re_principal_name);
1731 else
1732 newte->principal_name = NULL;
1734 newte->totalbytes = 0;
1735 newte->fh_u.fh3 = args->where.dir;
1737 return (newte);
1740 static struct transentry *
1741 trans_link3(
1742 nfslog_request_record *logrec,
1743 char *fhpath,
1744 char *path1,
1745 char *path2)
1747 struct transentry *newte;
1748 /* LINTED */
1749 nfslog_LINK3args *args = (nfslog_LINK3args *)logrec->re_rpc_arg;
1750 /* LINTED */
1751 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1753 char *tpath1 = NULL;
1754 char *tpath2 = NULL;
1756 if (*res != NFS3_OK)
1757 return (NULL);
1759 if ((newte = create_te()) == NULL)
1760 return (NULL);
1762 if (!path1) {
1763 tpath1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
1764 NULL, fhpath, "trans_link3 from");
1765 tpath2 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->link.dir),
1766 args->link.name, fhpath, "trans_link3 to");
1767 path1 = tpath1;
1768 path2 = tpath2;
1771 newte->starttime = logrec->re_header.rh_timestamp;
1772 newte->lastupdate = logrec->re_header.rh_timestamp;
1773 newte->optype = TRANS_OPER_LINK;
1774 newte->datatype = TRANS_DATATYPE_BINARY;
1775 newte->transoption = TRANS_OPTION_NOACTION;
1776 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1777 newte->uid = logrec->re_header.rh_uid;
1778 newte->nfsvers = NFS_V3;
1779 newte->netid = strdup(logrec->re_netid);
1780 if (logrec->re_principal_name)
1781 newte->principal_name = strdup(logrec->re_principal_name);
1782 else
1783 newte->principal_name = NULL;
1784 newte->totalbytes = 0;
1785 newte->fh_u.fh3 = args->file;
1787 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1788 /* check for NULL malloc */
1789 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1791 if (tpath1) {
1792 free(tpath1);
1793 free(tpath2);
1796 return (newte);
1799 static struct transentry *
1800 trans_symlink3(
1801 nfslog_request_record *logrec,
1802 char *fhpath,
1803 char *path1)
1805 struct transentry *newte;
1806 /* LINTED */
1807 nfslog_SYMLINK3args *args = (nfslog_SYMLINK3args *)logrec->re_rpc_arg;
1808 /* LINTED */
1809 nfslog_SYMLINK3res *res = (nfslog_SYMLINK3res *)logrec->re_rpc_res;
1810 char *name;
1812 if (res->status != NFS3_OK)
1813 return (NULL);
1815 if ((newte = create_te()) == NULL)
1816 return (NULL);
1818 if (path1) {
1819 name = strdup(path1);
1820 } else {
1821 name = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1822 args->where.name, fhpath, "trans_symlink3");
1825 newte->starttime = logrec->re_header.rh_timestamp;
1826 newte->lastupdate = logrec->re_header.rh_timestamp;
1827 newte->optype = TRANS_OPER_SYMLINK;
1828 newte->datatype = TRANS_DATATYPE_BINARY;
1829 newte->transoption = TRANS_OPTION_NOACTION;
1830 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1831 newte->uid = logrec->re_header.rh_uid;
1832 newte->nfsvers = NFS_V3;
1833 newte->netid = strdup(logrec->re_netid);
1834 if (logrec->re_principal_name)
1835 newte->principal_name = strdup(logrec->re_principal_name);
1836 else
1837 newte->principal_name = NULL;
1838 newte->totalbytes = 0;
1839 newte->fh_u.fh3 = args->where.dir;
1841 newte->pathname = (char *)malloc(strlen(name) +
1842 strlen(args->symlink_data) + 3);
1843 /* check for NULL malloc */
1844 (void) sprintf(newte->pathname, "%s->%s", name, args->symlink_data);
1846 free(name);
1848 return (newte);
1852 * nfslog_process_trans_rec - processes the record in the buffer and outputs
1853 * to the trans log.
1854 * Return 0 for success, errno else.
1857 nfslog_process_trans_rec(void *transcookie, nfslog_request_record *logrec,
1858 char *fhpath, char *path1, char *path2)
1860 struct transentry *pte = NULL;
1861 struct nfslog_trans_file *tf = (struct nfslog_trans_file *)transcookie;
1863 /* ignore programs other than nfs */
1864 if (logrec->re_header.rh_prognum != NFS_PROGRAM)
1865 return (0);
1867 /* update the timestamp for use later in the timeout sequences */
1868 if (tf->lasttrans_timestamp.tv_sec <
1869 logrec->re_header.rh_timestamp.tv_sec)
1870 tf->lasttrans_timestamp =
1871 logrec->re_header.rh_timestamp;
1873 /* current time of this processing */
1874 tf->last_trans_read = time(0);
1876 /* ignore anything that is not a read or write */
1877 switch (logrec->re_header.rh_version) {
1878 case NFS_VERSION:
1879 switch (logrec->re_header.rh_procnum) {
1880 case RFS_READ:
1881 if (tf->trans_to_log & TRANSTOLOG_OPER_READ)
1882 pte = trans_read(logrec, tf, fhpath, path1);
1883 break;
1884 case RFS_WRITE:
1885 if (tf->trans_to_log & TRANSTOLOG_OPER_WRITE)
1886 pte = trans_write(logrec, tf, fhpath, path1);
1887 break;
1888 case RFS_SETATTR:
1889 if (tf->trans_to_log & TRANSTOLOG_OPER_SETATTR)
1890 pte = trans_setattr(logrec, tf,
1891 fhpath, path1);
1892 break;
1893 case RFS_REMOVE:
1894 if (tf->trans_to_log & TRANSTOLOG_OPER_REMOVE)
1895 pte = trans_remove(logrec, tf, fhpath, path1);
1896 break;
1897 case RFS_MKDIR:
1898 if (tf->trans_to_log & TRANSTOLOG_OPER_MKDIR)
1899 pte = trans_mkdir(logrec, fhpath, path1);
1900 break;
1901 case RFS_RMDIR:
1902 if (tf->trans_to_log & TRANSTOLOG_OPER_RMDIR)
1903 pte = trans_rmdir(logrec, fhpath, path1);
1904 break;
1905 case RFS_CREATE:
1906 if (tf->trans_to_log & TRANSTOLOG_OPER_CREATE)
1907 pte = trans_create(logrec, tf, fhpath, path1);
1908 break;
1909 case RFS_RENAME:
1910 if (tf->trans_to_log & TRANSTOLOG_OPER_RENAME)
1911 pte = trans_rename(logrec, tf,
1912 fhpath, path1, path2);
1913 break;
1914 case RFS_LINK:
1915 if (tf->trans_to_log & TRANSTOLOG_OPER_LINK)
1916 pte = trans_link(logrec, fhpath, path1, path2);
1917 break;
1918 case RFS_SYMLINK:
1919 if (tf->trans_to_log & TRANSTOLOG_OPER_SYMLINK)
1920 pte = trans_symlink(logrec, fhpath, path1);
1921 break;
1922 default:
1923 break;
1925 break;
1926 case NFS_V3:
1927 switch (logrec->re_header.rh_procnum) {
1928 case NFSPROC3_READ:
1929 if (tf->trans_to_log & TRANSTOLOG_OPER_READ)
1930 pte = trans_read3(logrec, tf, fhpath, path1);
1931 break;
1932 case NFSPROC3_WRITE:
1933 if (tf->trans_to_log & TRANSTOLOG_OPER_WRITE)
1934 pte = trans_write3(logrec, tf, fhpath, path1);
1935 break;
1936 case NFSPROC3_SETATTR:
1937 if (tf->trans_to_log & TRANSTOLOG_OPER_SETATTR)
1938 pte = trans_setattr3(logrec, tf,
1939 fhpath, path1);
1940 break;
1941 case NFSPROC3_REMOVE:
1942 if (tf->trans_to_log & TRANSTOLOG_OPER_REMOVE)
1943 pte = trans_remove3(logrec, tf,
1944 fhpath, path1);
1945 break;
1946 case NFSPROC3_MKDIR:
1947 if (tf->trans_to_log & TRANSTOLOG_OPER_MKDIR)
1948 pte = trans_mkdir3(logrec, fhpath, path1);
1949 break;
1950 case NFSPROC3_RMDIR:
1951 if (tf->trans_to_log & TRANSTOLOG_OPER_RMDIR)
1952 pte = trans_rmdir3(logrec, fhpath, path1);
1953 break;
1954 case NFSPROC3_CREATE:
1955 if (tf->trans_to_log & TRANSTOLOG_OPER_CREATE)
1956 pte = trans_create3(logrec, tf,
1957 fhpath, path1);
1958 break;
1959 case NFSPROC3_RENAME:
1960 if (tf->trans_to_log & TRANSTOLOG_OPER_RENAME)
1961 pte = trans_rename3(logrec, tf,
1962 fhpath, path1, path2);
1963 break;
1964 case NFSPROC3_MKNOD:
1965 if (tf->trans_to_log & TRANSTOLOG_OPER_MKNOD)
1966 pte = trans_mknod3(logrec, fhpath, path1);
1967 break;
1968 case NFSPROC3_LINK:
1969 if (tf->trans_to_log & TRANSTOLOG_OPER_LINK)
1970 pte = trans_link3(logrec,
1971 fhpath, path1, path2);
1972 break;
1973 case NFSPROC3_SYMLINK:
1974 if (tf->trans_to_log & TRANSTOLOG_OPER_SYMLINK)
1975 pte = trans_symlink3(logrec, fhpath, path1);
1976 break;
1977 default:
1978 break;
1980 break;
1981 default:
1982 break;
1985 if (pte != NULL) {
1986 nfslog_print_trans_logentry(pte, tf);
1987 remove_te(pte);
1990 return (0);
1993 static void
1994 nfslog_print_trans_logentry(struct transentry *pte,
1995 struct nfslog_trans_file *tf)
1997 char *remotehost;
1998 char datatype;
1999 char transoption;
2000 char *optype;
2001 char *prin;
2002 int prinid;
2003 char nfs_ident[32];
2005 remotehost = addrtoname(pte->pnb->buf);
2007 datatype = (pte->datatype == TRANS_DATATYPE_BINARY ? 'b' : 'a');
2008 transoption = (pte->transoption == TRANS_OPTION_NOACTION ? '_' : '?');
2010 if (tf->trans_output_type == TRANSLOG_BASIC) {
2011 (void) strcpy(nfs_ident, "nfs");
2012 } else {
2013 (void) strcpy(nfs_ident,
2014 (pte->nfsvers == NFS_V3 ? "nfs3-" : "nfs-"));
2015 (void) strcat(nfs_ident, pte->netid);
2018 switch (pte->optype) {
2019 case TRANS_OPER_READ:
2020 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2021 "read" : "o");
2022 break;
2023 case TRANS_OPER_WRITE:
2024 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2025 "write" : "i");
2026 break;
2027 case TRANS_OPER_REMOVE:
2028 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2029 "remove" : "?");
2030 break;
2031 case TRANS_OPER_MKDIR:
2032 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2033 "mkdir" : "?");
2034 break;
2035 case TRANS_OPER_CREATE:
2036 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2037 "create" : "?");
2038 break;
2039 case TRANS_OPER_RMDIR:
2040 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2041 "rmdir" : "?");
2042 break;
2043 case TRANS_OPER_SETATTR:
2044 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2045 "setattr" : "?");
2046 break;
2047 case TRANS_OPER_RENAME:
2048 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2049 "rename" : "?");
2050 break;
2051 case TRANS_OPER_MKNOD:
2052 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2053 "mknod" : "?");
2054 break;
2055 case TRANS_OPER_LINK:
2056 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2057 "link" : "?");
2058 break;
2059 case TRANS_OPER_SYMLINK:
2060 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2061 "symlink" : "?");
2062 break;
2063 default:
2064 optype = "?";
2065 break;
2067 if (strcmp(pte->principal_name, "") == 0) {
2068 prinid = 0;
2069 prin = "*";
2070 } else {
2071 prinid = 1;
2072 prin = pte->principal_name;
2074 (void) fprintf(tf->fp,
2075 "%.24s %d %s %d %s %c %c %s %c %ld %s %d %s\n",
2076 ctime((time_t *)&pte->starttime.tv_sec),
2077 pte->lastupdate.tv_sec - pte->starttime.tv_sec,
2078 remotehost,
2079 (uint32_t)pte->totalbytes,
2080 pte->pathname,
2081 datatype,
2082 transoption,
2083 optype,
2084 'r', /* anonymous == 'a', guest == 'g', real == 'r'), */
2085 pte->uid,
2086 nfs_ident,
2087 /* authenticated - fill in kerb/security? */
2088 prinid,
2089 /* authenticated ? authuser : "*" */
2090 prin);