static int merge_into_global_sparse(const char *sparse, const char *global, struct conf **confs) { int ret=-1; char *tmpfile=NULL; struct stat statp; char *lockfile=NULL; struct lock *lock=NULL; const char *globalsrc=NULL; if(!(tmpfile=prepend_n(global, "tmp", strlen("tmp"), "."))) goto end; // Get a lock before messing with the global sparse index. if(!(lockfile=prepend_n(global, "lock", strlen("lock"), ".")) || !(lock=lock_alloc_and_init(lockfile))) goto end; if(try_to_get_lock(lock)) goto end; if(!lstat(global, &statp)) globalsrc=global; if(merge_sparse_indexes(sparse, globalsrc, tmpfile, confs)) goto end; // FIX THIS: nasty race condition needs to be recoverable. if(do_rename(tmpfile, global)) goto end; ret=0; end: lock_release(lock); lock_free(&lock); if(lockfile) free(lockfile); if(tmpfile) free(tmpfile); return ret; }
struct asfd *champ_chooser_connect(struct async *as, struct sdirs *sdirs, struct conf **confs) { int champsock=-1; char *champname=NULL; struct asfd *chfd=NULL; const char *cname=NULL; // Connect to champ chooser now. // This may start up a new champ chooser. On a machine with multiple // cores, it may be faster to do now, way before it is actually needed // in phase2. if((champsock=connect_to_champ_chooser(sdirs, confs))<0) { logp("could not connect to champ chooser\n"); goto error; } if(!(chfd=setup_asfd(as, "champ chooser socket", &champsock, NULL, ASFD_STREAM_STANDARD, ASFD_FD_SERVER_TO_CHAMP_CHOOSER, -1, confs))) goto error; cname=get_string(confs[OPT_CNAME]); if(!(champname=prepend_n("cname", cname, strlen(cname), ":"))) goto error; if(chfd->write_str(chfd, CMD_GEN, champname) || chfd->read_expect(chfd, CMD_GEN, "cname ok")) goto error; free(champname); return chfd; error: free(champname); as->asfd_remove(as, chfd); asfd_free(&chfd); close_fd(&champsock); return NULL; }
static char *get_global_sparse_tmp(const char *global) { return prepend_n(global, "tmp", strlen("tmp"), "."); }