Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / cls / numops / cls_numops.cc
1 /*
2  * Ceph - scalable distributed file system
3  *
4  * Copyright (C) 2015 CERN
5  *
6  * Author: Joaquim Rocha <joaquim.rocha@cern.ch>
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2.1 of the License, or (at your option) any later version.
12  *
13  */
14
15 /** \file
16  *
17  * This is an OSD class that implements methods for object numeric options on
18  * its omap values.
19  *
20  */
21
22 #include "objclass/objclass.h"
23 #include <errno.h>
24 #include <string>
25 #include <sstream>
26 #include <cstdio>
27 #include <include/compat.h>
28
29 #define DECIMAL_PRECISION 10
30
31 CLS_VER(1,0)
32 CLS_NAME(numops)
33
34 static int add(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
35 {
36   string key, diff_str;
37
38   bufferlist::iterator iter = in->begin();
39   try {
40     ::decode(key, iter);
41     ::decode(diff_str, iter);
42   } catch (const buffer::error &err) {
43     CLS_LOG(20, "add: invalid decode of input");
44     return -EINVAL;
45   }
46
47   char *end_ptr = 0;
48   double difference = strtod(diff_str.c_str(), &end_ptr);
49
50   if (end_ptr && *end_ptr != '\0') {
51     CLS_ERR("add: invalid input value: %s", diff_str.c_str());
52     return -EINVAL;
53   }
54
55   bufferlist bl;
56   int ret = cls_cxx_map_get_val(hctx, key, &bl);
57
58   double value;
59
60   if (ret == -ENODATA || bl.length() == 0) {
61     value = 0;
62   } else if (ret < 0) {
63     if (ret != -ENOENT) {
64       CLS_ERR("add: error reading omap key %s: %d", key.c_str(), ret);
65     }
66     return ret;
67   } else {
68     std::string stored_value(bl.c_str(), bl.length());
69     end_ptr = 0;
70     value = strtod(stored_value.c_str(), &end_ptr);
71
72     if (end_ptr && *end_ptr != '\0') {
73       CLS_ERR("add: invalid stored value: %s", stored_value.c_str());
74       return -EBADMSG;
75     }
76   }
77
78   value += difference;
79
80   std::stringstream stream;
81   stream << std::setprecision(DECIMAL_PRECISION) << value;
82
83   bufferlist new_value;
84   new_value.append(stream.str());
85
86   return cls_cxx_map_set_val(hctx, key, &new_value);
87 }
88
89 static int mul(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
90 {
91   string key, diff_str;
92
93   bufferlist::iterator iter = in->begin();
94   try {
95     ::decode(key, iter);
96     ::decode(diff_str, iter);
97   } catch (const buffer::error &err) {
98     CLS_LOG(20, "add: invalid decode of input");
99     return -EINVAL;
100   }
101
102   char *end_ptr = 0;
103   double difference = strtod(diff_str.c_str(), &end_ptr);
104
105   if (end_ptr && *end_ptr != '\0') {
106     CLS_ERR("add: invalid input value: %s", diff_str.c_str());
107     return -EINVAL;
108   }
109
110   bufferlist bl;
111   int ret = cls_cxx_map_get_val(hctx, key, &bl);
112
113   double value;
114
115   if (ret == -ENODATA || bl.length() == 0) {
116     value = 0;
117   } else if (ret < 0) {
118     if (ret != -ENOENT) {
119       CLS_ERR("add: error reading omap key %s: %d", key.c_str(), ret);
120     }
121     return ret;
122   } else {
123     std::string stored_value(bl.c_str(), bl.length());
124     end_ptr = 0;
125     value = strtod(stored_value.c_str(), &end_ptr);
126
127     if (end_ptr && *end_ptr != '\0') {
128       CLS_ERR("add: invalid stored value: %s", stored_value.c_str());
129       return -EBADMSG;
130     }
131   }
132
133   value *= difference;
134
135   std::stringstream stream;
136   stream << std::setprecision(DECIMAL_PRECISION) << value;
137
138   bufferlist new_value;
139   new_value.append(stream.str());
140
141   return cls_cxx_map_set_val(hctx, key, &new_value);
142 }
143
144 CLS_INIT(numops)
145 {
146   CLS_LOG(20, "loading cls_numops");
147
148   cls_handle_t h_class;
149   cls_method_handle_t h_add;
150   cls_method_handle_t h_mul;
151
152   cls_register("numops", &h_class);
153
154   cls_register_cxx_method(h_class, "add",
155                           CLS_METHOD_RD | CLS_METHOD_WR,
156                           add, &h_add);
157
158   cls_register_cxx_method(h_class, "mul",
159                           CLS_METHOD_RD | CLS_METHOD_WR,
160                           mul, &h_mul);
161 }