985
* Allocate a new file as a volume. This is either done directly
986
* for raw/sparse files, or by calling qemu-img/qcow-create for
987
* special kinds of files
986
* Set up a volume definition to be added to a pool's volume list, but
987
* don't do any file creation or allocation. By separating the two processes,
988
* we allow allocation progress reporting (by polling the volume's 'info'
989
* function), and can drop the parent pool lock during the (slow) allocation.
990
992
virStorageBackendFileSystemVolCreate(virConnectPtr conn,
991
993
virStoragePoolObjPtr pool,
992
994
virStorageVolDefPtr vol)
996
if (VIR_ALLOC_N(vol->target.path, strlen(pool->def->target.path) +
997
1 + strlen(vol->name) + 1) < 0) {
998
virReportOOMError(conn);
1001
997
vol->type = VIR_STORAGE_VOL_FILE;
1002
strcpy(vol->target.path, pool->def->target.path);
1003
strcat(vol->target.path, "/");
1004
strcat(vol->target.path, vol->name);
999
if (virAsprintf(&vol->target.path, "%s/%s",
1000
pool->def->target.path,
1002
virReportOOMError(conn);
1005
1006
vol->key = strdup(vol->target.path);
1006
1007
if (vol->key == NULL) {
1007
1008
virReportOOMError(conn);
1011
if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW) {
1012
if ((fd = open(vol->target.path, O_RDWR | O_CREAT | O_EXCL,
1013
vol->target.perms.mode)) < 0) {
1015
static int createRaw(virConnectPtr conn,
1016
virStorageVolDefPtr vol,
1017
virStorageVolDefPtr inputvol) {
1021
unsigned long long remain;
1024
if ((fd = open(vol->target.path, O_RDWR | O_CREAT | O_EXCL,
1025
vol->target.perms.mode)) < 0) {
1026
virReportSystemError(conn, errno,
1027
_("cannot create path '%s'"),
1033
if ((inputfd = open(inputvol->target.path, O_RDONLY)) < 0) {
1014
1034
virReportSystemError(conn, errno,
1015
_("cannot create path '%s'"),
1020
/* Pre-allocate any data if requested */
1021
/* XXX slooooooooooooooooow on non-extents-based file systems */
1022
/* FIXME: Add in progress bars & bg thread if progress bar requested */
1023
if (vol->allocation) {
1024
if (track_allocation_progress) {
1025
unsigned long long remain = vol->allocation;
1028
/* Allocate in chunks of 512MiB: big-enough chunk
1029
* size and takes approx. 9s on ext3. A progress
1030
* update every 9s is a fair-enough trade-off
1032
unsigned long long bytes = 512 * 1024 * 1024;
1037
if ((r = safezero(fd, 0, vol->allocation - remain,
1039
virReportSystemError(conn, r,
1040
_("cannot fill file '%s'"),
1035
_("could not open input path '%s'"),
1036
inputvol->target.path);
1041
/* Seek to the final size, so the capacity is available upfront
1042
* for progress reporting */
1043
if (ftruncate(fd, vol->capacity) < 0) {
1044
virReportSystemError(conn, errno,
1045
_("cannot extend file '%s'"),
1050
remain = vol->capacity;
1052
if (inputfd != -1) {
1054
size_t bytes = 1024 * 1024;
1057
bzero(&zerobuf, sizeof(zerobuf));
1059
if (VIR_ALLOC_N(buf, bytes) < 0) {
1060
virReportOOMError(conn);
1064
while (amtread != 0) {
1070
if ((amtread = saferead(inputfd, buf, bytes)) < 0) {
1071
virReportSystemError(conn, errno,
1072
_("failed reading from file '%s'"),
1073
inputvol->target.path);
1078
/* Loop over amt read in 512 byte increments, looking for sparse
1082
int interval = ((512 > amtleft) ? amtleft : 512);
1083
int offset = amtread - amtleft;
1085
if (memcmp(buf+offset, zerobuf, interval) == 0) {
1086
if (lseek(fd, interval, SEEK_CUR) < 0) {
1087
virReportSystemError(conn, errno,
1088
_("cannot extend file '%s'"),
1041
1089
vol->target.path);
1042
unlink(vol->target.path);
1092
} else if (safewrite(fd, buf+offset, interval) < 0) {
1093
virReportSystemError(conn, errno,
1094
_("failed writing to file '%s'"),
1048
} else { /* No progress bars to be shown */
1099
} while ((amtleft -= 512) > 0);
1103
/* Pre-allocate any data if requested */
1104
/* XXX slooooooooooooooooow on non-extents-based file systems */
1106
if (track_allocation_progress) {
1109
/* Allocate in chunks of 512MiB: big-enough chunk
1110
* size and takes approx. 9s on ext3. A progress
1111
* update every 9s is a fair-enough trade-off
1113
unsigned long long bytes = 512 * 1024 * 1024;
1051
if ((r = safezero(fd, 0, 0, vol->allocation)) != 0) {
1118
if ((r = safezero(fd, 0, vol->allocation - remain,
1052
1120
virReportSystemError(conn, r,
1053
1121
_("cannot fill file '%s'"),
1054
1122
vol->target.path);
1055
unlink(vol->target.path);
1062
/* Now seek to final size, possibly making the file sparse */
1063
if (ftruncate(fd, vol->capacity) < 0) {
1127
} else { /* No progress bars to be shown */
1130
if ((r = safezero(fd, 0, 0, remain)) != 0) {
1131
virReportSystemError(conn, r,
1132
_("cannot fill file '%s'"),
1139
if (close(fd) < 0) {
1140
virReportSystemError(conn, errno,
1141
_("cannot close file '%s'"),
1147
if (inputfd != -1 && close(inputfd) < 0) {
1148
virReportSystemError(conn, errno,
1149
_("cannot close file '%s'"),
1150
inputvol->target.path);
1166
static int createFileDir(virConnectPtr conn,
1167
virStorageVolDefPtr vol,
1168
virStorageVolDefPtr inputvol) {
1170
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1172
_("cannot copy from volume to a directory volume"));
1176
if (mkdir(vol->target.path, vol->target.perms.mode) < 0) {
1177
virReportSystemError(conn, errno,
1178
_("cannot create path '%s'"),
1187
static int createQemuImg(virConnectPtr conn,
1188
virStorageVolDefPtr vol,
1189
virStorageVolDefPtr inputvol) {
1192
const char *type = virStorageVolFormatFileSystemTypeToString(vol->target.format);
1193
const char *backingType = vol->backingStore.path ?
1194
virStorageVolFormatFileSystemTypeToString(vol->backingStore.format) : NULL;
1196
const char *inputBackingPath = (inputvol ? inputvol->backingStore.path
1198
const char *inputPath = inputvol ? inputvol->target.path : NULL;
1199
/* Treat input block devices as 'raw' format */
1200
const char *inputType = inputPath ?
1201
virStorageVolFormatFileSystemTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_VOL_FILE_RAW : inputvol->target.format) :
1204
const char **imgargv;
1205
const char *imgargvnormal[] = {
1212
/* XXX including "backingType" here too, once QEMU accepts
1213
* the patches to specify it. It'll probably be -F backingType */
1214
const char *imgargvbacking[] = {
1217
"-b", vol->backingStore.path,
1222
const char *convargv[] = {
1223
QEMU_IMG, "convert",
1233
} else if (vol->backingStore.path) {
1234
imgargv = imgargvbacking;
1236
imgargv = imgargvnormal;
1240
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1241
_("unknown storage vol type %d"),
1242
vol->target.format);
1245
if (inputvol && inputType == NULL) {
1246
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1247
_("unknown storage vol type %d"),
1248
inputvol->target.format);
1252
if (vol->backingStore.path) {
1254
/* XXX: Not strictly required: qemu-img has an option a different
1255
* backing store, not really sure what use it serves though, and it
1256
* may cause issues with lvm. Untested essentially.
1258
if (!inputBackingPath ||
1259
!STREQ(inputBackingPath, vol->backingStore.path)) {
1260
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1261
"%s", _("a different backing store can not "
1266
if (backingType == NULL) {
1267
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1268
_("unknown storage vol backing store type %d"),
1269
vol->backingStore.format);
1272
if (access(vol->backingStore.path, R_OK) != 0) {
1064
1273
virReportSystemError(conn, errno,
1065
_("cannot extend file '%s'"),
1067
unlink(vol->target.path);
1274
_("inaccessible backing store volume %s"),
1275
vol->backingStore.path);
1281
snprintf(size, sizeof(size), "%llu", vol->capacity/1024);
1283
if (virRun(conn, imgargv, NULL) < 0) {
1290
#elif HAVE_QCOW_CREATE
1292
* Xen removed the fully-functional qemu-img, and replaced it
1293
* with a partially functional qcow-create. Go figure ??!?
1295
static int createQemuCreate(virConnectPtr conn,
1296
virStorageVolDefPtr vol,
1297
virStorageVolDefPtr inputvol) {
1299
const char *imgargv[4];
1302
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1304
_("cannot copy from volume with qcow-create"));
1308
if (vol->target.format != VIR_STORAGE_VOL_FILE_QCOW2) {
1309
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1310
_("unsupported storage vol type %d"),
1311
vol->target.format);
1314
if (vol->backingStore.path != NULL) {
1315
virStorageReportError(conn, VIR_ERR_NO_SUPPORT,
1316
_("copy-on-write image not supported with "
1321
/* Size in MB - yes different units to qemu-img :-( */
1322
snprintf(size, sizeof(size), "%llu", vol->capacity/1024/1024);
1324
imgargv[0] = QCOW_CREATE;
1326
imgargv[2] = vol->target.path;
1329
if (virRun(conn, imgargv, NULL) < 0) {
1335
#endif /* HAVE_QEMU_IMG, elif HAVE_QCOW_CREATE */
1338
_virStorageBackendFileSystemVolBuild(virConnectPtr conn,
1339
virStorageVolDefPtr vol,
1340
virStorageVolDefPtr inputvol)
1343
createFile create_func;
1345
if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW &&
1347
(inputvol->type == VIR_STORAGE_VOL_BLOCK ||
1348
inputvol->target.format == VIR_STORAGE_VOL_FILE_RAW))) {
1349
/* Raw file creation
1350
* Raw -> Raw copying
1351
* Block dev -> Raw copying
1353
create_func = createRaw;
1071
1354
} else if (vol->target.format == VIR_STORAGE_VOL_FILE_DIR) {
1072
if (mkdir(vol->target.path, vol->target.perms.mode) < 0) {
1073
virReportSystemError(conn, errno,
1074
_("cannot create path '%s'"),
1079
if ((fd = open(vol->target.path, O_RDWR)) < 0) {
1080
virReportSystemError(conn, errno,
1081
_("cannot read path '%s'"),
1355
create_func = createFileDir;
1086
1357
#if HAVE_QEMU_IMG
1087
const char *type = virStorageVolFormatFileSystemTypeToString(vol->target.format);
1088
const char *backingType = vol->backingStore.path ?
1089
virStorageVolFormatFileSystemTypeToString(vol->backingStore.format) : NULL;
1091
const char **imgargv;
1092
const char *imgargvnormal[] = {
1093
QEMU_IMG, "create", "-f", type, vol->target.path, size, NULL,
1095
/* XXX including "backingType" here too, once QEMU accepts
1096
* the patches to specify it. It'll probably be -F backingType */
1097
const char *imgargvbacking[] = {
1098
QEMU_IMG, "create", "-f", type, "-b", vol->backingStore.path, vol->target.path, size, NULL,
1102
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1103
_("unknown storage vol type %d"),
1104
vol->target.format);
1107
if (vol->backingStore.path == NULL) {
1108
imgargv = imgargvnormal;
1110
if (backingType == NULL) {
1111
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1112
_("unknown storage vol backing store type %d"),
1113
vol->backingStore.format);
1116
if (access(vol->backingStore.path, R_OK) != 0) {
1117
virReportSystemError(conn, errno,
1118
_("inaccessible backing store volume %s"),
1119
vol->backingStore.path);
1123
imgargv = imgargvbacking;
1127
snprintf(size, sizeof(size), "%llu", vol->capacity/1024);
1129
if (virRun(conn, imgargv, NULL) < 0) {
1130
unlink(vol->target.path);
1134
if ((fd = open(vol->target.path, O_RDONLY)) < 0) {
1135
virReportSystemError(conn, errno,
1136
_("cannot read path '%s'"),
1138
unlink(vol->target.path);
1358
create_func = createQemuImg;
1141
1359
#elif HAVE_QCOW_CREATE
1143
* Xen removed the fully-functional qemu-img, and replaced it
1144
* with a partially functional qcow-create. Go figure ??!?
1147
const char *imgargv[4];
1149
if (vol->target.format != VIR_STORAGE_VOL_FILE_QCOW2) {
1150
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1151
_("unsupported storage vol type %d"),
1152
vol->target.format);
1155
if (vol->backingStore.path != NULL) {
1156
virStorageReportError(conn, VIR_ERR_NO_SUPPORT,
1157
_("copy-on-write image not supported with "
1162
/* Size in MB - yes different units to qemu-img :-( */
1163
snprintf(size, sizeof(size), "%llu", vol->capacity/1024/1024);
1165
imgargv[0] = QCOW_CREATE;
1167
imgargv[2] = vol->target.path;
1170
if (virRun(conn, imgargv, NULL) < 0) {
1171
unlink(vol->target.path);
1175
if ((fd = open(vol->target.path, O_RDONLY)) < 0) {
1176
virReportSystemError(conn, errno,
1177
_("cannot read path '%s'"),
1179
unlink(vol->target.path);
1360
create_func = createQemuCreate;
1183
1362
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
1184
1363
"%s", _("creation of non-raw images "