void make_trace(char* path) { init_jcr(path); sds trace_file = sdsnew(path); char *p = trace_file + sdslen(trace_file) - 1; while (*p == '/') --p; *(p + 1) = 0; sdsupdatelen(trace_file); trace_file = sdscat(trace_file, ".trace"); NOTICE("output to %s", trace_file); start_read_phase(); start_chunk_phase(); start_hash_phase(); unsigned char code[41]; FILE *fp = fopen(trace_file, "w"); while (1) { struct chunk *c = sync_queue_pop(hash_queue); if (c == NULL) { break; } if (CHECK_CHUNK(c, CHUNK_FILE_START)) { destor_log(DESTOR_NOTICE, c->data); fprintf(fp, "file start %zd\n", strlen(c->data)); fprintf(fp, "%s\n", c->data); } else if (CHECK_CHUNK(c, CHUNK_FILE_END)) { fprintf(fp, "file end\n"); } else { hash2code(c->fp, code); code[40] = 0; fprintf(fp, "%s %d\n", code, c->size); } free_chunk(c); } fprintf(fp, "stream end"); fclose(fp); }
void processInputBuffer(redisClient *c) { again: /* Before to process the input buffer, make sure the client is not * waitig for a blocking operation such as BLPOP. Note that the first * iteration the client is never blocked, otherwise the processInputBuffer * would not be called at all, but after the execution of the first commands * in the input buffer the client may be blocked, and the "goto again" * will try to reiterate. The following line will make it return asap. */ if (c->flags & REDIS_BLOCKED || c->flags & REDIS_IO_WAIT) return; if (c->bulklen == -1) { /* Read the first line of the query */ char *p = strchr(c->querybuf,'\n'); size_t querylen; if (p) { sds query, *argv; int argc, j; query = c->querybuf; c->querybuf = sdsempty(); querylen = 1+(p-(query)); if (sdslen(query) > querylen) { /* leave data after the first line of the query in the buffer */ c->querybuf = sdscatlen(c->querybuf,query+querylen,sdslen(query)-querylen); } *p = '\0'; /* remove "\n" */ if (*(p-1) == '\r') *(p-1) = '\0'; /* and "\r" if any */ sdsupdatelen(query); /* Now we can split the query in arguments */ argv = sdssplitlen(query,sdslen(query)," ",1,&argc); sdsfree(query); if (c->argv) zfree(c->argv); c->argv = zmalloc(sizeof(robj*)*argc); for (j = 0; j < argc; j++) { if (sdslen(argv[j])) { c->argv[c->argc] = createObject(REDIS_STRING,argv[j]); c->argc++; } else { sdsfree(argv[j]); } } zfree(argv); if (c->argc) { /* Execute the command. If the client is still valid * after processCommand() return and there is something * on the query buffer try to process the next command. */ if (processCommand(c) && sdslen(c->querybuf)) goto again; } else { /* Nothing to process, argc == 0. Just process the query * buffer if it's not empty or return to the caller */ if (sdslen(c->querybuf)) goto again; } return; } else if (sdslen(c->querybuf) >= REDIS_REQUEST_MAX_SIZE) { redisLog(REDIS_VERBOSE, "Client protocol error"); freeClient(c); return; } } else { /* Bulk read handling. Note that if we are at this point the client already sent a command terminated with a newline, we are reading the bulk data that is actually the last argument of the command. */ int qbl = sdslen(c->querybuf); if (c->bulklen <= qbl) { /* Copy everything but the final CRLF as final argument */ c->argv[c->argc] = createStringObject(c->querybuf,c->bulklen-2); c->argc++; c->querybuf = sdsrange(c->querybuf,c->bulklen,-1); /* Process the command. If the client is still valid after * the processing and there is more data in the buffer * try to parse it. */ if (processCommand(c) && sdslen(c->querybuf)) goto again; return; } } }
/* * Create a new backupVersion structure for a backup run. */ struct backupVersion* create_backup_version(const char *path) { struct backupVersion *b = (struct backupVersion *) malloc( sizeof(struct backupVersion)); b->bv_num = get_next_version_number(); b->path = sdsnew(path); /* * If the path points to a file, */ int cur = sdslen(b->path) - 1; while (b->path[cur] != '/') { b->path[cur] = 0; cur--; } sdsupdatelen(b->path); b->deleted = 0; b->number_of_chunks = 0; b->number_of_files = 0; b->fname_prefix = sdsdup(recipepath); b->fname_prefix = sdscat(b->fname_prefix, "bv"); char s[20]; sprintf(s, "%d", b->bv_num); b->fname_prefix = sdscat(b->fname_prefix, s); sds fname = sdsdup(b->fname_prefix); fname = sdscat(fname, ".meta"); if ((b->metadata_fp = fopen(fname, "w")) == 0) { fprintf(stderr, "Can not create bv%d.meta!\n", b->bv_num); exit(1); } fseek(b->metadata_fp, 0, SEEK_SET); fwrite(&b->bv_num, sizeof(b->bv_num), 1, b->metadata_fp); fwrite(&b->deleted, sizeof(b->deleted), 1, b->metadata_fp); fwrite(&b->number_of_files, sizeof(b->number_of_files), 1, b->metadata_fp); fwrite(&b->number_of_chunks, sizeof(b->number_of_chunks), 1, b->metadata_fp); int pathlen = sdslen(b->path); fwrite(&pathlen, sizeof(pathlen), 1, b->metadata_fp); fwrite(b->path, sdslen(b->path), 1, b->metadata_fp); b->metabuf = malloc(metabufsize); b->metabufoff = 0; fname = sdscpy(fname, b->fname_prefix); fname = sdscat(fname, ".recipe"); if ((b->recipe_fp = fopen(fname, "w+")) <= 0) { fprintf(stderr, "Can not create bv%d.recipe!\n", b->bv_num); exit(1); } b->recordbuf = malloc(recordbufsize); b->recordbufoff = 0; fname = sdscpy(fname, b->fname_prefix); fname = sdscat(fname, ".records"); if ((b->record_fp = fopen(fname, "w")) <= 0) { fprintf(stderr, "Can not create bv%d.records!\n", b->bv_num); exit(1); } sdsfree(fname); return b; }