Exemplo n.º 1
0
static
#endif
int forward_past_entry(struct manio *manio, struct iobuf *target,
                       enum protocol protocol, man_off_t **pos)
{
    struct sbuf *sb=NULL;

    if(!(sb=sbuf_alloc(protocol)))
        goto error;

    man_off_t_free(pos);
    if(!(*pos=manio_tell(manio)))
    {
        logp("Could not manio_tell first pos in %s(): %s\n",
             __func__, strerror(errno));
        goto error;
    }

    while(1)
    {
        sbuf_free_content(sb);
        switch(manio_read(manio, sb))
        {
        case 0:
            break;
        case 1:
            logp("End of file in %s()\n", __func__);
            goto error;
        default:
            logp("Error in %s()\n", __func__);
            // Treat error in unchanged manio as not OK.
            goto error;
        }

        if(target->cmd==sb->path.cmd
                && !pathcmp(target->buf, sb->path.buf))
        {
            man_off_t_free(pos);
            if(!(*pos=manio_tell(manio)))
            {
                logp("Could not get pos in %s(): %s\n",
                     __func__, strerror(errno));
                goto error;
            }
            sbuf_free(&sb);
            return 0;
        }
    }

error:
    sbuf_free(&sb);
    man_off_t_free(pos);
    return -1;
}
Exemplo n.º 2
0
END_TEST

static void test_manifest_tell_seek(enum protocol protocol, int phase)
{
	struct slist *slist;
	struct manio *manio;
	struct sbuf *sb=NULL;
	man_off_t *offset=NULL;
	int entries=1000;
	prng_init(0);
	base64_init();
	hexmap_init();
	recursive_delete(path);

	slist=build_manifest(path, protocol, entries, phase);
	fail_unless(slist!=NULL);

	sb=slist->head;
	fail_unless((manio=do_manio_open(path, "rb", protocol, phase))!=NULL);
	read_manifest(&sb, manio, 0, entries/2, protocol, phase);
	fail_unless((offset=manio_tell(manio))!=NULL);
	fail_unless(sb!=NULL);
	fail_unless(!manio_close(&manio));

	fail_unless((manio=do_manio_open(path, "rb", protocol, phase))!=NULL);
	fail_unless(!manio_seek(manio, offset));
	read_manifest(&sb, manio, entries/2, entries, protocol, phase);
	fail_unless(sb==NULL);
	fail_unless(!manio_close(&manio));
	fail_unless(!manio);

	slist_free(&slist);
	man_off_t_free(&offset);
	tear_down();
}
Exemplo n.º 3
0
void build_manifest_phase2_from_slist(const char *path,
	struct slist *slist, enum protocol protocol, int short_write)
{
	struct sbuf *sb;
	struct manio *manio=NULL;

	for(sb=slist->head; sb; sb=sb->next)
		set_sbuf(slist, sb, 0 /* with_data_files */);

	fail_unless((manio=manio_open_phase2(path, "wb", protocol))!=NULL);

	for(sb=slist->head; sb; sb=sb->next)
	{
		fail_unless(!manio_write_sbuf(manio, sb));
		if(protocol==PROTO_2)
		{
			struct blk *blk=NULL;
			for(blk=sb->protocol2->bstart;
				blk && blk!=sb->protocol2->bend; blk=blk->next)
			{
				fail_unless(!manio_write_sig_and_path(manio,
					blk));
			}
			if(sbuf_is_filedata(sb) || sbuf_is_vssdata(sb))
			{
				struct iobuf endfile;
				iobuf_from_str(&endfile,
					CMD_END_FILE, (char *)"0:0");
				fail_unless(!iobuf_send_msg_fzp(&endfile,
					manio->fzp));
			}
			hack_protocol2_attr(&sb->attr);
		}
	}

	if(short_write)
	{
		man_off_t *pos;
		fail_unless((pos=manio_tell(manio))!=NULL);
		if(pos->offset>=short_write) pos->offset-=short_write;
		fail_unless(!manio_close_and_truncate(&manio,
			pos, 0 /* compression */));
		man_off_t_free(&pos);
	}
	fail_unless(!manio_close(&manio));
}
Exemplo n.º 4
0
// Return p1manio position.
static man_off_t *do_resume_work(struct sdirs *sdirs,
                                 struct dpth *dpth, struct conf **cconfs)
{
    man_off_t *pos=NULL;
    man_off_t *p1pos=NULL;
    struct iobuf *chb=NULL;
    struct manio *cmanio=NULL;
    struct manio *umanio=NULL;
    struct manio *p1manio=NULL;
    enum protocol protocol=get_protocol(cconfs);
    struct cntr *cntr=get_cntr(cconfs);
    int compression=get_int(cconfs[OPT_COMPRESSION]);

    if(!(p1manio=manio_open_phase1(sdirs->phase1data, "rb", protocol))
            || !(cmanio=manio_open_phase2(sdirs->changed, "rb", protocol))
            || !(umanio=manio_open_phase2(sdirs->unchanged, "rb", protocol)))
        goto end;

    if(!(chb=iobuf_alloc()))
        return NULL;

    logp("Setting up resume positions...\n");

    if(get_last_good_entry(cmanio, chb, cntr, dpth, protocol, &pos))
        goto error;
    if(manio_close_and_truncate(&cmanio, pos, compression)) goto error;
    man_off_t_free(&pos);
    if(chb->buf)
    {
        logp("  last good entry:    %s\n", chb->buf);
        // Now need to go to the appropriate places in p1manio and
        // unchanged.
        if(forward_past_entry(p1manio, chb, protocol, &p1pos))
            goto error;

        // The unchanged file needs to be positioned just before the
        // found entry, otherwise it ends up having a duplicated entry.
        if(forward_before_entry(umanio,
                                chb, cntr, dpth, protocol, &pos))
            goto error;
        if(manio_close_and_truncate(&umanio, pos, compression))
            goto error;
        man_off_t_free(&pos);
    }
    else
    {
        logp("  nothing previously transferred\n");
        if(!(p1pos=manio_tell(p1manio)))
            goto error;
        if(!(pos=manio_tell(umanio)))
            goto error;
        if(manio_close_and_truncate(&umanio, pos, compression))
            goto error;
    }

    // Now should have all file pointers in the right places to resume.

    goto end;
error:
    man_off_t_free(&p1pos);
end:
    iobuf_free(&chb);
    man_off_t_free(&pos);
    manio_close(&p1manio);
    manio_close(&cmanio);
    manio_close(&umanio);
    return p1pos;
}
Exemplo n.º 5
0
static
#endif
int get_last_good_entry(struct manio *manio, struct iobuf *result,
                        struct cntr *cntr, struct dpth *dpth, enum protocol protocol,
                        man_off_t **pos)
{
    int ars=0;
    int got_vss_start=0;
    struct sbuf *sb=NULL;
    struct iobuf lastpath;

    if(!(sb=sbuf_alloc(protocol)))
        goto error;

    iobuf_init(&lastpath);

    man_off_t_free(pos);
    if(!(*pos=manio_tell(manio)))
    {
        logp("Could not manio_tell first pos in %s(): %s\n",
             __func__, strerror(errno));
        goto error;
    }

    while(1)
    {
        if(sb->path.buf && !got_vss_start)
        {
            iobuf_free_content(&lastpath);
            iobuf_move(&lastpath, &sb->path);
            if(!sbuf_is_filedata(sb)
                    && !sbuf_is_vssdata(sb))
            {
                iobuf_free_content(result);
                iobuf_move(result, &lastpath);

                man_off_t_free(pos);
                if(!(*pos=manio_tell(manio)))
                {
                    logp("Could not manio_tell pos in %s(): %s\n",
                         __func__, strerror(errno));
                    goto error;
                }
            }
        }
        if(sb->endfile.buf && !got_vss_start)
        {
            iobuf_free_content(result);
            iobuf_move(result, &lastpath);

            man_off_t_free(pos);
            if(!(*pos=manio_tell(manio)))
            {
                logp("Could not manio_tell pos in %s(): %s\n",
                     __func__, strerror(errno));
                goto error;
            }
        }

        sbuf_free_content(sb);
        ars=manio_read(manio, sb);
        if(dpth && set_higher_datapth(sb, dpth)) goto error;

        switch(ars)
        {
        case 0:
            break;
        case 1:
            iobuf_free_content(&lastpath);
            sbuf_free(&sb);
            return 0;
        default:
            if(result->buf)
                logp("Error after %s in %s()\n",
                     result->buf, __func__);
            // Treat error in changed manio as
            // OK - could have been a short write.
            iobuf_free_content(&lastpath);
            sbuf_free(&sb);
            return 0;
        }

        // Some hacks for split_vss.
        switch(sb->path.cmd)
        {
        case CMD_VSS:
        case CMD_ENC_VSS:
            got_vss_start=1;
            break;
        case CMD_VSS_T:
        case CMD_ENC_VSS_T:
            got_vss_start=0;
            break;
        case CMD_FILE:
        case CMD_ENC_FILE:
            if(S_ISDIR(sb->statp.st_mode))
                got_vss_start=0;
            break;
        default:
            break;
        }

        if(cntr)
        {
            // FIX THIS: cannot distinguish between new and
            // changed files.
            cntr_add_changed(cntr, sb->path.cmd);
            if(sb->endfile.buf)
            {
                uint64_t e=strtoull(sb->endfile.buf, NULL, 10);
                cntr_add_bytes(cntr, e);
            }
        }
    }

error:
    iobuf_free_content(&lastpath);
    sbuf_free(&sb);
    man_off_t_free(pos);
    return -1;
}
Exemplo n.º 6
0
static
#endif
int forward_before_entry(struct manio *manio, struct iobuf *target,
                         struct cntr *cntr, struct dpth *dpth, enum protocol protocol,
                         man_off_t **pos)
{
    int ars=0;
    struct sbuf *sb=NULL;

    if(!(sb=sbuf_alloc(protocol)))
        goto error;

    man_off_t_free(pos);
    if(!(*pos=manio_tell(manio)))
    {
        logp("Could not manio_tell first pos in %s(): %s\n",
             __func__, strerror(errno));
        goto error;
    }

    while(1)
    {
        if(sb->endfile.buf
                || (sb->path.buf && !sbuf_is_filedata(sb)))
        {
            man_off_t_free(pos);
            if(!(*pos=manio_tell(manio)))
            {
                logp("Could not manio_tell pos in %s(): "
                     "%s\n", __func__, strerror(errno));
                goto error;
            }
        }

        sbuf_free_content(sb);
        ars=manio_read(manio, sb);
        if(dpth && set_higher_datapth(sb, dpth)) goto error;

        switch(ars)
        {
        case 0:
            break;
        case 1:
            sbuf_free(&sb);
            return 0;
        default:
            logp("Error in %s(), but continuing\n",
                 __func__);
            // Treat error in unchanged manio as
            // OK - could have been a short write.
            sbuf_free(&sb);
            return 0;
        }

        if(iobuf_pathcmp(target, &sb->path)<=0)
        {
            sbuf_free(&sb);
            return 0;
        }

        if(cntr)
        {
            cntr_add_same(cntr, sb->path.cmd);
            if(sb->endfile.buf)
            {
                uint64_t e=strtoull(sb->endfile.buf, NULL, 10);
                cntr_add_bytes(cntr, e);
            }
        }
    }

error:
    sbuf_free(&sb);
    man_off_t_free(pos);
    return -1;
}