HarryWei / cloudxy

Automatically exported from code.google.com/p/cloudxy
6 stars 3 forks source link

revise snapshot bug #12

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
bug概述
=======  
           T1                                   T2                               T3                             T4
|---------------------------|          |--------------------------|         
|------------------------|         |---------------------|
|     null  |     T1      |          |     T1 |    T2        |         |    T2  
 |    T3     |         |    T3  |    T4    |
|---------------------------|          |--------------------------|         
|------------------------|         |---------------------|     .......

注意:上图的第一个域表示 up snapshot name, 第二个域表示 
current snapshot name。

如果要删除T2, 那么我们需要把T3的up snapshot name 域修改为T1, 
这样才能达到revise的结果,
结果如下:
           T1                                 T3                             T4
|---------------------------|        |------------------------|         
|---------------------|
|     null  |     T1      |        |    T1   |    T3     |         |    T3  |   
 T4   |
|---------------------------|        |------------------------|         
|---------------------|     .......
但是当前我们代码中的revise_snapshot_relation没有实现如上功能��
�

修复bug后的代码
==============

static gboolean predicate_same_upname_snapshot(gpointer key,gpointer 
value,gpointer user_data){
       char * ss_name = (char*)key;
      struct snapshot *ss = (struct snapshot*)value;
       char * del_ss_name = (char*)user_data;
 -       if(g_strcmp0(ss_name,del_ss_name) == 0){
+       if(g_strcmp0(ss->up_sname,del_ss_name) == 0){ 
          return TRUE;
       }
       return FALSE;
}

static void revise_snapshot_relation(GHashTable *ss_hashtable,GList 
*remove_list){
     int i;
     for(i = 0; i < g_list_length(remove_list); i++){
        char * ss_name = g_list_nth_data(remove_list,i);
            struct snapshot *ss = g_hash_table_lookup(ss_hashtable,ss_name);
        g_assert(ss!=NULL);
        char *up_ss_name = ss->up_sname;
        struct snapshot *revise_ss = g_hash_table_find (ss_hashtable,predicate_same_upname_snapshot,ss_name);
        if(revise_ss !=NULL){
                   snprintf(revise_ss->up_sname,HLFS_FILE_NAME_MAX,"%s",ss->up_sname);
        }
        g_hash_table_remove(ss_hashtable, ss->sname);
 -       g_free(ss);
     }
     return ;
}

测试代码
========
jiawei@jiawei-laptop:~/workshop15/cloudxy/branches/snapshot/test$ cat test1.c
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define HLFS_FILE_NAME_MAX            (80)

struct snapshot {
    uint64_t timestamp;
    uint64_t inode_addr;
    char sname[HLFS_FILE_NAME_MAX];
    char up_sname[HLFS_FILE_NAME_MAX]; /* for tree style snapshot */
} __attribute__((packed));

/* load all snapshot will remove del snapshot and revise relation upname */
static gboolean predicate_same_upname_snapshot(gpointer key,gpointer 
value,gpointer user_data){
        g_message("enter func %s", __func__);
       char * ss_name = (char*)key;
       struct snapshot *ss = (struct snapshot*)value;
       char * del_ss_name = (char*)user_data;
       if(g_strcmp0(ss->up_sname,del_ss_name) == 0){
        g_message("leave func %s", __func__);
          return TRUE;
       }
        g_message("leave func %s", __func__);
       return FALSE;
}

static void revise_snapshot_relation(GHashTable *ss_hashtable,GList 
*remove_list){
    g_message("enter func %s", __func__);
     int i = 0;
     g_message("del list length is %d", g_list_length(remove_list));
     for(i = 0; i < g_list_length(remove_list); i++){
        char * ss_name = g_list_nth_data(remove_list,i);
        struct snapshot *ss = g_hash_table_lookup(ss_hashtable,ss_name);
        g_message("99 dbg del ss %s", ss->sname);
        g_assert(ss!=NULL);
        char *up_ss_name = ss->up_sname;
        struct snapshot *revise_ss = g_hash_table_find (ss_hashtable,predicate_same_upname_snapshot,ss_name);
        if(revise_ss !=NULL){
           snprintf(revise_ss->up_sname,HLFS_FILE_NAME_MAX,"%s",ss->up_sname);
        }
        g_message("99 dbg revise %s", revise_ss->sname);
        g_hash_table_remove(ss_hashtable, ss->sname);
        g_message("99 dbg revise %s", revise_ss->sname);
//        g_free(ss);
     }
    g_message("leave func %s", __func__);
     return ;
}

int main(int argc, char **argv) {
    int i = 0;
    char up_sname[128];
    memset(up_sname, 0, 128);
    struct snapshot ss[4];
    memset(ss, 0, 4);
    GHashTable *ss_hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
    for (i = 0; i < 4; i++) {
        ss[i].timestamp = i;
        ss[i].inode_addr = i;
        sprintf(ss[i].sname, "%s%d", "T", i);
        sprintf(ss[i].up_sname, "%s", up_sname);
        memset(up_sname, 0, 128);
        strcpy(up_sname, ss[i].sname);
        g_hash_table_insert(ss_hashtable, ss[i].sname, &ss[i]);
    }
    GList *to_remove_ss_list = NULL;
    to_remove_ss_list = g_list_append(to_remove_ss_list, "T1");
//    to_remove_ss_list = g_list_append(to_remove_ss_list, "T2");
    g_message("list is %s", (char *) to_remove_ss_list->data);
    revise_snapshot_relation(ss_hashtable, to_remove_ss_list);
    g_message("99 dbg");
    GList *values = g_hash_table_get_values(ss_hashtable);
    for (i = 0; i < g_list_length(values); i++) {
        struct snapshot *value = g_list_nth_data(values, i);
        printf("snapshot %d is -------------\n", i);
        printf("name is %s\n", value->sname);
        printf("up name is %s\n", value->up_sname);
    }
    g_hash_table_destroy(ss_hashtable);
    return 0;
}

输出结果
========
jiawei@jiawei-laptop:~/workshop15/cloudxy/branches/snapshot/test/build$ ./test
** Message: list is T1
** Message: enter func revise_snapshot_relation
** Message: del list length is 1
** Message: 99 dbg del ss T1
** Message: enter func predicate_same_upname_snapshot
** Message: leave func predicate_same_upname_snapshot
** Message: enter func predicate_same_upname_snapshot
** Message: leave func predicate_same_upname_snapshot
** Message: 99 dbg revise T2
** Message: 99 dbg revise T2
** Message: leave func revise_snapshot_relation
** Message: 99 dbg
snapshot 0 is -------------
name is T0
up name is
snapshot 1 is -------------
name is T3
up name is T2
snapshot 2 is -------------
name is T2
up name is T0

bug当前状态
==========
这个bug目前还未处理,我希望康师哥review一下,我再修复,��
�能我的测试用例
还存在问题。

测试用例存在的问题
====================
当我把 g_hash_table_new_full加上自动free,就会出现free invalid 
pointer 错误,求解。

Original issue reported on code.google.com by harryxi...@gmail.com on 29 Jan 2012 at 4:54

GoogleCodeExporter commented 9 years ago

已经进行了修复,效率有所提升。

测试概述
========
revise 前快照图如下:

       T0                                        T1                               T2                              T3
|---------------------------|          |--------------------------|         
|------------------------|         |---------------------|
|     null  |     T0      |          |     T0 |    T1        |         |    T1  
 |    T2     |         |    T2  |    T3    |
|---------------------------|          |--------------------------|         
|------------------------|         |---------------------|    

                                                                                     T4
                                                                           |-------------------------|
                                                                           |     T1   |     T4    |
                                                                           |-------------------------|                 ..................
revise 后的快照图如下:(我们这里删除了 T1)

            T0                                       T2                              T3
|---------------------------|               |------------------------|         
|---------------------|
|     null  |     T0      |               |    T0   |    T2     |         |    
T2  |    T3    |
|---------------------------|               |------------------------|         
|---------------------|    

                                                                                     T4
                                                                           |-------------------------|
                                                                           |     T0   |     T4    |
                                                                           |-------------------------|                 ..................

注意:上图的第一个域表示 up snapshot name, 第二个域表示 
current snapshot name。

测试代码
========

#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define HLFS_FILE_NAME_MAX            (80)

struct snapshot {
    uint64_t timestamp;
    uint64_t inode_addr;
    char sname[HLFS_FILE_NAME_MAX];
    char up_sname[HLFS_FILE_NAME_MAX]; /* for tree style snapshot */
} __attribute__((packed));

/* load all snapshot will remove del snapshot and revise relation upname */
static void predicate_same_upname_snapshot(gpointer key,gpointer value,gpointer 
user_data){

        g_message("enter func %s", __func__);
       char * ss_name = (char*)key;
       struct snapshot *ss = (struct snapshot*)value;
       struct snapshot *del_ss = (struct snapshot *)user_data;
       if(g_strcmp0(ss->up_sname,del_ss->sname) == 0){
           snprintf(ss->up_sname, HLFS_FILE_NAME_MAX, "%s", del_ss->up_sname);

       }
        g_message("leave func %s", __func__);
       return ;

}

static void revise_snapshot_relation(GHashTable *ss_hashtable,GList 
*remove_list){
    g_message("enter func %s", __func__);
     int i = 0;
     g_message("del list length is %d", g_list_length(remove_list));
     for(i = 0; i < g_list_length(remove_list); i++){
        char * ss_name = g_list_nth_data(remove_list,i);
        struct snapshot *ss = g_hash_table_lookup(ss_hashtable,ss_name);
        g_message("99 dbg del ss %s", ss->sname);
        g_assert(ss!=NULL);
        char *up_ss_name = ss->up_sname;
        g_hash_table_foreach (ss_hashtable,predicate_same_upname_snapshot,ss);
        g_hash_table_remove(ss_hashtable, ss->sname);

     }
    g_message("leave func %s", __func__);
     return ;
}

int main(int argc, char **argv) {
    int i = 0;
    char up_sname[128];
    memset(up_sname, 0, 128);
    struct snapshot ss[4];
    memset(ss, 0, 4 * sizeof(struct snapshot));

    GHashTable *ss_hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
    for (i = 0; i < 4; i++) {
        ss[i].timestamp = i;
        ss[i].inode_addr = i;
        sprintf(ss[i].sname, "%s%d", "T", i);
        sprintf(ss[i].up_sname, "%s", up_sname);
        memset(up_sname, 0, 128);
        strcpy(up_sname, ss[i].sname);
        g_hash_table_insert(ss_hashtable, ss[i].sname, &ss[i]);
    }
    struct snapshot _ss;
    memset(&_ss, 0, sizeof(struct snapshot));
    _ss.timestamp = 0;
    _ss.inode_addr = 0;
    sprintf(_ss.sname, "%s", "T4");
    sprintf(_ss.up_sname, "%s", "T1");
    g_hash_table_insert(ss_hashtable, _ss.sname, &_ss);

    GList *to_remove_ss_list = NULL;
    to_remove_ss_list = g_list_append(to_remove_ss_list, "T1");
- Show quoted text -
** Message: leave func revise_snapshot_relation
** Message: 99 dbg
snapshot 0 is -------------
name is T0
up name is
snapshot 1 is -------------
name is T4
up name is T0

snapshot 2 is -------------
name is T3
up name is T2
snapshot 3 is -------------
name is T2
up name is T0 

Original comment by harryxi...@gmail.com on 30 Jan 2012 at 2:49