static int qemu_rbd_snap_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) { BDRVRBDState *s = bs->opaque; QEMUSnapshotInfo *sn_info, *sn_tab = NULL; int i, snap_count; rbd_snap_info_t *snaps; int max_snaps = RBD_MAX_SNAPS; do { snaps = g_new(rbd_snap_info_t, max_snaps); snap_count = rbd_snap_list(s->image, snaps, &max_snaps); if (snap_count <= 0) { g_free(snaps); } } while (snap_count == -ERANGE); if (snap_count <= 0) { goto done; } sn_tab = g_new0(QEMUSnapshotInfo, snap_count); for (i = 0; i < snap_count; i++) { const char *snap_name = snaps[i].name; sn_info = sn_tab + i; pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), snap_name); pstrcpy(sn_info->name, sizeof(sn_info->name), snap_name); sn_info->vm_state_size = snaps[i].size; sn_info->date_sec = 0; sn_info->date_nsec = 0; sn_info->vm_clock_nsec = 0; } rbd_snap_list_end(snaps); g_free(snaps); done: *psn_tab = sn_tab; return snap_count; }
void test_ls_snaps(rbd_image_t image, int num_expected, ...) { rbd_snap_info_t *snaps; int num_snaps, i, j, expected_size, max_size = 10; char *expected; va_list ap; snaps = (rbd_snap_info_t *) malloc(sizeof(rbd_snap_info_t *) * 10); num_snaps = rbd_snap_list(image, snaps, &max_size); printf("num snaps is: %d\nexpected: %d\n", num_snaps, num_expected); assert(num_snaps == num_expected); for (i = 0; i < num_snaps; i++) { printf("snap: %s\n", snaps[i].name); } va_start(ap, num_expected); for (i = num_expected; i > 0; i--) { expected = va_arg(ap, char *); expected_size = va_arg(ap, int); int found = 0; for (j = 0; j < num_snaps; j++) { if (snaps[j].name == NULL) continue; if (strcmp(snaps[j].name, expected) == 0) { printf("found %s with size %llu\n", snaps[j].name, (unsigned long long) snaps[j].size); assert((int)snaps[j].size == expected_size); free((void *) snaps[j].name); snaps[j].name = NULL; found = 1; break; } } assert(found); } for (i = 0; i < num_snaps; i++) { assert(snaps[i].name == NULL); } free(snaps); }