/** ******************************************************************************* * \brief ******************************************************************************/ IV *iv_resize(IV *piv, uint64_t n, uint64_t m) { uint64_t bits = n * m; uint64_t words = divup(bits, 64); uint64_t bytes = sizeof(IV) + words * sizeof(uint64_t); IV *iv = am_realloc(piv,bytes); if (iv == NULL) { errno = ENOMEM; KV_TRC_FFDC(pAT, "FFDC: iv %p n %"PRIu64" m %"PRIu64", errno = %d", piv, n, m, errno); } else { iv->n = n; iv->m = m; iv->bits = bits; iv->words = words; iv->mask = 1; iv->mask <<= m; iv->mask -= 1; iv->bar = 64 - m; } KV_TRC_DBG(pAT, "iv %p n %"PRIu64" m %"PRIu64"", piv, n, m); return iv; }
PRIVATE size_t write_data_callback(void *ptr, size_t size, size_t nmemb, void *data) { size_t line_len = size * nmemb; WebData *mem = data; /** * if content-length detection in write_header_callback was not successful, mem->response->data will be NULL * as a fallback, allocate a predefined size of memory and realloc if necessary **/ if(!mem->response->data) { mem->response->buffer_size = DATA_BUFFER_SIZE; mem->response->data = (char*)am_malloc(mem->response->buffer_size); dbg_printf(P_INFO2, "[write_data_callback] allocated %d bytes for mem->response->data", mem->response->buffer_size); } if(mem->response->buffer_pos + line_len + 1 > mem->response->buffer_size) { do { mem->response->buffer_size *= 2; }while(mem->response->buffer_size < mem->response->buffer_pos + line_len + 1); mem->response->data = (char *)am_realloc(mem->response->data, mem->response->buffer_size); } if(mem->response->data) { memcpy(&(mem->response->data[mem->response->buffer_pos]), ptr, line_len); mem->response->buffer_pos += line_len; mem->response->data[mem->response->buffer_pos] = 0; } return line_len; }
PRIVATE size_t write_header_callback(void *ptr, size_t size, size_t nmemb, void *data) { size_t line_len = size * nmemb; WebData *mem = (WebData*)data; const char *line = (const char*)ptr; char *tmp = NULL; char *filename = NULL; const char *content_pattern = "Content-Disposition:\\s(inline|attachment);\\s+filename=\"?(.+?)\"?;?\\r?\\n?$"; int content_length = 0; static uint8_t isMoveHeader = 0; /* check the header if it is a redirection header */ if(line_len >= 9 && !memcmp(line, "Location:", 9)) { isMoveHeader = 1; if(mem->response->data != NULL) { am_free(mem->response->data); mem->response->data = NULL; mem->response->buffer_size = 0; mem->content_length = 0; } } else if(line_len >= 15 && !memcmp(line, "Content-Length:", 15)) { /* parse header for Content-Length to allocate correct size for data->response->data */ tmp = getRegExMatch("Content-Length:\\s(\\d+)", line, 1); if(tmp != NULL) { dbg_printf(P_INFO2, "Content-Length: %s", tmp); content_length = atoi(tmp); if(content_length > 0 && !isMoveHeader) { mem->content_length = content_length; mem->response->buffer_size = content_length + 1; mem->response->data = am_realloc(mem->response->data, mem->response->buffer_size); } am_free(tmp); } } else if(line_len >= 19 && !memcmp(line, "Content-Disposition", 19)) { /* parse header for Content-Disposition to get correct filename */ filename = getRegExMatch(content_pattern, line, 2); if(filename) { mem->content_filename = filename; dbg_printf(P_INFO2, "[write_header_callback] Found filename: %s", mem->content_filename); } } else if(line_len >= 2 && !memcmp(line, "\r\n", 2)) { /* We're at the end of a header, reaset the relocation flag */ isMoveHeader = 0; } return line_len; }
PRIVATE size_t parse_Transmission_response(void *ptr, size_t size, size_t nmemb, void *data) { size_t line_len = size * nmemb; const char *line = ptr; WebData *mem = data; const char *session_key = "X-Transmission-Session-Id: "; const size_t key_len = strlen( session_key ); char *tmp = NULL; int content_length = 0; if( (line_len >= key_len) && !memcmp(line, session_key, key_len) ) { const char * begin = line + key_len; const char * end = begin; while( !isspace( *end ) ) { ++end; } am_free( gSessionID ); gSessionID = NULL; gSessionID = am_strndup( begin, end-begin ); /* parse header for Content-Length to allocate correct size for data->response->data */ } else if(line_len >= 15 && !memcmp(line, "Content-Length:", 15)) { tmp = getRegExMatch("Content-Length:\\s(\\d+)", line, 1); if(tmp != NULL) { dbg_printf(P_INFO2, "Content-Length: %s", tmp); content_length = atoi(tmp); if(content_length > 0) { mem->content_length = content_length; mem->response->buffer_size = content_length + 1; mem->response->data = am_realloc(mem->response->data, mem->response->buffer_size); } am_free(tmp); } } return line_len; }
int ark_check_persistence(_ARK *_arkp, uint64_t flags) { int32_t rc = -1; char *p_data_orig = NULL; char *p_data = NULL; ark_io_list_t *bl_array = NULL; p_cntr_t *pptr = NULL; P_ARK_t *pcfg = NULL; hash_t *htp = NULL; BL *blp = NULL; uint64_t rdblks = 0; if (flags & ARK_KV_PERSIST_LOAD) {KV_TRC(pAT, "PERSIST_LOAD");} // Ignore the persistence data and load from scratch if ( (!(flags & ARK_KV_PERSIST_LOAD)) || (flags & ARK_KV_VIRTUAL_LUN) ) { return -1; } p_data_orig = am_malloc(_arkp->bsize); if (p_data_orig == NULL) { KV_TRC_FFDC(pAT, "Out of memory allocating %"PRIu64" bytes for the first " "persistence block", _arkp->bsize); rc = ENOMEM; } else { p_data = ptr_align(p_data_orig); bl_array = bl_chain_no_bl(0, 1); rc = ea_async_io(_arkp->ea, ARK_EA_READ, (void *)p_data, bl_array, 1, 1); am_free(bl_array); } if (rc == 0) { // We've read the first block. We check to see if // persistence data is present and if so, then // read the rest of the data from the flash. pptr = (p_cntr_t *)p_data; _arkp->persdata = p_data_orig; if ( memcmp(pptr->p_cntr_magic, ARK_P_MAGIC, sizeof(pptr->p_cntr_magic) != 0)) { KV_TRC_FFDC(pAT, "No magic number found in persistence data: %d", EINVAL); // The magic number does not match so data is either // not present or is corrupted. rc = -1; } else { // Now we check version and the first persistence data // needs to be the ARK_PERSIST_CONFIG block if (pptr->p_cntr_version != ARK_P_VERSION_1 && pptr->p_cntr_version != ARK_P_VERSION_2) { KV_TRC_FFDC(pAT, "Invalid / unsupported version: %"PRIu64"", pptr->p_cntr_version); rc = EINVAL; } else { // Read in the rest of the persistence data pcfg = (P_ARK_t *)(pptr->p_cntr_data + pptr->p_cntr_cfg_offset); rdblks = pcfg->pblocks; if (rdblks > 1) { p_data_orig = am_realloc(p_data_orig, (rdblks * _arkp->bsize)); if (p_data_orig == NULL) { KV_TRC_FFDC(pAT, "Out of memory allocating %"PRIu64" bytes for " "full persistence block", (rdblks * _arkp->bsize)); rc = ENOMEM; } else { p_data = ptr_align(p_data_orig); bl_array = bl_chain_no_bl(0, rdblks); if (bl_array == NULL) { KV_TRC_FFDC(pAT, "Out of memory allocating %"PRIu64" blocks for " "full persistence data", rdblks); rc = ENOMEM; } } // We are still good to read the rest of the data // from the flash if (rc == 0) { KV_TRC(pAT, "PERSIST_RD rdblks:%ld", rdblks); rc = ea_async_io(_arkp->ea, ARK_EA_READ, (void *)p_data, bl_array, rdblks, 1); am_free(bl_array); pptr = (p_cntr_t *)p_data; pcfg = (P_ARK_t *)(pptr->p_cntr_data + pptr->p_cntr_cfg_offset); _arkp->persdata = p_data_orig; } } } } } // If rc == 0, that means we have persistence data if (rc == 0) { KV_TRC(pAT, "PERSIST_META size %ld bsize %ld hcount %ld bcount %ld " "nthrds %d nasyncs %d basyncs %d blkbits %ld version:%ld", pcfg->size, pcfg->bsize, pcfg->hcount, pcfg->bcount, pcfg->nthrds, pcfg->nasyncs, pcfg->basyncs, pcfg->blkbits, pptr->p_cntr_version); _arkp->persload = 1; _arkp->size = pcfg->size; _arkp->flags = flags; _arkp->bsize = pcfg->bsize; _arkp->bcount = pcfg->bcount; _arkp->blkbits = pcfg->blkbits; _arkp->grow = pcfg->grow; _arkp->hcount = pcfg->hcount; _arkp->vlimit = pcfg->vlimit; _arkp->blkused = pcfg->blkused; _arkp->pers_stats.kv_cnt = pcfg->pstats.kv_cnt; _arkp->pers_stats.blk_cnt = pcfg->pstats.blk_cnt; _arkp->pers_stats.byte_cnt = pcfg->pstats.byte_cnt; KV_TRC(pAT, "ARK_META size %ld bsize %ld hcount %ld bcount %ld " "nthrds %d nasyncs %ld basyncs %d blkbits %ld", _arkp->size, _arkp->bsize, _arkp->hcount, _arkp->bcount, _arkp->nthrds, _arkp->nasyncs, _arkp->basyncs, _arkp->blkbits); htp = (hash_t *)(pptr->p_cntr_data + pptr->p_cntr_ht_offset); _arkp->ht = hash_new(htp->n); if (_arkp->ht == NULL) { if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;} rc = errno; KV_TRC_FFDC(pAT, "ht_new failed: n:%ld rc:%d", htp->n, rc); goto error_exit; } memcpy(_arkp->ht, htp, pptr->p_cntr_ht_size); blp = (BL *)(pptr->p_cntr_data + pptr->p_cntr_bl_offset); _arkp->bl = bl_new(blp->n, blp->w); if (_arkp->bl == NULL) { if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;} rc = errno; KV_TRC_FFDC(pAT, "bl_new failed: n:%ld w:%ld rc:%d", blp->n, blp->w, rc); goto error_exit; } _arkp->bl->count = blp->count; _arkp->bl->head = blp->head; _arkp->bl->hold = blp->hold; _arkp->bl->top = blp->top; if (pptr->p_cntr_version == ARK_P_VERSION_1) { IV *piv = (IV *)(pptr->p_cntr_data + pptr->p_cntr_bliv_offset); KV_TRC(pAT, "PERSIST_VERSION_1 LOADED"); _arkp->bl->top = _arkp->bl->n; // copy IV->data from piv->data memcpy(_arkp->bl->list->data, piv->data, pptr->p_cntr_bliv_size); } else if (pptr->p_cntr_version == ARK_P_VERSION_2) { KV_TRC(pAT, "PERSIST_VERSION_2 LOADED"); // copy IV->data from bliv_offset memcpy(_arkp->bl->list->data, pptr->p_cntr_data + pptr->p_cntr_bliv_offset, pptr->p_cntr_bliv_size); } else { rc = EINVAL; KV_TRC_FFDC(pAT, "bad persistent version number: ver:%ld", pptr->p_cntr_version); goto error_exit; } KV_TRC(pAT, "BL_META: n:%ld count:%ld head:%ld hold:%ld top:%ld", _arkp->bl->n, _arkp->bl->count, _arkp->bl->head, _arkp->bl->hold, _arkp->bl->top); } error_exit: am_free(p_data_orig); return rc; }