Motr  M0
libdemo.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  */
19 
20 #include "lib/trace.h" /* M0_LOG */
21 #include "lib/memory.h" /* m0_alloc */
22 #include "lib/string.h" /* m0_strdup */
23 #include "lib/misc.h" /* m0_full_name_hash */
24 #include "lib/buf.h" /* m0_buf */
25 #include "fid/fid.h" /* m0_fid */
26 #include "fop/fom.h" /* M0_FSO_AGAIN */
27 #include "stob/io.h" /* m0_stob_io_init */
28 #include "iscservice/isc.h" /* m0_isc_comp_register */
29 
30 #include "util.h"
31 #include "common.h"
32 #include "libdemo.h"
33 #include "libdemo_xc.h"
34 
35 static bool is_valid_string(struct m0_buf *in)
36 {
37  return m0_buf_streq(in, "hello") || m0_buf_streq(in, "Hello") ||
38  m0_buf_streq(in, "HELLO");
39 }
40 
41 int hello_world(struct m0_buf *in, struct m0_buf *out,
42  struct m0_isc_comp_private *comp_data, int *rc)
43 {
44  char *out_str;
45 
46  if (is_valid_string(in)) {
47  /*
48  * Note: The out buffer allocated here is freed
49  * by iscservice, and a computation shall not free
50  * it in the end of computation.
51  */
52  out_str = m0_strdup("world");
53  if (out_str != NULL) {
54  m0_buf_init(out, out_str, strlen(out_str));
55  *rc = 0;
56  } else
57  *rc = -ENOMEM;
58  } else
59  *rc = -EINVAL;
60 
61  return M0_FSO_AGAIN;
62 }
63 
64 enum op {MIN, MAX};
65 
66 int launch_io(struct m0_isc_comp_private *pdata, struct m0_buf *in, int *rc)
67 {
68  struct m0_stob_io *stio = (struct m0_stob_io *)pdata->icp_data;
69  struct m0_fom *fom = pdata->icp_fom;
70  struct isc_targs ta = {};
71 
72  *rc = m0_xcode_obj_dec_from_buf(&M0_XCODE_OBJ(isc_targs_xc, &ta),
73  in->b_addr, in->b_nob);
74  if (*rc != 0) {
75  M0_LOG(M0_ERROR, "failed to xdecode args: rc=%d", *rc);
76  return M0_FSO_AGAIN;
77  }
78 
79  *rc = m0_isc_io_launch(stio, &ta.ist_cob, &ta.ist_ioiv, fom);
80  if (*rc != 0) {
81  /*
82  * EAGAIN has a special meaning in the calling isc code,
83  * so make sure we don't return it by accident.
84  */
85  if (*rc == -EAGAIN)
86  *rc = -EBUSY;
87  return M0_FSO_AGAIN;
88  }
89 
90  *rc = -EAGAIN; /* Wait for the I/O result. */
91  return M0_FSO_WAIT;
92 }
93 
94 int compute_minmax(enum op op, struct m0_isc_comp_private *pdata,
95  struct m0_buf *out, int *rc)
96 {
97  int i = 0;
98  int n;
99  double val;
100  FILE *f;
101  char *p;
102  m0_bcount_t len;
103  struct mm_result res = {};
104  struct m0_buf buf = M0_BUF_INIT0;
105 
106  len = m0_isc_io_res((struct m0_stob_io *)pdata->icp_data, &p);
107  if (len < 0) {
108  *rc = M0_ERR_INFO((int)len, "failed to read data");
109  return M0_FSO_AGAIN;
110  }
111 
112  f = fmemopen(p, len, "r");
113  if (f == NULL) {
114  *rc = M0_ERR(-errno);
115  return M0_FSO_AGAIN;
116  }
117 
118  /*
119  * 1st value should go to the lbuf always, because it can be
120  * the right cut of the last value from the previous unit.
121  *
122  * We count it as the 1st element in the buffer.
123  */
124  if (fscanf(f, "%lf %n", &val, &n) < 1) {
125  fclose(f);
126  *rc = M0_ERR(-EINVAL);
127  return M0_FSO_AGAIN;
128  }
129  res.mr_lbuf.b_addr = p;
130  res.mr_lbuf.b_nob = n;
131  res.mr_nr = 1;
132 
133  /* Read 1st element to compare with (2nd element in the buffer). */
134  if (fscanf(f, "%lf ", &val) < 1)
135  goto out;
136  res.mr_val = val;
137  res.mr_idx = 1;
138 
139  for (i = 2; fscanf(f, "%lf %n", &val, &n) > 0 && !feof(f); i++) {
140  if (op == MIN ? val < res.mr_val :
141  val > res.mr_val) {
142  res.mr_idx = i;
143  res.mr_val = val;
144  }
145  }
146  res.mr_nr = i;
147  /*
148  * Last value should always go to the rbuf, because it can be
149  * the left cut of the first value in the next unit.
150  *
151  * rbuf element is counted as lbuf in the next unit. It may
152  * happen that there is no cut of element on the border. I.e.
153  * the last element is fully present at the end of the unit and
154  * the 1st element is fully present in the beginning of the next
155  * unit. This case must be checked by the client code (it should
156  * assume that there might be two elements present in the result
157  * of gluing rbuf and lbuf of who units). And if so, the index
158  * and the number of elements should be incremented by client.
159  */
160  res.mr_rbuf.b_addr = p + ftell(f) - n;
161  res.mr_rbuf.b_nob = n;
162  out:
163  *rc = m0_xcode_obj_enc_to_buf(&M0_XCODE_OBJ(mm_result_xc, &res),
164  &buf.b_addr, &buf.b_nob) ?:
165  m0_buf_copy_aligned(out, &buf, M0_0VEC_SHIFT);
166 
167  m0_buf_free(&buf);
168  fclose(f);
169 
170  return M0_FSO_AGAIN;
171 }
172 
183 int do_minmax(enum op op, struct m0_buf *in, struct m0_buf *out,
184  struct m0_isc_comp_private *data, int *rc)
185 {
186  int res;
187  struct m0_stob_io *stio = (struct m0_stob_io *)data->icp_data;
188 
189  if (stio == NULL) { /* 1st call */
190  M0_ALLOC_PTR(stio);
191  if (stio == NULL) {
192  *rc = -ENOMEM;
193  return M0_FSO_AGAIN;
194  }
195  data->icp_data = stio;
196  res = launch_io(data, in, rc);
197  if (*rc != -EAGAIN)
198  m0_free(stio);
199  } else {
200  res = compute_minmax(op, data, out, rc);
201  m0_isc_io_fini(stio);
202  m0_free(stio);
203  }
204 
205  return res;
206 }
207 
222 int comp_min(struct m0_buf *in, struct m0_buf *out,
223  struct m0_isc_comp_private *comp_data, int *rc)
224 {
225  return do_minmax(MIN, in, out, comp_data, rc);
226 }
227 
228 int comp_max(struct m0_buf *in, struct m0_buf *out,
229  struct m0_isc_comp_private *comp_data, int *rc)
230 {
231  return do_minmax(MAX, in, out, comp_data, rc);
232 }
233 
234 static void comp_reg(const char *f_name, int (*ftn)(struct m0_buf *arg_in,
235  struct m0_buf *args_out,
236  struct m0_isc_comp_private
237  *comp_data, int *rc))
238 {
239  struct m0_fid comp_fid;
240  int rc;
241 
242  isc_fid_get(f_name, &comp_fid);
243  rc = m0_isc_comp_register(ftn, f_name, &comp_fid);
244  if (rc == -EEXIST)
245  fprintf(stderr, "Computation already exists");
246  else if (rc == -ENOMEM)
247  fprintf(stderr, "Out of memory");
248 }
249 
250 void motr_lib_init(void)
251 {
252  comp_reg("hello_world", hello_world);
253  comp_reg("comp_min", comp_min);
254  comp_reg("comp_max", comp_max);
255  m0_xc_iscservice_demo_libdemo_init();
256 }
M0_INTERNAL int m0_buf_copy_aligned(struct m0_buf *dst, const struct m0_buf *src, unsigned shift)
Definition: buf.c:119
static struct m0_addb2_philter p
Definition: consumer.c:40
#define m0_strdup(s)
Definition: string.h:43
void * icp_data
Definition: isc.h:142
#define NULL
Definition: misc.h:38
void isc_fid_get(const char *f_name, struct m0_fid *fid)
Definition: common.c:26
Definition: idx_mock.c:52
static FILE * f
Definition: adieu.c:79
M0_INTERNAL bool m0_buf_streq(const struct m0_buf *buf, const char *str)
Definition: buf.c:132
#define M0_LOG(level,...)
Definition: trace.h:167
M0_INTERNAL void m0_buf_init(struct m0_buf *buf, void *data, uint32_t nob)
Definition: buf.c:37
struct m0_bufvec data
Definition: di.c:40
int compute_minmax(enum op op, struct m0_isc_comp_private *pdata, struct m0_buf *out, int *rc)
Definition: libdemo.c:94
uint64_t m0_bcount_t
Definition: types.h:77
static bool is_valid_string(struct m0_buf *in)
Definition: libdemo.c:35
Definition: sock.c:887
struct m0_fom * icp_fom
Definition: isc.h:134
op
Definition: libdemo.c:64
Definition: buf.h:37
int i
Definition: dir.c:1033
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL int64_t m0_isc_io_res(struct m0_stob_io *stio, char **buf)
Definition: isc.c:913
if(value==NULL)
Definition: dir.c:350
void motr_lib_init(void)
Definition: libdemo.c:250
int comp_min(struct m0_buf *in, struct m0_buf *out, struct m0_isc_comp_private *comp_data, int *rc)
Definition: libdemo.c:222
int comp_max(struct m0_buf *in, struct m0_buf *out, struct m0_isc_comp_private *comp_data, int *rc)
Definition: libdemo.c:228
#define M0_BUF_INIT0
Definition: buf.h:71
M0_INTERNAL int m0_xcode_obj_enc_to_buf(struct m0_xcode_obj *obj, void **buf, m0_bcount_t *len)
Definition: xcode.c:832
Definition: libdemo.c:64
Definition: dump.c:103
Definition: io.h:285
M0_INTERNAL void m0_buf_free(struct m0_buf *buf)
Definition: buf.c:55
Definition: fom.h:481
uint64_t n
Definition: fops.h:107
M0_INTERNAL void m0_isc_io_fini(struct m0_stob_io *stio)
Definition: isc.c:923
static void comp_reg(const char *f_name, int(*ftn)(struct m0_buf *arg_in, struct m0_buf *args_out, struct m0_isc_comp_private *comp_data, int *rc))
Definition: libdemo.c:234
Definition: fid.h:38
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL int m0_xcode_obj_dec_from_buf(struct m0_xcode_obj *obj, void *buf, m0_bcount_t len)
Definition: xcode.c:850
int launch_io(struct m0_isc_comp_private *pdata, struct m0_buf *in, int *rc)
Definition: libdemo.c:66
int hello_world(struct m0_buf *in, struct m0_buf *out, struct m0_isc_comp_private *comp_data, int *rc)
Definition: libdemo.c:41
int do_minmax(enum op op, struct m0_buf *in, struct m0_buf *out, struct m0_isc_comp_private *data, int *rc)
Definition: libdemo.c:183
#define M0_XCODE_OBJ(type, ptr)
Definition: xcode.h:962
Definition: libdemo.c:64
#define out(...)
Definition: gen.c:41
void m0_free(void *data)
Definition: memory.c:146
M0_INTERNAL int m0_isc_comp_register(int(*ftn)(struct m0_buf *arg_in, struct m0_buf *args_out, struct m0_isc_comp_private *comp_data, int *rc), const char *f_name, const struct m0_fid *ftn_fid)
Definition: isc.c:609
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL int m0_isc_io_launch(struct m0_stob_io *stio, struct m0_fid *cob, struct m0_io_indexvec *iv, struct m0_fom *fom)
Definition: isc.c:841