[Sheepdog] 答复: [PATCH] sheep: change snapshot/clone flow

无觉 wujue.yht at taobao.com
Fri Apr 6 11:47:04 CEST 2012


I think this is a useful patch. Is there some comments, thanks

Best Regards
Haiting

-----邮件原件-----
发件人: yaohaiting.wujue at gmail.com [mailto:yaohaiting.wujue at gmail.com]
发送时间: 2012年3月27日 13:54
收件人: sheepdog at lists.wpkg.org
抄送: 无觉
主题: [PATCH] sheep: change snapshot/clone flow

From: HaiTing Yao <wujue.yht at taobao.com>

When create snapshot for source VDI, the new created VDI used as source
VDI, and the old source VDI used as snapshot. This flow make users
confused about VDI and snapshot relation. The snapshot metadata maybe is
stored on multi-VDI, so need read multi VDIs inode to get snapshot list.

When create snapshot, we does not need change new created VDI to source
VDI. The source VDI just need use snapshot VDI ID as its object data ID.

Show one example.

Before modification:

  Name        Id    Size    Used  Shared    Creation time   VDI id   Tag
s v1           1   64 MB   20 MB  0.0 MB 2012-03-26 16:55   709128
s v1           2   64 MB  0.0 MB   20 MB 2012-03-26 16:56   709129   sn3
  v1           3   64 MB  0.0 MB   20 MB 2012-03-26 16:56   70912a

After modification:

  Name        Id    Size    Used  Shared    Creation time   VDI id   Tag
  v1           0   64 MB   20 MB  0.0 MB 2012-03-27 11:06   709128
s v1           1   64 MB  0.0 MB   20 MB 2012-03-27 11:06   709129
s v1           2   64 MB  0.0 MB   20 MB 2012-03-27 11:07   70912a   sn3

Signed-off-by: HaiTing Yao <wujue.yht at taobao.com>
---
 collie/common.c          |    2 +-
 collie/vdi.c             |   30 +++++++++++++++++++-----------
 include/sheepdog_proto.h |    6 +++---
 sheep/vdi.c              |   18 ++++++++++--------
 4 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/collie/common.c b/collie/common.c
index f4301c4..636b821 100644
--- a/collie/common.c
+++ b/collie/common.c
@@ -13,7 +13,7 @@

 int is_current(struct sheepdog_inode *i)
 {
-       return !i->snap_ctime;
+       return !i->snap_id;
 }

 char *size_to_str(uint64_t _size, char *str, int str_size)
diff --git a/collie/vdi.c b/collie/vdi.c
index e0678a6..8a30c99 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -90,7 +90,9 @@ static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid,
        for (idx = 0; idx < MAX_DATA_OBJS; idx++) {
                if (!i->data_vdi_id[idx])
                        continue;
-               if (is_data_obj_writeable(i, idx))
+               if (!i->parent_vdi_id)
+                       my_objs++;
+               else if ((!i->snap_id) && (i->io_vdi_id == i->data_vdi_id[idx]))
                        my_objs++;
                else
                        cow_objs++;
@@ -511,7 +513,7 @@ out:
 static int vdi_snapshot(int argc, char **argv)
 {
        char *vdiname = argv[optind++];
-       uint32_t vid;
+       uint32_t vid, own_vid;
        int ret;
        char buf[SD_INODE_HEADER_SIZE];
        struct sheepdog_inode *inode = (struct sheepdog_inode *)buf;
@@ -528,20 +530,26 @@ static int vdi_snapshot(int argc, char **argv)
                return EXIT_FAILURE;
        }

-       ret = sd_read_object(vid_to_vdi_oid(vid), inode, SD_INODE_HEADER_SIZE, 0);
-       if (ret != SD_RES_SUCCESS) {
-               fprintf(stderr, "Failed to read an inode header\n");
+       ret = do_vdi_create(vdiname, inode->vdi_size, vid, &own_vid, 1);
+
+       if (ret < 0) {
+               fprintf(stderr, "Failed to write VDI %s\n", vdiname);
                return EXIT_FAILURE;
        }

        if (vdi_cmd_data.snapshot_tag[0]) {
-               ret = sd_write_object(vid_to_vdi_oid(vid), 0, vdi_cmd_data.snapshot_tag,
+               ret = sd_read_object(vid_to_vdi_oid(own_vid), inode, SD_INODE_HEADER_SIZE, 0);
+               if (ret != SD_RES_SUCCESS) {
+                       fprintf(stderr, "Failed to read an inode header\n");
+                       return EXIT_FAILURE;
+               }
+               ret = sd_write_object(vid_to_vdi_oid(own_vid), 0, vdi_cmd_data.snapshot_tag,
                                      SD_MAX_VDI_TAG_LEN,
                                      offsetof(struct sheepdog_inode, tag),
                                      0, inode->nr_copies, 0);
        }

-       return do_vdi_create(vdiname, inode->vdi_size, vid, NULL, 1);
+       return ret;
 }

 static int vdi_clone(int argc, char **argv)
@@ -1150,7 +1158,7 @@ static int vdi_write(int argc, char **argv)
                        remain -= ret;
                }

-               inode->data_vdi_id[idx] = inode->vdi_id;
+               inode->data_vdi_id[idx] = inode->io_vdi_id;
                oid = vid_to_data_oid(inode->data_vdi_id[idx], idx);
                ret = sd_write_object(oid, old_oid, buf, len, offset, flags,
                                      inode->nr_copies, create);
@@ -1161,9 +1169,9 @@ static int vdi_write(int argc, char **argv)
                }

                if (create) {
-                       ret = sd_write_object(vid_to_vdi_oid(vid), 0, &vid, sizeof(vid),
-                                             SD_INODE_HEADER_SIZE + sizeof(vid) * idx, 0,
-                                             inode->nr_copies, 0);
+                       ret = sd_write_object(vid_to_vdi_oid(vid), 0, &inode->io_vdi_id,
+                               sizeof(inode->io_vdi_id), SD_INODE_HEADER_SIZE + sizeof(vid) * idx,
+                               0, inode->nr_copies, 0);
                        if (ret) {
                                ret = EXIT_FAILURE;
                                goto out;
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 2d0d5ec..a4d4093 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -176,7 +176,6 @@ struct sheepdog_inode {
        char name[SD_MAX_VDI_LEN];
        char tag[SD_MAX_VDI_TAG_LEN];
        uint64_t ctime;
-       uint64_t snap_ctime;
        uint64_t vm_clock_nsec;
        uint64_t vdi_size;
        uint64_t vm_state_size;
@@ -186,9 +185,10 @@ struct sheepdog_inode {
        uint32_t snap_id;
        uint32_t vdi_id;
        uint32_t parent_vdi_id;
+       uint32_t io_vdi_id;
        uint32_t child_vdi_id[MAX_CHILDREN];
        uint32_t data_vdi_id[MAX_DATA_OBJS];
-};
+} __attribute__((packed));

 struct sheepdog_vdi_attr {
        char name[SD_MAX_VDI_LEN];
@@ -237,7 +237,7 @@ static inline uint64_t hash_64(uint64_t val, unsigned int bits)

 static inline int is_data_obj_writeable(struct sheepdog_inode *inode, int idx)
 {
-       return inode->vdi_id == inode->data_vdi_id[idx];
+       return inode->io_vdi_id == inode->data_vdi_id[idx];
 }

 static inline int is_vdi_obj(uint64_t oid)
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 45e77fe..4a0d4ab 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -82,10 +82,10 @@ static int create_vdi_obj(uint32_t epoch, char *name, uint32_t new_vid, uint64_t
                                ret = SD_RES_BASE_VDI_READ;
                                goto out;
                        }
-
-                       cur->snap_ctime = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000;
-               } else
-                       base->snap_ctime = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000;
+               } else {
+                       base->io_vdi_id = new_vid;
+                       size = base->vdi_size;
+               }
        }

        strncpy(new->name, name, sizeof(new->name));
@@ -96,6 +96,7 @@ static int create_vdi_obj(uint32_t epoch, char *name, uint32_t new_vid, uint64_t
        new->nr_copies = copies;
        new->block_size_shift = find_next_bit(&block_size, BITS_PER_LONG, 0);
        new->snap_id = snapid;
+       new->io_vdi_id = new_vid;

        if (base_vid) {
                int i;
@@ -192,14 +193,15 @@ static int find_first_vdi(uint32_t epoch, unsigned long start, unsigned long end
                }

                if (!strncmp(inode->name, name, strlen(inode->name))) {
+                       if (!*next_snap)
+                               *next_snap = inode->snap_id + 1;
                        vdi_found = 1;
                        if (tag && tag[0] &&
                            strncmp(inode->tag, tag, sizeof(inode->tag)) != 0)
                                continue;
-                       if (snapid && snapid != inode->snap_id)
+                       if (snapid != inode->snap_id)
                                continue;

-                       *next_snap = inode->snap_id + 1;
                        *vid = inode->vdi_id;
                        *nr_copies = inode->nr_copies;
                        if (ctime)
@@ -280,7 +282,7 @@ int add_vdi(uint32_t epoch, char *data, int data_len, uint64_t size,
            int is_snapshot, unsigned int *nr_copies)
 {
        uint32_t cur_vid = 0;
-       uint32_t next_snapid;
+       uint32_t next_snapid = 0;
        unsigned long nr, deleted_nr = SD_NR_VDIS, right_nr = SD_NR_VDIS;
        int ret;
        char *name;
@@ -313,7 +315,7 @@ int add_vdi(uint32_t epoch, char *data, int data_len, uint64_t size,
                else
                        nr = deleted_nr; /* we can recycle a deleted VDI */

-               next_snapid = 1;
+               next_snapid = 0;
        }

        *new_vid = nr;
--
1.7.1


________________________________

This email (including any attachments) is confidential and may be legally privileged. If you received this email in error, please delete it immediately and do not copy it or use it for any purpose or disclose its contents to any other person. Thank you.

本电邮(包括任何附件)可能含有机密资料并受法律保护。如您不是正确的收件人,请您立即删除本邮件。请不要将本电邮进行复制并用作任何其他用途、或透露本邮件之内容。谢谢。


More information about the sheepdog mailing list