int restore_line(const char *filename,uint64_t lv,char *line) { char *ptr; uint32_t ts; int status; char* errormsgs[]={ ERROR_STRINGS }; status = ERROR_MISMATCH; ptr = line; EAT(ptr,filename,lv,':'); EAT(ptr,filename,lv,' '); GETU32(ts,ptr); EAT(ptr,filename,lv,'|'); switch (*ptr) { case 'A': if (strncmp(ptr,"ACCESS",6)==0) { status = do_access(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"ATTR",4)==0) { status = do_attr(filename,lv,ts,ptr+4); } else if (strncmp(ptr,"APPEND",6)==0) { status = do_append(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"ACQUIRE",7)==0) { status = do_acquire(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"AQUIRE",6)==0) { status = do_acquire(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'C': if (strncmp(ptr,"CREATE",6)==0) { status = do_create(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"CUSTOMER",8)==0) { // deprecated status = do_session(filename,lv,ts,ptr+8); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'E': if (strncmp(ptr,"EMPTYTRASH",10)==0) { status = do_emptytrash(filename,lv,ts,ptr+10); } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) { status = do_emptyreserved(filename,lv,ts,ptr+13); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'F': if (strncmp(ptr,"FREEINODES",10)==0) { status = do_freeinodes(filename,lv,ts,ptr+10); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'I': if (strncmp(ptr,"INCVERSION",10)==0) { status = do_incversion(filename,lv,ts,ptr+10); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'L': if (strncmp(ptr,"LENGTH",6)==0) { status = do_length(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"LINK",4)==0) { status = do_link(filename,lv,ts,ptr+4); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'M': if (strncmp(ptr,"MOVE",4)==0) { status = do_move(filename,lv,ts,ptr+4); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'P': if (strncmp(ptr,"PURGE",5)==0) { status = do_purge(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'Q': if (strncmp(ptr,"QUOTA",5)==0) { status = do_quota(filename,lv,ts,ptr+5); } break; case 'R': if (strncmp(ptr,"RELEASE",7)==0) { status = do_release(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"REPAIR",6)==0) { status = do_repair(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'S': if (strncmp(ptr,"SETEATTR",8)==0) { status = do_seteattr(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SETGOAL",7)==0) { status = do_setgoal(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SETPATH",7)==0) { status = do_setpath(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SETTRASHTIME",12)==0) { status = do_settrashtime(filename,lv,ts,ptr+12); } else if (strncmp(ptr,"SETXATTR",8)==0) { status = do_setxattr(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SNAPSHOT",8)==0) { status = do_snapshot(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SYMLINK",7)==0) { status = do_symlink(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SESSION",7)==0) { status = do_session(filename,lv,ts,ptr+7); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'T': if (strncmp(ptr,"TRUNC",5)==0) { status = do_trunc(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'U': if (strncmp(ptr,"UNLINK",6)==0) { status = do_unlink(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"UNDEL",5)==0) { status = do_undel(filename,lv,ts,ptr+5); } else if (strncmp(ptr,"UNLOCK",6)==0) { status = do_unlock(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'W': if (strncmp(ptr,"WRITE",5)==0) { status = do_write(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; default: printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } if (status>STATUS_OK) { printf("%s:%"PRIu64": error: %d (%s)\n",filename,lv,status,errormsgs[status]); } return status; }
int restore(void) { FILE *fd; char buff[10000]; char *ptr; uint64_t v,lv; uint32_t ts; uint8_t status; uint32_t dplen; char *datapath = NULL; char *logpath = NULL; char* errormsgs[]={ ERROR_STRINGS }; v = shadow_fs_getversion(); lv = 0; MFSLOG(LOG_NOTICE,"meta data version: %"PRIu64"",v); datapath = strdup(DATA_PATH); dplen = strlen(datapath); logpath = malloc(dplen+sizeof("/changelog.0.mfs")); memcpy(logpath,datapath,dplen); memcpy(logpath+dplen,"/changelog.0.mfs",sizeof("/changelog.0.mfs")); fd = fopen(logpath,"r"); if (fd==NULL) { MFSLOG(LOG_NOTICE,"can't open changemeta file: %s",logpath); return 1; } while (fgets(buff,10000,fd)) { ptr = buff; GETU64(lv,ptr); if (lv<v) { // skip } else { status = ERROR_MISMATCH; EAT(ptr,lv,':'); EAT(ptr,lv,' '); GETU32(ts,ptr); EAT(ptr,lv,'|'); switch (*ptr) { case 'A': if (strncmp(ptr,"ACCESS",6)==0) { status = do_access(lv,ts,ptr+6); } else if (strncmp(ptr,"ATTR",4)==0) { status = do_attr(lv,ts,ptr+4); } else if (strncmp(ptr,"APPEND",6)==0) { status = do_append(lv,ts,ptr+6); } else if (strncmp(ptr,"AQUIRE",6)==0) { status = do_aquire(lv,ts,ptr+6); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'C': if (strncmp(ptr,"CREATE",6)==0) { status = do_create(lv,ts,ptr+6); } else if (strncmp(ptr,"CUSTOMER",8)==0) { // deprecated status = do_session(lv,ts,ptr+8); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'E': if (strncmp(ptr,"EMPTYTRASH",10)==0) { status = do_emptytrash(lv,ts,ptr+10); } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) { status = do_emptyreserved(lv,ts,ptr+13); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'F': if (strncmp(ptr,"FREEINODES",10)==0) { status = do_freeinodes(lv,ts,ptr+10); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'I': if (strncmp(ptr,"INCVERSION",10)==0) { status = do_incversion(lv,ts,ptr+10); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'L': if (strncmp(ptr,"LENGTH",6)==0) { status = do_length(lv,ts,ptr+6); } else if (strncmp(ptr,"LINK",4)==0) { status = do_link(lv,ts,ptr+4); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'M': if (strncmp(ptr,"MOVE",4)==0) { status = do_move(lv,ts,ptr+4); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'P': if (strncmp(ptr,"PURGE",5)==0) { status = do_purge(lv,ts,ptr+5); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'R': if (strncmp(ptr,"RELEASE",7)==0) { status = do_release(lv,ts,ptr+7); } else if (strncmp(ptr,"REPAIR",6)==0) { status = do_repair(lv,ts,ptr+6); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'S': if (strncmp(ptr,"SETEATTR",8)==0) { status = do_seteattr(lv,ts,ptr+8); } else if (strncmp(ptr,"SETGOAL",7)==0) { status = do_setgoal(lv,ts,ptr+7); } else if (strncmp(ptr,"SETPATH",7)==0) { status = do_setpath(lv,ts,ptr+7); } else if (strncmp(ptr,"SETTRASHTIME",12)==0) { status = do_settrashtime(lv,ts,ptr+12); } else if (strncmp(ptr,"SNAPSHOT",8)==0) { status = do_snapshot(lv,ts,ptr+8); } else if (strncmp(ptr,"SYMLINK",7)==0) { status = do_symlink(lv,ts,ptr+7); } else if (strncmp(ptr,"SESSION",7)==0) { status = do_session(lv,ts,ptr+7); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'T': if (strncmp(ptr,"TRUNC",5)==0) { status = do_trunc(lv,ts,ptr+5); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'U': if (strncmp(ptr,"UNLINK",6)==0) { status = do_unlink(lv,ts,ptr+6); } else if (strncmp(ptr,"UNDEL",5)==0) { status = do_undel(lv,ts,ptr+5); } else if (strncmp(ptr,"UNLOCK",6)==0) { status = do_unlock(lv,ts,ptr+6); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'W': if (strncmp(ptr,"WRITE",5)==0) { status = do_write(lv,ts,ptr+5); } else { MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; default: MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr); } /** * let the restore continue if we missed some meta data, otherwise the * * Dongyang Zhang */ if (status!=STATUS_OK) { MFSLOG(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s)",lv,status,errormsgs[status]); return 1; } v = shadow_fs_getversion(); if (lv+1!=v) { MFSLOG(LOG_ERR,"%"PRIu64": version mismatch",lv); return 1; } } } fclose(fd); MFSLOG(LOG_NOTICE,"version after applying changelog: %"PRIu64"",v); return 0; }
int replay(const char *log_data) { uint64_t fv,lv; //fv = filesystem's version lv = log's version uint32_t ts; uint8_t status; char buff[10000]; char *ptr; char* errormsgs[]={ ERROR_STRINGS }; char *test_ptr; sprintf(buff,"%s",log_data); ptr = buff; //for test test_ptr = buff; fv = shadow_fs_getversion(); GETU64(lv,ptr); if(lv < fv) { MFSLOG(LOG_ERR,"the changelog's verison %lu is smaller than filesystem's version %lu",lv,fv); //more complicated method to ensure consistency } else { status = ERROR_MISMATCH; EAT(ptr,lv,':'); EAT(ptr,lv,' '); GETU32(ts,ptr); EAT(ptr,lv,'|'); switch (*ptr) { case 'A': if (strncmp(ptr,"ACCESS",6)==0) { status = do_access(lv,ts,ptr+6); } else if (strncmp(ptr,"ATTR",4)==0) { status = do_attr(lv,ts,ptr+4); } else if (strncmp(ptr,"APPEND",6)==0) { status = do_append(lv,ts,ptr+6); } else if (strncmp(ptr,"AQUIRE",6)==0) { status = do_aquire(lv,ts,ptr+6); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'C': if (strncmp(ptr,"CREATE",6)==0) { status = do_create(lv,ts,ptr+6); } else if (strncmp(ptr,"CUSTOMER",8)==0) { // deprecated status = do_session(lv,ts,ptr+8); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'E': if (strncmp(ptr,"EMPTYTRASH",10)==0) { status = do_emptytrash(lv,ts,ptr+10); } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) { status = do_emptyreserved(lv,ts,ptr+13); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'F': if (strncmp(ptr,"FREEINODES",10)==0) { status = do_freeinodes(lv,ts,ptr+10); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'I': if (strncmp(ptr,"INCVERSION",10)==0) { status = do_incversion(lv,ts,ptr+10); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'L': if (strncmp(ptr,"LENGTH",6)==0) { status = do_length(lv,ts,ptr+6); } else if (strncmp(ptr,"LINK",4)==0) { status = do_link(lv,ts,ptr+4); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'M': if (strncmp(ptr,"MOVE",4)==0) { status = do_move(lv,ts,ptr+4); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'P': if (strncmp(ptr,"PURGE",5)==0) { status = do_purge(lv,ts,ptr+5); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'R': if (strncmp(ptr,"RELEASE",7)==0) { status = do_release(lv,ts,ptr+7); } else if (strncmp(ptr,"REPAIR",6)==0) { status = do_repair(lv,ts,ptr+6); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'S': if (strncmp(ptr,"SETEATTR",8)==0) { status = do_seteattr(lv,ts,ptr+8); } else if (strncmp(ptr,"SETGOAL",7)==0) { status = do_setgoal(lv,ts,ptr+7); } else if (strncmp(ptr,"SETPATH",7)==0) { status = do_setpath(lv,ts,ptr+7); } else if (strncmp(ptr,"SETTRASHTIME",12)==0) { status = do_settrashtime(lv,ts,ptr+12); } else if (strncmp(ptr,"SNAPSHOT",8)==0) { status = do_snapshot(lv,ts,ptr+8); } else if (strncmp(ptr,"SYMLINK",7)==0) { status = do_symlink(lv,ts,ptr+7); } else if (strncmp(ptr,"SESSION",7)==0) { status = do_session(lv,ts,ptr+7); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'T': if (strncmp(ptr,"TRUNC",5)==0) { status = do_trunc(lv,ts,ptr+5); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'U': if (strncmp(ptr,"UNLINK",6)==0) { status = do_unlink(lv,ts,ptr+6); } else if (strncmp(ptr,"UNDEL",5)==0) { status = do_undel(lv,ts,ptr+5); } else if (strncmp(ptr,"UNLOCK",6)==0) { status = do_unlock(lv,ts,ptr+6); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; case 'W': if (strncmp(ptr,"WRITE",5)==0) { status = do_write(lv,ts,ptr+5); } else { MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } break; default: MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr); } /** * if master is down, slave switch, we may missed some metadata * return 0 to let the process continue, otherwise, we will reply the * log forever. * * Dongyang, Zhang */ if (status!=STATUS_OK) { MFSLOG(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s),the log is (%s)",lv,status,errormsgs[status],test_ptr); // syslog(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s)",lv,status,errormsgs[status]); return 1; } fv = shadow_fs_getversion(); if (lv+1!=fv) { MFSLOG(LOG_ERR,"%"PRIu64": version mismatch fsversion:%"PRIu64"",lv,fv); return 1; } } return 0; }
int main(int argc, char *argv[], char *envp[]) { int rv; const char *cp; #ifdef LOGGING_LIBQB enum qb_log_target_slot i; #endif init_set_proc_title(argc, argv, envp); get_time(&start_time); memset(&cl, 0, sizeof(cl)); strncpy(cl.configfile, BOOTH_DEFAULT_CONF, BOOTH_PATH_LEN - 1); cl.lockfile[0] = 0; debug_level = 0; cp = ((cp = strstr(argv[0], ATTR_PROG)) && !strcmp(cp, ATTR_PROG) ? ATTR_PROG : "booth"); #ifndef LOGGING_LIBQB cl_log_set_entity(cp); #else qb_log_init(cp, LOG_USER, LOG_DEBUG); /* prio driven by debug_level */ for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) { if (i == QB_LOG_SYSLOG || i == QB_LOG_BLACKBOX) continue; qb_log_format_set(i, "%t %H %N: [%P]: %p: %b"); } (void) qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, "*", LOG_DEBUG); #endif cl_log_enable_stderr(TRUE); cl_log_set_facility(0); rv = read_arguments(argc, argv); if (rv < 0) goto out; switch (cl.type) { case STATUS: rv = do_status(cl.type); break; case ARBITRATOR: case DAEMON: case SITE: rv = do_server(cl.type); break; case CLIENT: rv = do_client(); break; case GEOSTORE: rv = do_attr(); break; } out: #ifdef LOGGING_LIBQB qb_log_fini(); #endif /* Normalize values. 0x100 would be seen as "OK" by waitpid(). */ return (rv >= 0 && rv < 0x70) ? rv : 1; }