moved farm.c from sheep/farm to collie/farm and made minor modification.

Signed-off-by: Kai Zhang <[email protected]>
---
 collie/farm/farm.c |  228 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 collie/farm/farm.h |    2 +
 2 files changed, 230 insertions(+), 0 deletions(-)

diff --git a/collie/farm/farm.c b/collie/farm/farm.c
index 283cd9b..c95d5a1 100644
--- a/collie/farm/farm.c
+++ b/collie/farm/farm.c
@@ -22,3 +22,231 @@ inline char *get_object_directory(void)
 {
        return farm_obj_dir;
 }
+
+static int create_directory(const char *p)
+{
+       int i, ret = -1;
+       struct strbuf buf = STRBUF_INIT;
+
+       strbuf_addstr(&buf, p);
+       strbuf_addstr(&buf, "/.farm");
+       if (xmkdir(buf.buf, 0755) < 0)
+               goto out;
+
+       if (!strlen(farm_dir))
+               strbuf_copyout(&buf, farm_dir, sizeof(farm_dir));
+
+       strbuf_addstr(&buf, "/objects");
+       if (xmkdir(buf.buf, 0755) < 0)
+               goto out;
+
+       for (i = 0; i < 256; i++) {
+               strbuf_addf(&buf, "/%02x", i);
+               if (xmkdir(buf.buf, 0755) < 0)
+                       goto out;
+
+               strbuf_remove(&buf, buf.len - 3, 3);
+       }
+
+       if (!strlen(farm_obj_dir))
+               strbuf_copyout(&buf, farm_obj_dir, sizeof(farm_obj_dir));
+
+       ret = 0;
+out:
+       if (ret)
+               sd_eprintf("fail to create directory %m");
+       strbuf_release(&buf);
+       return ret;
+}
+
+static int get_trunk_sha1(uint32_t epoch, unsigned char *outsha1)
+{
+       int i, nr_logs = -1, ret = -1;
+       struct snap_log *log_buf, *log_free = NULL;
+       void *snap_buf = NULL;
+       struct sha1_file_hdr hdr;
+
+       log_free = log_buf = snap_log_read(&nr_logs);
+       if (nr_logs < 0)
+               goto out;
+
+       if (!epoch)
+               epoch = nr_logs;
+
+       for (i = 0; i < nr_logs; i++, log_buf++) {
+               if (log_buf->epoch != epoch)
+                       continue;
+               snap_buf = snap_file_read(log_buf->sha1, &hdr);
+               if (!snap_buf)
+                       goto out;
+               memcpy(outsha1, snap_buf, SHA1_LEN);
+               ret = 0;
+               goto out;
+       }
+       sd_eprintf("could not find epoch %"PRIu32, epoch);
+out:
+       if (ret)
+               sd_eprintf("fail to get trunk sha1");
+       if (log_free)
+               free(log_free);
+       if (snap_buf)
+               free(snap_buf);
+       return ret;
+}
+
+static int notify_vdi_add(uint32_t vdi_id, uint32_t nr_copies)
+{
+       int ret = -1;
+       struct sd_req hdr;
+       char *buf = NULL;
+
+       sd_init_req(&hdr, SD_OP_NOTIFY_VDI_ADD);
+       hdr.vdi_state.new_vid = vdi_id;
+       hdr.vdi_state.copies = nr_copies;
+       hdr.vdi_state.set_bitmap = true;
+
+       ret = collie_exec_req(sdhost, sdport, &hdr, buf);
+
+       if (ret)
+               sd_eprintf("fail to notify vdi add event(%" PRIx32 ", %d)",
+                       vdi_id, nr_copies);
+       if (buf)
+               free(buf);
+       return ret;
+}
+
+static int fill_trunk_entry(uint64_t oid, enum obj_type type,
+                       int nr_copies, void *buf, size_t size, void *data)
+{
+       int ret = -1;
+
+       struct strbuf *trunk_entries = data;
+       struct trunk_entry new_entry = {};
+       struct sha1_file_hdr hdr = { .priv = 0 };
+       struct strbuf obj_strbuf = STRBUF_INIT;
+
+       /* fill sha1 file */
+       memcpy(hdr.tag, TAG_DATA, TAG_LEN);
+       hdr.size = size;
+
+       /* fill obj_strbuf */
+       strbuf_add(&obj_strbuf, buf, size);
+       strbuf_insert(&obj_strbuf, 0, &hdr, sizeof(hdr));
+
+       /* write sha1 file and fill trunk entry */
+       if (sha1_file_write((void *)obj_strbuf.buf,
+                           obj_strbuf.len,
+                           new_entry.sha1) != 0)
+               goto out;
+
+       new_entry.oid = oid;
+       new_entry.type = type;
+       new_entry.nr_copies = nr_copies;
+       strbuf_add(trunk_entries, &new_entry, sizeof(struct trunk_entry));
+
+       ret = 0;
+out:
+       if (ret)
+               sd_eprintf("fail to fill trunk entry");
+       strbuf_release(&obj_strbuf);
+       return ret;
+}
+
+int farm_init(const char *path)
+{
+       int ret = -1;
+
+       if (create_directory(path) < 0)
+               goto out;
+       if (snap_init(farm_dir) < 0)
+               goto out;
+       return 0;
+out:
+       if (ret)
+               sd_eprintf("fail to init farm");
+       return ret;
+}
+
+int farm_save_snapshot(void)
+{
+       unsigned char snap_sha1[SHA1_LEN];
+       unsigned char trunk_sha1[SHA1_LEN];
+       struct strbuf trunk_entries = STRBUF_INIT;
+       void *snap_log = NULL;
+       int log_nr, epoch;
+       int ret = -1;
+
+       snap_log = snap_log_read(&log_nr);
+       if (!snap_log)
+               goto out;
+
+       epoch = log_nr + 1;
+
+       if (parse_obj(fill_trunk_entry, &trunk_entries) < 0)
+               goto out;
+
+       if (trunk_file_write(trunk_sha1, &trunk_entries) < 0)
+               goto out;
+
+       if (snap_file_write(epoch, trunk_sha1, snap_sha1) < 0)
+               goto out;
+
+       if (snap_log_write(epoch, snap_sha1) != 0)
+               goto out;
+
+       ret = 0;
+out:
+       if (snap_log)
+               free(snap_log);
+       strbuf_release(&trunk_entries);
+       return ret;
+}
+
+int farm_load_snapshot(uint32_t epoch)
+{
+       int ret = -1;
+       struct trunk_entry *trunk_entry, *trunk_free = NULL;
+       struct sha1_file_hdr trunk_hdr;
+       unsigned char trunk_sha1[SHA1_LEN];
+       uint64_t nr_trunks, idx;
+
+       if (get_trunk_sha1(epoch, trunk_sha1) < 0)
+               goto out;
+
+       trunk_free = trunk_entry = trunk_file_read(trunk_sha1, &trunk_hdr);
+
+       if (!trunk_entry)
+               goto out;
+
+       nr_trunks = trunk_hdr.priv;
+
+       for (idx = 0; idx < nr_trunks; idx++, trunk_entry++) {
+               struct sha1_file_hdr hdr;
+               void *buffer = NULL;
+               uint64_t oid = trunk_entry->oid;
+
+               buffer = sha1_file_read(trunk_entry->sha1, &hdr);
+               if (!buffer) {
+                       sd_eprintf("oid %"PRIx64" not restored", oid);
+                       goto out;
+               }
+
+               if (trunk_entry->type == VDI)
+                       if (notify_vdi_add(oid_to_vid(oid),
+                                          trunk_entry->nr_copies) < 0)
+                               goto out;
+
+               if (sd_write_object(oid, 0, buffer, hdr.size, 0, 0,
+                                   trunk_entry->nr_copies,
+                                   true, true) != 0) {
+                       sd_eprintf("oid %"PRIx64" not restored", oid);
+                       goto out;
+               }
+       }
+       ret = 0;
+
+out:
+       if (trunk_free)
+               free(trunk_free);
+       return ret;
+}
diff --git a/collie/farm/farm.h b/collie/farm/farm.h
index 1d4c92a..2631236 100644
--- a/collie/farm/farm.h
+++ b/collie/farm/farm.h
@@ -46,6 +46,8 @@ struct sha1_file_hdr {
 
 /* farm.c */
 int farm_init(const char *path);
+int farm_save_snapshot(void);
+int farm_load_snapshot(uint32_t epoch);
 char *get_object_directory(void);
 
 /* trunk.c */
-- 
1.7.1

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to