1 #include <rados/librados.h> 2 #include <rbd/librbd.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 rados_t init_rados() 7 { 8 // we will use all of these below 9 int ret = 0; 10 rados_t rados = NULL; 11 12 // 1. init rados object 13 ret = rados_create(&rados, "admin"); // just use the client.admin keyring 14 if (ret < 0) { 15 // let's handle any error that might have come back 16 printf("couldn't initialize rados! err %d\n", ret); 17 return NULL; 18 } 19 else 20 { 21 printf("inited rados cluster object\n"); 22 } 23 return rados; 24 } 25 26 rados_ioctx_t init_ioctx(rados_t rados) 27 { 28 int ret = 0; 29 rados_ioctx_t io_ctx = NULL; 30 31 // 2. read ceph config file 32 ret = rados_conf_read_file(rados, "/etc/ceph/ceph.conf"); 33 if (ret < 0) { 34 // This could fail if the config file is malformed, but it'd be hard. 35 printf("failed to parse config file! err %d\n", ret); 36 return NULL; 37 } 38 39 // 3. connect to ceph cluster 40 ret = rados_connect(rados); 41 if (ret < 0) { 42 printf("couldn't connect to cluster! err %d\n", ret); 43 return NULL; 44 } else { 45 printf("connected to the rados cluster\n"); 46 } 47 48 // 4. init io context for rbd pool 49 const char *pool_name = "sunbin"; 50 ret = rados_ioctx_create(rados, pool_name, &io_ctx); 51 if (ret < 0) 52 { 53 printf("couldn't setup ioctx! err %d\n", ret); 54 rados_shutdown(rados); 55 return NULL; 56 } else { 57 printf("created an ioctx for pool: sunbin\n"); 58 } 59 60 return io_ctx; 61 } 62 63 rbd_image_t init_image(rados_ioctx_t io_ctx) 64 { 65 int ret = 0; 66 67 // 5. open rbd image 68 rbd_image_t image; 69 const char *image_name = "rbd01"; 70 ret = rbd_open(io_ctx, image_name, &image, NULL); 71 if (ret < 0) { 72 printf("couldn't open rbd image! err %d\n", ret); 73 return NULL; 74 } else { 75 printf("opened an rbd image: rbd01\n"); 76 } 77 return image; 78 } 79 80 int get_rbd_size(rbd_image_t image) 81 { 82 int ret = 0; 83 uint64_t size = 0; 84 85 // 6. get rbd image size 86 ret = rbd_get_size(image, &size); 87 if (ret < 0) { 88 printf("couldn't get image size! err %d\n", ret); 89 return EXIT_FAILURE; 90 } else { 91 printf("The size of the image is: %dMB\n", size / 1024 / 1024); 92 } 93 94 return size; 95 } 96 97 void rbd_finish_aiocb(rbd_completion_t c, void *arg) 98 { 99 // int ret = rbd_aio_wait_for_complete(c); 100 int ret = rbd_aio_get_return_value(c); 101 rbd_aio_release(c); 102 103 // for aio read callback, the read data should be copied here to caller 104 printf("aio callback: %d, %s\n", ret, (const char *)arg); 105 } 106 107 int aio_write(rbd_image_t image, const char *buff) 108 { 109 int off = 128; 110 rbd_completion_t c; 111 int ret = rbd_aio_create_completion((void *)buff, (rbd_callback_t)rbd_finish_aiocb, &c); 112 if (ret < 0) { 113 printf("create callback failed %s\n", ret); 114 return ret; 115 } 116 117 int len = strlen(buff); 118 ret = rbd_aio_write(image, off, len, buff, c); 119 if (ret < 0) { 120 printf("write to image failed %s\n", ret); 121 return ret; 122 } 123 printf("write %s to image end\n", buff); 124 125 return ret; 126 } 127 128 int aio_read(rbd_image_t image, char *buff) 129 { 130 int off = 128; 131 int len = 10; 132 rbd_completion_t c; 133 int ret = rbd_aio_create_completion(buff, (rbd_callback_t)rbd_finish_aiocb, &c); 134 if (ret < 0) 135 { 136 printf("create callback failed %s\n", ret); 137 return ret; 138 } 139 memset(buff, 0, 128); 140 ret = rbd_aio_read(image, off, len, buff, c); 141 if (ret < 0) 142 { 143 printf("read from image failed %s\n", ret); 144 return ret; 145 } 146 printf("read from image end\n"); 147 148 return ret; 149 } 150 151 int main() 152 { 153 int ret; 154 char buff[128] = {0}; 155 int len; 156 157 rados_t rados = init_rados(); 158 if (!rados) { 159 perror("init_rados"); 160 return EXIT_FAILURE; 161 } 162 rados_ioctx_t io_ctx = init_ioctx(rados); 163 if (!io_ctx) { 164 perror("init_ioctx"); 165 rados_shutdown(rados); 166 return EXIT_FAILURE; 167 } 168 169 rbd_image_t image = init_image(io_ctx); 170 if (!image) { 171 perror("init_image"); 172 rados_ioctx_destroy(io_ctx); 173 rados_shutdown(rados); 174 return EXIT_FAILURE; 175 } 176 177 int size = get_rbd_size(image); 178 printf("image size: %d\n", size); 179 180 sprintf(buff, "%s", "abcd123efg"); 181 aio_write(image, buff); 182 183 aio_read(image, buff); 184 185 // 7. close image, io context and rados object 186 ret = rbd_close(image); 187 if (ret < 0) { 188 printf("couldn't close rbd image! err %d\n", ret); 189 return EXIT_FAILURE; 190 } else { 191 printf("closed rbd image: rbd01\n"); 192 } 193 rados_ioctx_destroy(io_ctx); 194 rados_shutdown(rados); 195 196 return 0; 197 }