| 1115 | } |
| 1116 | |
| 1117 | int copy(ImageCtx *src, IoCtx& dest_md_ctx, const char *destname, |
| 1118 | ImageOptions& opts, ProgressContext &prog_ctx, size_t sparse_size) |
| 1119 | { |
| 1120 | CephContext *cct = (CephContext *)dest_md_ctx.cct(); |
| 1121 | uint64_t option; |
| 1122 | if (opts.get(RBD_IMAGE_OPTION_FLATTEN, &option) == 0) { |
| 1123 | lderr(cct) << "copy does not support 'flatten' image option" << dendl; |
| 1124 | return -EINVAL; |
| 1125 | } |
| 1126 | if (opts.get(RBD_IMAGE_OPTION_CLONE_FORMAT, &option) == 0) { |
| 1127 | lderr(cct) << "copy does not support 'clone_format' image option" |
| 1128 | << dendl; |
| 1129 | return -EINVAL; |
| 1130 | } |
| 1131 | |
| 1132 | ldout(cct, 20) << "copy " << src->name |
| 1133 | << (src->snap_name.length() ? "@" + src->snap_name : "") |
| 1134 | << " -> " << destname << " opts = " << opts << dendl; |
| 1135 | |
| 1136 | src->image_lock.lock_shared(); |
| 1137 | uint64_t features = src->features; |
| 1138 | uint64_t src_size = src->get_image_size(src->snap_id); |
| 1139 | src->image_lock.unlock_shared(); |
| 1140 | uint64_t format = 2; |
| 1141 | if (opts.get(RBD_IMAGE_OPTION_FORMAT, &format) != 0) { |
| 1142 | opts.set(RBD_IMAGE_OPTION_FORMAT, format); |
| 1143 | } |
| 1144 | uint64_t stripe_unit = src->stripe_unit; |
| 1145 | if (opts.get(RBD_IMAGE_OPTION_STRIPE_UNIT, &stripe_unit) != 0) { |
| 1146 | opts.set(RBD_IMAGE_OPTION_STRIPE_UNIT, stripe_unit); |
| 1147 | } |
| 1148 | uint64_t stripe_count = src->stripe_count; |
| 1149 | if (opts.get(RBD_IMAGE_OPTION_STRIPE_COUNT, &stripe_count) != 0) { |
| 1150 | opts.set(RBD_IMAGE_OPTION_STRIPE_COUNT, stripe_count); |
| 1151 | } |
| 1152 | uint64_t order = src->order; |
| 1153 | if (opts.get(RBD_IMAGE_OPTION_ORDER, &order) != 0) { |
| 1154 | opts.set(RBD_IMAGE_OPTION_ORDER, order); |
| 1155 | } |
| 1156 | if (opts.get(RBD_IMAGE_OPTION_FEATURES, &features) != 0) { |
| 1157 | opts.set(RBD_IMAGE_OPTION_FEATURES, features); |
| 1158 | } |
| 1159 | if (features & ~RBD_FEATURES_ALL) { |
| 1160 | lderr(cct) << "librbd does not support requested features" << dendl; |
| 1161 | return -ENOSYS; |
| 1162 | } |
| 1163 | |
| 1164 | int r = create(dest_md_ctx, destname, "", src_size, opts, "", "", false); |
| 1165 | if (r < 0) { |
| 1166 | lderr(cct) << "header creation failed" << dendl; |
| 1167 | return r; |
| 1168 | } |
| 1169 | opts.set(RBD_IMAGE_OPTION_ORDER, static_cast<uint64_t>(order)); |
| 1170 | |
| 1171 | ImageCtx *dest = new librbd::ImageCtx(destname, "", nullptr, dest_md_ctx, |
| 1172 | false); |
| 1173 | r = dest->state->open(0); |
| 1174 | if (r < 0) { |
no test coverage detected