static ngx_int_t
ngx_http_tfs_parse_rc_info(ngx_http_tfs_rcs_info_t *rc_info_node,
    ngx_http_tfs_rc_ctx_t *rc_ctx,  u_char *data)
{
    u_char                                   *p;
    uint8_t                                   is_master;
    uint32_t                                  cluster_id, cluster_id_len, len;
    ngx_int_t                                 dup_info_size, rc;
    ngx_uint_t                                i, j;
    ngx_http_tfs_group_info_t                *group_info;
    ngx_http_tfs_logical_cluster_t           *logical_cluster;
    ngx_http_tfs_physical_cluster_t          *physical_cluster;
    ngx_http_tfs_cluster_group_info_t        *cluster_group_info, *cluster_group_info2;
    ngx_http_tfs_tair_server_addr_info_t     *dup_server_info;

    p = data;

    /* rc servers count */
    rc_info_node->rc_servers_count = *((uint32_t *) p);
    p += sizeof(uint32_t);

    if (rc_info_node->rc_servers_count > 0) {
        rc_info_node->rc_servers = ngx_slab_alloc_locked(rc_ctx->shpool,
                                                         rc_info_node->rc_servers_count * sizeof(uint64_t));
        if (rc_info_node->rc_servers == NULL) {
            ngx_http_tfs_expire_and_alloc(rc_info_node->rc_servers,
                                          rc_info_node->rc_servers_count * sizeof(uint64_t));
        }

        ngx_memcpy(rc_info_node->rc_servers, p,
                   rc_info_node->rc_servers_count * sizeof(uint64_t));
        p += sizeof(uint64_t) * rc_info_node->rc_servers_count;
    }

    /* logical cluster count */
    rc_info_node->logical_cluster_count = *((uint32_t *) p);
    p += sizeof(uint32_t);

    logical_cluster = rc_info_node->logical_clusters;
    for (i = 0; i < rc_info_node->logical_cluster_count; i++) {
        logical_cluster->need_duplicate = *p;
        p += sizeof(uint8_t);

        if (logical_cluster->need_duplicate) {
            len = *((uint32_t *) p);
            p += sizeof(uint32_t);

            if (len > 0) {
                dup_info_size = len - 1;
                dup_server_info = &logical_cluster->dup_server_info;

                rc = ngx_http_tfs_parse_tair_server_addr_info(dup_server_info, p,
                                                              dup_info_size, rc_ctx->shpool, 1);
                if (rc == NGX_ERROR) {
                    return NGX_ERROR;
                }

                logical_cluster->dup_server_addr_hash = ngx_murmur_hash2(p, dup_info_size);
                p += dup_info_size + 1;

                rc_info_node->need_duplicate = 1;
            }
        }

        logical_cluster->rw_cluster_count = *((uint32_t *) p);
        p += sizeof(uint32_t);

        physical_cluster = logical_cluster->rw_clusters;
        for (j = 0; j < logical_cluster->rw_cluster_count; j++) {
            /* cluster stat */
            physical_cluster->cluster_stat = *((uint32_t *) p);
            p += sizeof(uint32_t);

            /* access type */
            physical_cluster->access_type = *((uint32_t *) p);
            p += sizeof(uint32_t);

            /* cluster id */
            len = *((uint32_t *) p);
            if (len <= 0) {
                physical_cluster->cluster_id_text.len = 0;
                return NGX_ERROR;
            }

            physical_cluster->cluster_id_text.len = len - 1;
            p += sizeof(uint32_t);

            physical_cluster->cluster_id_text.data = ngx_slab_alloc_locked(rc_ctx->shpool,
                                                   physical_cluster->cluster_id_text.len);
            if (physical_cluster->cluster_id_text.data == NULL) {
                ngx_http_tfs_expire_and_alloc(physical_cluster->cluster_id_text.data,
                                              physical_cluster->cluster_id_text.len);
            }
            ngx_memcpy(physical_cluster->cluster_id_text.data, p, physical_cluster->cluster_id_text.len);
            /* this cluster id need get from ns */
            physical_cluster->cluster_id = 0;
            p += physical_cluster->cluster_id_text.len + 1;

            /* name server vip */
            len = *((uint32_t *) p);
            if (len <= 0) {
                physical_cluster->ns_vip_text.len = 0;
                return NGX_ERROR;
            }

            physical_cluster->ns_vip_text.len = len - 1;
            p += sizeof(uint32_t);

            physical_cluster->ns_vip_text.data = ngx_slab_alloc_locked(rc_ctx->shpool,
                                                                       physical_cluster->ns_vip_text.len);
            if (physical_cluster->ns_vip_text.data == NULL) {
                ngx_http_tfs_expire_and_alloc(physical_cluster->ns_vip_text.data,
                                              physical_cluster->ns_vip_text.len);
            }
            ngx_memcpy(physical_cluster->ns_vip_text.data, p, physical_cluster->ns_vip_text.len);

            p += physical_cluster->ns_vip_text.len + 1;

            ngx_http_tfs_parse_inet(&physical_cluster->ns_vip_text, &physical_cluster->ns_vip);

            physical_cluster++;
        }

        logical_cluster++;
    }

    /* report interval */
    rc_info_node->report_interval = *((uint32_t *) p);
    p += sizeof(uint32_t);

    /* modify time */
    rc_info_node->modify_time = *((uint64_t *) p);
    p += sizeof(uint64_t);

    /* root server */
    rc_info_node->meta_root_server = *((uint64_t *) p);
    p += sizeof(uint64_t);

    /* remote block cache */
    len = *((uint32_t *) p);
    p += sizeof(uint32_t);
    rc_info_node->remote_block_cache_info.len = 0;

    if (len > 0) {
        rc_info_node->remote_block_cache_info.len = len - 1;

        rc_info_node->remote_block_cache_info.data = ngx_slab_alloc_locked(rc_ctx->shpool,
                                    rc_info_node->remote_block_cache_info.len);
        if (rc_info_node->remote_block_cache_info.data == NULL) {
            ngx_http_tfs_expire_and_alloc(rc_info_node->remote_block_cache_info.data,
                                          rc_info_node->remote_block_cache_info.len);
        }

        ngx_memcpy(rc_info_node->remote_block_cache_info.data, p, len - 1);
        p += len;
    }

    /* unlink & update cluster */
    rc_info_node->unlink_cluster_count = *((uint32_t *) p);
    p += sizeof(uint32_t);

    cluster_group_info = rc_info_node->unlink_clusters;

    for (i = 0; i < rc_info_node->unlink_cluster_count; i++) {
        /* skip cluster_stat */
        p += sizeof(uint32_t);
        /* skip access type */
        p += sizeof(uint32_t);

        cluster_id_len = *((uint32_t *) p);
        p += sizeof(uint32_t);

        cluster_id = ngx_http_tfs_get_cluster_id(p);
        is_master = ngx_http_tfs_cluster_is_master(p);
        p += cluster_id_len;

        for (j = 0; j < i; j++) {
            cluster_group_info2 = &rc_info_node->unlink_clusters[j];
            if (cluster_group_info2->cluster_id == cluster_id) {
                break;
            }
        }

        if (j >= i) {
            group_info = &cluster_group_info[i].group_info[0];
            cluster_group_info[i].info_count = 1;
            cluster_group_info[i].group_count = 0;
            cluster_group_info[i].cluster_id = cluster_id;
            group_info->is_master = is_master;

        } else {
            group_info = &cluster_group_info2->group_info[cluster_group_info2->info_count++];
            group_info->is_master = is_master;
        }

        /* name server vip */
        len = *((uint32_t *) p);
        if (len <= 0) {
            group_info->ns_vip_text.len = 0;
            return NGX_ERROR;
        }

        group_info->ns_vip_text.len = len - 1;
        p += sizeof(uint32_t);

        group_info->ns_vip_text.data = ngx_slab_alloc_locked(rc_ctx->shpool,
                                                             group_info->ns_vip_text.len);
        if (group_info->ns_vip_text.data == NULL) {
            ngx_http_tfs_expire_and_alloc(group_info->ns_vip_text.data,
                                          group_info->ns_vip_text.len);
        }

        memcpy(group_info->ns_vip_text.data, p, group_info->ns_vip_text.len);

        group_info->group_seq = -1;
        p += len;

        ngx_http_tfs_parse_inet(&group_info->ns_vip_text, &group_info->ns_vip);
    }

    /* use remote cache flag */
    rc_info_node->use_remote_block_cache = *((uint32_t *) p);
    return NGX_OK;
}
Exemplo n.º 2
0
ngx_int_t
ngx_http_tfs_get_remote_block_cache_instance(
    ngx_http_tfs_remote_block_cache_ctx_t *ctx,
    ngx_str_t *server_addr)
{
    size_t                                server_addr_len;
    uint32_t                              server_addr_hash;
    ngx_int_t                             rc, i;
    ngx_str_t                            *st, *group_name;
    ngx_array_t                           config_server;
    ngx_http_tfs_t                       *t;
    ngx_http_tfs_tair_instance_t         *instance;
    ngx_http_tfs_tair_server_addr_info_t  server_addr_info;

    if (server_addr->len == 0
        || server_addr->data == NULL)
    {
        return NGX_ERROR;
    }

    t = ctx->data;
    server_addr_len = server_addr->len;
    server_addr_hash = ngx_murmur_hash2(server_addr->data, server_addr_len);

    instance = ctx->tair_instance;
    if (instance->server != NULL) {
        if (instance->server_addr_hash == server_addr_hash) {
            return NGX_OK;
        }

        ngx_http_etair_destory_server(instance->server,
                                      (ngx_cycle_t *) ngx_cycle);
        instance->server = NULL;
    }

    rc = ngx_http_tfs_parse_tair_server_addr_info(&server_addr_info,
                                                  server_addr->data,
                                                  server_addr_len,
                                                  t->pool, 0);
    if (rc == NGX_ERROR) {
        return NGX_ERROR;
    }

    rc = ngx_array_init(&config_server, t->pool,
                        NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT,
                        sizeof(ngx_str_t));
    if (rc == NGX_ERROR) {
        return NGX_ERROR;
    }

    for (i = 0; i < NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT; i++) {
        if (server_addr_info.server[i].len > 0 ) {
            st = (ngx_str_t *) ngx_array_push(&config_server);
            *st = server_addr_info.server[i];
        }
    }

    group_name = &server_addr_info.server[NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT];
    instance->server = ngx_http_etair_create_server(group_name,
                                                    &config_server,
                                                    t->main_conf->tair_timeout,
                                                    (ngx_cycle_t *) ngx_cycle);
    if (instance->server == NULL) {
        return NGX_ERROR;
    }
    instance->server_addr_hash = server_addr_hash;
    instance->area = server_addr_info.area;

    return NGX_OK;
}