📄 taper.c
字号:
g_get_current_time(&start_time); if (getconf_seen(CNF_DEVICE_OUTPUT_BUFFER_SIZE)) { max_memory = getconf_size(CNF_DEVICE_OUTPUT_BUFFER_SIZE); if (getconf_seen(CNF_TAPEBUFS)) { g_fprintf(stderr, "Configuration directives 'device_output_buffer_size' " "and \n" "'tapebufs' are incompatible; using former.\n"); } } else if (getconf_seen(CNF_TAPEBUFS)) { max_memory = getconf_int(CNF_TAPEBUFS) * device_write_max_size(taper_state->device); } else { /* Use default. */ max_memory = getconf_size(CNF_DEVICE_OUTPUT_BUFFER_SIZE); } queue_result = do_consumer_producer_queue_full (taper_source_producer, dump_info->source, counting_consumer, &consumer_data, device_write_max_size(taper_state->device), max_memory, streaming_mode); g_get_current_time(&end_time); run_time = timesub(end_time, start_time); /* The device_write_consumer may have closed the file with a short * write, so we only finish here if it needs it. */ if (taper_state->device->in_file && !device_finish_file(taper_state->device)) { queue_result = queue_result | QUEUE_CONSUMER_ERROR; } if (!finish_part_attempt(taper_state, dump_info, queue_result, run_time, consumer_data.bytes_written)) { break; } }}/* Handle a PORT_WRITE command. */static void process_port_write(taper_state_t * state, struct cmdargs * cmdargs) { dump_info_t dump_state; guint64 splitsize; guint64 fallback_splitsize; char * split_diskbuffer; char * argnames[] = {"command", /* 1 */ "handle", /* 2 */ "hostname", /* 3 */ "diskname", /* 4 */ "level", /* 5 */ "datestamp", /* 6 */ "splitsize", /* 7 */ "split_diskbuffer", /* 8 */ "fallback_splitsize", /* 9 */ NULL }; validate_args(PORT_WRITE, cmdargs, argnames); dump_state.handle = g_strdup(cmdargs->argv[2]); dump_state.hostname = g_strdup(cmdargs->argv[3]); dump_state.diskname = unquote_string(cmdargs->argv[4]); errno = 0; dump_state.level = strtol(cmdargs->argv[5], NULL, 10); if (errno != 0) { error("error [taper PORT-WRITE: Invalid dump level %s]", cmdargs->argv[5]); g_assert_not_reached(); } dump_state.timestamp = strdup(cmdargs->argv[6]); errno = 0; splitsize = g_ascii_strtoull(cmdargs->argv[7], NULL, 10); if (errno != 0) { error("error [taper PORT-WRITE: Invalid splitsize %s]", cmdargs->argv[7]); g_assert_not_reached(); } if (strcmp(cmdargs->argv[8], "NULL") == 0) { split_diskbuffer = NULL; } else { split_diskbuffer = g_strdup(cmdargs->argv[8]); } errno = 0; fallback_splitsize = g_ascii_strtoull(cmdargs->argv[9], NULL, 10); if (errno != 0) { error("error [taper PORT-WRITE: Invalid fallback_splitsize %s]", cmdargs->argv[9]); g_assert_not_reached(); } dump_state.id_string = g_strdup_printf("%s:%s.%d", dump_state.hostname, dump_state.diskname, dump_state.level); if (!open_read_socket(&dump_state, split_diskbuffer, splitsize, fallback_splitsize)) { free(split_diskbuffer); return; } free(split_diskbuffer); run_device_output(state, &dump_state); free_dump_info(&dump_state);}/* Handle a FILE_WRITE command. */static void process_file_write(taper_state_t * state, struct cmdargs * cmdargs) { dump_info_t dump_state; char * holding_disk_file; guint64 splitsize; char * argnames[] = {"command", /* 1 */ "handle", /* 2 */ "filename", /* 3 */ "hostname", /* 4 */ "diskname", /* 5 */ "level", /* 6 */ "datestamp", /* 7 */ "splitsize", /* 8 */ NULL }; validate_args(FILE_WRITE, cmdargs, argnames); dump_state.handle = g_strdup(cmdargs->argv[2]); holding_disk_file = unquote_string(cmdargs->argv[3]); dump_state.hostname = g_strdup(cmdargs->argv[4]); dump_state.diskname = unquote_string(cmdargs->argv[5]); errno = 0; dump_state.level = strtol(cmdargs->argv[6], NULL, 10); if (errno != 0) { error("error [taper FILE-WRITE: Invalid dump level %s]", cmdargs->argv[5]); g_assert_not_reached(); } dump_state.timestamp = strdup(cmdargs->argv[7]); errno = 0; splitsize = g_ascii_strtoull(cmdargs->argv[8], NULL, 10); if (errno != 0) { error("error [taper FILE-WRITE: Invalid splitsize %s]", cmdargs->argv[8]); g_assert_not_reached(); } dump_state.id_string = g_strdup_printf("%s:%s.%d", dump_state.hostname, dump_state.diskname, dump_state.level); dump_state.source = taper_source_new(dump_state.handle, FILE_WRITE, holding_disk_file, -1, NULL, splitsize, -1); /* FIXME: This should be handled properly. */ g_assert(dump_state.source != NULL); run_device_output(state, &dump_state); free_dump_info(&dump_state); amfree(holding_disk_file);}/* Send QUITTING message to driver and associated logging. Always returns false. */static gboolean send_quitting(taper_state_t * state) { putresult(QUITTING, "\n"); g_fprintf(stderr,"taper: DONE\n"); cleanup(state); return FALSE;}/* This function recieves the START_TAPER command from driver, and returns the attached timestamp. */static gboolean find_first_tape(taper_state_t * state) { cmd_t cmd; /* Note: cmdargs.argv is never freed. In the entire Amanda codebase. */ struct cmdargs cmdargs; tape_search_request_t search_request; GThread * tape_search = NULL; gboolean use_threads; /* We save the value here in case it changes while we're running. */ use_threads = g_thread_supported(); search_request.state = state; search_request.prolong = TRUE; search_request.errmsg = NULL; if (use_threads) { tape_search = g_thread_create(tape_search_thread, &search_request, TRUE, NULL); } cmd = getcmd(&cmdargs); switch (cmd) { case START_TAPER: { gboolean search_result; state->driver_start_time = strdup(cmdargs.argv[2]); if (use_threads) { search_result = GPOINTER_TO_INT(g_thread_join(tape_search)); } else { search_result = GPOINTER_TO_INT(tape_search_thread(&search_request)); } if (search_result) { putresult(TAPER_OK, "\n"); } else { putresult(TAPE_ERROR, "Could not find a tape to use.\n"); log_add(L_ERROR, "no-tape [%s]", "Could not find a tape to use"); if (search_request.errmsg != NULL) { char *c, *c1; c = c1 = search_request.errmsg; while (*c != '\0') { if (*c == '\n') { *c = '\0'; log_add(L_WARNING,"%s", c1); c1 = c+1; } c++; } if (strlen(c1) > 1 ) log_add(L_WARNING,"%s", c1); } } amfree(search_request.errmsg); return TRUE; } case QUIT: search_request.prolong = FALSE; if (use_threads) { g_thread_join(tape_search); } return send_quitting(state); default: error("error [file_reader_side cmd %d argc %d]", cmd, cmdargs.argc); } g_assert_not_reached();}/* In running mode (not startup mode), get a command from driver and deal with it. */static gboolean process_driver_command(taper_state_t * state) { cmd_t cmd; struct cmdargs cmdargs; char * q; /* This will return QUIT if driver has died. */ cmd = getcmd(&cmdargs); switch (cmd) { case PORT_WRITE: /* * PORT-WRITE * handle * hostname * features * diskname * level * datestamp * splitsize * split_diskbuffer */ process_port_write(state, &cmdargs); break; case FILE_WRITE: /* * FILE-WRITE * handle * filename * hostname * features * diskname * level * datestamp * splitsize */ process_file_write(state, &cmdargs); break; case QUIT: return send_quitting(state); default: if (cmdargs.argc >= 1) { q = squote(cmdargs.argv[1]); } else if (cmdargs.argc >= 0) { q = squote(cmdargs.argv[0]); } else { q = stralloc("(no input?)"); } putresult(BAD_COMMAND, "%s\n", q); amfree(q); break; } return TRUE;}int main(int argc, char ** argv) { char * tapelist_name; int have_changer; taper_state_t state; config_overwrites_t *cfg_ovr = NULL; char *cfg_opt = NULL; /* * Configure program for internationalization: * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs. */ setlocale(LC_MESSAGES, "C"); textdomain("amanda"); safe_fd(-1, 0); set_pname("taper"); dbopen("server"); device_api_init(); init_taper_state(&state); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); g_fprintf(stderr, _("%s: pid %ld executable %s version %s\n"), get_pname(), (long) getpid(), argv[0], version()); dbprintf(_("%s: pid %ld executable %s version %s\n"), get_pname(), (long) getpid(), argv[0], version()); /* Process options */ cfg_ovr = extract_commandline_config_overwrites(&argc, &argv); if(argc > 2) { error("Too many arguments!\n"); g_assert_not_reached(); } if (argc > 1) cfg_opt = argv[1]; config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD | CONFIG_INIT_FATAL, cfg_opt); apply_config_overwrites(cfg_ovr); safe_cd(); set_logerror(logerror); check_running_as(RUNNING_AS_DUMPUSER); dbrename(config_name, DBG_SUBDIR_SERVER); tapelist_name = config_dir_relative(getconf_str(CNF_TAPELIST)); if (read_tapelist(tapelist_name) != 0) { error("could not load tapelist \"%s\"", tapelist_name); g_assert_not_reached(); } amfree(tapelist_name); have_changer = changer_init(); if (have_changer < 0) { error("changer initialization failed: %s", strerror(errno)); g_assert_not_reached(); } state.next_tape_label = NULL; state.next_tape_device = NULL; state.cur_tape = 0; if (!find_first_tape(&state)) { return EXIT_SUCCESS; } while (process_driver_command(&state)); return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -