void fcgi_delete_file(void) { const char *rev = get_arg("rev"); const sx_hashfs_volume_t *vol; rc_ty s; s = sx_hashfs_volume_by_name(hashfs, volume, &vol); if(s != OK) quit_errmsg(rc2http(s), msg_get_reason()); if(!sx_hashfs_is_or_was_my_volume(hashfs, vol, 0)) quit_errnum(404); if(has_priv(PRIV_CLUSTER)) { /* Request comes in from the cluster: apply locally */ s = sx_hashfs_file_delete(hashfs, vol, path, rev); if(s != OK) quit_errmsg(rc2http(s), msg_get_reason()); CGI_PUTS("\r\n"); } else { /* Request comes in from the user: create job */ job_t job; s = sx_hashfs_filedelete_job(hashfs, uid, vol, path, rev, &job); if(s != OK) quit_errmsg(rc2http(s), msg_get_reason()); send_job_info(job); } }
void fcgi_flush_tempfile(void) { job_t job; rc_ty s; auth_complete(); quit_unless_authed(); s = sx_hashfs_putfile_commitjob(hashfs, user, uid, path, &job); if(s != OK) quit_errmsg(rc2http(s), msg_get_reason()); send_job_info(job); return; }
/* * Do a verification of the specified files against the Catlaog * * Returns: false on failure * true on success */ bool do_verify(JCR *jcr) { int JobLevel; const char *level; BSOCK *fd = NULL; BSOCK *sd = NULL; int status; char ed1[100]; JOB_DBR jr; JobId_t verify_jobid = 0; const char *Name; free_wstorage(jcr); /* we don't write */ memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr)); /* * Find JobId of last job that ran. Note, we do this when * the job actually starts running, not at schedule time, * so that we find the last job that terminated before * this job runs rather than before it is scheduled. This * permits scheduling a Backup and Verify at the same time, * but with the Verify at a lower priority. * * For VERIFY_CATALOG we want the JobId of the last INIT. * For VERIFY_VOLUME_TO_CATALOG, we want the JobId of the * last backup Job. */ JobLevel = jcr->getJobLevel(); switch (JobLevel) { case L_VERIFY_CATALOG: case L_VERIFY_VOLUME_TO_CATALOG: case L_VERIFY_DISK_TO_CATALOG: memcpy(&jr, &jcr->jr, sizeof(jr)); if (jcr->res.verify_job && (JobLevel == L_VERIFY_VOLUME_TO_CATALOG || JobLevel == L_VERIFY_DISK_TO_CATALOG)) { Name = jcr->res.verify_job->name(); } else { Name = NULL; } Dmsg1(100, "find last jobid for: %s\n", NPRT(Name)); /* * See if user supplied a jobid= as run argument or from menu */ if (jcr->VerifyJobId) { verify_jobid = jcr->VerifyJobId; Dmsg1(100, "Supplied jobid=%d\n", verify_jobid); } else { if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) { if (JobLevel == L_VERIFY_CATALOG) { Jmsg(jcr, M_FATAL, 0, _( "Unable to find JobId of previous InitCatalog Job.\n" "Please run a Verify with Level=InitCatalog before\n" "running the current Job.\n")); } else { Jmsg(jcr, M_FATAL, 0, _( "Unable to find JobId of previous Job for this client.\n")); } return false; } verify_jobid = jr.JobId; } Dmsg1(100, "Last full jobid=%d\n", verify_jobid); /* * Now get the job record for the previous backup that interests * us. We use the verify_jobid that we found above. */ jcr->previous_jr.JobId = verify_jobid; if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) { Jmsg(jcr, M_FATAL, 0, _("Could not get job record for previous Job. ERR=%s"), db_strerror(jcr->db)); return false; } if (!(jcr->previous_jr.JobStatus == JS_Terminated || jcr->previous_jr.JobStatus == JS_Warnings)) { Jmsg(jcr, M_FATAL, 0, _("Last Job %d did not terminate normally. JobStatus=%c\n"), verify_jobid, jcr->previous_jr.JobStatus); return false; } Jmsg(jcr, M_INFO, 0, _("Verifying against JobId=%d Job=%s\n"), jcr->previous_jr.JobId, jcr->previous_jr.Job); } /* * If we are verifying a Volume, we need the Storage * daemon, so open a connection, otherwise, just * create a dummy authorization key (passed to * File daemon but not used). */ switch (JobLevel) { case L_VERIFY_VOLUME_TO_CATALOG: /* * Note: negative status is an error, zero status, means * no files were backed up, so skip calling SD and * client. */ status = create_restore_bootstrap_file(jcr); if (status < 0) { /* error */ return false; } else if (status == 0) { /* No files, nothing to do */ verify_cleanup(jcr, JS_Terminated); /* clean up */ return true; /* get out */ } if (jcr->res.verify_job) { jcr->res.fileset = jcr->res.verify_job->fileset; } break; default: jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */ break; } Dmsg2(100, "ClientId=%u JobLevel=%c\n", jcr->previous_jr.ClientId, JobLevel); if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); return false; } /* * Print Job Start message */ Jmsg(jcr, M_INFO, 0, _("Start Verify JobId=%s Level=%s Job=%s\n"), edit_uint64(jcr->JobId, ed1), level_to_str(JobLevel), jcr->Job); switch (JobLevel) { case L_VERIFY_VOLUME_TO_CATALOG: /* * Start conversation with Storage daemon */ jcr->setJobStatus(JS_Blocked); if (!connect_to_storage_daemon(jcr, 10, me->SDConnectTimeout, true)) { return false; } sd = jcr->store_bsock; /* * Now start a job with the Storage daemon */ if (!start_storage_daemon_job(jcr, jcr->res.rstorage, NULL, /* send_bsr */ true)) { return false; } jcr->passive_client = jcr->res.client->passive; if (!jcr->passive_client) { /* * Start the Job in the SD. */ if (!sd->fsend("run")) { return false; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { return false; } Dmsg0(50, "Storage daemon connection OK\n"); } /* * OK, now connect to the File daemon and ask him for the files. */ jcr->setJobStatus(JS_Blocked); if (!connect_to_file_daemon(jcr, 10, me->FDConnectTimeout, true)) { goto bail_out; } send_job_info(jcr); fd = jcr->file_bsock; /* * Check if the file daemon supports passive client mode. */ if (jcr->passive_client && jcr->FDVersion < FD_VERSION_51) { Jmsg(jcr, M_FATAL, 0, _("Client \"%s\" doesn't support passive client mode. " "Please upgrade your client or disable compat mode.\n"), jcr->res.client->name()); goto bail_out; } break; default: /* * OK, now connect to the File daemon and ask him for the files. */ jcr->setJobStatus(JS_Blocked); if (!connect_to_file_daemon(jcr, 10, me->FDConnectTimeout, true)) { goto bail_out; } send_job_info(jcr); fd = jcr->file_bsock; break; } jcr->setJobStatus(JS_Running); Dmsg0(30, ">filed: Send include list\n"); if (!send_include_list(jcr)) { goto bail_out; } Dmsg0(30, ">filed: Send exclude list\n"); if (!send_exclude_list(jcr)) { goto bail_out; } /* * Send Level command to File daemon, as well as the Storage address if appropriate. */ switch (JobLevel) { case L_VERIFY_INIT: level = "init"; break; case L_VERIFY_CATALOG: level = "catalog"; break; case L_VERIFY_VOLUME_TO_CATALOG: if (!jcr->RestoreBootstrap) { Jmsg0(jcr, M_FATAL, 0, _("Deprecated feature ... use bootstrap.\n")); goto bail_out; } if (!jcr->passive_client) { int tls_need = BNET_TLS_NONE; STORERES *store = jcr->res.rstore; /* * Send Storage daemon address to the File daemon */ if (store->SDDport == 0) { store->SDDport = store->SDport; } /* * TLS Requirement */ if (store->tls.enable) { if (store->tls.require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } fd->fsend(storaddrcmd, store->address, store->SDDport, tls_need, jcr->sd_auth_key); if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) { goto bail_out; } } else { int tls_need = BNET_TLS_NONE; CLIENTRES *client = jcr->res.client; /* * TLS Requirement */ if (client->tls.enable) { if (client->tls.require) { tls_need = BNET_TLS_REQUIRED; } else { tls_need = BNET_TLS_OK; } } /* * Tell the SD to connect to the FD. */ sd->fsend(passiveclientcmd, client->address, client->FDport, tls_need); if (!response(jcr, sd, OKpassiveclient, "Passive client", DISPLAY_ERROR)) { goto bail_out; } /* * Start the Job in the SD. */ if (!sd->fsend("run")) { goto bail_out; } /* * Now start a Storage daemon message thread */ if (!start_storage_daemon_message_thread(jcr)) { goto bail_out; } Dmsg0(50, "Storage daemon connection OK\n"); } level = "volume"; break; case L_VERIFY_DATA: level = "data"; break; case L_VERIFY_DISK_TO_CATALOG: level="disk_to_catalog"; break; default: Jmsg2(jcr, M_FATAL, 0, _("Unimplemented Verify level %d(%c)\n"), JobLevel, JobLevel); goto bail_out; } if (!send_runscripts_commands(jcr)) { goto bail_out; } /* * Send verify command/level to File daemon */ fd->fsend(verifycmd, level); if (!response(jcr, fd, OKverify, "Verify", DISPLAY_ERROR)) { goto bail_out; } /* * Now get data back from File daemon and * compare it to the catalog or store it in the * catalog depending on the run type. */ switch (JobLevel) { case L_VERIFY_CATALOG: /* * Verify from catalog */ Dmsg0(10, "Verify level=catalog\n"); jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ jcr->SDJobStatus = JS_Terminated; get_attributes_and_compare_to_catalog(jcr, jcr->previous_jr.JobId); break; case L_VERIFY_VOLUME_TO_CATALOG: /* * Verify Volume to catalog entries */ Dmsg0(10, "Verify level=volume\n"); get_attributes_and_compare_to_catalog(jcr, jcr->previous_jr.JobId); break; case L_VERIFY_DISK_TO_CATALOG: /* * Verify Disk attributes to catalog */ Dmsg0(10, "Verify level=disk_to_catalog\n"); jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ jcr->SDJobStatus = JS_Terminated; get_attributes_and_compare_to_catalog(jcr, jcr->previous_jr.JobId); break; case L_VERIFY_INIT: /* * Build catalog */ Dmsg0(10, "Verify level=init\n"); jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ jcr->SDJobStatus = JS_Terminated; get_attributes_and_put_in_catalog(jcr); db_end_transaction(jcr, jcr->db); /* terminate any open transaction */ db_write_batch_file_records(jcr); break; default: Jmsg1(jcr, M_FATAL, 0, _("Unimplemented verify level %d\n"), JobLevel); goto bail_out; } status = wait_for_job_termination(jcr); verify_cleanup(jcr, status); return true; bail_out: if (jcr->file_bsock) { jcr->file_bsock->signal(BNET_TERMINATE); jcr->file_bsock->close(); delete jcr->file_bsock; jcr->file_bsock = NULL; } return false; }