dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / nfslog / nfslog_trans.c
blob3fea9c23296f5944033cc927e956ff1b1879b05a
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 #include <stdio.h>
28 #include <errno.h>
29 #include <malloc.h>
30 #include <strings.h>
31 #include <stddef.h>
32 #include <search.h>
33 #include <syslog.h>
34 #include <libintl.h>
35 #include <unistd.h>
36 #include <rpc/rpc.h>
37 #include <netconfig.h>
38 #include <netdir.h>
39 #include <nfs/nfs_sec.h>
40 #include <nfs/export.h>
41 #include <rpc/auth.h>
42 #include <rpc/svc.h>
43 #include <rpc/xdr.h>
44 #include <rpc/clnt.h>
45 #include <nfs/nfs.h>
46 #include <nfs/nfs_log.h>
47 #include <assert.h>
48 #include "fhtab.h"
49 #include "nfslogd.h"
52 * How long should an entry stay in the list before being forced
53 * out and a trans log entry printed
55 #define TRANS_ENTRY_TIMEOUT 60
57 extern char *addrtoname(void *);
59 struct transentry {
60 struct transentry *next;
61 struct transentry *prev;
62 timestruc32_t starttime; /* when did transaction start? */
63 timestruc32_t lastupdate; /* last operation for this entry */
64 #define TRANS_OPER_READ 1
65 #define TRANS_OPER_WRITE 2
66 #define TRANS_OPER_SETATTR 3
67 #define TRANS_OPER_REMOVE 4
68 #define TRANS_OPER_MKDIR 5
69 #define TRANS_OPER_CREATE 6
70 #define TRANS_OPER_RMDIR 7
71 #define TRANS_OPER_RENAME 8
72 #define TRANS_OPER_MKNOD 9
73 #define TRANS_OPER_LINK 10
74 #define TRANS_OPER_SYMLINK 11
75 uchar_t optype; /* read, write, ...? */
76 #define TRANS_DATATYPE_NA /* not applicable data type */
77 #define TRANS_DATATYPE_ASCII 0 /* transfer done as ascii */
78 #define TRANS_DATATYPE_BINARY 1 /* transfer done as binary */
79 uchar_t datatype;
81 * Action taken by server before transfer was made -- noaction,
82 * compressed, tar or uncompressed.
84 #define TRANS_OPTION_NOACTION 0
85 uchar_t transoption;
86 char *pathname;
87 struct netbuf *pnb;
88 uid_t uid;
89 int nfsvers;
90 char *netid;
91 char *principal_name;
92 uint64_t totalbytes; /* total operated upon in history */
93 union {
94 fhandle_t fh;
95 nfs_fh3 fh3;
96 } fh_u;
99 struct nfslog_trans_file {
100 struct nfslog_trans_file *next; /* next file in list */
101 struct nfslog_trans_file *prev; /* next file in list */
102 int refcnt; /* number of references to this struct */
103 char *path; /* pathname of file */
104 FILE *fp; /* file pointer */
105 /* timestamp of the last transaction processed for this file */
106 timestruc32_t lasttrans_timestamp;
107 /* 'current' time that last trans was processed */
108 time_t last_trans_read;
109 uint32_t trans_to_log; /* transactions that are to be logged */
110 uint32_t trans_output_type;
111 struct transentry *te_list_v3_read;
112 struct transentry *te_list_v3_write;
113 struct transentry *te_list_v2_read;
114 struct transentry *te_list_v2_write;
117 static struct nfslog_trans_file *trans_file_head = NULL;
119 static void nfslog_print_trans_logentry(struct transentry *,
120 struct nfslog_trans_file *);
123 static struct netbuf *
124 netbufdup(struct netbuf *pnb)
126 struct netbuf *pnewnb;
127 uint32_t size;
129 size = offsetof(struct netbuf, buf);
130 size += pnb->len;
132 if ((pnewnb = (struct netbuf *)malloc(sizeof (*pnewnb))) == NULL)
133 return (NULL);
134 if ((pnewnb->buf = malloc(pnb->len)) == NULL) {
135 free(pnewnb);
136 return (NULL);
139 pnewnb->maxlen = pnb->maxlen;
140 pnewnb->len = pnb->len;
141 bcopy(pnb->buf, pnewnb->buf, pnb->len);
142 return (pnewnb);
145 static void
146 freenetbuf(struct netbuf *pnb)
148 free(pnb->buf);
149 free(pnb);
152 static struct transentry *
153 create_te()
155 struct transentry *pte;
157 if ((pte = (struct transentry *)calloc(1, sizeof (*pte))) == NULL) {
158 /* failure message or action */
159 return (NULL);
162 pte->next = pte->prev = NULL;
164 return (pte);
167 static struct transentry *
168 insert_te(
169 struct transentry *te_list,
170 struct transentry *entry)
172 struct transentry *pte;
175 * First check for any non-filehandle comparisons that may be needed.
177 switch (entry->optype) {
178 case TRANS_OPER_REMOVE:
179 case TRANS_OPER_RENAME:
180 for (pte = te_list->next; pte != te_list; pte = pte->next) {
181 /* if path names match, then return */
182 if (strcmp(pte->pathname, entry->pathname) == 0) {
183 return (pte);
186 return (NULL);
187 default:
188 break;
191 for (pte = te_list->next; pte != te_list; pte = pte->next) {
192 /* If the file handles match, then we have a hit */
193 if (entry->nfsvers == NFS_VERSION) {
194 if (bcmp(&(pte->fh_u.fh), &(entry->fh_u.fh),
195 sizeof (fhandle_t)) == 0) {
196 switch (entry->optype) {
197 case TRANS_OPER_READ:
198 case TRANS_OPER_WRITE:
199 if (pte->uid == entry->uid) {
200 return (pte);
202 break;
203 default:
204 return (pte);
207 } else {
208 if (pte->fh_u.fh3.fh3_length ==
209 entry->fh_u.fh3.fh3_length &&
210 bcmp(pte->fh_u.fh3.fh3_u.data,
211 entry->fh_u.fh3.fh3_u.data,
212 pte->fh_u.fh3.fh3_length) == 0)
213 switch (entry->optype) {
214 case TRANS_OPER_READ:
215 case TRANS_OPER_WRITE:
216 if (pte->uid == entry->uid) {
217 return (pte);
219 break;
220 default:
221 return (pte);
226 * XXX - should compare more of the information to make sure
227 * it is a match.
231 * other operation types do not generate an entry for
232 * further analysis
234 switch (entry->optype) {
235 case TRANS_OPER_READ:
236 case TRANS_OPER_WRITE:
237 break;
238 default:
239 return (NULL);
242 insque(entry, te_list);
244 return (NULL); /* NULL signifies insertion and no record found */
247 static void
248 remove_te(struct transentry *pte)
250 if (pte->next)
251 remque(pte);
253 free(pte->principal_name);
254 free(pte->pathname);
255 if (pte->pnb) freenetbuf(pte->pnb);
256 free(pte->netid);
258 free(pte);
262 * nfslog_trans_file_free - frees a record
264 static void
265 nfslog_trans_file_free(struct nfslog_trans_file *transrec)
267 if (transrec == NULL)
268 return;
269 if (transrec->path != NULL) {
270 if (debug)
271 (void) printf("freeing transpath '%s'\n",
272 transrec->path);
273 free(transrec->path);
275 free(transrec);
279 * On success returns a pointer to the trans_file that matches
280 * 'path', 'output_type' and 'transtolog'. The reference count for this
281 * object is incremented as well.
282 * Returns NULL if it is not in the list.
284 static struct nfslog_trans_file *
285 nfslog_trans_file_find(
286 char *path,
287 uint32_t output_type,
288 uint32_t transtolog)
290 struct nfslog_trans_file *tfp;
292 for (tfp = trans_file_head; tfp != NULL; tfp = tfp->next) {
293 if ((strcmp(path, tfp->path) == 0) &&
294 (output_type == tfp->trans_output_type) &&
295 (transtolog == tfp->trans_to_log)) {
296 if (debug)
297 (void) printf("Found transfile '%s'\n", path);
298 (tfp->refcnt)++;
299 return (tfp);
302 return (NULL);
307 * nfslog_close_trans_file - decrements the reference count on
308 * this object. On last reference it closes transfile and
309 * frees resources
311 static void
312 nfslog_close_trans_file(struct nfslog_trans_file *tf)
314 assert(tf != NULL);
315 assert(tf->refcnt > 0);
316 if (tf->refcnt > 1) {
317 (tf->refcnt)--;
318 return;
321 if (tf->fp != NULL) {
322 (void) fsync(fileno(tf->fp));
323 (void) fclose(tf->fp);
327 * Disconnect from list
329 tf->prev->next = tf->next;
330 if (tf->next != NULL)
331 tf->next->prev = tf->prev;
334 * Adjust the head of the list if appropriate
336 if (tf == trans_file_head)
337 trans_file_head = tf->next;
339 nfslog_trans_file_free(tf);
343 * nfslog_open_trans_file - open the output trans file and mallocs.
344 * The object is then inserted at the beginning of the global
345 * transfile list.
346 * Returns 0 for success, error else.
348 * *error contains the last error encountered on this object. It can
349 * be used to avoid reporting the same error endlessly, by comparing
350 * the current error to the last error. It is reset to the current error
351 * code on return.
353 void *
354 nfslog_open_trans_file(
355 char *transpath,
356 uint32_t output_type,
357 uint32_t transtolog,
358 int *error)
360 int preverror = *error;
361 struct nfslog_trans_file *transrec;
363 transrec = nfslog_trans_file_find(transpath, output_type, transtolog);
364 if (transrec != NULL)
365 return (transrec);
367 if ((transrec = malloc(sizeof (*transrec))) == NULL) {
368 *error = errno;
369 if (*error != preverror) {
370 syslog(LOG_ERR, gettext("nfslog_open_trans_file: %s"),
371 strerror(*error));
373 return (NULL);
375 bzero(transrec, sizeof (*transrec));
377 if ((transrec->path = strdup(transpath)) == NULL) {
378 *error = errno;
379 if (*error != preverror) {
380 syslog(LOG_ERR, gettext("nfslog_open_trans_file: %s"),
381 strerror(*error));
383 nfslog_trans_file_free(transrec);
384 return (NULL);
387 if ((transrec->fp = fopen(transpath, "a")) == NULL) {
388 *error = errno;
389 if (*error != preverror) {
390 syslog(LOG_ERR, gettext("Cannot open '%s': %s"),
391 transpath, strerror(*error));
393 nfslog_trans_file_free(transrec);
394 return (NULL);
397 transrec->te_list_v3_read =
398 (struct transentry *)malloc(sizeof (struct transentry));
399 transrec->te_list_v3_write =
400 (struct transentry *)malloc(sizeof (struct transentry));
401 transrec->te_list_v2_read =
402 (struct transentry *)malloc(sizeof (struct transentry));
403 transrec->te_list_v2_write =
404 (struct transentry *)malloc(sizeof (struct transentry));
406 if (transrec->te_list_v3_read == NULL ||
407 transrec->te_list_v3_write == NULL ||
408 transrec->te_list_v2_read == NULL ||
409 transrec->te_list_v2_write == NULL) {
410 free(transrec->te_list_v3_read);
411 free(transrec->te_list_v3_write);
412 free(transrec->te_list_v2_read);
413 free(transrec->te_list_v2_write);
414 nfslog_close_trans_file(transrec);
415 return (NULL);
418 transrec->te_list_v3_read->next =
419 transrec->te_list_v3_read->prev = transrec->te_list_v3_read;
420 transrec->te_list_v3_write->next =
421 transrec->te_list_v3_write->prev = transrec->te_list_v3_write;
422 transrec->te_list_v2_read->next =
423 transrec->te_list_v2_read->prev = transrec->te_list_v2_read;
424 transrec->te_list_v2_write->next =
425 transrec->te_list_v2_write->prev = transrec->te_list_v2_write;
428 * Indicate what transaction types to log
430 transrec->trans_to_log = transtolog;
433 * Indicate whether to print 'full' or 'basic' version
434 * of the transactions
436 transrec->trans_output_type = output_type;
439 * Insert at the beginning of the list.
441 transrec->next = trans_file_head;
442 if (trans_file_head != NULL)
443 trans_file_head->prev = transrec;
444 trans_file_head = transrec->prev = transrec;
446 transrec->refcnt = 1;
448 transrec->lasttrans_timestamp.tv_sec = 0;
449 transrec->lasttrans_timestamp.tv_nsec = 0;
450 transrec->last_trans_read = time(0);
452 if (debug)
453 (void) printf("New transfile '%s'\n", transrec->path);
455 return (transrec);
458 void
459 nfslog_process_trans_timeout(
460 struct nfslog_trans_file *tf,
461 uint32_t force_flush)
463 struct transentry *pte;
464 time_t cur_time = time(0);
467 * If we have not seen a transaction on this file for
468 * a long time, then we need to flush everything out since
469 * we may not be getting anything else in for awhile.
471 if (difftime(cur_time, tf->last_trans_read) >
472 (2 * MAX(TRANS_ENTRY_TIMEOUT, idle_time)))
473 force_flush = TRUE;
475 restart1:
476 for (pte = tf->te_list_v3_read->next;
477 pte != tf->te_list_v3_read;
478 pte = pte->next) {
479 if (force_flush == TRUE ||
480 (difftime(tf->lasttrans_timestamp.tv_sec,
481 pte->lastupdate.tv_sec) >
482 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
483 nfslog_print_trans_logentry(pte, tf);
484 remove_te(pte);
485 goto restart1;
488 restart2:
489 for (pte = tf->te_list_v3_write->next;
490 pte != tf->te_list_v3_write;
491 pte = pte->next) {
492 if (force_flush == TRUE ||
493 (difftime(tf->lasttrans_timestamp.tv_sec,
494 pte->lastupdate.tv_sec) >
495 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
496 nfslog_print_trans_logentry(pte, tf);
497 remove_te(pte);
498 goto restart2;
501 restart3:
502 for (pte = tf->te_list_v2_read->next;
503 pte != tf->te_list_v2_read;
504 pte = pte->next) {
505 if (force_flush == TRUE ||
506 (difftime(tf->lasttrans_timestamp.tv_sec,
507 pte->lastupdate.tv_sec) >
508 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
509 nfslog_print_trans_logentry(pte, tf);
510 remove_te(pte);
511 goto restart3;
514 restart4:
515 for (pte = tf->te_list_v2_write->next;
516 pte != tf->te_list_v2_write;
517 pte = pte->next) {
518 if (force_flush == TRUE ||
519 (difftime(tf->lasttrans_timestamp.tv_sec,
520 pte->lastupdate.tv_sec) >
521 MAX(TRANS_ENTRY_TIMEOUT, idle_time))) {
522 nfslog_print_trans_logentry(pte, tf);
523 remove_te(pte);
524 goto restart4;
528 (void) fflush(tf->fp);
532 * Flushes outstanding transactions to disk, and closes
533 * the transaction log.
535 void
536 nfslog_close_transactions(void **transcookie)
538 assert(*transcookie != NULL);
539 nfslog_process_trans_timeout(
540 (struct nfslog_trans_file *)(*transcookie), TRUE);
541 nfslog_close_trans_file((struct nfslog_trans_file *)(*transcookie));
542 *transcookie = NULL;
545 static struct transentry *
546 trans_read(
547 nfslog_request_record *logrec,
548 struct nfslog_trans_file *tf,
549 char *fhpath,
550 char *path1)
552 struct transentry *newte;
553 struct transentry *pte = NULL;
554 /* LINTED */
555 nfslog_nfsreadargs *args = (nfslog_nfsreadargs *)logrec->re_rpc_arg;
556 /* LINTED */
557 nfslog_rdresult *res = (nfslog_rdresult *)logrec->re_rpc_res;
559 if (res->r_status != NFS_OK)
560 return (NULL);
562 if ((newte = create_te()) == NULL)
563 return (NULL);
565 if (!path1) {
566 newte->pathname = nfslog_get_path(&args->ra_fhandle,
567 NULL, fhpath, "trans_read");
568 } else {
569 newte->pathname = strdup(path1);
572 /* prep the struct for insertion */
573 newte->starttime = logrec->re_header.rh_timestamp;
574 newte->lastupdate = logrec->re_header.rh_timestamp;
575 newte->optype = TRANS_OPER_READ;
576 newte->datatype = TRANS_DATATYPE_BINARY;
577 newte->transoption = TRANS_OPTION_NOACTION;
578 newte->pnb = netbufdup(&(logrec->re_ipaddr));
579 newte->uid = logrec->re_header.rh_uid;
580 newte->nfsvers = NFS_VERSION;
581 newte->netid = strdup(logrec->re_netid);
582 if (logrec->re_principal_name)
583 newte->principal_name = strdup(logrec->re_principal_name);
584 else
585 newte->principal_name = NULL;
586 newte->totalbytes = res->nfslog_rdresult_u.r_ok.rrok_count;
587 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->ra_fhandle));
589 if (res->nfslog_rdresult_u.r_ok.rrok_count <
590 res->nfslog_rdresult_u.r_ok.filesize) {
591 if (pte = insert_te(tf->te_list_v2_read, newte)) {
592 /* free this since entry was found (not inserted) */
593 remove_te(newte);
595 pte->totalbytes +=
596 res->nfslog_rdresult_u.r_ok.rrok_count;
598 if (pte->lastupdate.tv_sec <=
599 logrec->re_header.rh_timestamp.tv_sec)
600 pte->lastupdate =
601 logrec->re_header.rh_timestamp;
603 if (pte->totalbytes <
604 res->nfslog_rdresult_u.r_ok.filesize) {
605 pte = NULL; /* prevent printing of log entry */
608 } else {
609 pte = newte; /* print a log record - complete file read */
612 return (pte);
615 static struct transentry *
616 trans_write(
617 nfslog_request_record *logrec,
618 struct nfslog_trans_file *tf,
619 char *fhpath,
620 char *path1)
622 struct transentry *newte;
623 struct transentry *pte = NULL;
624 /* LINTED */
625 nfslog_writeargs *args = (nfslog_writeargs *)logrec->re_rpc_arg;
626 /* LINTED */
627 nfslog_writeresult *res = (nfslog_writeresult *)logrec->re_rpc_res;
629 if (res->wr_status != NFS_OK)
630 return (NULL);
632 if ((newte = create_te()) == NULL)
633 return (NULL);
635 if (!path1) {
636 newte->pathname = nfslog_get_path(&args->waargs_fhandle,
637 NULL, fhpath, "trans_write");
638 } else {
639 newte->pathname = strdup(path1);
642 newte->starttime = logrec->re_header.rh_timestamp;
643 newte->lastupdate = logrec->re_header.rh_timestamp;
644 newte->optype = TRANS_OPER_WRITE;
645 newte->datatype = TRANS_DATATYPE_BINARY;
646 newte->transoption = TRANS_OPTION_NOACTION;
647 newte->pnb = netbufdup(&(logrec->re_ipaddr));
648 newte->uid = logrec->re_header.rh_uid;
649 newte->nfsvers = NFS_VERSION;
650 newte->netid = strdup(logrec->re_netid);
651 if (logrec->re_principal_name)
652 newte->principal_name = strdup(logrec->re_principal_name);
653 else
654 newte->principal_name = NULL;
655 newte->totalbytes = args->waargs_totcount;
656 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->waargs_fhandle));
658 if (pte = insert_te(tf->te_list_v2_write, newte)) {
660 * if the write would have increased the total byte count
661 * over the filesize, then generate a log entry and remove
662 * the write record and insert the new one.
664 if (pte->totalbytes + args->waargs_totcount >
665 res->nfslog_writeresult_u.wr_size) {
666 nfslog_print_trans_logentry(pte, tf);
667 remove_te(pte);
668 (void) insert_te(tf->te_list_v2_write, newte);
669 pte = NULL;
670 } else {
671 /* free this since entry was found (not inserted) */
672 remove_te(newte);
674 pte->totalbytes += args->waargs_totcount;
676 if (pte->lastupdate.tv_sec <=
677 logrec->re_header.rh_timestamp.tv_sec) {
678 pte->lastupdate =
679 logrec->re_header.rh_timestamp;
681 pte = NULL; /* prevent printing of log entry */
684 return (pte);
687 static struct transentry *
688 trans_setattr(
689 nfslog_request_record *logrec,
690 struct nfslog_trans_file *tf,
691 char *fhpath,
692 char *path1)
694 struct transentry *newte;
695 struct transentry *pte = NULL;
696 /* LINTED */
697 nfslog_setattrargs *args = (nfslog_setattrargs *)logrec->re_rpc_arg;
698 /* LINTED */
699 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
701 if (*res != NFS_OK)
702 return (NULL);
704 if (args->saa_sa.sa_size == (uint32_t)-1)
705 return (NULL);
707 * should check the size of the file to see if it
708 * is being truncated below current eof. if so
709 * a record should be generated.... XXX
711 if (args->saa_sa.sa_size != 0)
712 return (NULL);
714 if ((newte = create_te()) == NULL)
715 return (NULL);
717 if (!path1) {
718 newte->pathname = nfslog_get_path(&args->saa_fh, NULL,
719 fhpath, "trans_setattr2");
720 } else {
721 newte->pathname = strdup(path1);
724 newte->starttime = logrec->re_header.rh_timestamp;
725 newte->lastupdate = logrec->re_header.rh_timestamp;
726 newte->optype = TRANS_OPER_SETATTR;
727 newte->datatype = TRANS_DATATYPE_BINARY;
728 newte->transoption = TRANS_OPTION_NOACTION;
729 newte->pnb = netbufdup(&(logrec->re_ipaddr));
730 newte->uid = logrec->re_header.rh_uid;
731 newte->nfsvers = NFS_VERSION;
732 newte->netid = strdup(logrec->re_netid);
733 if (logrec->re_principal_name)
734 newte->principal_name = strdup(logrec->re_principal_name);
735 else
736 newte->principal_name = NULL;
737 newte->totalbytes = 0;
738 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->saa_fh));
740 if (pte = insert_te(tf->te_list_v2_write, newte)) {
741 nfslog_print_trans_logentry(pte, tf);
742 remove_te(pte);
744 if (pte = insert_te(tf->te_list_v2_read, newte)) {
745 nfslog_print_trans_logentry(pte, tf);
746 remove_te(pte);
749 return (newte);
752 static struct transentry *
753 trans_create(
754 nfslog_request_record *logrec,
755 struct nfslog_trans_file *tf,
756 char *fhpath,
757 char *path1)
759 struct transentry *newte;
760 struct transentry *pte = NULL;
761 /* LINTED */
762 nfslog_createargs *args = (nfslog_createargs *)logrec->re_rpc_arg;
763 /* LINTED */
764 nfslog_diropres *res = (nfslog_diropres *)logrec->re_rpc_res;
766 if (res->dr_status != NFS_OK)
767 return (NULL);
769 if ((newte = create_te()) == NULL)
770 return (NULL);
772 if (!path1) {
773 newte->pathname =
774 nfslog_get_path(&args->ca_da.da_fhandle,
775 args->ca_da.da_name,
776 fhpath, "trans_create2");
777 } else {
778 newte->pathname = strdup(path1);
781 newte->starttime = logrec->re_header.rh_timestamp;
782 newte->lastupdate = logrec->re_header.rh_timestamp;
783 newte->optype = TRANS_OPER_CREATE;
784 newte->datatype = TRANS_DATATYPE_BINARY;
785 newte->transoption = TRANS_OPTION_NOACTION;
786 newte->pnb = netbufdup(&(logrec->re_ipaddr));
787 newte->uid = logrec->re_header.rh_uid;
788 newte->nfsvers = NFS_VERSION;
789 newte->netid = strdup(logrec->re_netid);
790 if (logrec->re_principal_name)
791 newte->principal_name = strdup(logrec->re_principal_name);
792 else
793 newte->principal_name = NULL;
795 if (args->ca_sa.sa_size == (uint32_t)-1)
796 newte->totalbytes = 0;
797 else
798 newte->totalbytes = args->ca_sa.sa_size;
800 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(
801 &res->nfslog_diropres_u.dr_ok.drok_fhandle));
804 * if the file is being truncated on create, we need to flush
805 * any outstanding read/write transactions
807 if (args->ca_sa.sa_size != (uint32_t)-1) {
808 if (pte = insert_te(tf->te_list_v2_write, newte)) {
809 nfslog_print_trans_logentry(pte, tf);
810 remove_te(pte);
812 if (pte = insert_te(tf->te_list_v2_read, newte)) {
813 nfslog_print_trans_logentry(pte, tf);
814 remove_te(pte);
818 return (newte);
821 static struct transentry *
822 trans_remove(
823 nfslog_request_record *logrec,
824 struct nfslog_trans_file *tf,
825 char *fhpath,
826 char *path1)
828 struct transentry *newte;
829 struct transentry *pte = NULL;
830 /* LINTED */
831 nfslog_diropargs *args = (nfslog_diropargs *)logrec->re_rpc_arg;
832 /* LINTED */
833 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
835 if (*res != NFS_OK)
836 return (NULL);
838 if ((newte = create_te()) == NULL)
839 return (NULL);
841 if (!path1) {
842 char *name = args->da_name;
843 fhandle_t *dfh = &args->da_fhandle;
844 newte->pathname = nfslog_get_path(dfh, name,
845 fhpath, "trans_remove2");
846 } else {
847 newte->pathname = strdup(path1);
850 newte->starttime = logrec->re_header.rh_timestamp;
851 newte->lastupdate = logrec->re_header.rh_timestamp;
852 newte->optype = TRANS_OPER_REMOVE;
853 newte->datatype = TRANS_DATATYPE_BINARY;
854 newte->transoption = TRANS_OPTION_NOACTION;
855 newte->pnb = netbufdup(&(logrec->re_ipaddr));
856 newte->uid = logrec->re_header.rh_uid;
857 newte->nfsvers = NFS_VERSION;
858 newte->netid = strdup(logrec->re_netid);
859 if (logrec->re_principal_name)
860 newte->principal_name = strdup(logrec->re_principal_name);
861 else
862 newte->principal_name = NULL;
863 newte->totalbytes = 0;
864 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->da_fhandle));
866 if (pte = insert_te(tf->te_list_v2_write, newte)) {
867 nfslog_print_trans_logentry(pte, tf);
868 remove_te(pte);
870 if (pte = insert_te(tf->te_list_v2_read, newte)) {
871 nfslog_print_trans_logentry(pte, tf);
872 remove_te(pte);
874 if (pte = insert_te(tf->te_list_v3_write, newte)) {
875 nfslog_print_trans_logentry(pte, tf);
876 remove_te(pte);
878 if (pte = insert_te(tf->te_list_v3_read, newte)) {
879 nfslog_print_trans_logentry(pte, tf);
880 remove_te(pte);
883 return (newte);
886 static struct transentry *
887 trans_mkdir(
888 nfslog_request_record *logrec,
889 char *fhpath,
890 char *path1)
892 struct transentry *newte;
893 /* LINTED */
894 nfslog_createargs *args = (nfslog_createargs *)logrec->re_rpc_arg;
895 /* LINTED */
896 nfslog_diropres *res = (nfslog_diropres *)logrec->re_rpc_res;
898 if (res->dr_status != NFS_OK)
899 return (NULL);
901 if ((newte = create_te()) == NULL)
902 return (NULL);
904 if (!path1) {
905 nfslog_diropargs *dargs = &args->ca_da;
906 char *name = dargs->da_name;
907 fhandle_t *dfh = &dargs->da_fhandle;
908 newte->pathname = nfslog_get_path(dfh, name,
909 fhpath, "trans_mkdir2");
910 } else {
911 newte->pathname = strdup(path1);
914 newte->starttime = logrec->re_header.rh_timestamp;
915 newte->lastupdate = logrec->re_header.rh_timestamp;
916 newte->optype = TRANS_OPER_MKDIR;
917 newte->datatype = TRANS_DATATYPE_BINARY;
918 newte->transoption = TRANS_OPTION_NOACTION;
919 newte->pnb = netbufdup(&(logrec->re_ipaddr));
920 newte->uid = logrec->re_header.rh_uid;
921 newte->nfsvers = NFS_VERSION;
922 newte->netid = strdup(logrec->re_netid);
923 if (logrec->re_principal_name)
924 newte->principal_name = strdup(logrec->re_principal_name);
925 else
926 newte->principal_name = NULL;
927 newte->totalbytes = 0;
928 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->ca_da.da_fhandle));
930 return (newte);
933 static struct transentry *
934 trans_rmdir(
935 nfslog_request_record *logrec,
936 char *fhpath,
937 char *path1)
939 struct transentry *newte;
940 /* LINTED */
941 nfslog_diropargs *args = (nfslog_diropargs *)logrec->re_rpc_arg;
942 /* LINTED */
943 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
945 if (*res != NFS_OK)
946 return (NULL);
948 if ((newte = create_te()) == NULL)
949 return (NULL);
951 if (!path1) {
952 char *name = args->da_name;
953 fhandle_t *dfh = &args->da_fhandle;
954 newte->pathname = nfslog_get_path(dfh, name,
955 fhpath, "trans_rmdir2");
956 } else {
957 newte->pathname = strdup(path1);
960 newte->starttime = logrec->re_header.rh_timestamp;
961 newte->lastupdate = logrec->re_header.rh_timestamp;
962 newte->optype = TRANS_OPER_RMDIR;
963 newte->datatype = TRANS_DATATYPE_BINARY;
964 newte->transoption = TRANS_OPTION_NOACTION;
965 newte->pnb = netbufdup(&(logrec->re_ipaddr));
966 newte->uid = logrec->re_header.rh_uid;
967 newte->nfsvers = NFS_VERSION;
968 newte->netid = strdup(logrec->re_netid);
969 if (logrec->re_principal_name)
970 newte->principal_name = strdup(logrec->re_principal_name);
971 else
972 newte->principal_name = NULL;
973 newte->totalbytes = 0;
974 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->da_fhandle));
976 return (newte);
979 static struct transentry *
980 trans_rename(
981 nfslog_request_record *logrec,
982 struct nfslog_trans_file *tf,
983 char *fhpath,
984 char *path1,
985 char *path2)
987 struct transentry *newte;
988 struct transentry *pte = NULL;
989 /* LINTED */
990 nfslog_rnmargs *args = (nfslog_rnmargs *)logrec->re_rpc_arg;
991 /* LINTED */
992 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
993 char *tpath1 = NULL;
994 char *tpath2 = NULL;
996 if (*res != NFS_OK)
997 return (NULL);
999 if ((newte = create_te()) == NULL)
1000 return (NULL);
1002 if (!path1) {
1003 char *from_name, *to_name;
1004 fhandle_t *from_dfh, *to_dfh;
1006 from_name = args->rna_from.da_name;
1007 from_dfh = &args->rna_from.da_fhandle;
1008 to_name = args->rna_to.da_name;
1009 to_dfh = &args->rna_to.da_fhandle;
1011 path1 = tpath1 = nfslog_get_path(from_dfh, from_name,
1012 fhpath, "trans_rename from");
1013 path2 = tpath2 = nfslog_get_path(to_dfh, to_name,
1014 fhpath, "trans_rename to");
1017 newte->pathname = path1; /* no need to strdup here */
1018 newte->starttime = logrec->re_header.rh_timestamp;
1019 newte->lastupdate = logrec->re_header.rh_timestamp;
1020 newte->optype = TRANS_OPER_RENAME;
1021 newte->datatype = TRANS_DATATYPE_BINARY;
1022 newte->transoption = TRANS_OPTION_NOACTION;
1023 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1024 newte->uid = logrec->re_header.rh_uid;
1025 newte->nfsvers = NFS_VERSION;
1026 newte->netid = strdup(logrec->re_netid);
1027 if (logrec->re_principal_name)
1028 newte->principal_name = strdup(logrec->re_principal_name);
1029 else
1030 newte->principal_name = NULL;
1031 newte->totalbytes = 0;
1032 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->rna_from.da_fhandle));
1034 /* switch path names for the file for renames */
1035 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1036 free(pte->pathname);
1037 pte->pathname = strdup(path2);
1039 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1040 free(pte->pathname);
1041 pte->pathname = strdup(path2);
1043 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1044 free(pte->pathname);
1045 pte->pathname = strdup(path2);
1047 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1048 free(pte->pathname);
1049 pte->pathname = strdup(path2);
1052 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1053 /* check for NULL malloc */
1054 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1056 if (tpath1) {
1057 free(tpath1);
1058 free(tpath2);
1061 return (newte);
1064 static struct transentry *
1065 trans_link(
1066 nfslog_request_record *logrec,
1067 char *fhpath,
1068 char *path1,
1069 char *path2)
1071 struct transentry *newte;
1072 /* LINTED */
1073 nfslog_linkargs *args = (nfslog_linkargs *)logrec->re_rpc_arg;
1074 /* LINTED */
1075 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
1076 char *tpath1 = NULL;
1077 char *tpath2 = NULL;
1079 if (*res != NFS_OK)
1080 return (NULL);
1082 if ((newte = create_te()) == NULL)
1083 return (NULL);
1085 if (!path1) {
1086 fhandle_t *fh = &args->la_from;
1087 char *name = args->la_to.da_name;
1088 fhandle_t *dfh = &args->la_to.da_fhandle;
1090 path1 = tpath1 = nfslog_get_path(fh, NULL,
1091 fhpath, "trans_link from");
1092 path2 = tpath2 = nfslog_get_path(dfh, name,
1093 fhpath, "trans_link to");
1096 newte->starttime = logrec->re_header.rh_timestamp;
1097 newte->lastupdate = logrec->re_header.rh_timestamp;
1098 newte->optype = TRANS_OPER_LINK;
1099 newte->datatype = TRANS_DATATYPE_BINARY;
1100 newte->transoption = TRANS_OPTION_NOACTION;
1101 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1102 newte->uid = logrec->re_header.rh_uid;
1103 newte->nfsvers = NFS_VERSION;
1104 newte->netid = strdup(logrec->re_netid);
1105 if (logrec->re_principal_name)
1106 newte->principal_name = strdup(logrec->re_principal_name);
1107 else
1108 newte->principal_name = NULL;
1109 newte->totalbytes = 0;
1110 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->la_from));
1112 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1113 /* check for NULL malloc */
1114 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1116 if (tpath1) {
1117 free(tpath1);
1118 free(tpath2);
1121 return (newte);
1124 static struct transentry *
1125 trans_symlink(
1126 nfslog_request_record *logrec,
1127 char *fhpath,
1128 char *path1)
1130 struct transentry *newte;
1131 /* LINTED */
1132 nfslog_symlinkargs *args = (nfslog_symlinkargs *)logrec->re_rpc_arg;
1133 /* LINTED */
1134 nfsstat *res = (nfsstat *)logrec->re_rpc_res;
1135 char *tpath1 = NULL;
1137 if (*res != NFS_OK)
1138 return (NULL);
1140 if ((newte = create_te()) == NULL)
1141 return (NULL);
1143 if (!path1) {
1144 char *name = args->sla_from.da_name;
1145 fhandle_t *dfh = &args->sla_from.da_fhandle;
1147 path1 = tpath1 = nfslog_get_path(dfh, name,
1148 fhpath, "trans_symlink");
1151 newte->starttime = logrec->re_header.rh_timestamp;
1152 newte->lastupdate = logrec->re_header.rh_timestamp;
1153 newte->optype = TRANS_OPER_SYMLINK;
1154 newte->datatype = TRANS_DATATYPE_BINARY;
1155 newte->transoption = TRANS_OPTION_NOACTION;
1156 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1157 newte->uid = logrec->re_header.rh_uid;
1158 newte->nfsvers = NFS_VERSION;
1159 newte->netid = strdup(logrec->re_netid);
1160 if (logrec->re_principal_name)
1161 newte->principal_name = strdup(logrec->re_principal_name);
1162 else
1163 newte->principal_name = NULL;
1164 newte->totalbytes = 0;
1165 newte->fh_u.fh = *(NFSLOG_GET_FHANDLE2(&args->sla_from.da_fhandle));
1167 newte->pathname = (char *)malloc(strlen(path1) +
1168 strlen(args->sla_tnm) + 3);
1169 (void) sprintf(newte->pathname, "%s->%s", path1, args->sla_tnm);
1171 free(tpath1);
1173 return (newte);
1176 static struct transentry *
1177 trans_read3(
1178 nfslog_request_record *logrec,
1179 struct nfslog_trans_file *tf,
1180 char *fhpath,
1181 char *path1)
1183 struct transentry *newte;
1184 struct transentry *pte = NULL;
1185 /* LINTED */
1186 nfslog_READ3args *args = (nfslog_READ3args *)logrec->re_rpc_arg;
1187 /* LINTED */
1188 nfslog_READ3res *res = (nfslog_READ3res *)logrec->re_rpc_res;
1190 if (res->status != NFS3_OK)
1191 return (NULL);
1193 if ((newte = create_te()) == NULL)
1194 return (NULL);
1196 if (!path1) {
1197 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->file);
1198 newte->pathname = nfslog_get_path(fh, NULL,
1199 fhpath, "trans_read3");
1200 } else {
1201 newte->pathname = strdup(path1);
1204 /* prep the struct for insertion */
1205 newte->starttime = logrec->re_header.rh_timestamp;
1206 newte->lastupdate = logrec->re_header.rh_timestamp;
1207 newte->optype = TRANS_OPER_READ;
1208 newte->datatype = TRANS_DATATYPE_BINARY;
1209 newte->transoption = TRANS_OPTION_NOACTION;
1210 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1211 newte->uid = logrec->re_header.rh_uid;
1212 newte->nfsvers = NFS_V3;
1213 newte->netid = strdup(logrec->re_netid);
1214 if (logrec->re_principal_name)
1215 newte->principal_name = strdup(logrec->re_principal_name);
1216 else
1217 newte->principal_name = NULL;
1218 newte->totalbytes = res->nfslog_READ3res_u.ok.count;
1219 newte->fh_u.fh3 = args->file;
1221 if (res->nfslog_READ3res_u.ok.count <
1222 res->nfslog_READ3res_u.ok.filesize) {
1223 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1224 /* free this since entry was found (not inserted) */
1225 remove_te(newte);
1227 pte->totalbytes += res->nfslog_READ3res_u.ok.count;
1229 if (pte->lastupdate.tv_sec <=
1230 logrec->re_header.rh_timestamp.tv_sec)
1231 pte->lastupdate =
1232 logrec->re_header.rh_timestamp;
1234 if (pte->totalbytes <
1235 res->nfslog_READ3res_u.ok.filesize) {
1236 pte = NULL; /* prevent printing of log entry */
1239 } else {
1240 pte = newte; /* print a log record - complete file read */
1243 return (pte);
1246 static struct transentry *
1247 trans_write3(
1248 nfslog_request_record *logrec,
1249 struct nfslog_trans_file *tf,
1250 char *fhpath,
1251 char *path1)
1253 struct transentry *newte;
1254 struct transentry *pte = NULL;
1255 /* LINTED */
1256 nfslog_WRITE3args *args = (nfslog_WRITE3args *)logrec->re_rpc_arg;
1257 /* LINTED */
1258 nfslog_WRITE3res *res = (nfslog_WRITE3res *)logrec->re_rpc_res;
1260 if (res->status != NFS3_OK)
1261 return (NULL);
1263 if ((newte = create_te()) == NULL)
1264 return (NULL);
1266 if (!path1) {
1267 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->file);
1268 newte->pathname = nfslog_get_path(fh, NULL,
1269 fhpath, "trans_write3");
1270 } else {
1271 newte->pathname = strdup(path1);
1274 newte->starttime = logrec->re_header.rh_timestamp;
1275 newte->lastupdate = logrec->re_header.rh_timestamp;
1276 newte->optype = TRANS_OPER_WRITE;
1277 newte->datatype = TRANS_DATATYPE_BINARY;
1278 newte->transoption = TRANS_OPTION_NOACTION;
1279 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1280 newte->uid = logrec->re_header.rh_uid;
1281 newte->nfsvers = NFS_V3;
1282 newte->netid = strdup(logrec->re_netid);
1283 if (logrec->re_principal_name)
1284 newte->principal_name = strdup(logrec->re_principal_name);
1285 else
1286 newte->principal_name = NULL;
1287 newte->totalbytes = res->nfslog_WRITE3res_u.ok.count;
1288 newte->fh_u.fh3 = args->file;
1290 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1292 * if the write would have increased the total byte count
1293 * over the filesize, then generate a log entry and remove
1294 * the write record and insert the new one.
1296 if (pte->totalbytes + res->nfslog_WRITE3res_u.ok.count >
1297 res->nfslog_WRITE3res_u.ok.filesize) {
1298 nfslog_print_trans_logentry(pte, tf);
1299 remove_te(pte);
1300 (void) insert_te(tf->te_list_v3_write, newte);
1301 pte = NULL;
1302 } else {
1303 /* free this since entry was found (not inserted) */
1304 remove_te(newte);
1306 pte->totalbytes += res->nfslog_WRITE3res_u.ok.count;
1308 if (pte->lastupdate.tv_sec <=
1309 logrec->re_header.rh_timestamp.tv_sec) {
1310 pte->lastupdate =
1311 logrec->re_header.rh_timestamp;
1313 pte = NULL; /* prevent printing of log entry */
1316 return (pte);
1319 static struct transentry *
1320 trans_setattr3(
1321 nfslog_request_record *logrec,
1322 struct nfslog_trans_file *tf,
1323 char *fhpath,
1324 char *path1)
1326 struct transentry *newte;
1327 struct transentry *pte = NULL;
1328 /* LINTED */
1329 nfslog_SETATTR3args *args = (nfslog_SETATTR3args *)logrec->re_rpc_arg;
1330 /* LINTED */
1331 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1333 if (*res != NFS3_OK)
1334 return (NULL);
1336 if (!args->size.set_it)
1337 return (NULL);
1339 * should check the size of the file to see if it
1340 * is being truncated below current eof. if so
1341 * a record should be generated.... XXX
1343 if (args->size.size != 0)
1344 return (NULL);
1346 if ((newte = create_te()) == NULL)
1347 return (NULL);
1349 if (!path1) {
1350 fhandle_t *fh = NFSLOG_GET_FHANDLE3(&args->object);
1351 newte->pathname = nfslog_get_path(fh, NULL,
1352 fhpath, "trans_setattr3");
1353 } else {
1354 newte->pathname = strdup(path1);
1357 newte->starttime = logrec->re_header.rh_timestamp;
1358 newte->lastupdate = logrec->re_header.rh_timestamp;
1359 newte->optype = TRANS_OPER_SETATTR;
1360 newte->datatype = TRANS_DATATYPE_BINARY;
1361 newte->transoption = TRANS_OPTION_NOACTION;
1362 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1363 newte->uid = logrec->re_header.rh_uid;
1364 newte->nfsvers = NFS_V3;
1365 newte->netid = strdup(logrec->re_netid);
1366 if (logrec->re_principal_name)
1367 newte->principal_name = strdup(logrec->re_principal_name);
1368 else
1369 newte->principal_name = NULL;
1370 newte->totalbytes = 0;
1371 newte->fh_u.fh3 = args->object;
1373 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1374 nfslog_print_trans_logentry(pte, tf);
1375 remove_te(pte);
1377 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1378 nfslog_print_trans_logentry(pte, tf);
1379 remove_te(pte);
1382 return (newte);
1385 static struct transentry *
1386 trans_create3(
1387 nfslog_request_record *logrec,
1388 struct nfslog_trans_file *tf,
1389 char *fhpath,
1390 char *path1)
1392 struct transentry *newte;
1393 struct transentry *pte = NULL;
1394 /* LINTED */
1395 nfslog_CREATE3args *args = (nfslog_CREATE3args *)logrec->re_rpc_arg;
1396 /* LINTED */
1397 nfslog_CREATE3res *res = (nfslog_CREATE3res *)logrec->re_rpc_res;
1399 if (res->status != NFS3_OK)
1400 return (NULL);
1402 if ((newte = create_te()) == NULL)
1403 return (NULL);
1405 if (!path1) {
1406 newte->pathname =
1407 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1408 args->where.name,
1409 fhpath, "trans_create3");
1410 } else {
1411 newte->pathname = strdup(path1);
1414 newte->starttime = logrec->re_header.rh_timestamp;
1415 newte->lastupdate = logrec->re_header.rh_timestamp;
1416 newte->optype = TRANS_OPER_CREATE;
1417 newte->datatype = TRANS_DATATYPE_BINARY;
1418 newte->transoption = TRANS_OPTION_NOACTION;
1419 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1420 newte->uid = logrec->re_header.rh_uid;
1421 newte->nfsvers = NFS_V3;
1422 newte->netid = strdup(logrec->re_netid);
1423 if (logrec->re_principal_name)
1424 newte->principal_name = strdup(logrec->re_principal_name);
1425 else
1426 newte->principal_name = NULL;
1428 if (!args->how.nfslog_createhow3_u.size.set_it)
1429 newte->totalbytes = 0;
1430 else
1431 newte->totalbytes =
1432 args->how.nfslog_createhow3_u.size.size;
1434 newte->fh_u.fh3 = args->where.dir;
1436 if (args->how.nfslog_createhow3_u.size.set_it) {
1437 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1438 nfslog_print_trans_logentry(pte, tf);
1439 remove_te(pte);
1441 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1442 nfslog_print_trans_logentry(pte, tf);
1443 remove_te(pte);
1447 return (newte);
1450 static struct transentry *
1451 trans_remove3(
1452 nfslog_request_record *logrec,
1453 struct nfslog_trans_file *tf,
1454 char *fhpath,
1455 char *path1)
1457 struct transentry *newte;
1458 struct transentry *pte = NULL;
1459 /* LINTED */
1460 nfslog_REMOVE3args *args = (nfslog_REMOVE3args *)logrec->re_rpc_arg;
1461 /* LINTED */
1462 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1464 if (*res != NFS3_OK)
1465 return (NULL);
1467 if ((newte = create_te()) == NULL)
1468 return (NULL);
1470 if (!path1) {
1471 newte->pathname =
1472 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object.dir),
1473 args->object.name,
1474 fhpath, "trans_remove3");
1475 } else {
1476 newte->pathname = strdup(path1);
1479 newte->starttime = logrec->re_header.rh_timestamp;
1480 newte->lastupdate = logrec->re_header.rh_timestamp;
1481 newte->optype = TRANS_OPER_REMOVE;
1482 newte->datatype = TRANS_DATATYPE_BINARY;
1483 newte->transoption = TRANS_OPTION_NOACTION;
1484 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1485 newte->uid = logrec->re_header.rh_uid;
1486 newte->nfsvers = NFS_V3;
1487 newte->netid = strdup(logrec->re_netid);
1488 if (logrec->re_principal_name)
1489 newte->principal_name = strdup(logrec->re_principal_name);
1490 else
1491 newte->principal_name = NULL;
1492 newte->totalbytes = 0;
1493 newte->fh_u.fh3 = args->object.dir;
1495 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1496 nfslog_print_trans_logentry(pte, tf);
1497 remove_te(pte);
1499 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1500 nfslog_print_trans_logentry(pte, tf);
1501 remove_te(pte);
1503 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1504 nfslog_print_trans_logentry(pte, tf);
1505 remove_te(pte);
1507 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1508 nfslog_print_trans_logentry(pte, tf);
1509 remove_te(pte);
1512 return (newte);
1515 static struct transentry *
1516 trans_mkdir3(
1517 nfslog_request_record *logrec,
1518 char *fhpath,
1519 char *path1)
1521 struct transentry *newte;
1522 /* LINTED */
1523 nfslog_MKDIR3args *args = (nfslog_MKDIR3args *)logrec->re_rpc_arg;
1524 /* LINTED */
1525 nfslog_MKDIR3res *res = (nfslog_MKDIR3res *)logrec->re_rpc_res;
1527 if (res->status != NFS3_OK)
1528 return (NULL);
1530 if ((newte = create_te()) == NULL)
1531 return (NULL);
1533 if (!path1) {
1534 newte->pathname =
1535 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1536 args->where.name,
1537 fhpath, "trans_mkdir3");
1538 } else {
1539 newte->pathname = strdup(path1);
1542 newte->starttime = logrec->re_header.rh_timestamp;
1543 newte->lastupdate = logrec->re_header.rh_timestamp;
1544 newte->optype = TRANS_OPER_MKDIR;
1545 newte->datatype = TRANS_DATATYPE_BINARY;
1546 newte->transoption = TRANS_OPTION_NOACTION;
1547 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1548 newte->uid = logrec->re_header.rh_uid;
1549 newte->nfsvers = NFS_V3;
1550 newte->netid = strdup(logrec->re_netid);
1551 if (logrec->re_principal_name)
1552 newte->principal_name = strdup(logrec->re_principal_name);
1553 else
1554 newte->principal_name = NULL;
1555 newte->totalbytes = 0;
1556 newte->fh_u.fh3 = args->where.dir;
1558 return (newte);
1561 static struct transentry *
1562 trans_rmdir3(
1563 nfslog_request_record *logrec,
1564 char *fhpath,
1565 char *path1)
1567 struct transentry *newte;
1568 /* LINTED */
1569 nfslog_RMDIR3args *args = (nfslog_RMDIR3args *)logrec->re_rpc_arg;
1570 /* LINTED */
1571 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1573 if (*res != NFS3_OK)
1574 return (NULL);
1576 if ((newte = create_te()) == NULL)
1577 return (NULL);
1579 if (!path1) {
1580 newte->pathname =
1581 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->object.dir),
1582 args->object.name,
1583 fhpath, "trans_rmdir3");
1584 } else {
1585 newte->pathname = strdup(path1);
1588 newte->starttime = logrec->re_header.rh_timestamp;
1589 newte->lastupdate = logrec->re_header.rh_timestamp;
1590 newte->optype = TRANS_OPER_RMDIR;
1591 newte->datatype = TRANS_DATATYPE_BINARY;
1592 newte->transoption = TRANS_OPTION_NOACTION;
1593 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1594 newte->uid = logrec->re_header.rh_uid;
1595 newte->nfsvers = NFS_V3;
1596 newte->netid = strdup(logrec->re_netid);
1597 if (logrec->re_principal_name)
1598 newte->principal_name = strdup(logrec->re_principal_name);
1599 else
1600 newte->principal_name = NULL;
1601 newte->totalbytes = 0;
1602 newte->fh_u.fh3 = args->object.dir;
1604 return (newte);
1607 static struct transentry *
1608 trans_rename3(
1609 nfslog_request_record *logrec,
1610 struct nfslog_trans_file *tf,
1611 char *fhpath,
1612 char *path1,
1613 char *path2)
1615 struct transentry *newte;
1616 struct transentry *pte = NULL;
1617 /* LINTED */
1618 nfslog_RENAME3args *args = (nfslog_RENAME3args *)logrec->re_rpc_arg;
1619 /* LINTED */
1620 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1621 char *tpath1 = NULL;
1622 char *tpath2 = NULL;
1624 if (*res != NFS3_OK)
1625 return (NULL);
1627 if ((newte = create_te()) == NULL)
1628 return (NULL);
1630 if (!path1) {
1631 path1 = tpath1 =
1632 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->from.dir),
1633 args->from.name, fhpath, "trans_rename3 from");
1634 path2 = tpath2 =
1635 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->to.dir),
1636 args->to.name, fhpath, "trans_rename3 to");
1639 newte->pathname = path1; /* no need to strdup here */
1640 newte->starttime = logrec->re_header.rh_timestamp;
1641 newte->lastupdate = logrec->re_header.rh_timestamp;
1642 newte->optype = TRANS_OPER_RENAME;
1643 newte->datatype = TRANS_DATATYPE_BINARY;
1644 newte->transoption = TRANS_OPTION_NOACTION;
1645 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1646 newte->uid = logrec->re_header.rh_uid;
1647 newte->nfsvers = NFS_V3;
1648 newte->netid = strdup(logrec->re_netid);
1649 if (logrec->re_principal_name)
1650 newte->principal_name = strdup(logrec->re_principal_name);
1651 else
1652 newte->principal_name = NULL;
1653 newte->totalbytes = 0;
1654 newte->fh_u.fh3 = args->from.dir;
1656 /* switch path names for the file for renames */
1657 if (pte = insert_te(tf->te_list_v3_write, newte)) {
1658 free(pte->pathname);
1659 pte->pathname = strdup(path2);
1661 if (pte = insert_te(tf->te_list_v3_read, newte)) {
1662 free(pte->pathname);
1663 pte->pathname = strdup(path2);
1665 if (pte = insert_te(tf->te_list_v2_write, newte)) {
1666 free(pte->pathname);
1667 pte->pathname = strdup(path2);
1669 if (pte = insert_te(tf->te_list_v2_read, newte)) {
1670 free(pte->pathname);
1671 pte->pathname = strdup(path2);
1674 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1675 /* check for NULL malloc */
1676 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1678 if (tpath1) {
1679 free(tpath1);
1680 free(tpath2);
1683 return (newte);
1686 static struct transentry *
1687 trans_mknod3(
1688 nfslog_request_record *logrec,
1689 char *fhpath,
1690 char *path1)
1692 struct transentry *newte;
1693 /* LINTED */
1694 nfslog_MKNOD3args *args = (nfslog_MKNOD3args *)logrec->re_rpc_arg;
1695 /* LINTED */
1696 nfslog_MKNOD3res *res = (nfslog_MKNOD3res *)logrec->re_rpc_res;
1698 if (res->status != NFS3_OK)
1699 return (NULL);
1701 if ((newte = create_te()) == NULL)
1702 return (NULL);
1704 if (!path1) {
1705 newte->pathname =
1706 nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1707 args->where.name,
1708 fhpath, "trans_mknod3");
1709 } else {
1710 newte->pathname = strdup(path1);
1713 newte->starttime = logrec->re_header.rh_timestamp;
1714 newte->lastupdate = logrec->re_header.rh_timestamp;
1715 newte->optype = TRANS_OPER_MKNOD;
1716 newte->datatype = TRANS_DATATYPE_BINARY;
1717 newte->transoption = TRANS_OPTION_NOACTION;
1718 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1719 newte->uid = logrec->re_header.rh_uid;
1720 newte->nfsvers = NFS_V3;
1721 newte->netid = strdup(logrec->re_netid);
1722 if (logrec->re_principal_name)
1723 newte->principal_name = strdup(logrec->re_principal_name);
1724 else
1725 newte->principal_name = NULL;
1727 newte->totalbytes = 0;
1728 newte->fh_u.fh3 = args->where.dir;
1730 return (newte);
1733 static struct transentry *
1734 trans_link3(
1735 nfslog_request_record *logrec,
1736 char *fhpath,
1737 char *path1,
1738 char *path2)
1740 struct transentry *newte;
1741 /* LINTED */
1742 nfslog_LINK3args *args = (nfslog_LINK3args *)logrec->re_rpc_arg;
1743 /* LINTED */
1744 nfsstat3 *res = (nfsstat3 *)logrec->re_rpc_res;
1746 char *tpath1 = NULL;
1747 char *tpath2 = NULL;
1749 if (*res != NFS3_OK)
1750 return (NULL);
1752 if ((newte = create_te()) == NULL)
1753 return (NULL);
1755 if (!path1) {
1756 tpath1 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->file),
1757 NULL, fhpath, "trans_link3 from");
1758 tpath2 = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->link.dir),
1759 args->link.name, fhpath, "trans_link3 to");
1760 path1 = tpath1;
1761 path2 = tpath2;
1764 newte->starttime = logrec->re_header.rh_timestamp;
1765 newte->lastupdate = logrec->re_header.rh_timestamp;
1766 newte->optype = TRANS_OPER_LINK;
1767 newte->datatype = TRANS_DATATYPE_BINARY;
1768 newte->transoption = TRANS_OPTION_NOACTION;
1769 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1770 newte->uid = logrec->re_header.rh_uid;
1771 newte->nfsvers = NFS_V3;
1772 newte->netid = strdup(logrec->re_netid);
1773 if (logrec->re_principal_name)
1774 newte->principal_name = strdup(logrec->re_principal_name);
1775 else
1776 newte->principal_name = NULL;
1777 newte->totalbytes = 0;
1778 newte->fh_u.fh3 = args->file;
1780 newte->pathname = (char *)malloc(strlen(path1) + strlen(path2) + 3);
1781 /* check for NULL malloc */
1782 (void) sprintf(newte->pathname, "%s->%s", path1, path2);
1784 if (tpath1) {
1785 free(tpath1);
1786 free(tpath2);
1789 return (newte);
1792 static struct transentry *
1793 trans_symlink3(
1794 nfslog_request_record *logrec,
1795 char *fhpath,
1796 char *path1)
1798 struct transentry *newte;
1799 /* LINTED */
1800 nfslog_SYMLINK3args *args = (nfslog_SYMLINK3args *)logrec->re_rpc_arg;
1801 /* LINTED */
1802 nfslog_SYMLINK3res *res = (nfslog_SYMLINK3res *)logrec->re_rpc_res;
1803 char *name;
1805 if (res->status != NFS3_OK)
1806 return (NULL);
1808 if ((newte = create_te()) == NULL)
1809 return (NULL);
1811 if (path1) {
1812 name = strdup(path1);
1813 } else {
1814 name = nfslog_get_path(NFSLOG_GET_FHANDLE3(&args->where.dir),
1815 args->where.name, fhpath, "trans_symlink3");
1818 newte->starttime = logrec->re_header.rh_timestamp;
1819 newte->lastupdate = logrec->re_header.rh_timestamp;
1820 newte->optype = TRANS_OPER_SYMLINK;
1821 newte->datatype = TRANS_DATATYPE_BINARY;
1822 newte->transoption = TRANS_OPTION_NOACTION;
1823 newte->pnb = netbufdup(&(logrec->re_ipaddr));
1824 newte->uid = logrec->re_header.rh_uid;
1825 newte->nfsvers = NFS_V3;
1826 newte->netid = strdup(logrec->re_netid);
1827 if (logrec->re_principal_name)
1828 newte->principal_name = strdup(logrec->re_principal_name);
1829 else
1830 newte->principal_name = NULL;
1831 newte->totalbytes = 0;
1832 newte->fh_u.fh3 = args->where.dir;
1834 newte->pathname = (char *)malloc(strlen(name) +
1835 strlen(args->symlink_data) + 3);
1836 /* check for NULL malloc */
1837 (void) sprintf(newte->pathname, "%s->%s", name, args->symlink_data);
1839 free(name);
1841 return (newte);
1845 * nfslog_process_trans_rec - processes the record in the buffer and outputs
1846 * to the trans log.
1847 * Return 0 for success, errno else.
1850 nfslog_process_trans_rec(void *transcookie, nfslog_request_record *logrec,
1851 char *fhpath, char *path1, char *path2)
1853 struct transentry *pte = NULL;
1854 struct nfslog_trans_file *tf = (struct nfslog_trans_file *)transcookie;
1856 /* ignore programs other than nfs */
1857 if (logrec->re_header.rh_prognum != NFS_PROGRAM)
1858 return (0);
1860 /* update the timestamp for use later in the timeout sequences */
1861 if (tf->lasttrans_timestamp.tv_sec <
1862 logrec->re_header.rh_timestamp.tv_sec)
1863 tf->lasttrans_timestamp =
1864 logrec->re_header.rh_timestamp;
1866 /* current time of this processing */
1867 tf->last_trans_read = time(0);
1869 /* ignore anything that is not a read or write */
1870 switch (logrec->re_header.rh_version) {
1871 case NFS_VERSION:
1872 switch (logrec->re_header.rh_procnum) {
1873 case RFS_READ:
1874 if (tf->trans_to_log & TRANSTOLOG_OPER_READ)
1875 pte = trans_read(logrec, tf, fhpath, path1);
1876 break;
1877 case RFS_WRITE:
1878 if (tf->trans_to_log & TRANSTOLOG_OPER_WRITE)
1879 pte = trans_write(logrec, tf, fhpath, path1);
1880 break;
1881 case RFS_SETATTR:
1882 if (tf->trans_to_log & TRANSTOLOG_OPER_SETATTR)
1883 pte = trans_setattr(logrec, tf,
1884 fhpath, path1);
1885 break;
1886 case RFS_REMOVE:
1887 if (tf->trans_to_log & TRANSTOLOG_OPER_REMOVE)
1888 pte = trans_remove(logrec, tf, fhpath, path1);
1889 break;
1890 case RFS_MKDIR:
1891 if (tf->trans_to_log & TRANSTOLOG_OPER_MKDIR)
1892 pte = trans_mkdir(logrec, fhpath, path1);
1893 break;
1894 case RFS_RMDIR:
1895 if (tf->trans_to_log & TRANSTOLOG_OPER_RMDIR)
1896 pte = trans_rmdir(logrec, fhpath, path1);
1897 break;
1898 case RFS_CREATE:
1899 if (tf->trans_to_log & TRANSTOLOG_OPER_CREATE)
1900 pte = trans_create(logrec, tf, fhpath, path1);
1901 break;
1902 case RFS_RENAME:
1903 if (tf->trans_to_log & TRANSTOLOG_OPER_RENAME)
1904 pte = trans_rename(logrec, tf,
1905 fhpath, path1, path2);
1906 break;
1907 case RFS_LINK:
1908 if (tf->trans_to_log & TRANSTOLOG_OPER_LINK)
1909 pte = trans_link(logrec, fhpath, path1, path2);
1910 break;
1911 case RFS_SYMLINK:
1912 if (tf->trans_to_log & TRANSTOLOG_OPER_SYMLINK)
1913 pte = trans_symlink(logrec, fhpath, path1);
1914 break;
1915 default:
1916 break;
1918 break;
1919 case NFS_V3:
1920 switch (logrec->re_header.rh_procnum) {
1921 case NFSPROC3_READ:
1922 if (tf->trans_to_log & TRANSTOLOG_OPER_READ)
1923 pte = trans_read3(logrec, tf, fhpath, path1);
1924 break;
1925 case NFSPROC3_WRITE:
1926 if (tf->trans_to_log & TRANSTOLOG_OPER_WRITE)
1927 pte = trans_write3(logrec, tf, fhpath, path1);
1928 break;
1929 case NFSPROC3_SETATTR:
1930 if (tf->trans_to_log & TRANSTOLOG_OPER_SETATTR)
1931 pte = trans_setattr3(logrec, tf,
1932 fhpath, path1);
1933 break;
1934 case NFSPROC3_REMOVE:
1935 if (tf->trans_to_log & TRANSTOLOG_OPER_REMOVE)
1936 pte = trans_remove3(logrec, tf,
1937 fhpath, path1);
1938 break;
1939 case NFSPROC3_MKDIR:
1940 if (tf->trans_to_log & TRANSTOLOG_OPER_MKDIR)
1941 pte = trans_mkdir3(logrec, fhpath, path1);
1942 break;
1943 case NFSPROC3_RMDIR:
1944 if (tf->trans_to_log & TRANSTOLOG_OPER_RMDIR)
1945 pte = trans_rmdir3(logrec, fhpath, path1);
1946 break;
1947 case NFSPROC3_CREATE:
1948 if (tf->trans_to_log & TRANSTOLOG_OPER_CREATE)
1949 pte = trans_create3(logrec, tf,
1950 fhpath, path1);
1951 break;
1952 case NFSPROC3_RENAME:
1953 if (tf->trans_to_log & TRANSTOLOG_OPER_RENAME)
1954 pte = trans_rename3(logrec, tf,
1955 fhpath, path1, path2);
1956 break;
1957 case NFSPROC3_MKNOD:
1958 if (tf->trans_to_log & TRANSTOLOG_OPER_MKNOD)
1959 pte = trans_mknod3(logrec, fhpath, path1);
1960 break;
1961 case NFSPROC3_LINK:
1962 if (tf->trans_to_log & TRANSTOLOG_OPER_LINK)
1963 pte = trans_link3(logrec,
1964 fhpath, path1, path2);
1965 break;
1966 case NFSPROC3_SYMLINK:
1967 if (tf->trans_to_log & TRANSTOLOG_OPER_SYMLINK)
1968 pte = trans_symlink3(logrec, fhpath, path1);
1969 break;
1970 default:
1971 break;
1973 break;
1974 default:
1975 break;
1978 if (pte != NULL) {
1979 nfslog_print_trans_logentry(pte, tf);
1980 remove_te(pte);
1983 return (0);
1986 static void
1987 nfslog_print_trans_logentry(struct transentry *pte,
1988 struct nfslog_trans_file *tf)
1990 char *remotehost;
1991 char datatype;
1992 char transoption;
1993 char *optype;
1994 char *prin;
1995 int prinid;
1996 char nfs_ident[32];
1998 remotehost = addrtoname(pte->pnb->buf);
2000 datatype = (pte->datatype == TRANS_DATATYPE_BINARY ? 'b' : 'a');
2001 transoption = (pte->transoption == TRANS_OPTION_NOACTION ? '_' : '?');
2003 if (tf->trans_output_type == TRANSLOG_BASIC) {
2004 (void) strcpy(nfs_ident, "nfs");
2005 } else {
2006 (void) strcpy(nfs_ident,
2007 (pte->nfsvers == NFS_V3 ? "nfs3-" : "nfs-"));
2008 (void) strcat(nfs_ident, pte->netid);
2011 switch (pte->optype) {
2012 case TRANS_OPER_READ:
2013 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2014 "read" : "o");
2015 break;
2016 case TRANS_OPER_WRITE:
2017 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2018 "write" : "i");
2019 break;
2020 case TRANS_OPER_REMOVE:
2021 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2022 "remove" : "?");
2023 break;
2024 case TRANS_OPER_MKDIR:
2025 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2026 "mkdir" : "?");
2027 break;
2028 case TRANS_OPER_CREATE:
2029 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2030 "create" : "?");
2031 break;
2032 case TRANS_OPER_RMDIR:
2033 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2034 "rmdir" : "?");
2035 break;
2036 case TRANS_OPER_SETATTR:
2037 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2038 "setattr" : "?");
2039 break;
2040 case TRANS_OPER_RENAME:
2041 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2042 "rename" : "?");
2043 break;
2044 case TRANS_OPER_MKNOD:
2045 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2046 "mknod" : "?");
2047 break;
2048 case TRANS_OPER_LINK:
2049 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2050 "link" : "?");
2051 break;
2052 case TRANS_OPER_SYMLINK:
2053 optype = (tf->trans_output_type == TRANSLOG_EXTENDED ?
2054 "symlink" : "?");
2055 break;
2056 default:
2057 optype = "?";
2058 break;
2060 if (strcmp(pte->principal_name, "") == 0) {
2061 prinid = 0;
2062 prin = "*";
2063 } else {
2064 prinid = 1;
2065 prin = pte->principal_name;
2067 (void) fprintf(tf->fp,
2068 "%.24s %d %s %d %s %c %c %s %c %ld %s %d %s\n",
2069 ctime((time_t *)&pte->starttime.tv_sec),
2070 pte->lastupdate.tv_sec - pte->starttime.tv_sec,
2071 remotehost,
2072 (uint32_t)pte->totalbytes,
2073 pte->pathname,
2074 datatype,
2075 transoption,
2076 optype,
2077 'r', /* anonymous == 'a', guest == 'g', real == 'r'), */
2078 pte->uid,
2079 nfs_ident,
2080 /* authenticated - fill in kerb/security? */
2081 prinid,
2082 /* authenticated ? authuser : "*" */
2083 prin);