static #endif int reload_from_clientdir(struct cstat **clist) { int reloaded=0; struct cstat *c; for(c=*clist; c; c=c->next) { time_t ltime=0; struct stat statp; struct stat lstatp; struct sdirs *sdirs; if(!c->permitted) continue; sdirs=(struct sdirs *)c->sdirs; if(!sdirs || !sdirs->client) continue; if(stat(sdirs->client, &statp)) { // No clientdir. if(!c->run_status) cstat_set_run_status(c); continue; } if(!lstat(sdirs->lock->path, &lstatp)) ltime=lstatp.st_mtime; if(statp.st_mtime==c->clientdir_mtime && ltime==c->lockfile_mtime && c->run_status!=RUN_STATUS_SERVER_CRASHED) //&& !c->cntr) { // clientdir has not changed - no need to do anything. continue; } c->clientdir_mtime=statp.st_mtime; c->lockfile_mtime=ltime; cstat_set_run_status(c); bu_list_free(&c->bu); // FIX THIS: should probably not load everything each time. // if(bu_get_current(sdirs, &c->bu)) // goto error; if(bu_get_list_with_working(sdirs, &c->bu, c)) goto error; reloaded++; } return reloaded; error: return -1; }
static void test_cstat_set_run_status_idle(enum protocol protocol) { struct cstat *cstat; cstat=set_run_status_setup(protocol, 1 /*permitted*/); cstat_set_run_status(cstat); fail_unless(cstat->run_status==RUN_STATUS_IDLE); tear_down(&cstat); }
static void test_cstat_set_run_status_not_permitted(enum protocol protocol) { struct cstat *cstat; cstat=set_run_status_setup(protocol, 0 /*not permitted*/); cstat_set_run_status(cstat); fail_unless(cstat->run_status==RUN_STATUS_UNSET); tear_down(&cstat); }
static void test_cstat_set_run_status_client_crashed(enum protocol protocol) { struct cstat *cstat; cstat=set_run_status_setup(protocol, 1 /*permitted*/); fail_unless(recursive_delete(BASE)==0); build_storage_dirs((struct sdirs *)cstat->sdirs, sd1w, ARR_LEN(sd1w)); cstat_set_run_status(cstat); fail_unless(cstat->run_status==RUN_STATUS_CLIENT_CRASHED); tear_down(&cstat); }
static void test_cstat_set_run_status_server_crashed(enum protocol protocol) { struct cstat *cstat; struct sdirs *sdirs; cstat=set_run_status_setup(protocol, 1 /*permitted*/); fail_unless(recursive_delete(BASE)==0); build_storage_dirs((struct sdirs *)cstat->sdirs, sd1w, ARR_LEN(sd1w)); sdirs=(struct sdirs *)cstat->sdirs; build_file(sdirs->lock->path, NULL); cstat_set_run_status(cstat); fail_unless(cstat->run_status==RUN_STATUS_SERVER_CRASHED); tear_down(&cstat); }
static void test_cstat_set_run_status_running(enum protocol protocol) { int waitstat; struct cstat *cstat; struct sdirs *sdirs; struct lock *lock; cstat=set_run_status_setup(protocol, 1 /*permitted*/); clean(); build_storage_dirs((struct sdirs *)cstat->sdirs, sd1w, ARR_LEN(sd1w)); sdirs=(struct sdirs *)cstat->sdirs; lock=sdirs->lock; switch(fork()) { case -1: fail_unless(0==1); break; case 0: // Child. { lock_get_quick(lock); sleep(2); lock_release(lock); exit(0); } default: break; } // Parent. sleep(1); lock_get(lock); fail_unless(lock->status==GET_LOCK_NOT_GOT); cstat_set_run_status(cstat); fail_unless(cstat->run_status==RUN_STATUS_RUNNING); wait(&waitstat); tear_down(&cstat); }
static int parse_client_data(struct asfd *srfd, struct cstat *clist, struct conf **confs) { int ret=0; char *command=NULL; char *client=NULL; char *backup=NULL; char *logfile=NULL; char *browse=NULL; const char *cp=NULL; struct cstat *cstat=NULL; struct bu *bu=NULL; //printf("got client data: '%s'\n", srfd->rbuf->buf); cp=srfd->rbuf->buf; // The client monitor will send an initial blank line to kick things // off. Until it is sent, we will not even have entered the code // in this file. So, without it, data from the parent will not have // been read, and the monitor client will be given incomplete // information for its first response. // Just ignore the new line at this point, it has served its purpose. if(srfd->rbuf->len==1 && !strcmp(cp, "\n")) { ret=0; goto end; } command=get_str(&cp, "j:", 0); client=get_str(&cp, "c:", 0); backup=get_str(&cp, "b:", 0); logfile=get_str(&cp, "l:", 0); browse=get_str(&cp, "p:", 1); if(command) { if(!strcmp(command, "pretty-print-on")) { json_set_pretty_print(1); if(json_send_warn(srfd, "Pretty print on")) goto error; } else if(!strcmp(command, "pretty-print-off")) { json_set_pretty_print(0); if(json_send_warn(srfd, "Pretty print off")) goto error; } else { if(json_send_warn(srfd, "Unknown command")) goto error; } goto end; } if(browse) { free_w(&logfile); if(!(logfile=strdup_w("manifest", __func__))) goto error; strip_trailing_slashes(&browse); } //dump_cbno(clist, "pcd"); if(client && *client) { if(!(cstat=cstat_get_by_name(clist, client))) { if(json_send_warn(srfd, "Could not find client")) goto error; goto end; } if(cstat_set_backup_list(cstat)) { if(json_send_warn(srfd, "Could not get backup list")) goto error; goto end; } } if(cstat && backup) { unsigned long bno=0; if(!(bno=strtoul(backup, NULL, 10))) { if(json_send_warn(srfd, "Could not get backup number")) goto error; goto end; } for(bu=cstat->bu; bu; bu=bu->prev) if(bu->bno==bno) break; if(!bu) { if(json_send_warn(srfd, "Backup not found")) goto error; goto end; } } if(logfile) { if(strcmp(logfile, "manifest") && strcmp(logfile, "backup") && strcmp(logfile, "restore") && strcmp(logfile, "verify") && strcmp(logfile, "backup_stats") && strcmp(logfile, "restore_stats") && strcmp(logfile, "verify_stats")) { if(json_send_warn(srfd, "File not supported")) goto error; goto end; } } /* printf("client: %s\n", client?:""); printf("backup: %s\n", backup?:""); printf("logfile: %s\n", logfile?:""); */ if(cstat) { if(!cstat->run_status) cstat_set_run_status(cstat); } else for(cstat=clist; cstat; cstat=cstat->next) { if(!cstat->run_status) cstat_set_run_status(cstat); } if(json_send(srfd, clist, cstat, bu, logfile, browse, get_int(confs[OPT_MONITOR_BROWSE_CACHE]))) goto error; goto end; error: ret=-1; end: free_w(&client); free_w(&backup); free_w(&logfile); free_w(&browse); return ret; }