//读取Master的packet,怀疑是复制chunk操作,待确定 //调用:masterconn_gotpacket() void masterconn_chunkop(masterconn *eptr,const uint8_t *data,uint32_t length) { uint64_t chunkid; uint32_t version,newversion; uint64_t copychunkid; uint32_t copyversion; uint32_t leng; uint8_t *ptr; #ifdef BGJOBS void *packet; #else /* BGJOBS */ uint8_t status; #endif /* BGJOBS */ if (length!=8+4+8+4+4+4) { syslog(LOG_NOTICE,"MATOCS_CHUNKOP - wrong size (%"PRIu32"/32)",length); eptr->mode = KILL; return; } chunkid = get64bit(&data); version = get32bit(&data); newversion = get32bit(&data); copychunkid = get64bit(&data); copyversion = get32bit(&data); leng = get32bit(&data); #ifdef BGJOBS packet = masterconn_create_detached_packet(CSTOMA_CHUNKOP,8+4+4+8+4+4+1); if (packet==NULL) { eptr->mode=KILL; return; } ptr = masterconn_get_packet_data(packet); put64bit(&ptr,chunkid); put32bit(&ptr,version); put32bit(&ptr,newversion); put64bit(&ptr,copychunkid); put32bit(&ptr,copyversion); put32bit(&ptr,leng); job_chunkop(eptr->jpool,masterconn_chunkopfinished,packet,chunkid,version,newversion,copychunkid,copyversion,leng); #else /* BGJOBS */ status = hdd_chunkop(chunkid,version,newversion,copychunkid,copyversion,leng); ptr = masterconn_create_attached_packet(eptr,CSTOMA_CHUNKOP,8+4+4+8+4+4+1); if (ptr==NULL) { eptr->mode=KILL; return; } put64bit(&ptr,chunkid); put32bit(&ptr,version); put32bit(&ptr,newversion); put64bit(&ptr,copychunkid); put32bit(&ptr,copyversion); put32bit(&ptr,leng); put8bit(&ptr,status); #endif /* BGJOBS */ }
void* job_worker(void *arg) { worker *w = (worker*)arg; jobpool *jp = w->jp; job *jptr; uint8_t *jptrarg; uint8_t status,jstate; uint32_t jobid; uint32_t op; // syslog(LOG_NOTICE,"worker %p started (jobqueue: %p ; jptr:%p ; jptrarg:%p ; status:%p )",(void*)pthread_self(),jp->jobqueue,(void*)&jptr,(void*)&jptrarg,(void*)&status); for (;;) { queue_get(jp->jobqueue,&jobid,&op,&jptrarg,NULL); // syslog(LOG_NOTICE,"job worker got job: %"PRIu32",%"PRIu32,jobid,op); jptr = (job*)jptrarg; zassert(pthread_mutex_lock(&(jp->jobslock))); if (jobid==0 && op==0 && jptrarg==NULL) { // queue has been closed job_close_worker(w); zassert(pthread_mutex_unlock(&(jp->jobslock))); return NULL; } jp->workers_avail--; if (jp->workers_avail==0 && jp->workers_total<jp->workers_max) { job_spawn_worker(jp); } if (jptr!=NULL) { jstate=jptr->jstate; if (jptr->jstate==JSTATE_ENABLED) { jptr->jstate=JSTATE_INPROGRESS; } } else { jstate=JSTATE_DISABLED; } zassert(pthread_mutex_unlock(&(jp->jobslock))); switch (op) { case OP_INVAL: status = ERROR_EINVAL; break; /* case OP_MAINSERV: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { mainserv_serve(*((int*)(jptr->args))); status = STATUS_OK; } break; */ case OP_CHUNKOP: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_chunkop(opargs->chunkid,opargs->version,opargs->newversion,opargs->copychunkid,opargs->copyversion,opargs->length); } break; /* case OP_OPEN: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_open(ocargs->chunkid,ocargs->version); } break; case OP_CLOSE: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_close(ocargs->chunkid); } break; case OP_READ: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_read(rdargs->chunkid,rdargs->version,rdargs->blocknum,rdargs->buffer,rdargs->offset,rdargs->size,rdargs->crcbuff); } break; case OP_WRITE: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_write(wrargs->chunkid,wrargs->version,wrargs->blocknum,wrargs->buffer,wrargs->offset,wrargs->size,wrargs->crcbuff); } break; */ case OP_SERV_READ: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = mainserv_read(rwargs->sock,rwargs->packet,rwargs->length); } break; case OP_SERV_WRITE: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = mainserv_write(rwargs->sock,rwargs->packet,rwargs->length); } break; case OP_REPLICATE: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = replicate(rpargs->chunkid,rpargs->version,rpargs->xormasks,rpargs->srccnt,((uint8_t*)(jptr->args))+sizeof(chunk_rp_args)); } break; case OP_GETBLOCKS: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_get_blocks(ijargs->chunkid,ijargs->version,ijargs->pointer); } break; case OP_GETCHECKSUM: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_get_checksum(ijargs->chunkid,ijargs->version,ijargs->pointer); } break; case OP_GETCHECKSUMTAB: if (jstate==JSTATE_DISABLED) { status = ERROR_NOTDONE; } else { status = hdd_get_checksum_tab(ijargs->chunkid,ijargs->version,ijargs->pointer); } break; default: // OP_EXIT // syslog(LOG_NOTICE,"worker %p exiting (jobqueue: %p)",(void*)pthread_self(),jp->jobqueue); zassert(pthread_mutex_lock(&(jp->jobslock))); job_close_worker(w); zassert(pthread_mutex_unlock(&(jp->jobslock))); return NULL; } job_send_status(jp,jobid,status); zassert(pthread_mutex_lock(&(jp->jobslock))); jp->workers_avail++; if (jp->workers_avail > jp->workers_max_idle) { job_close_worker(w); zassert(pthread_mutex_unlock(&(jp->jobslock))); return NULL; } zassert(pthread_mutex_unlock(&(jp->jobslock))); } }