[Analysis] Ceph programming instance interface Librbd (C ++) -- image creation and data read/write, cephlibrbd

Source: Internet
Author: User

[Analysis] Ceph programming instance interface Librbd (C ++) -- image creation and data read/write, cephlibrbd

Currently, we have two ways to use Ceph Block Storage :?
-Use QEMU/KVM to interact with Ceph Block devices through librbd. This mainly provides block storage devices for virtual machines, as shown in ;?

-Use the kernel module to interact with the Host kernel, mainly to provide block device support for physical machines.

Librbd is the abstraction of Block Storage interfaces provided by Ceph. It provides multiple interfaces, such as C/C ++ and Python. For C ++, the two most important classes areRBD? And?Image .?RBD? It is mainly responsible for creating, deleting, and cloning images.Image? Class is responsible for reading and writing images.

Preparations

For any client application, you must first connect to a running Ceph cluster.

Obtain cluster handle
// Declare the Rados object and initialize librados: Rados rados; ret = rados. init ("admin"); // just use the client. admin keyringif (ret <0) {// let's handle any error that might have come back std: cerr <"couldn't initialize rados! Err "<ret <std: endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else {std :: cout <"we just set up a rados cluster object" <std: endl;} // obtain the configuration file information:/etc/ceph. conf // 1. according to the command line parameter/* ret = rados. conf_parse_argv (argc, argv); if (ret <0) {// This really can't happen, but we need to check to be a good citizen. std: cerr <"failed to parse config options! Error "<ret <std: endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else {std: cout <" we just parsed our config options "<std:: endl; // We also want to apply the config file if the user specified // one, and conf_parse_argv won't do that for us. for (int I = 0; I <argc; ++ I) {if (strcmp (argv [I], "-c") = 0) | (strcmp (argv [I], "-- conf") = 0) {ret = rados. conf_read_file (argv [I + 1]); if (Ret <0) {// This cocould fail if the config file is malformed, but it 'd be hard. std: cerr <"failed to parse config file" <argv [I + 1] <"! Error "<ret <std: endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} break ;}}* // 2. in the program, specify ret = rados. conf_read_file ("/etc/ceph. conf "); if (ret <0) {// This cocould fail if the config file is malformed, but it 'd be hard. std: cerr <"failed to parse config file! Err "<ret <std: endl; ret = EXIT_FAILURE; return EXIT_FAILURE ;}

Connect to a cluster
ret = rados.connect();if (ret < 0) { std::cerr << "couldn't connect to cluster! err " << ret << std::endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else { std::cout << "we just connected to the rados cluster" << std::endl;}

Create an I/O Context

If there is no storage pool, you need to create a new storage pool first.

Create a storage pool
Const char * pool_name = "gnar"; ret = rados. pool_create (pool_name); if (ret <0) {std: cerr <"couldn't create pool! Error "<ret <std: endl; ret = EXIT_FAILURE; rados. shutdown (); // disconnect cluster connection return EXIT_FAILURE;} else {std: cout <"we just created a new pool named" <pool_name <std :: endl ;}

Create an I/O Context
Librados: IoCtx io_ctx; // I/O context const char * pool_name = "gnar"; ret = rados. ioctx_create (pool_name, io_ctx); if (ret <0) {std: cerr <"couldn't setup ioctx! Err "<ret <std: endl; ret = EXIT_FAILURE; rados. shutdown (); // disconnect cluster connection return EXIT_FAILURE;} else {std: cout <"we just created an ioctx for our pool" <std: endl ;}

Several RBD image APIs Declare An RBD object and create an rbd Image
Librbd: RBD rbd; const char * image_name = "rumboo"; uint64_t init_size = (uint64_t) 200*1024*1024; // The image initialization size is mbuint64_t features = 1; // affects the number of feature int order = 22; // The default value is 22, that is, 4 MB (1 <22) ret = rbd. create2 (io_ctx, image_name, init_size, features, & order); if (ret <0) {std: cerr <"couldn't create rbd image! Err "<ret <std: endl; ret = EXIT_FAILURE; io_ctx.close (); // disable the I/O context rados. shutdown (); // disconnect cluster connection return EXIT_FAILURE;} else {std: cout <"We just created an rbd image" <std: endl ;}

Open the rbd Image
Librbd: RBD rbd; const char * image_name = "rumboo"; librbd: Image image; ret = rbd. open (io_ctx, image, image_name); if (ret <0) {std: cerr <"couldn't open rbd image! Err "<ret <std: endl; ret = EXIT_FAILURE; io_ctx.close (); // disable the I/O context rados. shutdown (); // disconnect the cluster connection return EXIT_FAILURE;} else {std: cout <"We just opened an rbd image" <std: endl ;}

View image size
uint64_t size = 0;ret = image.size(&size);if (ret < 0) { std::cerr << "couldn't get image size! err " << ret << std::endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else { std::cout << "The size of the image is " << size << std::endl;}

Resize an image
Size = (uint64_t) 500*1024*1024; // adjust the image size by 500 MBret = image. resize (size); if (ret <0) {std: cerr <"couldn't change the size of the image! Err "<ret <std: endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else {std :: cout <"We just change the size of the image" <std: endl ;}

View image ID
std::string id;ret = image.get_id(&id);if (ret < 0) { std::cerr << "couldn't get image ID! err " << ret << std::endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else { std::cout << "The ID of the image is " << id << std::endl;}

View image features
features = 0;ret = image.features(&features);if (ret < 0) { std::cerr << "couldn't get image features! err " << ret << std::endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else { std::cout << "The features of the image are " << features << std::endl;}

View image status information
librbd::image_info_t info;ret = image.stat(info, sizeof(info));if (ret < 0) { std::cerr << "couldn't get image stat_info! err " << ret << std::endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else { std::cout << "info.size is " << info.size << std::endl; std::cout << "info.obj_size is " << info.obj_size << std::endl; std::cout << "info.num_objs is " << info.num_objs << std::endl; std::cout << "info.order is " << info.order << std::endl; std::cout << "info.block_name_prefix is " << info.block_name_prefix << std::endl;}

View the storage pool ID
std::cout << "data pool id is " << image.get_data_pool_id() << std::endl;
  • 1View block_name_prefix
    std::cout << "block name prefix is " << image.get_block_name_prefix() << std::endl;

    View flags
    uint64_t flags = 0;ret = image.get_flags(&flags);if (ret < 0) { std::cerr << "couldn't get image flags! err " << ret << std::endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else { std::cout << "image flags is " << flags << std::endl;}

    View striped Parameters
    std::cout << "image stripe unit is " << image.get_stripe_unit() << std::endl;std::cout << "image stripe count is " << image.get_stripe_count() << std::endl;

    RBD image data read/writeData read/write-synchronous
    Optional ofs_w = (optional) 0; // read/write offset uint64_t ofs_r = (uint64_t) 0; size_t len_w = 100; // read/write length size_t len_r = 100; ceph: bufferlist bl_w; // read/write bufferlistceph: bufferlist bl_r; const char * fn_ I = "input"; // read/Write File Name const char * fn_o = "output"; std: string error; ret = bl_r.read_file (fn_ I, & error); std: cout <"read file ret =" <ret <std: endl; if (ret <0) {std: cerr <"couldn't read file! Err "<ret <std: endl; ret = EXIT_FAILURE; image. close (); // close the rbd image io_ctx.close (); // close the I/O context rados. shutdown (); // disconnect the cluster connection return EXIT_FAILURE;} else {std: cout <"We just read a file" <std: endl ;} ssize_t ret_w = image. write2 (ofs_w, len_w, bl_r, 0); ssize_t ret_r = image. read2 (ofs_r, len_r, bl_w, 0); ret = bl_1_write_file (fn_o, 0644); std: cout <"write file ret =" <ret <std :: endl; if (re T <0) {std: cerr <"couldn't write file! Err "<ret <std: endl; ret = EXIT_FAILURE; image. close (); // close the rbd image io_ctx.close (); // close the I/O context rados. shutdown (); // disconnect cluster connection return EXIT_FAILURE;} else {std: cout <"We just wrote a file" <std: endl ;}

    Data read/write-asynchronous
    Std: string data = "foo"; uint64_t ofs_aiow = (uint64_t) 100; // read/write offset uint64_t ofs_aior = (uint64_t) 100; size_lent _aiow = 600; // read/write length size_t len_aior = 600; ceph: bufferlist bytes; // read/write bufferlistceph: bufferlist bl_aior; librbd: RBD: AioCompletion * write_completion = new librbd:: AioCompletion (NULL, (librbd: callback_t) simple_write_cb); // read and write AioCompletionlibrbd: RBD: AioCompletion * read_complet Ion = new librbd: RBD: AioCompletion (NULL, (librbd: callback_t) simple_read_cb); for (int I = 0; I <200; ++ I) {bl_aior.append (data);} std: cout <bl_aior.to_str () <std: endl; ret = image. aio_write2 (ofs_aiow, len_aiow, bl_aior, write_completion, 0); if (ret <0) {std: cerr <"couldn't start write! Error "<ret <std: endl; ret = EXIT_FAILURE; image. close (); // close the rbd image io_ctx.close (); // close the I/O context rados. shutdown (); // disconnect the cluster connection return EXIT_FAILURE;} write_completion-> wait_for_complete (); // wait until the write is completed ret_w = write_completion-> get_return_value (); if (ret_w <0) {std: cerr <"couldn't write! Error "<ret <std: endl; ret_w = EXIT_FAILURE; image. close (); // close the rbd image io_ctx.close (); // close the I/O context rados. shutdown (); // disconnect the cluster connection return EXIT_FAILURE;} else {std: cout <"we just write data successfully, return value is" <ret_w <std :: endl;} ret = image. aio_read2 (ofs_aior, len_aior, bl_aiow, read_completion, 0); if (ret <0) {std: cerr <"couldn't start read! Error "<ret <std: endl; ret = EXIT_FAILURE; image. close (); // close the rbd image io_ctx.close (); // close the I/O context rados. shutdown (); // disconnect the cluster connection return EXIT_FAILURE;} read_completion-> wait_for_complete (); // wait until the read is completed ret_r = read_completion-> get_return_value (); if (ret_r <0) {std: cerr <"couldn't read! Error "<ret <std: endl; ret_r = EXIT_FAILURE; image. close (); // close the rbd image io_ctx.close (); // close the I/O context rados. shutdown (); // disconnect the cluster connection return EXIT_FAILURE;} else {std: cout <"we just read data successfully, return value is" <ret_r <std :: endl;} std: cout <bl_aio1_to_str () <std: endl; write_completion-> release (); read_completion-> release (); void simple_write_cb (librbd :: completion_t cb, void * arg) {Std: cout <"write completion cb called! "<Std: endl;} // simple callback function for librbd: RBD: AioCompletionvoid simple_read_cb (librbd: completion_t cb, void * arg) {std :: cout <"read completion cb called! "<Std: endl ;}

    Finishing work

    At last, you must not forget to close the rbd image and I/O context and disconnect the cluster.

    Ret = image. close (); // close the rbd image if (ret <0) {std: cerr <"couldn't close rbd image! Err "<ret <std: endl; ret = EXIT_FAILURE; return EXIT_FAILURE;} else {std: cout <" we just closed an rbd image "<std:: endl;} io_ctx.close (); // close the I/O context rados. shutdown (); // disconnect the cluster and return EXIT_SUCCESS;

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.