Skip to content

Commit b11df5d

Browse files
committed
wrappers for fcntl
Initially we are only going to log dup variants but we will eventually log fcntl locks as well.
1 parent 4e6b2b2 commit b11df5d

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

darshan-runtime/lib/darshan-posix.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ DARSHAN_FORWARD_DECL(creat64, int, (const char* path, mode_t mode));
5555
DARSHAN_FORWARD_DECL(dup, int, (int oldfd));
5656
DARSHAN_FORWARD_DECL(dup2, int, (int oldfd, int newfd));
5757
DARSHAN_FORWARD_DECL(dup3, int, (int oldfd, int newfd, int flags));
58+
DARSHAN_FORWARD_DECL(fcntl, int, (int, int, ...));
59+
DARSHAN_FORWARD_DECL(fcntl64, int, (int, int, ...));
5860
DARSHAN_FORWARD_DECL(fileno, int, (FILE *stream));
5961
DARSHAN_FORWARD_DECL(mkstemp, int, (char *template));
6062
DARSHAN_FORWARD_DECL(mkostemp, int, (char *template, int flags));
@@ -787,6 +789,85 @@ int DARSHAN_DECL(dup3)(int oldfd, int newfd, int flags)
787789
return(ret);
788790
}
789791

792+
/* wrapping fcntl is a little strange for two related reasons:
793+
* - the code can do a lot of different things based on 'cmd'
794+
* - some of those 'cmd' (not all) take a third argument
795+
*
796+
* There are some worrying notes in the documentation about calling va_args
797+
* when there's no third (variable) argument, but we observed glibc doing that
798+
* and our testing seems to indicate it's ok to do so.
799+
*
800+
* So we'll always grab the variable argument, even if it's not there, and
801+
* always pass whatever we get to the real fcntl. Then we'll figure out if the
802+
* command was something we should log or not, and update our stats accordingly
803+
*/
804+
805+
int DARSHAN_DECL(fcntl)(int fd, int cmd, ...)
806+
{
807+
int ret;
808+
double tm1, tm2;
809+
va_list arg;
810+
void *next;
811+
812+
MAP_OR_FAIL(fcntl);
813+
814+
va_start(arg, cmd);
815+
next = va_arg(arg, void*);
816+
va_end(arg);
817+
818+
tm1 = POSIX_WTIME();
819+
ret = __real_fcntl(fd, cmd, next);
820+
tm2 = POSIX_WTIME();
821+
822+
struct posix_file_record_ref *rec_ref;
823+
824+
/* some code (e.g. python) prefers (portabilty? functionality?) to
825+
* duplicate the file descriptor via fcntl instead of dup/dup2/dup3 */
826+
if (ret >= 0 && (cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC)) {
827+
POSIX_PRE_RECORD();
828+
rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash,
829+
&fd, sizeof(fd));
830+
831+
POSIX_RECORD_REFOPEN(ret, rec_ref, tm1, tm2, POSIX_DUPS);
832+
POSIX_POST_RECORD();
833+
}
834+
835+
return ret;
836+
}
837+
838+
int DARSHAN_DECL(fcntl64)(int fd, int cmd, ...)
839+
{
840+
int ret;
841+
double tm1, tm2;
842+
va_list arg;
843+
void *next;
844+
845+
MAP_OR_FAIL(fcntl64);
846+
847+
va_start(arg, cmd);
848+
next = va_arg(arg, void*);
849+
va_end(arg);
850+
851+
tm1 = POSIX_WTIME();
852+
ret = __real_fcntl64(fd, cmd, next);
853+
tm2 = POSIX_WTIME();
854+
855+
struct posix_file_record_ref *rec_ref;
856+
857+
/* this is a duplicate of code in fcntl, but when I try to break this out
858+
* into a separate 'fcntl_common' routine, POSIX_PRE_RECORD() macro cannot
859+
* find the __darshan_disabled variable, and furthermore I get weird
860+
* "failed to seek" errors. Am I going to have to make this a macro? */
861+
if (ret >= 0 && (cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC)) {
862+
POSIX_PRE_RECORD();
863+
rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash,
864+
&fd, sizeof(fd));
865+
POSIX_RECORD_REFOPEN(ret, rec_ref, tm1, tm2, POSIX_DUPS);
866+
POSIX_POST_RECORD();
867+
}
868+
869+
return ret;
870+
}
790871
int DARSHAN_DECL(fileno)(FILE *stream)
791872
{
792873
int ret;

darshan-runtime/share/ld-opts/darshan-posix-ld-opts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
--wrap=dup
99
--wrap=dup2
1010
--wrap=dup3
11+
--wrap=fcntl
12+
--wrap=fcntl64
1113
--wrap=mkstemp
1214
--wrap=mkostemp
1315
--wrap=mkstemps

0 commit comments

Comments
 (0)