コード例 #1
0
ファイル: dir_hier_move.cpp プロジェクト: niclaslockner/boinc
int main(int argc, char** argv) {
    char* src_dir, *dst_dir;
    int fanout=0;
    std::string filename;
    char dst_path[MAXPATHLEN], src_path[MAXPATHLEN];
    int retval;
    
    if ( (argc == 1) || !strcmp(argv[1], "-h")  || !strcmp(argv[1],"--help") || (argc != 4) ) {
        fprintf(stderr, "%s", usage);
        exit(1);
    }
    src_dir = argv[1];
    dst_dir = argv[2];
    fanout = atoi(argv[3]);
    if (!fanout) {
        fprintf(stderr, "%s", usage);
        exit(1);
    }

    DirScanner scanner(src_dir);
    while (scanner.scan(filename)) {
        retval = dir_hier_path(filename.c_str(), dst_dir, fanout, dst_path, true);
        if (retval) {
            fprintf(stderr, "dir_hier_path: %s\n", boincerror(retval));
            exit(1);
        }
        sprintf(src_path, "%s/%s", src_dir, filename.c_str());
        retval = rename(src_path, dst_path);
        if (retval) {
            perror("rename");
            exit(1);
        }
    }
}
コード例 #2
0
// get the path a WU's input file
//
int get_file_path(WORKUNIT& wu, char* path) {
    char buf[256];
    bool flag;
    flag = parse_str(wu.xml_doc, "<name>", buf, sizeof(buf));
    if (!flag) return ERR_XML_PARSE;
    dir_hier_path(buf, config.download_dir, config.uldl_dir_fanout, path);
    return 0;
}
コード例 #3
0
// If using locality scheduling, there are probably many result that
// use same file, so decrement available space ONLY if the host
// doesn't yet have this file. Note: this gets the file size from the
// download dir.
//
// Return value 0 means that this routine was successful in adjusting
// the available disk space in the work request.  Return value <0
// means that it was not successful, and that something went wrong.
// Return values >0 mean that the host does not contain the file, and
// that no previously assigned work includes the file, and so the disk
// space in the work request should be adjusted by the calling
// routine, in the same way as if there was no scheduling locality.
//
int decrement_disk_space_locality( WORKUNIT& wu) {
    char filename[256], path[MAXPATHLEN];
    int filesize;
    struct stat buf;

    // get filename from WU name
    //
    if (extract_filename(wu.name, filename)) {
        log_messages.printf(MSG_CRITICAL,
            "No filename found in [WU#%d %s]\n", wu.id, wu.name
        );
        return -1;
    }

    // when checking to see if the host has the file, we need to
    // ignore the last WU included at the end of the reply, since it
    // corresponds to the one that we are (possibly) going to send!
    // So make a copy and pop the current WU off the end.

    if (!host_has_file(filename, true))
        return 1;

    // If we are here, then the host ALREADY has the file, or its size
    // has already been accounted for in a previous WU.  In this case,
    // don't count the file size again in computing the disk
    // requirements of this request.

    // Get path to file, and determine its size
    dir_hier_path(
        filename, config.download_dir, config.uldl_dir_fanout, path, false
    );
    if (stat(path, &buf)) {
        log_messages.printf(MSG_CRITICAL,
            "Unable to find file %s at path %s\n", filename, path
        );
        return -1;
    }

    filesize=buf.st_size;

    if (filesize<wu.rsc_disk_bound) {
        g_wreq->disk_available -= (wu.rsc_disk_bound-filesize);
        if (config.debug_locality) {
            log_messages.printf(MSG_NORMAL,
                "[locality] [HOST#%d] reducing disk needed for WU by %d bytes (length of %s)\n",
                g_reply->host.id, filesize, filename
            );
        }
        return 0;
    }

    log_messages.printf(MSG_CRITICAL,
        "File %s size %d bytes > wu.rsc_disk_bound for WU#%d (%s)\n",
        path, filesize, wu.id, wu.name
    );
    return -1;
}
コード例 #4
0
// Given a filename, find its full path in the upload directory hierarchy
// Return ERR_OPENDIR if dir isn't there (possibly recoverable error),
// ERR_NOT_FOUND if dir is there but not file
//
int get_file_path(
    const char *filename, char* upload_dir, int fanout, char* path
) {
    dir_hier_path(filename, upload_dir, fanout, path, true);
    if (boinc_file_exists(path)) {
        return 0;
    }
    char* p = strrchr(path, '/');
    *p = 0;
    if (boinc_file_exists(path)) {
        return ERR_NOT_FOUND;
    }
    return ERR_OPENDIR;
}
コード例 #5
0
int handle_remove(const char* name) {
    DB_VDA_FILE vf;
    char buf[1024];
    sprintf(buf, "where name='%s'", name);
    int retval = vf.lookup(buf);
    if (retval) return retval;

    // delete DB records
    //
    DB_VDA_CHUNK_HOST ch;
    sprintf(buf, "vda_file_id=%d", vf.id);
    ch.delete_from_db_multi(buf);
    vf.delete_from_db();

    dir_hier_path(name, config.download_dir, config.uldl_dir_fanout, buf);
    unlink(buf);
    retval = chdir(vf.dir);
    if (retval) perror("chdir");
    retval = system("/bin/rm -r [0-9]* Coding data.vda");
    if (retval) perror("system");
    return 0;
}
コード例 #6
0
ファイル: dir_hier_path.cpp プロジェクト: abergstr/BOINC
int main(int argc, char** argv) {
    char path[256];
    int retval;

    if ( (argc == 1) ||  !strcmp(argv[1], "-h")  || !strcmp(argv[1],"--help") || (argc != 2) ) {
      printf (usage);
      exit(1);
    }

    retval = config.parse_file();
    if (retval) {
        fprintf(stderr, "Can't parse config.xml: %s\n", boincerror(retval));
        exit(1);
    }

    retval = dir_hier_path(
        argv[1], config.download_dir, config.uldl_dir_fanout, path, true
    );
    if (retval) {
        fprintf(stderr, "dir_hier_path(): %d\n", retval);
        exit(1);
    }
    printf("%s\n", path);
}
コード例 #7
0
// always returns HTML reply
//
int handle_get_file_size(char* file_name) {
    struct stat sbuf;
    char path[MAXPATHLEN], buf[256];
    int retval, pid, fd;

    // TODO: check to ensure path doesn't point somewhere bad
    // Use 64-bit variant
    //
    retval = dir_hier_path(
        file_name, config.upload_dir, config.uldl_dir_fanout, path
    );
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "Failed to find/create directory for file '%s' in '%s'.\n",
            file_name, config.upload_dir
        );
        return return_error(ERR_TRANSIENT, "can't open file");
    }

    // if the volume is full, report a transient error
    // to prevent the client from starting a transfer
    //
    if (volume_full(config.upload_dir)) {
        return return_error(ERR_TRANSIENT, "Server is out of disk space");
    }

    fd = open(path, O_WRONLY|O_APPEND);

    if (fd<0 && ENOENT==errno) {
        // file does not exist: return zero length
        //
        log_messages.printf(MSG_NORMAL,
            "handle_get_file_size(): [%s] returning zero\n", file_name
        );
        return return_success("<file_size>0</file_size>");
    }

    if (fd<0) {
        // can't get file descriptor: try again later
        //
        log_messages.printf(MSG_CRITICAL,
            "handle_get_file_size(): cannot open [%s] %s\n",
            file_name, strerror(errno)
        );
        return return_error(ERR_TRANSIENT, "can't open file");
    }

    if ((pid=mylockf(fd))) {
        // file locked by another file_upload_handler: try again later
        //
        close(fd);
        log_messages.printf(MSG_CRITICAL,
            "handle_get_file_size(): [%s] returning error\n", file_name
        );
        return return_error(ERR_TRANSIENT,
            "[%s] locked by file_upload_handler PID=%d", file_name, pid
        );
    }
    // file exists, writable, not locked by anyone else, so return length.
    //
    retval = stat(path, &sbuf);
    close(fd);
    if (retval) {
        // file DOES perhaps exist, but can't stat it: try again later
        //
        log_messages.printf(MSG_CRITICAL,
            "handle_get_file_size(): [%s] returning error %s\n",
            file_name, strerror(errno)
        );
        return return_error(ERR_TRANSIENT, "cannot stat file" );
    }

    log_messages.printf(MSG_NORMAL,
        "handle_get_file_size(): [%s] returning %d\n",
        file_name, (int)sbuf.st_size
    );
    sprintf(buf, "<file_size>%d</file_size>", (int)sbuf.st_size);
    return return_success(buf);
}
コード例 #8
0
// ALWAYS generates an HTML reply
//
int handle_file_upload(FILE* in, R_RSA_PUBLIC_KEY& key) {
    char buf[256], path[MAXPATHLEN], signed_xml[1024];
    char name[256], stemp[256];
    double max_nbytes=-1;
    char xml_signature[1024];
    int retval;
    double offset=0, nbytes = -1;
    bool is_valid, btemp;

    strcpy(name, "");
    strcpy(xml_signature, "");
    bool found_data = false;
    while (fgets(buf, 256, in)) {
#if 1
        log_messages.printf(MSG_NORMAL, "got:%s\n", buf);
#endif
        if (match_tag(buf, "<file_info>")) continue;
        if (match_tag(buf, "</file_info>")) continue;
        if (match_tag(buf, "<signed_xml>")) continue;
        if (match_tag(buf, "</signed_xml>")) continue;
        if (parse_bool(buf, "generated_locally", btemp)) continue;
        if (parse_bool(buf, "upload_when_present", btemp)) continue;
        if (parse_str(buf, "<url>", stemp, sizeof(stemp))) continue;
        if (parse_str(buf, "<md5_cksum>", stemp, sizeof(stemp))) continue;
        if (match_tag(buf, "<xml_signature>")) {
            copy_element_contents(
                in, "</xml_signature>", xml_signature, sizeof(xml_signature)
            );
            continue;
        }
        if (parse_str(buf, "<name>", name, sizeof(name))) {
            strcpy(this_filename, name);
            continue;
        }
        if (parse_double(buf, "<max_nbytes>", max_nbytes)) continue;
        if (parse_double(buf, "<offset>", offset)) continue;
        if (parse_double(buf, "<nbytes>", nbytes)) continue;
        if (match_tag(buf, "<data>")) {
            found_data = true;
            break;
        }
        log_messages.printf(MSG_CRITICAL, "unrecognized: %s", buf);
    }
    if (strlen(name) == 0) {
        return return_error(ERR_PERMANENT, "Missing name");
    }
    if (!found_data) {
        return return_error(ERR_PERMANENT, "Missing <data> tag");
    }
    if (!config.ignore_upload_certificates) {
        if (strlen(xml_signature) == 0) {
            return return_error(ERR_PERMANENT, "missing signature");
        }
        if (max_nbytes < 0) {
            return return_error(ERR_PERMANENT, "missing max_nbytes");
        }
        sprintf(signed_xml,
            "<name>%s</name><max_nbytes>%.0f</max_nbytes>",
            name, max_nbytes
        );
        retval = check_string_signature(
            signed_xml, xml_signature, key, is_valid
        );
        if (retval || !is_valid) {
            log_messages.printf(MSG_CRITICAL,
                "check_string_signature() [%s] [%s] retval %d, is_valid = %d\n",
                signed_xml, xml_signature,
                retval, is_valid
            );
            log_messages.printf(MSG_NORMAL,
                "signed xml: %s\n", signed_xml
            );
            log_messages.printf(MSG_NORMAL,
                "signature: %s\n", xml_signature
            );
            return return_error(ERR_PERMANENT, "invalid signature");
        }
    }
    if (nbytes < 0) {
        return return_error(ERR_PERMANENT, "nbytes missing or negative");
    }

    // enforce limits in signed XML
    //
    if (!config.ignore_upload_certificates) {
        if (nbytes > max_nbytes) {
            sprintf(buf,
                "file size (%d KB) exceeds limit (%d KB)",
                (int)(nbytes/1024), (int)(max_nbytes/1024)
            );
            copy_socket_to_null(in);
            return return_error(ERR_PERMANENT, buf);
        }
    }

    // make sure filename is legit
    //
    if (strstr(name, "..")) {
        return return_error(ERR_PERMANENT,
            "file_upload_handler: .. found in filename: %s",
            name
        );
    }

    if (strlen(name) == 0) {
        return return_error(ERR_PERMANENT,
            "file_upload_handler: no filename; nbytes %f", nbytes
        );
    }

    retval = dir_hier_path(
        name, config.upload_dir, config.uldl_dir_fanout,
        path, true
    );
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "Failed to find/create directory for file '%s' in '%s'\n",
            name, config.upload_dir
        );
        return return_error(ERR_TRANSIENT, "can't open file");
    }
    log_messages.printf(MSG_NORMAL,
        "Starting upload of %s from %s [offset=%.0f, nbytes=%.0f]\n",
        name,
        get_remote_addr(),
        offset, nbytes
    );
#ifndef _USING_FCGI_
    fflush(stderr);
#endif
    if (offset >= nbytes) {
        log_messages.printf(MSG_CRITICAL,
            "ERROR: offset >= nbytes!!\n"
        );
        return return_success(0);
    }
    retval = copy_socket_to_file(in, path, offset, nbytes);
    log_messages.printf(MSG_NORMAL,
        "Ended upload of %s from %s; retval %d\n",
        name,
        get_remote_addr(),
        retval
    );
#ifndef _USING_FCGI_
    fflush(stderr);
#endif
    return retval;
}
コード例 #9
0
int SCHED_CONFIG::download_path(const char* filename, char* path) {
    return dir_hier_path(filename, download_dir, uldl_dir_fanout, path, true);
}
コード例 #10
0
void rename_wu_files() {
  int i, retval;
  char oldname[256],newname[1024];
  unsigned long sz;
  DB_WORKUNIT db_wu;
  const char *name[1];
  char *wudir="./wu_inbox";
  xml_encoding encoding=(noencode?_binary:_x_setiathome);
  FILE *tmpfile;

  if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) {
    boinc_db.print_error("boinc_db.open");
    log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Fatal error in boinc_db.open\n");
    exit(1);
  }

  for (i=0;i<NSTRIPS;i++) {
    name[0]=wuheaders[i].name;
    sprintf(oldname,"%s/%s",wudir,name[0]);

    //sprintf(newname,"%s%s/%s",projectdir,WU_SUBDIR,name[0]);
    retval = dir_hier_path(name[0],
                           boinc_config.download_dir,
                           boinc_config.uldl_dir_fanout,
                           newname,
			   true
    );
    if (retval) {
        char buf[1024];
        log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"[%s] dir_hier_path() failed: %d\n", name[0], retval);
	exit(1);
    } 

    struct stat sbuf;
    if (!stat(oldname,&sbuf) && (tmpfile=fopen(oldname,"a"))) {
       std::string tmpstr=xml_encode_string(bin_data[i],encoding);
       fprintf(tmpfile,"<data length=%ld encoding=\"%s\">",tmpstr.size(),
            xml_encoding_names[encoding]);
       fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile);
       fprintf(tmpfile,"</data>\n");
       fprintf(tmpfile,"</workunit>\n");
       sz=bin_data[i].size();

       fclose(tmpfile);
    } else {
        log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Header file no longer exists! splitter start script may be failing\n ");
	exit(1);
    }  
    if (!nodb) {
      if (!filecopy(oldname,newname)) {
        db_wu.clear();
        db_wu.opaque=wuheaders[i].id;
        strncpy(db_wu.name,name[0],sizeof(db_wu.name)-2);
        db_wu.appid=app.id;
        //db_wu.rsc_fpops_est=2.79248e+13*6;
        //db_wu.rsc_fpops_bound=4.46797e+14*6;
	double beam=wuheaders[i].group_info->receiver_cfg->beam_width;
        double ar=wuheaders[i].group_info->data_desc.true_angle_range;
        double dur=(double)(wuheaders[i].group_info->data_desc.nsamples)/wuheaders[i].subband_desc.sample_rate;
        double min_slew=wuheaders[i].group_info->analysis_cfg->pot_min_slew;
        double max_slew=wuheaders[i].group_info->analysis_cfg->pot_max_slew;
	if ( ar <= beam ) {
	  db_wu.rsc_fpops_est=9.193e+13;
	} else if ( ar <= ( dur*min_slew ) ) {
          db_wu.rsc_fpops_est=5.962e+13+2.296e+12/ar;
        } else if ( ar <= ( dur*max_slew ) ) {
          db_wu.rsc_fpops_est=5.749e+13+1.476e+13/ar;
        } else {
          db_wu.rsc_fpops_est=3.535e+13;
        }
	db_wu.rsc_fpops_est*=(0.333/wuheaders[i].group_info->analysis_cfg->chirp_resolution);
        db_wu.rsc_fpops_bound=db_wu.rsc_fpops_est*10;
        db_wu.rsc_memory_bound=33554432;
        db_wu.rsc_disk_bound=33554432;
        // Our minimum is a 40 MFLOP machine
        db_wu.delay_bound=std::max(86400.0*7,db_wu.rsc_fpops_est/4e+7);
        db_wu.min_quorum=sah_config.min_quorum;
        db_wu.target_nresults=sah_config.target_nresults;
        db_wu.max_error_results=sah_config.max_error_results;
        db_wu.max_total_results=sah_config.max_total_results;
        db_wu.max_success_results=sah_config.max_success_results;
        strncpy(db_wu.app_name,appname,sizeof(db_wu.app_name)-2);
        if (create_work(db_wu,
                        wu_template,
                        result_template_filename,
                        result_template_filepath,
                        name,
                        1,
		        boinc_config,
		        NULL
                       )
           ) {
          log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"create work failed\n");
          exit(1);
        }
        //unlink(oldname);   // we now *always* unlink
      } else {
	  log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"file copy failed\n");
          exit(1);
      }
      unlink(oldname);
    }
  }
  boinc_db.close();
}
コード例 #11
0
// ALWAYS generates an HTML reply
//
int handle_file_upload(FILE* in, R_RSA_PUBLIC_KEY& key) {
    char buf[256], path[512], temp[256];
    FILE_INFO file_info;
    int retval;
    double nbytes=-1, offset=0;
    bool is_valid;

    while (fgets(buf, 256, in)) {
#if 0
        log_messages.printf(MSG_NORMAL, "got:%s\n", buf);
#endif
        if (match_tag(buf, "<file_info>")) {
            retval = file_info.parse(in);
            if (retval) {
                return return_error(ERR_PERMANENT, "FILE_INFO::parse");
            }
#if 0
            log_messages.printf(MSG_NORMAL,
                "file info:\n%s\n", file_info.signed_xml
            );
#endif
            if (!config.ignore_upload_certificates) {
                if (!file_info.signed_xml || !file_info.xml_signature) {
                    log_messages.printf(MSG_CRITICAL,
                        "file info is missing signature\n"
                    );
                    return return_error(ERR_PERMANENT, "invalid signature");
                } else {
                    retval = verify_string(
                        file_info.signed_xml, file_info.xml_signature, key, is_valid
                    );
                    if (retval || !is_valid) {
                        log_messages.printf(MSG_CRITICAL,
                            "verify_string() [%s] [%s] retval %d, is_valid = %d\n",
                            file_info.signed_xml, file_info.xml_signature,
                            retval, is_valid
                        );
                        log_messages.printf(MSG_NORMAL,
                            "signed xml: %s", file_info.signed_xml
                        );
                        log_messages.printf(MSG_NORMAL,
                            "signature: %s", file_info.xml_signature
                        );
                        return return_error(ERR_PERMANENT, "invalid signature");
                    }
                }
            }
            continue;
        }
        if (parse_double(buf, "<offset>", offset)) continue;
        if (parse_double(buf, "<nbytes>", nbytes)) continue;
        if (parse_str(buf, "<md5_cksum>", temp, sizeof(temp))) continue;
        if (match_tag(buf, "<data>")) {
            if (nbytes < 0) {
                return return_error(ERR_PERMANENT, "nbytes missing or negative");
            }

            // enforce limits in signed XML
            //
            if (!config.ignore_upload_certificates) {
                if (nbytes > file_info.max_nbytes) {
                    sprintf(buf,
                        "file size (%d KB) exceeds limit (%d KB)",
                        (int)(nbytes/1024), (int)(file_info.max_nbytes/1024)
                    );
                    copy_socket_to_null(in);
                    return return_error(ERR_PERMANENT, buf);
                }
            }

            // make sure filename is legit
            //
            if (strstr(file_info.name, "..")) {
                return return_error(ERR_PERMANENT,
                    "file_upload_handler: .. found in filename: %s",
                    file_info.name
                );
            }

            if (strlen(file_info.name) == 0) {
                return return_error(ERR_PERMANENT,
                    "file_upload_handler: no filename; nbytes %f", nbytes
                );
            }

            retval = dir_hier_path(
                file_info.name, config.upload_dir, config.uldl_dir_fanout,
                path, true
            );
            if (retval) {
                log_messages.printf(MSG_CRITICAL,
                    "Failed to find/create directory for file '%s' in '%s'\n",
                    file_info.name, config.upload_dir
                );
                return return_error(ERR_TRANSIENT, "can't open file");
            }
            log_messages.printf(MSG_NORMAL,
                "Starting upload of %s from %s [offset=%.0f, nbytes=%.0f]\n",
                file_info.name,
                get_remote_addr(),
                offset, nbytes
            );
#ifndef _USING_FCGI_
            fflush(stderr);
#endif
            if (offset >= nbytes) {
                log_messages.printf(MSG_CRITICAL,
                    "ERROR: offset >= nbytes!!\n"
                );
                return return_success(0);
            }
            retval = copy_socket_to_file(in, path, offset, nbytes);
            log_messages.printf(MSG_NORMAL,
                "Ended upload of %s from %s; retval %d\n",
                file_info.name,
                get_remote_addr(),
                retval
            );
#ifndef _USING_FCGI_
            fflush(stderr);
#endif
            return retval;
        }
        log_messages.printf(MSG_CRITICAL,
            "unrecognized: %s", buf
        );
    }
    return return_error(ERR_PERMANENT, "Missing <data> tag");
}