Skip to content

Instantly share code, notes, and snippets.

@mcast
Last active August 29, 2015 14:20
Show Gist options
  • Save mcast/875f50127eb3e7f6e249 to your computer and use it in GitHub Desktop.
Save mcast/875f50127eb3e7f6e249 to your computer and use it in GitHub Desktop.
Attempt to provoke hang in irodsFs (FUSE)
sendMany: sendMany.c
gcc -g -o $@ $<
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/fcntl.h>
#include <sys/sendfile.h>
/* mostly pasted from Linux manpages */
int bail(char *s, int retval) {
if (retval < 0) {
perror(s);
exit(2);
}
return retval;
}
int do_connect(char* host, char* port) {
struct addrinfo hints;
struct addrinfo *rp, *result;
int sfd, s;
/* Obtain address(es) matching host/port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
s = getaddrinfo(host, port, &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo(%s:%s): %s\n", host, port, gai_strerror(s));
exit(2);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
printf("try %s:%s...", host, port);
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE);
} else {
socklen_t len; /* input */
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
int gai;
if (gai =
getnameinfo(rp->ai_addr, rp->ai_addrlen,
hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
NI_NUMERICHOST | NI_NUMERICSERV)) {
printf(" connected to something? %s\n", gai_strerror(gai));
} else {
printf(" %s:%s\n", hbuf, sbuf);
}
}
freeaddrinfo(result);
return sfd;
}
void put_ts(void) {
struct timeval t;
struct tm lt;
char hhmmss[10];
bail("gettimeofday", gettimeofday(&t, NULL));
if (!(localtime_r(&t.tv_sec, &lt) && strftime(hhmmss, sizeof(hhmmss), "%T", &lt))) {
hhmmss[0] = '?';
hhmmss[1] = 0;
}
printf("%s.%06d: ", hhmmss, (int)t.tv_usec);
}
int main (int argc, char** argv) {
// 1st arg: connect somewhere
// Linux < 2.6.33 (that's us) needs a socket; later can be "any file"
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
if (argc < 4) {
fprintf(stderr, "Syntax: %s <host> <port> <filename>+\n", argv[0]);
return 1;
}
int i;
char header[] = "Load of files coming, all jumbled up\n";
for(i=3; i<argc; i++) {
char* path = argv[i];
int fd;
ssize_t sent;
struct stat fst;
put_ts();
int out = do_connect(argv[1], argv[2]);
bail("write", write(out, header, strlen(header)));
put_ts();
printf("open %s ...", path);
fd = bail("open", open(path, O_RDONLY | O_NONBLOCK));
bail("fstat", fstat(fd, &fst)); // result unused so far
printf(" fd %d\n", fd);
put_ts();
printf(" sendfile...");
sent = bail("sendfile", sendfile(out, fd, NULL, 4 * 1024 * 1024));
printf(" send %.3f MiB / %lu bytes\n", sent * 1.0 / 1024 / 1024, sent);
put_ts();
bail("shutdown", shutdown(out, SHUT_WR));
printf(" shutdown(%d)\n", out);
// bail("close", close(fd));
}
return 0;
}
#!/bin/sh
killall -INT socat
socat -d tcp4-listen:1234,fork,reuseaddr - > out.sink </dev/null &
watch -n1 'ls -lh out.sink; echo; netstat -nap | grep 1234'
#!/usr/bin/env perl
use strict;
use warnings;
use YAML 'Dump';
# Input was generated by
# strace -o strace.log -ff -i -q -tt -T -v -x -s 256 "$@"
#
# Figure out what's going on by whittling out junk
sub main {
my %fd; # set of interesting fd numbers
$fd{moo}='fump';
while (<>) {
my $show = 0;
if (my ($t,$ip, $fn, $args, $rc, $fn_t) =
m{^(\d\d:\d\d:\d\d\.\d+) \[ *([0-9a-f]+)\] (\w+)\((.*?)\) = (.*?)(?: <(\d+\.\d+)>)?$}) {
# ($rc,$fn_t)=('?',undef) when function didn't return
if ($fn eq 'open' && $args =~ m{/mnt/} && $rc =~ /^\d+$/) {
$show = $fd{$rc} = token();
} elsif ($fn eq 'open' && $args =~ m{/mnt/} && $rc =~ /^-\d+/) {
$show = token().'!';
} elsif ($fn eq 'sendfile') {
my ($sockfd, $infd) = $args =~ m{^(\d+), (\d+),} or die "No sockfd on $_";
$show = $fd{$sockfd} = $fd{$infd}
if $fd{$infd};
} elsif ($fn =~ m{^(fstat|recvfrom|writev)$}) {
my ($infd) = $args =~ m{^(\d+),};
$show = $fd{$infd};
} elsif ($fn eq 'shutdown') {
my ($sockfd) = $args =~ m{^(\d+),};
$show = $fd{$sockfd};
} elsif ($fn eq 'close' && $args =~ /^\d+$/) {
$show = delete $fd{$args};
}
if ($show && defined $fn_t) {
$show.='!' if $fn_t > 1.0;
}
} else {
warn "Ignored $ARGV:$.:$_";
}
if (0) {
print "$ARGV:$.:$show\n $_" if $show;
} else {
printf("%-8.8s %s", $show || '', $_);
}
} continue {
if (eof) {
print Dump({ leftover_fd => \%fd }) if keys %fd;
close ARGV;
}
}
return 0;
}
my $_tok;
sub token {
$_tok = 'tokAAA' if !$_tok;
return $_tok++;
}
exit main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment