X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Freporter.c;h=f9fabea9535f5ed26d7096d5e198bd1219454e6d;hb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;hp=6f0e248678157a65224dff3e8d92f3fdd760acf1;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/server-src/reporter.c b/server-src/reporter.c index 6f0e248..f9fabea 100644 --- a/server-src/reporter.c +++ b/server-src/reporter.c @@ -63,7 +63,7 @@ #define STATUS_TAPE 16 typedef struct line_s { - struct line_s *next; + struct line_s *next, *last; char *str; } line_t; @@ -84,6 +84,7 @@ typedef struct repdata_s { timedata_t taper; timedata_t dumper; timedata_t chunker; + timedata_t planner; int level; struct repdata_s *next; } repdata_t; @@ -302,6 +303,7 @@ addline( /* allocate new line node */ new = (line_t *) alloc(SIZEOF(line_t)); new->next = NULL; + new->last = NULL; new->str = stralloc(str); /* add to end of list */ @@ -309,9 +311,12 @@ addline( if (p == NULL) { *lp = new; } else { - while (p->next != NULL) - p = p->next; - p->next = new; + if (p->last) { + p->last->next = new; + } else { + p->next = new; + } + p->last = new; } } @@ -344,6 +349,7 @@ main( char *lbl_templ = NULL; config_overwrites_t *cfg_ovr = NULL; char *cfg_opt = NULL; + char *mailer; /* * Configure program for internationalization: @@ -460,26 +466,30 @@ main( amfree(cwd); -#if !defined MAILER - if(!outfname) { - g_printf(_("You must run amreport with '-f ' because configure\n")); - g_printf(_("didn't find a mailer.\n")); - exit (1); - } -#endif - /* read configuration files */ /* ignore any errors reading the config file (amreport can run without a config) */ config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt); - if (cfg_ovr) apply_config_overwrites(cfg_ovr); + apply_config_overwrites(cfg_ovr); + + if (config_errors(NULL) >= CFGERR_WARNINGS) { + config_print_errors(); + } check_running_as(RUNNING_AS_DUMPUSER); - dbrename(config_name, DBG_SUBDIR_SERVER); + dbrename(get_config_name(), DBG_SUBDIR_SERVER); safe_cd(); /* must be called *after* config_init() */ + mailer = getconf_str(CNF_MAILER); + if (mailer && *mailer == '\0') + mailer = NULL; + if (!mailer && !outfname) { + g_printf(_("You must run amreport with '-f ' because a mailer is not defined\n")); + exit (1); + } + conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE)); /* Ignore error from read_diskfile */ read_diskfile(conf_diskfile, &diskq); @@ -605,41 +615,6 @@ main( /* ignore SIGPIPE so if a child process dies we do not also go away */ signal(SIGPIPE, SIG_IGN); - /* open pipe to mailer */ - - if(outfname) { - /* output to a file */ - if((mailf = fopen(outfname,"w")) == NULL) { - error(_("could not open output file: %s %s"), outfname, strerror(errno)); - /*NOTREACHED*/ - } - if (mailto != NULL) { - g_fprintf(mailf, "To: %s\n", mailto); - g_fprintf(mailf, "Subject: %s\n\n", subj_str); - } - - } else { -#ifdef MAILER - if(mailto) { - mail_cmd = vstralloc(MAILER, - " -s", " \"", subj_str, "\"", - " ", mailto, NULL); - if((mailf = popen(mail_cmd, "w")) == NULL) { - error(_("could not open pipe to \"%s\": %s"), - mail_cmd, strerror(errno)); - /*NOTREACHED*/ - } - } - else { - if(mailout) { - g_printf(_("No mail sent! ")); - g_printf(_("No valid mail address has been specified in amanda.conf or on the commmand line\n")); - } - mailf = NULL; - } -#endif - } - /* open pipe to print spooler if necessary) */ if(psfname) { @@ -694,10 +669,55 @@ main( } } - amfree(subj_str); - sort_disks(); + /* open pipe to mailer */ + + if(outfname) { + /* output to a file */ + if((mailf = fopen(outfname,"w")) == NULL) { + error(_("could not open output file: %s %s"), outfname, strerror(errno)); + /*NOTREACHED*/ + } + if (mailto != NULL) { + g_fprintf(mailf, "To: %s\n", mailto); + g_fprintf(mailf, "Subject: %s\n\n", subj_str); + } + + } else if (mailer) { + if(mailto) { + send_amreport_t send_amreport; + int do_mail; + + send_amreport = getconf_send_amreport(CNF_SEND_AMREPORT_ON); + do_mail = send_amreport == SEND_AMREPORT_ALL || + (send_amreport == SEND_AMREPORT_STRANGE && + (!got_finish || first_failed || errsum || + first_strange || errdet || strangedet)) || + (send_amreport == SEND_AMREPORT_ERROR && + (!got_finish || first_failed || errsum || errdet)); + if (do_mail) { + mail_cmd = vstralloc(mailer, + " -s", " \"", subj_str, "\"", + " ", mailto, NULL); + if((mailf = popen(mail_cmd, "w")) == NULL) { + error(_("could not open pipe to \"%s\": %s"), + mail_cmd, strerror(errno)); + /*NOTREACHED*/ + } + } + } + else { + if (mailout) { + g_printf(_("No mail sent! ")); + g_printf(_("No valid mail address has been specified in amanda.conf or on the commmand line\n")); + } + mailf = NULL; + } + } + + amfree(subj_str); + if(mailf) { if(!got_finish) fputs(_("*** THE DUMPS DID NOT FINISH PROPERLY!\n\n"), mailf); @@ -705,7 +725,7 @@ main( if (ghostname) { g_fprintf(mailf, _("Hostname: %s\n"), ghostname); g_fprintf(mailf, _("Org : %s\n"), getconf_str(CNF_ORG)); - g_fprintf(mailf, _("Config : %s\n"), config_name); + g_fprintf(mailf, _("Config : %s\n"), get_config_name()); g_fprintf(mailf, _("Date : %s\n"), nicedate(run_datestamp ? run_datestamp : "0")); g_fprintf(mailf,"\n"); @@ -776,7 +796,7 @@ main( int exitcode; if((exitcode = pclose(mailf)) != 0) { char *exitstr = str_exit_status("mail command", exitcode); - error(exitstr); + error("%s", exitstr); /*NOTREACHED*/ } mailf = NULL; @@ -807,20 +827,24 @@ main( double q = (b); \ if (!isnormal(q)) \ g_fprintf((fp)," -- "); \ - else if ((q = (a)/q) >= 999.95) \ - g_fprintf((fp), "###.#"); \ + else if ((q = (a)/q) >= 99999.95) \ + g_fprintf((fp), "#####"); \ + else if (q >= 999.95) \ + g_fprintf((fp), "%5.0lf",q); \ else \ - g_fprintf((fp), "%5.1lf",q); \ + g_fprintf((fp), "%5.1lf",q); \ } while(0) #define divzero_wide(fp,a,b) \ do { \ double q = (b); \ if (!isnormal(q)) \ g_fprintf((fp)," -- "); \ - else if ((q = (a)/q) >= 99999.95) \ - g_fprintf((fp), "#####.#"); \ + else if ((q = (a)/q) >= 9999999.95) \ + g_fprintf((fp), "#######"); \ + else if (q >= 99999.95) \ + g_fprintf((fp), "%7.0lf",q); \ else \ - g_fprintf((fp), "%7.1lf",q); \ + g_fprintf((fp), "%7.1lf",q); \ } while(0) static void @@ -1047,7 +1071,7 @@ output_tapeinfo(void) if (h_size > 0) { g_fprintf(mailf, _("There are %lld%s of dumps left in the holding disk.\n"), - (long long)h_size, displayunit); + (long long)du(h_size), displayunit); if (getconf_boolean(CNF_AUTOFLUSH)) { g_fprintf(mailf, _("They will be flushed on the next run.\n")); } else { @@ -1282,7 +1306,7 @@ CalcMaxWidth(void) "%3d:%02d", mnsc(repdata->dumper.sec)); else g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); + " "); CheckStringMax(&ColumnData[DumpTime], TimeRateBuffer); CheckFloatMax(&ColumnData[DumpRate], repdata->dumper.kps); @@ -1298,14 +1322,14 @@ CalcMaxWidth(void) "%3d:%02d", mnsc(repdata->taper.sec)); else g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); + " "); CheckStringMax(&ColumnData[TapeTime], TimeRateBuffer); if(repdata->taper.result == L_SUCCESS || repdata->taper.result == L_CHUNKSUCCESS) CheckFloatMax(&ColumnData[TapeRate], repdata->taper.kps); else - CheckStringMax(&ColumnData[TapeRate], "N/A "); + CheckStringMax(&ColumnData[TapeRate], " "); } } } @@ -1323,6 +1347,7 @@ output_summary(void) int i, h, w1, wDump, wTape; double outsize, origsize; double f; + int cdWidth; HostName = StringToColumn("HostName"); Disk = StringToColumn("Disk"); @@ -1411,9 +1436,14 @@ output_summary(void) qdevname = quote_string(devname); devlen = strlen(qdevname); if (devlen > (size_t)cd->Width) { - fputc('-', mailf); - g_fprintf(mailf, cd->Format, cd->Width-1, cd->Precision-1, - qdevname+devlen - (cd->Width-1) ); + int nb = 1; + if (strcmp(devname, qdevname)) { + nb = 2; + fputc('"', mailf); + } + fputc('-', mailf); + g_fprintf(mailf, cd->Format, cd->Width-nb, cd->Precision-nb, + qdevname+devlen - (cd->Width-nb) ); } else g_fprintf(mailf, cd->Format, cd->Width, cd->Width, qdevname); @@ -1476,7 +1506,7 @@ output_summary(void) if(isnormal(origsize)) g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, du(origsize)); else - g_fprintf(mailf, "%*.*s", cd->Width, cd->Width, "N/A"); + g_fprintf(mailf, "%*.*s", cd->Width, cd->Width, ""); cd= &ColumnData[OutKB]; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); @@ -1496,23 +1526,46 @@ output_summary(void) fputs(sDivZero(pct(outsize), f, Compress), mailf); cd= &ColumnData[DumpTime]; + cdWidth = 0; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); if(repdata->dumper.result == L_SUCCESS || - repdata->dumper.result == L_CHUNKSUCCESS) + repdata->dumper.result == L_CHUNKSUCCESS) { g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "%3d:%02d", mnsc(repdata->dumper.sec)); - else - g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); - g_fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer); + "%3d:%02d", mnsc(repdata->dumper.sec)); + g_fprintf(mailf, cd->Format, cd->Width, cd->Width, + TimeRateBuffer); + } else { + cdWidth = cd->Width; + } cd= &ColumnData[DumpRate]; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); - if(repdata->dumper.result == L_SUCCESS || - repdata->dumper.result == L_CHUNKSUCCESS) - g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, repdata->dumper.kps); - else - g_fprintf(mailf, "%*s", cd->Width, "N/A "); + if (repdata->dumper.result == L_SUCCESS || + repdata->dumper.result == L_CHUNKSUCCESS) { + g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, + repdata->dumper.kps); + } else if (repdata->dumper.result == L_FAIL) { + if (repdata->chunker.result == L_PARTIAL || + repdata->taper.result == L_PARTIAL) { + int i; + cdWidth += cd->Width; + i = (cdWidth - strlen("PARTIAL")) / 2; + g_fprintf(mailf, "%*s%*s", cdWidth-i, "PARTIAL", i, ""); + } else { + int i; + cdWidth += cd->Width; + i = (cdWidth - strlen("FAILED")) / 2; + g_fprintf(mailf, "%*s%*s", cdWidth-i, "FAILED", i, ""); + } + } else if (repdata->dumper.result == L_BOGUS) { + int i; + cdWidth += cd->Width; + i = (cdWidth - strlen("FLUSH")) / 2; + g_fprintf(mailf, "%*s%*s", cdWidth-i, "FLUSH", i, ""); + } else { + cdWidth += cd->Width; + g_fprintf(mailf, "%*s", cdWidth, ""); + } cd= &ColumnData[TapeTime]; g_fprintf(mailf, "%*s", cd->PrefixSpace, ""); @@ -1530,7 +1583,7 @@ output_summary(void) "%3d:%02d", mnsc(repdata->taper.sec)); else g_snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), - "N/A "); + " "); g_fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer); cd= &ColumnData[TapeRate]; @@ -1540,7 +1593,7 @@ output_summary(void) repdata->taper.result == L_CHUNKSUCCESS) g_fprintf(mailf, cd->Format, cd->Width, cd->Precision, repdata->taper.kps); else - g_fprintf(mailf, "%*s", cd->Width, "N/A "); + g_fprintf(mailf, "%*s", cd->Width, " "); if (repdata->chunker.result == L_PARTIAL) g_fprintf(mailf, " PARTIAL"); @@ -1916,10 +1969,23 @@ static void handle_note(void) { char *str = NULL; + char *pidstr; - str = vstrallocf(" %s: %s", program_str[curprog], curstr); - addline(¬es, str); - amfree(str); + if (curprog == P_DRIVER && + BSTRNCMP(curstr, "Taper protocol error") == 0) { + exit_status |= STATUS_TAPE; + } + pidstr = index(curstr,' '); + if (pidstr) { + pidstr++; + } + /* Don't report the pid lines */ + if ((!pidstr || BSTRNCMP(pidstr, "pid ") != 0) && + BSTRNCMP(curstr, "pid-done ") != 0) { + str = vstrallocf(" %s: %s", program_str[curprog], curstr); + addline(¬es, str); + amfree(str); + } } @@ -2338,6 +2404,17 @@ handle_success( if(!isnormal(origkb)) origkb = 0.1; } + if (curprog == P_TAPER && logtype == L_PARTIAL) { + char *t = index(s-1,']'); + if (t) { + char *errmsg, *u; + errmsg = unquote_string(t+1); + u = vstrallocf(" %s: partial %s: %s", + prefix(hostname, diskname, level), + program_str[curprog], errmsg); + addline(&errsum, u); + } + } } @@ -2613,6 +2690,8 @@ handle_failed(void) if(curprog == P_TAPER) sp = &(repdata->taper); + else if (curprog == P_PLANNER) + sp = &(repdata->planner); else sp = &(repdata->dumper); if(sp->result != L_SUCCESS) @@ -2620,10 +2699,17 @@ handle_failed(void) } amfree(datestamp); - str = vstrallocf(_("FAILED %s"), errstr); - addtoX_summary(&first_failed, &last_failed, hostname, qdiskname, level, - str); - amfree(str); + if (!((curprog == P_CHUNKER && + strcmp(errstr, "[dumper returned FAILED]") == 0) || + (curprog == P_CHUNKER && + strcmp(errstr, "[Not enough holding disk space]") == 0) || + (curprog == P_CHUNKER && + strcmp(errstr, "[cannot read header: got 0 bytes instead of 32768]") == 0))) { + str = vstrallocf(_("FAILED %s"), errstr); + addtoX_summary(&first_failed, &last_failed, hostname, qdiskname, level, + str); + amfree(str); + } if(curprog == P_DUMPER) { addline(&errdet,""); @@ -2684,7 +2770,7 @@ generate_bad_estimate(void) else outsize = repdata->dumper.outsize; - if(repdata->est_csize * 0.9 > outsize) { + if( (repdata->est_csize * 0.9 > outsize) && ( repdata->est_csize - outsize > 1.0e5 ) ) { g_snprintf(s, 1000, _(" big estimate: %s %s %d"), repdata->disk->host->hostname, @@ -2699,7 +2785,7 @@ generate_bad_estimate(void) s[999] = '\0'; addline(¬es, s); } - else if(repdata->est_csize * 1.1 < outsize) { + else if( (repdata->est_csize * 1.1 < outsize) && (outsize - repdata->est_csize > 1.0e5 ) ) { g_snprintf(s, 1000, _(" small estimate: %s %s %d"), repdata->disk->host->hostname, @@ -2978,7 +3064,7 @@ do_postscript_output(void) else { g_fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8s) (%8.0lf) DrawHost\n", dp->host->hostname, dp->name, repdata->level, - repdata->taper.filenum, "N/A", + repdata->taper.filenum, "", outsize); } }