📄 driverio.c
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. U.M. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: James da Silva, Systems Design and Analysis Group * Computer Science Department * University of Maryland at College Park *//* * $Id: driverio.c,v 1.92 2006/08/24 01:57:16 paddy_s Exp $ * * I/O-related functions for driver program */#include "amanda.h"#include "util.h"#include "clock.h"#include "server_util.h"#include "conffile.h"#include "diskfile.h"#include "infofile.h"#include "logfile.h"#include "token.h"#define GLOBAL /* the global variables defined here */#include "driverio.h"int nb_chunker = 0;static const char *childstr(int);voidinit_driverio(void){ dumper_t *dumper; taper = -1; for(dumper = dmptable; dumper < dmptable + MAX_DUMPERS; dumper++) { dumper->fd = -1; }}static const char *childstr( int fd){ static char buf[NUM_STR_SIZE + 32]; dumper_t *dumper; if (fd == taper) return ("taper"); for (dumper = dmptable; dumper < dmptable + MAX_DUMPERS; dumper++) { if (dumper->fd == fd) return (dumper->name); if (dumper->chunker && dumper->chunker->fd == fd) return (dumper->chunker->name); } g_snprintf(buf, SIZEOF(buf), _("unknown child (fd %d)"), fd); return (buf);}voidstartup_tape_process( char *taper_program){ int fd[2]; char **config_options; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) { error(_("taper pipe: %s"), strerror(errno)); /*NOTREACHED*/ } if(fd[0] < 0 || fd[0] >= (int)FD_SETSIZE) { error(_("taper socketpair 0: descriptor %d out of range (0 .. %d)\n"), fd[0], (int)FD_SETSIZE-1); /*NOTREACHED*/ } if(fd[1] < 0 || fd[1] >= (int)FD_SETSIZE) { error(_("taper socketpair 1: descriptor %d out of range (0 .. %d)\n"), fd[1], (int)FD_SETSIZE-1); /*NOTREACHED*/ } switch(taper_pid = fork()) { case -1: error(_("fork taper: %s"), strerror(errno)); /*NOTREACHED*/ case 0: /* child process */ aclose(fd[0]); if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1) error(_("taper dup2: %s"), strerror(errno)); config_options = get_config_options(2); config_options[0] = "taper"; config_options[1] = config_name; safe_fd(-1, 0); execve(taper_program, config_options, safe_env()); error("exec %s: %s", taper_program, strerror(errno)); /*NOTREACHED*/ default: /* parent process */ aclose(fd[1]); taper = fd[0]; taper_ev_read = NULL; }}voidstartup_dump_process( dumper_t *dumper, char *dumper_program){ int fd[2]; char **config_options; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) { error(_("%s pipe: %s"), dumper->name, strerror(errno)); /*NOTREACHED*/ } switch(dumper->pid = fork()) { case -1: error(_("fork %s: %s"), dumper->name, strerror(errno)); /*NOTREACHED*/ case 0: /* child process */ aclose(fd[0]); if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1) error(_("%s dup2: %s"), dumper->name, strerror(errno)); config_options = get_config_options(2); config_options[0] = dumper->name ? dumper->name : "dumper", config_options[1] = config_name; safe_fd(-1, 0); execve(dumper_program, config_options, safe_env()); error(_("exec %s (%s): %s"), dumper_program, dumper->name, strerror(errno)); /*NOTREACHED*/ default: /* parent process */ aclose(fd[1]); dumper->fd = fd[0]; dumper->ev_read = NULL; dumper->busy = dumper->down = 0; dumper->dp = NULL; g_fprintf(stderr,_("driver: started %s pid %u\n"), dumper->name, (unsigned)dumper->pid); fflush(stderr); }}voidstartup_dump_processes( char *dumper_program, int inparallel, char *timestamp){ int i; dumper_t *dumper; char number[NUM_STR_SIZE]; for(dumper = dmptable, i = 0; i < inparallel; dumper++, i++) { g_snprintf(number, SIZEOF(number), "%d", i); dumper->name = stralloc2("dumper", number); dumper->chunker = &chktable[i]; chktable[i].name = stralloc2("chunker", number); chktable[i].dumper = dumper; chktable[i].fd = -1; startup_dump_process(dumper, dumper_program); dumper_cmd(dumper, START, (void *)timestamp); }}voidstartup_chunk_process( chunker_t *chunker, char *chunker_program){ int fd[2]; char **config_options; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) { error(_("%s pipe: %s"), chunker->name, strerror(errno)); /*NOTREACHED*/ } switch(chunker->pid = fork()) { case -1: error(_("fork %s: %s"), chunker->name, strerror(errno)); /*NOTREACHED*/ case 0: /* child process */ aclose(fd[0]); if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1) { error(_("%s dup2: %s"), chunker->name, strerror(errno)); /*NOTREACHED*/ } config_options = get_config_options(2); config_options[0] = chunker->name ? chunker->name : "chunker", config_options[1] = config_name; safe_fd(-1, 0); execve(chunker_program, config_options, safe_env()); error(_("exec %s (%s): %s"), chunker_program, chunker->name, strerror(errno)); /*NOTREACHED*/ default: /* parent process */ aclose(fd[1]); chunker->down = 0; chunker->fd = fd[0]; chunker->ev_read = NULL; g_fprintf(stderr,_("driver: started %s pid %u\n"), chunker->name, (unsigned)chunker->pid); fflush(stderr); }}cmd_tgetresult( int fd, int show, int *result_argc, char **result_argv, int max_arg){ int arg; cmd_t t; char *line; if((line = areads(fd)) == NULL) { if(errno) { error(_("reading result from %s: %s"), childstr(fd), strerror(errno)); /*NOTREACHED*/ } *result_argc = 0; /* EOF */ } else { *result_argc = split(line, result_argv, max_arg, " "); } if(show) { g_printf(_("driver: result time %s from %s:"), walltime_str(curclock()), childstr(fd)); if(line) { for(arg = 1; arg <= *result_argc; arg++) { g_printf(" %s", result_argv[arg]); } putchar('\n'); } else { g_printf(" (eof)\n"); } fflush(stdout); } amfree(line);#ifdef DEBUG g_printf("argc = %d\n", *result_argc); for(arg = 0; arg < *result_argc; arg++) g_printf("argv[%d] = \"%s\"\n", arg, result_argv[arg]);#endif if(*result_argc < 1) return BOGUS; for(t = (cmd_t)(BOGUS+1); t < LAST_TOK; t++) if(strcmp(result_argv[1], cmdstr[t]) == 0) return t; return BOGUS;}inttaper_cmd( cmd_t cmd, void *ptr, char *destname, int level, char *datestamp){ char *cmdline = NULL; char number[NUM_STR_SIZE]; char splitsize[NUM_STR_SIZE]; char fallback_splitsize[NUM_STR_SIZE]; char *diskbuffer = NULL; disk_t *dp; char *qname; char *qdest; switch(cmd) { case START_TAPER: cmdline = vstralloc(cmdstr[cmd], " ", (char *)ptr, "\n", NULL); break; case FILE_WRITE: dp = (disk_t *) ptr; qname = quote_string(dp->name); qdest = quote_string(destname); g_snprintf(number, SIZEOF(number), "%d", level); g_snprintf(splitsize, SIZEOF(splitsize), "%lld", (long long)dp->tape_splitsize * 1024); cmdline = vstralloc(cmdstr[cmd], " ", disk2serial(dp), " ", qdest, " ", dp->host->hostname, " ", qname, " ", number, " ", datestamp, " ", splitsize, "\n", NULL); amfree(qdest); amfree(qname); break; case PORT_WRITE: dp = (disk_t *) ptr; qname = quote_string(dp->name); g_snprintf(number, SIZEOF(number), "%d", level); /* If we haven't been given a place to buffer split dumps to disk, make the argument something besides and empty string so's taper won't get confused */ if(!dp->split_diskbuffer || dp->split_diskbuffer[0] == '\0'){ diskbuffer = "NULL"; } else { diskbuffer = dp->split_diskbuffer; } g_snprintf(splitsize, SIZEOF(splitsize), "%lld", (long long)dp->tape_splitsize * 1024); g_snprintf(fallback_splitsize, SIZEOF(fallback_splitsize), "%lld", (long long)dp->fallback_splitsize * 1024); cmdline = vstralloc(cmdstr[cmd], " ", disk2serial(dp), " ", dp->host->hostname, " ", qname, " ", number, " ", datestamp, " ", splitsize, " ", diskbuffer, " ", fallback_splitsize, "\n", NULL); amfree(qname); break; case DONE: /* handle */ case FAILED: /* handle */ dp = (disk_t *) ptr; cmdline = vstralloc(cmdstr[cmd], " ", disk2serial(dp), "\n", NULL); break; case NEW_TAPE: case NO_NEW_TAPE: case QUIT: cmdline = stralloc2(cmdstr[cmd], "\n"); break; default: error(_("Don't know how to send %s command to taper"), cmdstr[cmd]); /*NOTREACHED*/ } /* * Note: cmdline already has a '\n'. */ g_printf(_("driver: send-cmd time %s to taper: %s"), walltime_str(curclock()), cmdline); fflush(stdout); if ((fullwrite(taper, cmdline, strlen(cmdline))) < 0) { g_printf(_("writing taper command '%s' failed: %s\n"), cmdline, strerror(errno)); fflush(stdout); amfree(cmdline); return 0; } if(cmd == QUIT) aclose(taper); amfree(cmdline); return 1;}intdumper_cmd( dumper_t *dumper, cmd_t cmd, disk_t *dp){ char *cmdline = NULL; char number[NUM_STR_SIZE]; char numberport[NUM_STR_SIZE]; char *o; char *device; char *features; char *qname; char *qdest; switch(cmd) { case START: cmdline = vstralloc(cmdstr[cmd], " ", (char *)dp, "\n", NULL); break; case PORT_DUMP: if(dp && dp->device) { device = dp->device; } else { device = "NODEVICE"; } if (dp != NULL) { device = quote_string((dp->device) ? dp->device : "NODEVICE"); qname = quote_string(dp->name); g_snprintf(number, SIZEOF(number), "%d", sched(dp)->level); g_snprintf(numberport, SIZEOF(numberport), "%d", dumper->output_port); features = am_feature_to_string(dp->host->features); o = optionstr(dp, dp->host->features, NULL); if ( o == NULL ) { error(_("problem with option string, check the dumptype definition.\n")); } cmdline = vstralloc(cmdstr[cmd], " ", disk2serial(dp), " ", numberport, " ", dp->host->hostname, " ", features, " ", qname,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -