]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_torrent.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / rgw / rgw_torrent.cc
CommitLineData
11fdf7f2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
7c673cae
FG
4#include <errno.h>
5#include <stdlib.h>
6
7#include <sstream>
8
9#include "rgw_torrent.h"
10#include "include/str_list.h"
11#include "include/rados/librados.hpp"
12
11fdf7f2
TL
13#include "services/svc_sys_obj.h"
14
7c673cae
FG
15#define dout_subsys ceph_subsys_rgw
16
7c673cae
FG
17using ceph::crypto::MD5;
18using namespace librados;
19using namespace boost;
20using ceph::crypto::SHA1;
21
22seed::seed()
23{
24 seed::info.piece_length = 0;
25 seed::info.len = 0;
26 sha_len = 0;
27 is_torrent = false;
28}
29
30seed::~seed()
31{
32 seed::info.sha1_bl.clear();
33 bl.clear();
7c673cae
FG
34 s = NULL;
35 store = NULL;
36}
37
38void seed::init(struct req_state *p_req, RGWRados *p_store)
39{
40 s = p_req;
41 store = p_store;
42}
43
3efd9988
FG
44int seed::get_torrent_file(RGWRados::Object::Read &read_op,
45 uint64_t &total_len,
46 ceph::bufferlist &bl_data,
47 rgw_obj &obj)
7c673cae
FG
48{
49 /* add other field if config is set */
50 dencode.bencode_dict(bl);
51 set_announce();
52 if (!comment.empty())
53 {
54 dencode.bencode(COMMENT, comment, bl);
55 }
56 if (!create_by.empty())
57 {
58 dencode.bencode(CREATED_BY, create_by, bl);
59 }
60 if (!encoding.empty())
61 {
62 dencode.bencode(ENCODING, encoding, bl);
63 }
64
65 string oid, key;
7c673cae 66 get_obj_bucket_and_oid_loc(obj, oid, key);
28e407b8 67 ldout(s->cct, 20) << "NOTICE: head obj oid= " << oid << dendl;
7c673cae 68
28e407b8
AA
69 const set<string> obj_key{RGW_OBJ_TORRENT};
70 map<string, bufferlist> m;
11fdf7f2 71 const int r = read_op.state.cur_ioctx->omap_get_vals_by_keys(oid, obj_key, &m);
28e407b8
AA
72 if (r < 0) {
73 ldout(s->cct, 0) << "ERROR: omap_get_vals_by_keys failed: " << r << dendl;
74 return r;
7c673cae 75 }
28e407b8
AA
76 if (m.size() != 1) {
77 ldout(s->cct, 0) << "ERROR: omap key " RGW_OBJ_TORRENT " not found" << dendl;
78 return -EINVAL;
7c673cae 79 }
28e407b8 80 bl.append(std::move(m.begin()->second));
7c673cae
FG
81 dencode.bencode_end(bl);
82
83 bl_data = bl;
84 total_len = bl.length();
3efd9988 85 return 0;
7c673cae
FG
86}
87
88bool seed::get_flag()
89{
90 return is_torrent;
91}
92
31f18b77 93void seed::update(bufferlist &bl)
7c673cae
FG
94{
95 if (!is_torrent)
96 {
97 return;
98 }
7c673cae 99 info.len += bl.length();
31f18b77
FG
100 sha1(&h, bl, bl.length());
101}
102
103int seed::complete()
104{
105 uint64_t remain = info.len%info.piece_length;
106 uint8_t remain_len = ((remain > 0)? 1 : 0);
107 sha_len = (info.len/info.piece_length + remain_len)*CEPH_CRYPTO_SHA1_DIGESTSIZE;
108
109 int ret = 0;
110 /* produce torrent data */
111 do_encode();
112
113 /* save torrent data into OMAP */
114 ret = save_torrent_file();
115 if (0 != ret)
116 {
117 ldout(s->cct, 0) << "ERROR: failed to save_torrent_file() ret= "<< ret << dendl;
118 return ret;
119 }
120
121 return 0;
7c673cae
FG
122}
123
124off_t seed::get_data_len()
125{
126 return info.len;
127}
128
129void seed::set_create_date(ceph::real_time& value)
130{
131 utime_t date = ceph::real_clock::to_timespec(value);
132 create_date = date.sec();
133}
134
135void seed::set_info_pieces(char *buff)
136{
137 info.sha1_bl.append(buff, CEPH_CRYPTO_SHA1_DIGESTSIZE);
138}
139
140void seed::set_info_name(const string& value)
141{
142 info.name = value;
143}
144
145void seed::sha1(SHA1 *h, bufferlist &bl, off_t bl_len)
146{
147 off_t num = bl_len/info.piece_length;
148 off_t remain = 0;
149 remain = bl_len%info.piece_length;
150
151 char *pstr = bl.c_str();
152 char sha[25];
153
154 /* get sha1 */
155 for (off_t i = 0; i < num; i++)
156 {
157 memset(sha, 0x00, sizeof(sha));
11fdf7f2
TL
158 h->Update((unsigned char *)pstr, info.piece_length);
159 h->Final((unsigned char *)sha);
7c673cae
FG
160 set_info_pieces(sha);
161 pstr += info.piece_length;
162 }
163
164 /* process remain */
165 if (0 != remain)
166 {
167 memset(sha, 0x00, sizeof(sha));
11fdf7f2
TL
168 h->Update((unsigned char *)pstr, remain);
169 h->Final((unsigned char *)sha);
7c673cae
FG
170 set_info_pieces(sha);
171 }
172}
173
7c673cae
FG
174int seed::get_params()
175{
176 is_torrent = true;
11fdf7f2
TL
177 info.piece_length = g_conf()->rgw_torrent_sha_unit;
178 create_by = g_conf()->rgw_torrent_createby;
179 encoding = g_conf()->rgw_torrent_encoding;
180 origin = g_conf()->rgw_torrent_origin;
181 comment = g_conf()->rgw_torrent_comment;
182 announce = g_conf()->rgw_torrent_tracker;
7c673cae
FG
183
184 /* tracker and tracker list is empty, set announce to origin */
185 if (announce.empty() && !origin.empty())
186 {
187 announce = origin;
188 }
189
190 return 0;
191}
192
193void seed::set_announce()
194{
195 list<string> announce_list; // used to get announce list from conf
196 get_str_list(announce, ",", announce_list);
197
198 if (announce_list.empty())
199 {
200 ldout(s->cct, 5) << "NOTICE: announce_list is empty " << dendl;
201 return;
202 }
203
204 list<string>::iterator iter = announce_list.begin();
205 dencode.bencode_key(ANNOUNCE, bl);
206 dencode.bencode_key((*iter), bl);
207
208 dencode.bencode_key(ANNOUNCE_LIST, bl);
209 dencode.bencode_list(bl);
210 for (; iter != announce_list.end(); ++iter)
211 {
212 dencode.bencode_list(bl);
213 dencode.bencode_key((*iter), bl);
214 dencode.bencode_end(bl);
215 }
216 dencode.bencode_end(bl);
217}
218
219void seed::do_encode()
220{
221 /*Only encode create_date and sha1 info*/
222 /*Other field will be added if confi is set when run get torrent*/
223 dencode.bencode(CREATION_DATE, create_date, bl);
224
225 dencode.bencode_key(INFO_PIECES, bl);
226 dencode.bencode_dict(bl);
227 dencode.bencode(LENGTH, info.len, bl);
228 dencode.bencode(NAME, info.name, bl);
229 dencode.bencode(PIECE_LENGTH, info.piece_length, bl);
230
231 char info_sha[100] = { 0 };
232 sprintf(info_sha, "%" PRIu64, sha_len);
233 string sha_len_str = info_sha;
234 dencode.bencode_key(PIECES, bl);
235 bl.append(sha_len_str.c_str(), sha_len_str.length());
236 bl.append(':');
237 bl.append(info.sha1_bl.c_str(), sha_len);
238 dencode.bencode_end(bl);
239}
240
241int seed::save_torrent_file()
242{
243 int op_ret = 0;
244 string key = RGW_OBJ_TORRENT;
245 rgw_obj obj(s->bucket, s->object.name);
246
247 rgw_raw_obj raw_obj;
248 store->obj_to_raw(s->bucket_info.placement_rule, obj, &raw_obj);
249
11fdf7f2
TL
250 auto obj_ctx = store->svc.sysobj->init_obj_ctx();
251 auto sysobj = obj_ctx.get_obj(raw_obj);
252
253 op_ret = sysobj.omap().set(key, bl);
7c673cae
FG
254 if (op_ret < 0)
255 {
256 ldout(s->cct, 0) << "ERROR: failed to omap_set() op_ret = " << op_ret << dendl;
257 return op_ret;
258 }
259
260 return op_ret;
261}