X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Fchunker.c;h=6f81ad2b1cd9ef12cfdcf24ee2d156a3fde131cb;hb=d28952249e392eb31bc8eecc53f6c477f30c617b;hp=bbf8676653fe4f2b747b5e93d8d7a93b2196a316;hpb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;p=debian%2Famanda diff --git a/server-src/chunker.c b/server-src/chunker.c index bbf8676..6f81ad2 100644 --- a/server-src/chunker.c +++ b/server-src/chunker.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1999 University of Maryland at College Park + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -43,6 +44,7 @@ #include "util.h" #include "holding.h" #include "timestamp.h" +#include "sockaddr-util.h" #ifndef SEEK_SET #define SEEK_SET 0 @@ -96,8 +98,8 @@ static ssize_t write_tapeheader(int, dumpfile_t *); static void databuf_init(struct databuf *, int, char *, off_t, off_t); static int databuf_flush(struct databuf *); -static int startup_chunker(char *, off_t, off_t, struct databuf *, int *); -static int do_chunk(int, struct databuf *, int); +static int startup_chunker(char *, off_t, off_t, struct databuf *, int *, int *); +static int do_chunk(int, struct databuf *, int, int); /* we use a function pointer for full_write, so that we can "shim" in * full_write_with_fake_enospc for testing */ @@ -122,6 +124,7 @@ main( config_overrides_t *cfg_ovr = NULL; char *cfg_opt = NULL; char *m; + int header_socket; int data_socket; /* @@ -307,13 +310,13 @@ main( } if ((header_fd = startup_chunker(filename, use, chunksize, &db, - &data_socket)) < 0) { + &header_socket, &data_socket)) < 0) { q = quote_string(vstrallocf(_("[chunker startup failed: %s]"), errstr)); putresult(TRYAGAIN, "%s %s\n", handle, q); error("startup_chunker failed: %s", errstr); } command_in_transit = NULL; - if (header_fd >= 0 && do_chunk(header_fd, &db, data_socket)) { + if (header_fd >= 0 && do_chunk(header_fd, &db, header_socket, data_socket)) { char kb_str[NUM_STR_SIZE]; char kps_str[NUM_STR_SIZE]; double rt; @@ -430,6 +433,7 @@ startup_chunker( off_t use, off_t chunksize, struct databuf * db, + int *headersocket, int *datasocket) { int header_fd, outfd; @@ -438,6 +442,9 @@ startup_chunker( int header_socket, data_socket; int result; struct addrinfo *res; + struct addrinfo *res_addr; + sockaddr_union *addr = NULL; + sockaddr_union data_addr; header_port = 0; data_port = 0; @@ -446,10 +453,26 @@ startup_chunker( gai_strerror(result)); return -1; } - header_socket = stream_server(res->ai_family, &header_port, 0, + for (res_addr = res; res_addr != NULL; res_addr = res_addr->ai_next) { + g_debug("ra: %s\n", str_sockaddr((sockaddr_union*)res_addr->ai_addr)); + if (res_addr->ai_family == AF_INET) { + addr = (sockaddr_union *)res_addr->ai_addr; + break; + } + } + if (!addr) { + addr = (sockaddr_union *)res->ai_addr; + g_debug("addr: %s\n", str_sockaddr(addr)); + } + + header_socket = stream_server(SU_GET_FAMILY(addr), &header_port, 0, STREAM_BUFSIZE, 0); - data_socket = stream_server(res->ai_family, &data_port, 0, + data_socket = stream_server(SU_GET_FAMILY(addr), &data_port, 0, STREAM_BUFSIZE, 0); + copy_sockaddr(&data_addr, addr); + + SU_SET_PORT(&data_addr, data_port); + if (res) freeaddrinfo(res); if (header_socket < 0) { @@ -464,7 +487,7 @@ startup_chunker( return -1; } - putresult(PORT, "%d 127.0.0.1:%d\n", header_port, data_port); + putresult(PORT, "%d %s\n", header_port, str_sockaddr(&data_addr)); header_fd = stream_accept(header_socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE); @@ -475,7 +498,6 @@ startup_chunker( aclose(data_socket); return -1; } - aclose(header_socket); tmp_filename = vstralloc(filename, ".tmp", NULL); pc = strrchr(tmp_filename, '/'); @@ -505,6 +527,7 @@ startup_chunker( amfree(tmp_filename); databuf_init(db, outfd, filename, use, chunksize); db->filename_seq++; + *headersocket = header_socket; *datasocket = data_socket; return header_fd; } @@ -513,6 +536,7 @@ static int do_chunk( int header_fd, struct databuf * db, + int header_socket, int data_socket) { size_t nread; @@ -531,6 +555,8 @@ do_chunk( * chunk code will rewrite it. */ nread = full_read(header_fd, header_buf, SIZEOF(header_buf)); + aclose(header_fd); + aclose(header_socket); if (nread != sizeof(header_buf)) { if(errno != 0) { errstr = vstrallocf(_("cannot read header: %s"), strerror(errno)); @@ -568,7 +594,6 @@ do_chunk( aclose(data_socket); return 0; } - aclose(data_socket); /* * We've written the file header. Now, just write data until the @@ -579,12 +604,16 @@ do_chunk( db->datain += nread; while(db->dataout < db->datain) { if(!databuf_flush(db)) { + aclose(data_fd); + aclose(data_socket); return 0; } } } while(db->dataout < db->datain) { if(!databuf_flush(db)) { + aclose(data_fd); + aclose(data_socket); return 0; } } @@ -592,6 +621,8 @@ do_chunk( dumpsize += (off_t)1; /* count partial final KByte */ filesize += (off_t)1; } + aclose(data_fd); + aclose(data_socket); return 1; }