1    	// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2    	// vim: ts=8 sw=2 smarttab
3    	/*
4    	* Ceph - scalable distributed file system
5    	*
6    	* Copyright (C) 2011 New Dream Network
7    	*
8    	* This is free software; you can redistribute it and/or
9    	* modify it under the terms of the GNU Lesser General Public
10   	* License version 2.1, as published by the Free Software
11   	* Foundation.  See file COPYING.
12   	*
13   	*/
14   	
15   	#include "cross_process_sem.h"
16   	#include "include/rados/librados.h"
17   	#include "st_rados_create_pool.h"
18   	#include "systest_runnable.h"
19   	#include "systest_settings.h"
20   	
21   	#include <errno.h>
22   	#include <stdarg.h>
23   	#include <stdio.h>
24   	#include <stdlib.h>
25   	#include <unistd.h>
26   	#include <sstream>
27   	#include <string>
28   	
29   	using std::ostringstream;
30   	
31   	std::string StRadosCreatePool::
32   	get_random_buf(int sz)
33   	{
34   	  ostringstream oss;
(1) Event dont_call: "rand" should not be used for security-related applications, because linear congruential algorithms are too easy to break.
(2) Event remediation: Use a compliant random number generator, such as "/dev/random" or "/dev/urandom" on Unix-like systems, and CNG (Cryptography API: Next Generation) on Windows.
35   	  int size = rand() % sz; // yep, it's not very random
36   	  for (int i = 0; i < size; ++i) {
37   	    oss << ".";
38   	  }
39   	  return oss.str();
40   	}
41   	
42   	StRadosCreatePool::
43   	StRadosCreatePool(int argc, const char **argv,
44   			  CrossProcessSem *setup_sem,
45   			  CrossProcessSem *pool_setup_sem,
46   			  CrossProcessSem *close_create_pool,
47   			  const std::string &pool_name,
48   			  int num_objects,
49   			  const std::string &suffix)
50   	  : SysTestRunnable(argc, argv),
51   	    m_setup_sem(setup_sem),
52   	    m_pool_setup_sem(pool_setup_sem),
53   	    m_close_create_pool(close_create_pool),
54   	    m_pool_name(pool_name),
55   	    m_num_objects(num_objects),
56   	    m_suffix(suffix)
57   	{
58   	}
59   	
60   	StRadosCreatePool::
61   	~StRadosCreatePool()
62   	{
63   	}
64   	
65   	int StRadosCreatePool::
66   	run()
67   	{
68   	  int ret_val = 0;
69   	  rados_t cl;
70   	  RETURN1_IF_NONZERO(rados_create(&cl, NULL));
71   	  rados_conf_parse_argv(cl, m_argc, m_argv);
72   	  rados_conf_parse_argv(cl, m_argc, m_argv);
73   	  RETURN1_IF_NONZERO(rados_conf_read_file(cl, NULL));
74   	  std::string log_name = SysTestSettings::inst().get_log_name(get_id_str());
75   	  if (!log_name.empty())
76   	    rados_conf_set(cl, "log_file", log_name.c_str());
77   	  rados_conf_parse_env(cl, NULL);
78   	
79   	  if (m_setup_sem) {
80   	    m_setup_sem->wait();
81   	    m_setup_sem->post();
82   	  }
83   	
84   	  RETURN1_IF_NONZERO(rados_connect(cl));
85   	
86   	  printf("%s: creating pool %s\n", get_id_str(), m_pool_name.c_str());
87   	  rados_pool_create(cl, m_pool_name.c_str());
88   	  rados_ioctx_t io_ctx;
89   	  RETURN1_IF_NONZERO(rados_ioctx_create(cl, m_pool_name.c_str(), &io_ctx));
90   	
91   	  for (int i = 0; i < m_num_objects; ++i) {
92   	    char oid[128];
93   	    snprintf(oid, sizeof(oid), "%d%s", i, m_suffix.c_str());
94   	    std::string buf(get_random_buf(256));
95   	    int ret = rados_write(io_ctx, oid, buf.c_str(), buf.size(), 0);
96   	    if (ret != 0) {
97   	      printf("%s: rados_write(%s) failed with error: %d\n",
98   		     get_id_str(), oid, ret);
99   	      ret_val = ret;
100  	      goto out;
101  	    }
102  	    if (((i % 25) == 0) || (i == m_num_objects - 1)) {
103  	      printf("%s: created object %d...\n", get_id_str(), i);
104  	    }
105  	  }
106  	
107  	out:
108  	  printf("%s: finishing.\n", get_id_str());
109  	  if (m_pool_setup_sem)
110  	    m_pool_setup_sem->post();
111  	  if (m_close_create_pool)
112  	    m_close_create_pool->wait();
113  	  rados_ioctx_destroy(io_ctx);
114  	  rados_shutdown(cl);
115  	  return ret_val;
116  	}
117  	
118  	std::string get_temp_pool_name(const char* prefix)
119  	{
120  	  ceph_assert(prefix);
121  	  char hostname[80];
122  	  int ret = 0;
123  	  ret = gethostname(hostname, sizeof(hostname));
124  	  ceph_assert(!ret);
125  	  char poolname[256];
126  	  ret = snprintf(poolname, sizeof(poolname),
127  	                 "%s.%s-%d", prefix, hostname, getpid());
128  	  ceph_assert(ret > 0);
129  	  ceph_assert((unsigned int)ret < sizeof(poolname));
130  	  return poolname;
131  	}
132