CEPH RGW处理请求过程

原创 2015年11月17日 20:29:06

Rgw处理请求过程

Rest api:
Put  /{bucket}  HTTP/1.1
x-amz-acl: public-read-write
Authorization: AWS {access}:{hash-of-header-and-secret}

这里依civetweb来提供rest服务来介绍,一个请求的处理过程。
回调函数的注册:
在civetweb中注册了用于处理请求的回调函数,在文件/rgw/rgw_main.cc中:

Class RGWMongooseFrontend::run(){
。。。
struct mg_callbacks cb;
    memset((void *)&cb, 0, sizeof(cb));
    cb.begin_request = civetweb_callback;
    cb.log_message = rgw_civetweb_log_callback;
    cb.log_access = rgw_civetweb_log_access_callback;
    ctx = mg_start(&cb, &env, (const char **)&options);
。。。
}

回调函数civetweb_callback()也定义在rgw_main.cc文件中:

static int civetweb_callback(struct mg_connection *conn) {
//提取request信息
  struct mg_request_info *req_info = mg_get_request_info(conn);
  RGWProcessEnv *pe = static_cast<RGWProcessEnv *>(req_info->user_data);
  RGWRados *store = pe->store;
  RGWREST *rest = pe->rest;
  OpsLogSocket *olog = pe->olog;
//构建rgw内部表示的request对象,即RGWRequest。
  RGWRequest *req = new RGWRequest(store->get_new_req_id());
  RGWMongoose client_io(conn, pe->port);
//进入request的处理流程
  int ret = process_request(store, rest, req, &client_io, olog);
  if (ret < 0) {
    /* we don't really care about return code */
    dout(20) << "process_request() returned " << ret << dendl;
  }

  delete req;

// Mark as processed
  return 1;
}

一个请求进入之后主要的处理流程都在process_request中:

static int process_request(RGWRados *store, RGWREST *rest, RGWRequest *req, RGWClientIO *client_io, OpsLogSocket *olog)

{
  int ret = 0;
// 初始化客户端,主要是从request info中取出请求头来,初始化client_io.env(RGWMongoose client_io(conn, pe->port);)
  client_io->init(g_ceph_context);
//初始化请求开始时间,及获取系统时间设置req中的时间变量ts
  req->log_init();

  dout(1) << "====== starting new request req=" << hex << req << dec << " =====" << dendl;
  //更新性能计数器,累加请求一次。
  perfcounter->inc(l_rgw_req);
//初始化执行环境,获取client_io的env来初始化,rgw_env)
  RGWEnv& rgw_env = client_io->get_env();
//存储用于完成完成请求的所有信息(Store all the state necessary to complete and respond to an HTTP request)
  struct req_state rstate(g_ceph_context, &rgw_env);

  struct req_state *s = &rstate;
//初始化rados上下文
  RGWObjectCtx rados_ctx(store, s);//rados_ctx.store=store;rados_ctx.user_ctx=s
  s->obj_ctx = &rados_ctx;
//初始化存储
  s->req_id = store->unique_id(req->id);
  s->trans_id = store->unique_trans_id(req->id);
//记录日志
  req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());

  //初始化RGWOp *op
  RGWOp *op = NULL;
  int init_error = 0;
  bool should_log = false;
  RGWRESTMgr *mgr; //声明RGWRESTMgr对象

  //根据请求的url来选择对应的manager和该manager中的handler,(具体过程间handler的获取见[RGW处理请求中获取handler过程 ](http://blog.csdn.net/litianze99/article/details/49892753))
  RGWHandler *handler = rest->get_handler(store, s, client_io, &mgr, &init_error);
  if (init_error != 0) {
    abort_early(s, NULL, init_error);
    goto done;
  }

  should_log = mgr->get_logging();

  req->log(s, "getting op");
  op = handler->get_op(store);
  if (!op) {
    abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED);
    goto done;
  }
  req->op = op;
//检查请求中带的签名与本地服务端计算出的签名是否一致,判断请求是否合法详细过程见[ RGW中的请求的认证过程 ](http://blog.csdn.net/litianze99/article/details/49892813)
  req->log(s, "authorizing");
  ret = handler->authorize();
  if (ret < 0) {
    dout(10) << "failed to authorize request" << dendl;
    abort_early(s, op, ret);
    goto done;
  }
//判断用户是否被禁用,如果是则退出。
  if (s->user.suspended) {
    dout(10) << "user is suspended, uid=" << s->user.user_id << dendl;
    abort_early(s, op, -ERR_USER_SUSPENDED);
    goto done;
  }
  req->log(s, "reading permissions");
  ret = handler->read_permissions(op);
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "init op");

  ret = op->init_processing();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "verifying op mask");
//验证op mask
  ret = op->verify_op_mask();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "verifying op permissions");
  ret = op->verify_permission();
  if (ret < 0) {
    if (s->system_request) {
      dout(2) << "overriding permissions due to system operation" << dendl;
    } else {
      abort_early(s, op, ret);
      goto done;
    }
  }

  req->log(s, "verifying op params");
//验证op params
  ret = op->verify_params();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "executing");
  op->pre_exec();
  //开始执行具体请求的操作
  op->execute();
  op->complete();
done:
//结束客户端请求
  int r = client_io->complete_request();
  if (r < 0) {
    dout(0) << "ERROR: client_io->complete_request() returned " << r << dendl;
  }
  if (should_log) {
    rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
  }

  int http_ret = s->err.http_ret;

  req->log_format(s, "http status=%d", http_ret);

  if (handler)
//回收op对象
handler->put_op(op);
  //回收handler对象
  rest->put_handler(handler);

  dout(1) << "====== req done req=" << hex << req << dec << " http_status=" << http_ret << " ======" << dendl;

  return (ret < 0 ? ret : s->err.ret);
}

ceph rgw中所使用的池子

ceph rgw中所使用的池子 $ radosgw-admin zone get {     "domain_root": ".rgw",     "control_pool": ".rgw.co...
  • litianze99
  • litianze99
  • 2015年11月24日 11:35
  • 866

CEPH RGW 使用

创建一个S3风格用法的用户 ceph-admin-node@ceph-admin-node:~$ sudo radosgw-admin user create id=”harvis_rgw_user...
  • jiankangshiye
  • jiankangshiye
  • 2017年04月17日 18:58
  • 678

【实践】RGW+Ganesha环境部署

目前,Ganesha支持两种方式将Ceph导出为NFS,一种是基于CephFS——Ganesha通过FSAL-CEPH模块连接到CephFS,另一种是基于RGW——Ganesha通过FSAL-RGW模...
  • iamonlyme
  • iamonlyme
  • 2017年06月18日 15:58
  • 1793

对ceph radosgw的一些理解

Ceph本质上就是一个rados,利用命令rados就可以访问和使用ceph的对象存储,但作为一个真正产品机的对象存储服务,通常使用的是Restful api的方式进行访问和使用。而radosgw其实...
  • wytdahu
  • wytdahu
  • 2015年06月17日 11:56
  • 3620

S3 client 访问ceph rgw

S3 client 访问ceph rgw安装配置S3 client:安装,s3cmd是使用python编写的客户端:$pip install s3cmd 也可以使用yum 安装$yum install...
  • litianze99
  • litianze99
  • 2015年09月14日 14:38
  • 3097

ceph运维常用指令

ceph运维常用指令
  • wangtaoking1
  • wangtaoking1
  • 2015年06月25日 18:33
  • 12550

Ceph Log日志相关代码走读

以ceph-10.2.9版本,ceph-mds进程为例 创建CephContext类对象 如图一所示,ceph_mds.cc中main函数,首先调用了函数global_init, 在global_...
  • wbz002
  • wbz002
  • 2017年07月27日 10:06
  • 152

ceph-rest-api的IPv6环境配置

引言 ceph-rest-api 是一个 WSGI (网页服务器网关接口)应用程序,可作为网页服务独立运行,也可在支持 WSGI 的网页服务器下运行。它通过 HTTP 访问接口提供了 ceph 命令...
  • u011436273
  • u011436273
  • 2017年12月27日 09:15
  • 24

Ceph+RGW高可用部署方案

基础环境准备配置主机名集群中节点采用统一命名规则即可配置hosts文件解析配置主机名与IP地址解析关系,每个配置完成后将文件拷贝到其他节点,每个节点都需要配置免秘钥登录配置ansible工具执行节点与...
  • xuensong520
  • xuensong520
  • 2017年12月18日 01:38
  • 112

ceph-deploy的rgw命令

ceph-deploy的rgw命令用于将conf_data 和key 写入到远程host中,并启动ceph-radosg和ceph.target 其入口函数为E:\ceph-deploy-master...
  • tiantao2012
  • tiantao2012
  • 2017年12月08日 14:42
  • 63
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CEPH RGW处理请求过程
举报原因:
原因补充:

(最多只允许输入30个字)