Beispiel #1
0
int slice_write(void *buf, size_t len, unsigned char *outsha1)
{
	int count = DIV_ROUND_UP(len, SLICE_SIZE);
	size_t slen = count * SHA1_DIGEST_SIZE;
	char *sbuf = xmalloc(slen);
	char *p = buf;

	for (int i = 0; i < count; i++, p += SLICE_SIZE) {
		unsigned char sha1[SHA1_DIGEST_SIZE];
		size_t wlen = (ssize_t)len - SLICE_SIZE > 0 ? SLICE_SIZE : len;
		len -= SLICE_SIZE;

		if (sha1_file_write(p, wlen, sha1) < 0)
			goto err;
		memcpy(sbuf + i * SHA1_DIGEST_SIZE, sha1, SHA1_DIGEST_SIZE);
	}

	if (sha1_file_write(sbuf, slen, outsha1) < 0)
		goto err;
	free(sbuf);
	return 0;
err:
	free(sbuf);
	return -1;
}
Beispiel #2
0
int snap_file_write(uint32_t epoch, struct sd_node *nodes, int nr_nodes,
		unsigned char *trunksha1, unsigned char *outsha1)
{
	int ret = 0;
	struct strbuf buf = STRBUF_INIT;
	struct sha1_file_hdr hdr;

	memcpy(hdr.tag, TAG_SNAP, TAG_LEN);
	hdr.size = nr_nodes * sizeof(*nodes) + SHA1_LEN;
	hdr.priv = epoch;
	hdr.reserved = 0;

	strbuf_add(&buf, &hdr, sizeof(hdr));
	strbuf_add(&buf, trunksha1, SHA1_LEN);
	strbuf_add(&buf, (char *)nodes, nr_nodes * sizeof(*nodes));
	if (sha1_file_write((void *)buf.buf, buf.len, outsha1) < 0) {
		ret = -1;
		goto err;
	}

	dprintf("epoch: %" PRIu32 ", sha1: %s\n", epoch, sha1_to_hex(outsha1));
err:
	strbuf_release(&buf);
	return ret;
}
Beispiel #3
0
int snap_file_write(uint32_t epoch, unsigned char *trunksha1, unsigned char *outsha1, int user)
{
	int ret = 0;
	struct strbuf buf = STRBUF_INIT;
	struct sd_node nodes[SD_MAX_NODES];
	int tgt_epoch = user ? sys_epoch() : epoch;
	uint64_t epoch_size;
	struct sha1_file_hdr hdr;

	epoch_size = epoch_log_read(tgt_epoch, (char *)nodes, sizeof(nodes));
	if (epoch_size == -1)
		return -1;

	memcpy(hdr.tag, TAG_SNAP, TAG_LEN);
	hdr.size = epoch_size + SHA1_LEN;
	hdr.priv = tgt_epoch;
	hdr.reserved = 0;

	strbuf_add(&buf, &hdr, sizeof(hdr));
	strbuf_add(&buf, trunksha1, SHA1_LEN);
	strbuf_add(&buf, (char *)nodes, epoch_size);
	if (sha1_file_write((void *)buf.buf, buf.len, outsha1) < 0) {
		ret = -1;
		goto err;
	}

	dprintf("epoch %u, sha1: %s\n", epoch, sha1_to_hex(outsha1));
err:
	strbuf_release(&buf);
	return ret;
}
Beispiel #4
0
int snap_file_write(uint32_t idx, unsigned char *trunk_sha1,
		    unsigned char *outsha1)
{
	struct snap_file snap;
	snap.idx = idx;
	memcpy(snap.trunk_sha1, trunk_sha1, SHA1_DIGEST_SIZE);

	return sha1_file_write(&snap, sizeof(struct snap_file),
			       outsha1);
}
Beispiel #5
0
int trunk_file_write(unsigned char *outsha1)
{
	struct strbuf buf;
	struct sha1_file_hdr hdr = {};
	struct trunk_entry entry = {};
	struct dirent *d;
	DIR *dir;
	uint64_t data_size, oid, object_nr = 0;
	int ret = 0;

	/* Add the hdr first */
	for_each_object_in_wd(inc_object_nr, false, &object_nr);
	data_size = sizeof(struct trunk_entry) * object_nr;
	hdr.size = data_size;
	hdr.priv = object_nr;
	memcpy(hdr.tag, TAG_TRUNK, TAG_LEN);
	strbuf_init(&buf, sizeof(hdr) + data_size);
	strbuf_add(&buf, &hdr, sizeof(hdr));

	dir = opendir(obj_path);
	if (!dir) {
		ret = -1;
		goto out;
	}

	while ((d = readdir(dir))) {
		if (!strncmp(d->d_name, ".", 1))
			continue;

		oid = strtoull(d->d_name, NULL, 16);
		if (oid == 0 || oid == ULLONG_MAX)
			continue;

		entry.oid = oid;
		if (fill_entry_new_sha1(&entry) < 0) {
			ret = -1;
			goto out;
		}
		strbuf_add(&buf, &entry, sizeof(struct trunk_entry));
	}

	if (sha1_file_write((void *)buf.buf, buf.len, outsha1) < 0) {
		ret = -1;
		goto out;
	}
	dprintf("trunk sha1: %s\n", sha1_to_hex(outsha1));
out:
	closedir(dir);
	strbuf_release(&buf);
	return ret;
}
Beispiel #6
0
static int fill_entry_new_sha1(struct trunk_entry *entry)
{
	struct strbuf buf = STRBUF_INIT;
	int fd, ret = 0;
	struct sha1_file_hdr hdr = { .priv = 0 };

	memcpy(hdr.tag, TAG_DATA, TAG_LEN);
	strbuf_addstr(&buf, obj_path);
	strbuf_addf(&buf, "%016" PRIx64, entry->oid);
	fd = open(buf.buf, O_RDONLY);
	strbuf_reset(&buf);

	if (fd < 0) {
		dprintf("%m\n");
		ret = -1;
		goto out;
	}
	if (!strbuf_read(&buf, fd, SD_DATA_OBJ_SIZE) == SD_DATA_OBJ_SIZE) {
		dprintf("strbuf_read fail to read full\n");
		ret = -1;
		goto out_close;
	}
	hdr.size = buf.len;
	strbuf_insert(&buf, 0, &hdr, sizeof(hdr));

	if (sha1_file_write((void *)buf.buf, buf.len, entry->sha1) < 0) {
		ret = -1;
		goto out_close;
	}
	dprintf("data sha1:%s, %"PRIx64"\n", sha1_to_hex(entry->sha1),
		entry->oid);
out_close:
	close(fd);
out:
	strbuf_release(&buf);
	return ret;
}

static int inc_object_nr(uint64_t oid, void *arg)
{
	uint64_t *object_nr = arg;

	(*object_nr)++;

	return 0;
}
Beispiel #7
0
static int fill_entry_new_sha1(struct trunk_entry_incore *entry)
{
	struct strbuf buf = STRBUF_INIT;
	int fd, ret = 0;
	struct sha1_file_hdr hdr = { .priv = 0 };

	memcpy(hdr.tag, TAG_DATA, TAG_LEN);
	strbuf_addstr(&buf, obj_path);
	strbuf_addf(&buf, "%016" PRIx64, entry->raw.oid);
	fd = open(buf.buf, O_RDONLY);
	strbuf_reset(&buf);

	if (fd < 0) {
		dprintf("%m\n");
		ret = -1;
		goto out;
	}
	if (!strbuf_read(&buf, fd, SD_DATA_OBJ_SIZE) == SD_DATA_OBJ_SIZE) {
		dprintf("strbuf_read fail to read full\n");
		ret = -1;
		goto out_close;
	}
	hdr.size = buf.len;
	strbuf_insert(&buf, 0, &hdr, sizeof(hdr));

	if (sha1_file_write((void *)buf.buf, buf.len, entry->raw.sha1) < 0) {
		ret = -1;
		goto out_close;
	}
	dprintf("data sha1:%s, %"PRIx64"\n", sha1_to_hex(entry->raw.sha1),
		entry->raw.oid);
out_close:
	close(fd);
out:
	strbuf_release(&buf);
	return ret;
}

static inline int trunk_entry_no_sha1(struct trunk_entry_incore *entry)
{
	unsigned char empty[SHA1_LEN] = {0};

	return memcmp(entry->raw.sha1, empty, SHA1_LEN) == 0;
}