void masterconn_download_info(masterconn *eptr,const uint8_t *data,uint32_t length) { if (length!=1 && length!=8) { syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_INFO - wrong size (%"PRIu32"/1|8)",length); eptr->mode = KILL; return; } passert(data); if (length==1) { eptr->downloading = 0; syslog(LOG_NOTICE,"download start error"); return; } eptr->filesize = get64bit(&data); eptr->dloffset = 0; eptr->downloadretrycnt = 0; eptr->dlstartuts = monotonic_useconds(); if (eptr->downloading==1) { eptr->metafd = open("metadata_ml.tmp",O_WRONLY | O_TRUNC | O_CREAT,0666); } else if (eptr->downloading==11 || eptr->downloading==12) { eptr->metafd = open("changelog_ml.tmp",O_WRONLY | O_TRUNC | O_CREAT,0666); } else { syslog(LOG_NOTICE,"unexpected MATOAN_DOWNLOAD_INFO packet"); eptr->mode = KILL; return; } if (eptr->metafd<0) { mfs_errlog_silent(LOG_NOTICE,"error opening metafile"); masterconn_download_end(eptr); return; } masterconn_download_next(eptr); }
void masterconn_download_start(serventry *eptr,const uint8_t *data,uint32_t length) { if (length!=1 && length!=8) { MFSLOG(LOG_NOTICE,"MATOSLA_DOWNLOAD_START - wrong size (%"PRIu32"/1|8)",length); eptr->mode = KILL; return; } if (length==1) { MFSLOG(LOG_NOTICE,"download start error"); return; } eptr->filesize = get64bit(&data); eptr->dloffset = 0; eptr->retrycnt = 0; eptr->dlstartuts = main_utime(); if (eptr->downloading==1) { eptr->metafd = open("metadata.tmp",O_WRONLY | O_TRUNC | O_CREAT,0666); } else if (eptr->downloading==2) { eptr->metafd = open("changelog.0.tmp",O_WRONLY | O_TRUNC | O_CREAT,0666); } else { MFSLOG(LOG_NOTICE,"unexpected MATOSLA_DOWNLOAD_START packet"); eptr->mode = KILL; return; } if (eptr->metafd<0) { MFSLOG(LOG_NOTICE,"error opening metafile: %m"); masterconn_download_end(eptr,4); return; } masterconn_download_next(eptr); }
void masterconn_download_next(masterconn *eptr) { uint8_t *ptr; uint8_t filenum; int64_t dltime; if (eptr->dloffset>=eptr->filesize) { // end of file filenum = eptr->downloading; if (masterconn_download_end(eptr)<0) { return; } dltime = main_utime()-eptr->dlstartuts; if (dltime<=0) { dltime=1; } syslog(LOG_NOTICE,"%s downloaded %"PRIu64"B/%"PRIu64".%06"PRIu32"s (%.3lf MB/s)",(filenum==1)?"metadata":(filenum==2)?"sessions":(filenum==11)?"changelog_0":(filenum==12)?"changelog_1":"???",eptr->filesize,dltime/1000000,(uint32_t)(dltime%1000000),(double)(eptr->filesize)/(double)(dltime)); if (filenum==1) { if (masterconn_metadata_check("metadata_ml.tmp")==0) { if (BackMetaCopies>0) { char metaname1[100],metaname2[100]; int i; for (i=BackMetaCopies-1 ; i>0 ; i--) { snprintf(metaname1,100,"metadata_ml.mfs.back.%"PRIu32,i+1); snprintf(metaname2,100,"metadata_ml.mfs.back.%"PRIu32,i); rename(metaname2,metaname1); } rename("metadata_ml.mfs.back","metadata_ml.mfs.back.1"); } if (rename("metadata_ml.tmp","metadata_ml.mfs.back")<0) { syslog(LOG_NOTICE,"can't rename downloaded metadata - do it manually before next download"); } } if (eptr->oldmode==0) { masterconn_download_init(eptr,11); } else { masterconn_download_init(eptr,2); } } else if (filenum==11) { if (rename("changelog_ml.tmp","changelog_ml_back.0.mfs")<0) { syslog(LOG_NOTICE,"can't rename downloaded changelog - do it manually before next download"); } masterconn_download_init(eptr,12); } else if (filenum==12) { if (rename("changelog_ml.tmp","changelog_ml_back.1.mfs")<0) { syslog(LOG_NOTICE,"can't rename downloaded changelog - do it manually before next download"); } masterconn_download_init(eptr,2); } else if (filenum==2) { if (rename("sessions_ml.tmp","sessions_ml.mfs")<0) { syslog(LOG_NOTICE,"can't rename downloaded sessions - do it manually before next download"); } } } else { // send request for next data packet ptr = masterconn_createpacket(eptr,MLTOMA_DOWNLOAD_DATA,12); put64bit(&ptr,eptr->dloffset); if (eptr->filesize-eptr->dloffset>META_DL_BLOCK) { put32bit(&ptr,META_DL_BLOCK); } else { put32bit(&ptr,eptr->filesize-eptr->dloffset); } } }
void masterconn_download_next(serventry *eptr) { uint8_t *ptr; uint8_t filenum; uint64_t dltime; uint64_t starttime; if (eptr->dloffset>=eptr->filesize) { // end of file filenum = eptr->downloading; dltime = main_utime()-eptr->dlstartuts; MFSLOG(LOG_NOTICE,"%s downloaded %"PRIu64"B/%"PRIu64".%06"PRIu32"s (%.3lf MB/s)",(filenum==1)?"metadata":(filenum==2)?"changelog.0":"???",eptr->filesize,dltime/1000000,(uint32_t)(dltime%1000000),(double)(eptr->filesize)/(double)(dltime)); if (filenum==1) { if (rename("metadata.tmp","metadata.mfs")<0) { MFSLOG(LOG_NOTICE,"can't rename downloaded metadata - do it manually before next download"); } else { MFSLOG(LOG_NOTICE,"loading metadata ..."); fs_strinit(); chunk_strinit(); starttime = get_current_time(); if (fs_loadall(NULL)<0) { return; MFSLOG(LOG_NOTICE,"fs init failed"); } MFSLOG(LOG_NOTICE,"metadata file has been loaded"); } } else if (filenum==2) { if (rename("changelog.0.tmp","changelog.0.mfs")<0) { MFSLOG(LOG_NOTICE,"can't rename downloaded changelog.0.mfs - do it manually before next download"); } else { if (restore() < 0) { MFSLOG(LOG_ERR,"restore failed"); } else { meta_ready = 0; } } } //filenum:1,metadata finish ;2,changelog.0 finish if (masterconn_download_end(eptr,filenum)<0) { return; } } else { // send request for next data packet ptr = masterconn_createpacket(eptr,SLATOMA_DOWNLOAD_DATA,12); if (ptr==NULL) { eptr->mode=KILL; return; } put64bit(&ptr,eptr->dloffset); if (eptr->filesize-eptr->dloffset>META_DL_BLOCK) { put32bit(&ptr,META_DL_BLOCK); } else { put32bit(&ptr,eptr->filesize-eptr->dloffset); } } }
void masterconn_download_data(masterconn *eptr,const uint8_t *data,uint32_t length) { uint64_t offset; uint32_t leng; uint32_t crc; ssize_t ret; if (eptr->metafd<0) { syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - file not opened"); eptr->mode = KILL; return; } if (length<16) { syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - wrong size (%"PRIu32"/16+data)",length); eptr->mode = KILL; return; } passert(data); offset = get64bit(&data); leng = get32bit(&data); crc = get32bit(&data); if (leng+16!=length) { syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - wrong size (%"PRIu32"/16+%"PRIu32")",length,leng); eptr->mode = KILL; return; } if (offset!=eptr->dloffset) { syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - unexpected file offset (%"PRIu64"/%"PRIu64")",offset,eptr->dloffset); eptr->mode = KILL; return; } if (offset+leng>eptr->filesize) { syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - unexpected file size (%"PRIu64"/%"PRIu64")",offset+leng,eptr->filesize); eptr->mode = KILL; return; } #ifdef HAVE_PWRITE ret = pwrite(eptr->metafd,data,leng,offset); #else /* HAVE_PWRITE */ lseek(eptr->metafd,offset,SEEK_SET); ret = write(eptr->metafd,data,leng); #endif /* HAVE_PWRITE */ if (ret!=(ssize_t)leng) { mfs_errlog_silent(LOG_NOTICE,"error writing metafile"); if (eptr->downloadretrycnt>=5) { masterconn_download_end(eptr); } else { eptr->downloadretrycnt++; masterconn_download_next(eptr); } return; } if (crc!=mycrc32(0,data,leng)) { syslog(LOG_NOTICE,"metafile data crc error"); if (eptr->downloadretrycnt>=5) { masterconn_download_end(eptr); } else { eptr->downloadretrycnt++; masterconn_download_next(eptr); } return; } if (fsync(eptr->metafd)<0) { mfs_errlog_silent(LOG_NOTICE,"error syncing metafile"); if (eptr->downloadretrycnt>=5) { masterconn_download_end(eptr); } else { eptr->downloadretrycnt++; masterconn_download_next(eptr); } return; } eptr->dloffset+=leng; eptr->downloadretrycnt=0; masterconn_download_next(eptr); }