📄 amcheck.c
字号:
voidstart_host( am_host_t *hostp){ disk_t *dp; char *req = NULL; size_t req_len = 0; int disk_count; const security_driver_t *secdrv; char number[NUM_STR_SIZE]; if(hostp->up != HOST_READY) { return; } if (strcmp(hostp->hostname,"localhost") == 0) { g_fprintf(outf, _("WARNING: Usage of fully qualified hostname recommended for Client %s.\n"), hostp->hostname); } /* * The first time through here we send a "noop" request. This will * return the feature list from the client if it supports that. * If it does not, handle_result() will set the feature list to an * empty structure. In either case, we do the disks on the second * (and subsequent) pass(es). */ disk_count = 0; if(hostp->features != NULL) { /* selfcheck service */ int has_features = am_has_feature(hostp->features, fe_req_options_features); int has_hostname = am_has_feature(hostp->features, fe_req_options_hostname); int has_maxdumps = am_has_feature(hostp->features, fe_req_options_maxdumps); int has_config = am_has_feature(hostp->features, fe_req_options_config); if(!am_has_feature(hostp->features, fe_selfcheck_req) && !am_has_feature(hostp->features, fe_selfcheck_req_device)) { g_fprintf(outf, _("ERROR: Client %s does not support selfcheck REQ packet.\n"), hostp->hostname); g_fprintf(outf, _("Client might be of a very old version\n")); } if(!am_has_feature(hostp->features, fe_selfcheck_rep)) { g_fprintf(outf, _("ERROR: Client %s does not support selfcheck REP packet.\n"), hostp->hostname); g_fprintf(outf, _("Client might be of a very old version\n")); } if(!am_has_feature(hostp->features, fe_sendsize_req_options) && !am_has_feature(hostp->features, fe_sendsize_req_no_options) && !am_has_feature(hostp->features, fe_sendsize_req_device)) { g_fprintf(outf, _("ERROR: Client %s does not support sendsize REQ packet.\n"), hostp->hostname); g_fprintf(outf, _("Client might be of a very old version\n")); } if(!am_has_feature(hostp->features, fe_sendsize_rep)) { g_fprintf(outf, _("ERROR: Client %s does not support sendsize REP packet.\n"), hostp->hostname); g_fprintf(outf, _("Client might be of a very old version\n")); } if(!am_has_feature(hostp->features, fe_sendbackup_req) && !am_has_feature(hostp->features, fe_sendbackup_req_device)) { g_fprintf(outf, _("ERROR: Client %s does not support sendbackup REQ packet.\n"), hostp->hostname); g_fprintf(outf, _("Client might be of a very old version\n")); } if(!am_has_feature(hostp->features, fe_sendbackup_rep)) { g_fprintf(outf, _("ERROR: Client %s does not support sendbackup REP packet.\n"), hostp->hostname); g_fprintf(outf, _("Client might be of a very old version\n")); } g_snprintf(number, SIZEOF(number), "%d", hostp->maxdumps); req = vstralloc("SERVICE ", "selfcheck", "\n", "OPTIONS ", has_features ? "features=" : "", has_features ? our_feature_string : "", has_features ? ";" : "", has_maxdumps ? "maxdumps=" : "", has_maxdumps ? number : "", has_maxdumps ? ";" : "", has_hostname ? "hostname=" : "", has_hostname ? hostp->hostname : "", has_hostname ? ";" : "", has_config ? "config=" : "", has_config ? config_name : "", has_config ? ";" : "", "\n", NULL); req_len = strlen(req); req_len += 128; /* room for SECURITY ... */ req_len += 256; /* room for non-disk answers */ for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { char *l; size_t l_len; char *o; char *calcsize; char *qname; char *qdevice; if(dp->up != DISK_READY || dp->todo != 1) { continue; } o = optionstr(dp, hostp->features, outf); if (o == NULL) { remote_errors++; continue; } qname = quote_string(dp->name); qdevice = quote_string(dp->device); if ((dp->name && qname[0] == '"') || (dp->device && qdevice[0] == '"')) { if(!am_has_feature(hostp->features, fe_interface_quoted_text)) { g_fprintf(outf, _("WARNING: %s:%s:%s host does not support quoted text\n"), hostp->hostname, qname, qdevice); g_fprintf(outf, _("You must upgrade amanda on the client to " "specify a quoted text/device in the disklist, " "or don't use quoted text for the device.\n")); } } if(dp->device) { if(!am_has_feature(hostp->features, fe_selfcheck_req_device)) { g_fprintf(outf, _("ERROR: %s:%s (%s): selfcheck does not support device.\n"), hostp->hostname, qname, dp->device); g_fprintf(outf, _("You must upgrade amanda on the client to " "specify a diskdevice in the disklist " "or don't specify a diskdevice in the disklist.\n")); } if(!am_has_feature(hostp->features, fe_sendsize_req_device)) { g_fprintf(outf, _("ERROR: %s:%s (%s): sendsize does not support device.\n"), hostp->hostname, qname, dp->device); g_fprintf(outf, _("You must upgrade amanda on the client to " "specify a diskdevice in the disklist" " or don't specify a diskdevice in the disklist.\n")); } if(!am_has_feature(hostp->features, fe_sendbackup_req_device)) { g_fprintf(outf, _("ERROR: %s:%s (%s): sendbackup does not support device.\n"), hostp->hostname, qname, dp->device); g_fprintf(outf, _("You must upgrade amanda on the client to " "specify a diskdevice in the disklist" " or don't specify a diskdevice in the disklist.\n")); } } if(strcmp(dp->program,"DUMP") == 0 || strcmp(dp->program,"GNUTAR") == 0) { if(strcmp(dp->program, "DUMP") == 0 && !am_has_feature(hostp->features, fe_program_dump)) { g_fprintf(outf, _("ERROR: %s:%s does not support DUMP.\n"), hostp->hostname, qname); g_fprintf(outf, _("You must upgrade amanda on the client to use DUMP " "or you can use another program.\n")); } if(strcmp(dp->program, "GNUTAR") == 0 && !am_has_feature(hostp->features, fe_program_gnutar)) { g_fprintf(outf, _("ERROR: %s:%s does not support GNUTAR.\n"), hostp->hostname, qname); g_fprintf(outf, _("You must upgrade amanda on the client to use GNUTAR " "or you can use another program.\n")); } if(dp->estimate == ES_CALCSIZE && !am_has_feature(hostp->features, fe_calcsize_estimate)) { g_fprintf(outf, _("ERROR: %s:%s does not support CALCSIZE for " "estimate, using CLIENT.\n"), hostp->hostname, qname); g_fprintf(outf, _("You must upgrade amanda on the client to use " "CALCSIZE for estimate or don't use CALCSIZE for estimate.\n")); dp->estimate = ES_CLIENT; } if(dp->estimate == ES_CALCSIZE && am_has_feature(hostp->features, fe_selfcheck_calcsize)) calcsize = "CALCSIZE "; else calcsize = ""; if(dp->compress == COMP_CUST && !am_has_feature(hostp->features, fe_options_compress_cust)) { g_fprintf(outf, _("ERROR: Client %s does not support custom compression.\n"), hostp->hostname); g_fprintf(outf, _("You must upgrade amanda on the client to " "use custom compression\n")); g_fprintf(outf, _("Otherwise you can use the default client " "compression program.\n")); } if(dp->encrypt == ENCRYPT_CUST ) { if ( !am_has_feature(hostp->features, fe_options_encrypt_cust)) { g_fprintf(outf, _("ERROR: Client %s does not support data encryption.\n"), hostp->hostname); g_fprintf(outf, _("You must upgrade amanda on the client to use encryption program.\n")); remote_errors++; } else if ( dp->compress == COMP_SERVER_FAST || dp->compress == COMP_SERVER_BEST || dp->compress == COMP_SERVER_CUST ) { g_fprintf(outf, _("ERROR: %s: Client encryption with server compression " "is not supported. See amanda.conf(5) for detail.\n"), hostp->hostname); remote_errors++; } } if(dp->device) { l = vstralloc(calcsize, dp->program, " ", qname, " ", qdevice, " 0 OPTIONS |", o, "\n", NULL); } else { l = vstralloc(calcsize, dp->program, " ", qname, " 0 OPTIONS |", o, "\n", NULL); } } else { if(!am_has_feature(hostp->features, fe_program_backup_api)) { g_fprintf(outf, _("ERROR: %s:%s does not support BACKUP-API.\n"), hostp->hostname, qname); g_fprintf(outf, _("Dumptype configuration is not GNUTAR or DUMP." " It is case sensitive\n")); } if(dp->device) { l = vstralloc("BACKUP ", dp->program, " ", qname, " ", qdevice, " 0 OPTIONS |", o, "\n", NULL); } else { l = vstralloc("BACKUP ", dp->program, " ", qname, " 0 OPTIONS |", o, "\n", NULL); } } amfree(qname); amfree(qdevice); l_len = strlen(l); amfree(o); strappend(req, l); req_len += l_len; amfree(l); dp->up = DISK_ACTIVE; disk_count++; } } else { /* noop service */ req = vstralloc("SERVICE ", "noop", "\n", "OPTIONS ", "features=", our_feature_string, ";", "\n", NULL); for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { if(dp->up != DISK_READY || dp->todo != 1) { continue; } disk_count++; } } if(disk_count == 0) { amfree(req); hostp->up = HOST_DONE; return; } secdrv = security_getdriver(hostp->disks->security_driver); if (secdrv == NULL) { fprintf(stderr, _("Could not find security driver \"%s\" for host \"%s\". auth for this dle is invalid\n"), hostp->disks->security_driver, hostp->hostname); } else { protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf, req, conf_ctimeout, handle_result, hostp); } amfree(req); hostp->up = HOST_ACTIVE;}pid_tstart_client_checks( int fd){ am_host_t *hostp; disk_t *dp; int hostcount; pid_t pid; int userbad = 0; switch(pid = fork()) { case -1: error(_("INTERNAL ERROR:could not fork client check: %s"), strerror(errno)); /*NOTREACHED*/ case 0: break; default: return pid; } dup2(fd, 1); dup2(fd, 2); set_pname("amcheck-clients"); startclock(); if((outf = fdopen(fd, "w")) == NULL) { error(_("fdopen %d: %s"), fd, strerror(errno)); /*NOTREACHED*/ } errf = outf; g_fprintf(outf, _("\nAmanda Backup Client Hosts Check\n")); g_fprintf(outf, "--------------------------------\n"); protocol_init(); hostcount = remote_errors = 0; for(dp = origq.head; dp != NULL; dp = dp->next) { hostp = dp->host; if(hostp->up == HOST_READY && dp->todo == 1) { start_host(hostp); hostcount++; protocol_check(); } } protocol_run(); g_fprintf(outf, plural(_("Client check: %d host checked in %s seconds."), _("Client check: %d hosts checked in %s seconds."), hostcount), hostcount, walltime_str(curclock())); g_fprintf(outf, plural(_(" %d problem found.\n"), _(" %d problems found.\n"), remote_errors), remote_errors); fflush(outf); exit(userbad || remote_errors > 0); /*NOTREACHED*/ return 0;}static voidhandle_result( void * datap, pkt_t * pkt, security_handle_t * sech){ am_host_t *hostp; disk_t *dp; char *line; char *s; char *t; int ch; int tch; hostp = (am_host_t *)datap; hostp->up = HOST_READY; if (pkt == NULL) { g_fprintf(outf, _("WARNING: %s: selfcheck request failed: %s\n"), hostp->hostname, security_geterror(sech)); remote_errors++; hostp->up = HOST_DONE; return; }#if 0 g_fprintf(errf, _("got response from %s:\n----\n%s----\n\n"), hostp->hostname, pkt->body);#endif s = pkt->body; ch = *s++; while(ch) { line = s - 1; skip_quoted_line(s, ch); if (s[-2] == '\n') { s[-2] = '\0'; } if(strncmp_const(line, "OPTIONS ") == 0) { t = strstr(line, "features="); if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) { t += SIZEOF("features=")-1; am_release_feature_set(hostp->features); if((hostp->features = am_string_to_feature(t)) == NULL) { g_fprintf(outf, _("ERROR: %s: bad features value: %s\n"), hostp->hostname, line); g_fprintf(outf, _("The amfeature in the reply packet is invalid\n")); } } continue; } if(strncmp_const(line, "OK ") == 0) { continue; } t = line; if(strncmp_const_skip(line, "ERROR ", t, tch) == 0) { skip_whitespace(t, tch); /* * If the "error" is that the "noop" service is unknown, it * just means the client is "old" (does not support the service). * We can ignore this. */ if(!((hostp->features == NULL) && (pkt->type == P_NAK) && ((strcmp(t - 1, "unknown service: noop") == 0) || (strcmp(t - 1, "noop: invalid service") == 0)))) { g_fprintf(outf, _("ERROR: %s%s: %s\n"), (pkt->type == P_NAK) ? "NAK " : "", hostp->hostname, t - 1); remote_errors++; hostp->up = HOST_DONE; } continue; } g_fprintf(outf, _("ERROR: %s: unknown response: %s\n"), hostp->hostname, line); remote_errors++; hostp->up = HOST_DONE; } if(hostp->up == HOST_READY && hostp->features == NULL) { /* * The client does not support the features list, so give it an * empty one. */ dbprintf(_("no feature set from host %s\n"), hostp->hostname); hostp->features = am_set_default_feature_set(); } for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) { if(dp->up == DISK_ACTIVE) { dp->up = DISK_DONE; } } start_host(hostp); if(hostp->up == HOST_DONE) security_close_connection(sech, hostp->hostname); /* try to clean up any defunct processes, since Amanda doesn't wait() for them explicitly */ while(waitpid(-1, NULL, WNOHANG)> 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -