<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2013/12/7 Liu Yuan <span dir="ltr"><<a href="mailto:namei.unix@gmail.com" target="_blank">namei.unix@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Fri, Dec 06, 2013 at 05:04:18PM +0800, Robin Dong wrote:<br>
> From: Robin Dong <<a href="mailto:sanbai@taobao.com">sanbai@taobao.com</a>><br>
><br>
> Using hyper volume (size up to 16PB) to store large number of accounts<br>
> and containers.<br>
><br>
> Signed-off-by: Robin Dong <<a href="mailto:sanbai@taobao.com">sanbai@taobao.com</a>><br>
> ---<br>
>  sheep/http/http.c  |   2 +<br>
>  sheep/http/http.h  |   1 +<br>
>  sheep/http/kv.c    | 630 +++++++++++++++++++++++++++++++++++++++++++++++------<br>
>  sheep/http/kv.h    |  20 +-<br>
>  sheep/http/s3.c    |   4 +-<br>
>  sheep/http/swift.c |  98 ++++++---<br>
>  6 files changed, 654 insertions(+), 101 deletions(-)<br>
><br>
> diff --git a/sheep/http/http.c b/sheep/http/http.c<br>
> index 04ef364..cae3f44 100644<br>
> --- a/sheep/http/http.c<br>
> +++ b/sheep/http/http.c<br>
> @@ -52,6 +52,7 @@ static inline const char *strstatus(enum http_status status)<br>
>               [NO_CONTENT] = "204 No Content",<br>
>               [PARTIAL_CONTENT] = "206 Partial Content",<br>
>               [BAD_REQUEST] = "400 Bad Request",<br>
> +             [UNAUTHORIZED] = "401 Unauthorized",<br>
>               [NOT_FOUND] = "404 Not Found",<br>
>               [METHOD_NOT_ALLOWED] = "405 Method Not Allowed",<br>
>               [CONFLICT] = "409 Conflict",<br>
> @@ -233,6 +234,7 @@ static void http_run_request(struct work *work)<br>
><br>
>               if (method != NULL) {<br>
>                       method(req);<br>
> +                     sd_debug("req->status %d", req->status);<br>
>                       if (req->status != UNKNOWN)<br>
>                               goto out;<br>
>               }<br>
> diff --git a/sheep/http/http.h b/sheep/http/http.h<br>
> index 046d412..a8527d1 100644<br>
> --- a/sheep/http/http.h<br>
> +++ b/sheep/http/http.h<br>
> @@ -32,6 +32,7 @@ enum http_status {<br>
>       NO_CONTENT,                     /* 204 */<br>
>       PARTIAL_CONTENT,                /* 206 */<br>
>       BAD_REQUEST,                    /* 400 */<br>
> +     UNAUTHORIZED,                   /* 401 */<br>
>       NOT_FOUND,                      /* 404 */<br>
>       METHOD_NOT_ALLOWED,             /* 405 */<br>
>       CONFLICT,                       /* 409 */<br>
> diff --git a/sheep/http/kv.c b/sheep/http/kv.c<br>
> index 8113389..55a7e24 100644<br>
> --- a/sheep/http/kv.c<br>
> +++ b/sheep/http/kv.c<br>
> @@ -16,14 +16,25 @@<br>
><br>
>  #define FOR_EACH_VDI(nr, vdis) FOR_EACH_BIT(nr, vdis, SD_NR_VDIS)<br>
><br>
> -static int lookup_bucket(struct http_request *req, const char *bucket,<br>
> -                      uint32_t *vid)<br>
> +struct bucket_inode {<br>
> +     char bucket_name[SD_MAX_BUCKET_NAME];<br>
> +     uint64_t obj_count;<br>
> +     uint64_t bytes_used;<br>
> +     uint32_t vdi_id;                /* kv_onode stores in this vdi */<br>
<br>
</div></div>simply name it as onode_vid and no need for comment.<br>
<div class="im"><br>
> +     uint32_t pad;<br>
> +     uint64_t reserved[SD_MAX_BUCKET_NAME/sizeof(uint64_t) - 3];<br>
> +};<br>
<br>
</div>Use a union like in kv_onode to expelictly set how much space it actually takes.<br>
<div><div class="h5"><br>
> +<br>
> +#define MAX_BUCKETS (SD_MAX_VDI_SIZE / sizeof(struct bucket_inode))<br>
> +#define BUCKETS_PER_SD_OBJ (SD_DATA_OBJ_SIZE / sizeof(struct bucket_inode))<br>
> +<br>
> +static int lookup_vdi(const char *name, uint32_t *vid)<br>
>  {<br>
>       int ret;<br>
>       struct vdi_info info = {};<br>
>       struct vdi_iocb iocb = {<br>
> -             .name = bucket,<br>
> -             .data_len = strlen(bucket),<br>
> +             .name = name,<br>
> +             .data_len = strlen(name),<br>
>       };<br>
><br>
>       ret = vdi_lookup(&iocb, &info);<br>
> @@ -32,27 +43,23 @@ static int lookup_bucket(struct http_request *req, const char *bucket,<br>
>               *vid = info.vid;<br>
>               break;<br>
>       case SD_RES_NO_VDI:<br>
> -             sd_info("no such bucket %s", bucket);<br>
> -             http_response_header(req, NOT_FOUND);<br>
> -             return -1;<br>
> +             sd_info("no such vdi %s", name);<br>
> +             break;<br>
>       default:<br>
> -             sd_err("%s: bucket %s", sd_strerror(ret), bucket);<br>
> -             http_response_header(req, INTERNAL_SERVER_ERROR);<br>
> -             return -1;<br>
> +             sd_err("Failed to find vdi %s %s", name, sd_strerror(ret));<br>
>       }<br>
><br>
> -     return 0;<br>
> +     return ret;<br>
>  }<br>
><br>
> -/* Bucket operations */<br>
> -<br>
> -int kv_create_bucket(struct http_request *req, const char *bucket)<br>
> +static int kv_create_hyper_volume(const char *name, uint32_t *vdi_id)<br>
>  {<br>
>       struct sd_req hdr;<br>
> +     struct sd_rsp *rsp = (struct sd_rsp *)&hdr;<br>
>       int ret;<br>
>       char buf[SD_MAX_VDI_LEN] = {0};<br>
><br>
> -     pstrcpy(buf, SD_MAX_VDI_LEN, bucket);<br>
> +     pstrcpy(buf, SD_MAX_VDI_LEN, name);<br>
><br>
>       sd_init_req(&hdr, SD_OP_NEW_VDI);<br>
>       hdr.flags = SD_FLAG_CMD_WRITE;<br>
> @@ -64,44 +71,50 @@ int kv_create_bucket(struct http_request *req, const char *bucket)<br>
>       hdr.vdi.store_policy = 1;<br>
><br>
>       ret = exec_local_req(&hdr, buf);<br>
> -     switch (ret) {<br>
> -     case SD_RES_SUCCESS:<br>
> -             http_response_header(req, CREATED);<br>
> -             break;<br>
> -     case SD_RES_VDI_EXIST:<br>
> -             http_response_header(req, ACCEPTED);<br>
> -             break;<br>
> -     default:<br>
> -             sd_err("%s: bucket %s", sd_strerror(ret), bucket);<br>
> -             http_response_header(req, INTERNAL_SERVER_ERROR);<br>
> -             return -1;<br>
> -     }<br>
> +     if (rsp->result != SD_RES_SUCCESS)<br>
> +             sd_err("Failed to create VDI %s: %s", name,<br>
> +                    sd_strerror(rsp->result));<br>
><br>
> -     return 0;<br>
> -}<br>
> +     if (vdi_id)<br>
> +             *vdi_id = rsp->vdi.vdi_id;<br>
><br>
> -int kv_read_bucket(struct http_request *req, const char *bucket)<br>
> -{<br>
> -     /* TODO: read metadata of the bucket */<br>
> -     return -1;<br>
> +     return ret;<br>
>  }<br>
><br>
> -int kv_update_bucket(struct http_request *req, const char *bucket)<br>
> +static int discard_data_obj(uint64_t oid)<br>
>  {<br>
> -     /* TODO: update metadata of the bucket */<br>
> -     return -1;<br>
> +     int ret;<br>
> +     struct sd_req hdr;<br>
> +<br>
> +     sd_init_req(&hdr, SD_OP_DELETE_CACHE);<br>
> +     hdr.obj.oid = oid;<br>
> +<br>
> +     ret = exec_local_req(&hdr, NULL);<br>
> +     if (ret != SD_RES_SUCCESS) {<br>
> +             sd_err("Failed to execute request");<br>
> +             return ret;<br>
> +     }<br>
> +<br>
<br>
</div></div>Since our container can be accessed by multiple clients, I think we will never<br>
allow object cache for it, which is designed for a single client. So need to run<br>
SD_OP_DELETE_CACHE request.<br></blockquote><div><br></div><div>Do you mean "No need to run SD_OP_DELETE_CAHCE" ?  </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
For account HEAD operation:<br>
<br>
yliu@ubuntu-precise:~/sheepdog$ curl -i -X HEAD <a href="http://localhost/v1/yliu
HTTP/1.1" target="_blank">http://localhost/v1/yliu<br>
HTTP/1.1</a> 204 No Content<br>
Server: nginx/1.1.19<br>
Date: Sat, 07 Dec 2013 06:41:46 GMT<br>
Content-Type: text/plain;<br>
Connection: keep-alive<br>
X-Account-Container-Count: 2<br>
<br>
Seems that we need to pass X-Account-Bytes-Used too?<br>
<br>
For account GET operation:<br>
yliu@ubuntu-precise:~/sheepdog$ curl  -X GET <a href="http://localhost/v1/yliu" target="_blank">http://localhost/v1/yliu</a><br>
<br>
girls<br>
wives<br>
<br>
Seems that we write extra blank line and lack Content-Length field?<br>
<br>
Thanks<br>
<span class="HOEnZb"><font color="#888888">Yuan<br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br>--<br>Best Regard<br>Robin Dong
</div></div>