PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/libvirt-0.9.11/src/storage/storage_backend.c

#
C | 1666 lines | 1286 code | 229 blank | 151 comment | 314 complexity | 5cf4f19fb44de7537455a6b5b0bbf5ea MD5 | raw file
Possible License(s): LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * storage_backend.c: internal storage driver backend contract
  3. *
  4. * Copyright (C) 2007-2011 Red Hat, Inc.
  5. * Copyright (C) 2007-2008 Daniel P. Berrange
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * Author: Daniel P. Berrange <berrange@redhat.com>
  22. */
  23. #include <config.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #if HAVE_REGEX_H
  27. # include <regex.h>
  28. #endif
  29. #include <sys/types.h>
  30. #include <sys/wait.h>
  31. #include <unistd.h>
  32. #include <fcntl.h>
  33. #include <stdint.h>
  34. #include <sys/stat.h>
  35. #include <sys/param.h>
  36. #include <dirent.h>
  37. #include "dirname.h"
  38. #ifdef __linux__
  39. # include <sys/ioctl.h>
  40. # include <linux/fs.h>
  41. #endif
  42. #if HAVE_SELINUX
  43. # include <selinux/selinux.h>
  44. #endif
  45. #include "datatypes.h"
  46. #include "virterror_internal.h"
  47. #include "util.h"
  48. #include "memory.h"
  49. #include "internal.h"
  50. #include "secret_conf.h"
  51. #include "uuid.h"
  52. #include "storage_file.h"
  53. #include "storage_backend.h"
  54. #include "logging.h"
  55. #include "virfile.h"
  56. #include "command.h"
  57. #if WITH_STORAGE_LVM
  58. # include "storage_backend_logical.h"
  59. #endif
  60. #if WITH_STORAGE_ISCSI
  61. # include "storage_backend_iscsi.h"
  62. #endif
  63. #if WITH_STORAGE_SCSI
  64. # include "storage_backend_scsi.h"
  65. #endif
  66. #if WITH_STORAGE_MPATH
  67. # include "storage_backend_mpath.h"
  68. #endif
  69. #if WITH_STORAGE_DISK
  70. # include "storage_backend_disk.h"
  71. #endif
  72. #if WITH_STORAGE_DIR
  73. # include "storage_backend_fs.h"
  74. #endif
  75. #define VIR_FROM_THIS VIR_FROM_STORAGE
  76. static virStorageBackendPtr backends[] = {
  77. #if WITH_STORAGE_DIR
  78. &virStorageBackendDirectory,
  79. #endif
  80. #if WITH_STORAGE_FS
  81. &virStorageBackendFileSystem,
  82. &virStorageBackendNetFileSystem,
  83. #endif
  84. #if WITH_STORAGE_LVM
  85. &virStorageBackendLogical,
  86. #endif
  87. #if WITH_STORAGE_ISCSI
  88. &virStorageBackendISCSI,
  89. #endif
  90. #if WITH_STORAGE_SCSI
  91. &virStorageBackendSCSI,
  92. #endif
  93. #if WITH_STORAGE_MPATH
  94. &virStorageBackendMpath,
  95. #endif
  96. #if WITH_STORAGE_DISK
  97. &virStorageBackendDisk,
  98. #endif
  99. NULL
  100. };
  101. static int track_allocation_progress = 0;
  102. enum {
  103. TOOL_QEMU_IMG,
  104. TOOL_KVM_IMG,
  105. TOOL_QCOW_CREATE,
  106. };
  107. #define READ_BLOCK_SIZE_DEFAULT (1024 * 1024)
  108. #define WRITE_BLOCK_SIZE_DEFAULT (4 * 1024)
  109. static int ATTRIBUTE_NONNULL (2)
  110. virStorageBackendCopyToFD(virStorageVolDefPtr vol,
  111. virStorageVolDefPtr inputvol,
  112. int fd,
  113. unsigned long long *total,
  114. int is_dest_file)
  115. {
  116. int inputfd = -1;
  117. int amtread = -1;
  118. int ret = 0;
  119. size_t rbytes = READ_BLOCK_SIZE_DEFAULT;
  120. size_t wbytes = 0;
  121. int interval;
  122. char *zerobuf;
  123. char *buf = NULL;
  124. struct stat st;
  125. if ((inputfd = open(inputvol->target.path, O_RDONLY)) < 0) {
  126. ret = -errno;
  127. virReportSystemError(errno,
  128. _("could not open input path '%s'"),
  129. inputvol->target.path);
  130. goto cleanup;
  131. }
  132. #ifdef __linux__
  133. if (ioctl(fd, BLKBSZGET, &wbytes) < 0) {
  134. wbytes = 0;
  135. }
  136. #endif
  137. if ((wbytes == 0) && fstat(fd, &st) == 0)
  138. wbytes = st.st_blksize;
  139. if (wbytes < WRITE_BLOCK_SIZE_DEFAULT)
  140. wbytes = WRITE_BLOCK_SIZE_DEFAULT;
  141. if (VIR_ALLOC_N(zerobuf, wbytes) < 0) {
  142. ret = -errno;
  143. virReportOOMError();
  144. goto cleanup;
  145. }
  146. if (VIR_ALLOC_N(buf, rbytes) < 0) {
  147. ret = -errno;
  148. virReportOOMError();
  149. goto cleanup;
  150. }
  151. while (amtread != 0) {
  152. int amtleft;
  153. if (*total < rbytes)
  154. rbytes = *total;
  155. if ((amtread = saferead(inputfd, buf, rbytes)) < 0) {
  156. ret = -errno;
  157. virReportSystemError(errno,
  158. _("failed reading from file '%s'"),
  159. inputvol->target.path);
  160. goto cleanup;
  161. }
  162. *total -= amtread;
  163. /* Loop over amt read in 512 byte increments, looking for sparse
  164. * blocks */
  165. amtleft = amtread;
  166. do {
  167. interval = ((wbytes > amtleft) ? amtleft : wbytes);
  168. int offset = amtread - amtleft;
  169. if (is_dest_file && memcmp(buf+offset, zerobuf, interval) == 0) {
  170. if (lseek(fd, interval, SEEK_CUR) < 0) {
  171. ret = -errno;
  172. virReportSystemError(errno,
  173. _("cannot extend file '%s'"),
  174. vol->target.path);
  175. goto cleanup;
  176. }
  177. } else if (safewrite(fd, buf+offset, interval) < 0) {
  178. ret = -errno;
  179. virReportSystemError(errno,
  180. _("failed writing to file '%s'"),
  181. vol->target.path);
  182. goto cleanup;
  183. }
  184. } while ((amtleft -= interval) > 0);
  185. }
  186. if (fdatasync(fd) < 0) {
  187. ret = -errno;
  188. virReportSystemError(errno, _("cannot sync data to file '%s'"),
  189. vol->target.path);
  190. goto cleanup;
  191. }
  192. if (VIR_CLOSE(inputfd) < 0) {
  193. ret = -errno;
  194. virReportSystemError(errno,
  195. _("cannot close file '%s'"),
  196. inputvol->target.path);
  197. goto cleanup;
  198. }
  199. inputfd = -1;
  200. cleanup:
  201. VIR_FORCE_CLOSE(inputfd);
  202. VIR_FREE(zerobuf);
  203. VIR_FREE(buf);
  204. return ret;
  205. }
  206. static int
  207. virStorageBackendCreateBlockFrom(virConnectPtr conn ATTRIBUTE_UNUSED,
  208. virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
  209. virStorageVolDefPtr vol,
  210. virStorageVolDefPtr inputvol,
  211. unsigned int flags)
  212. {
  213. int fd = -1;
  214. int ret = -1;
  215. unsigned long long remain;
  216. struct stat st;
  217. gid_t gid;
  218. uid_t uid;
  219. virCheckFlags(0, -1);
  220. if ((fd = open(vol->target.path, O_RDWR)) < 0) {
  221. virReportSystemError(errno,
  222. _("cannot create path '%s'"),
  223. vol->target.path);
  224. goto cleanup;
  225. }
  226. remain = vol->allocation;
  227. if (inputvol) {
  228. int res = virStorageBackendCopyToFD(vol, inputvol,
  229. fd, &remain, 0);
  230. if (res < 0)
  231. goto cleanup;
  232. }
  233. if (fstat(fd, &st) == -1) {
  234. virReportSystemError(errno, _("stat of '%s' failed"),
  235. vol->target.path);
  236. goto cleanup;
  237. }
  238. uid = (vol->target.perms.uid != st.st_uid) ? vol->target.perms.uid : -1;
  239. gid = (vol->target.perms.gid != st.st_gid) ? vol->target.perms.gid : -1;
  240. if (((uid != -1) || (gid != -1))
  241. && (fchown(fd, uid, gid) < 0)) {
  242. virReportSystemError(errno,
  243. _("cannot chown '%s' to (%u, %u)"),
  244. vol->target.path, uid, gid);
  245. goto cleanup;
  246. }
  247. if (fchmod(fd, vol->target.perms.mode) < 0) {
  248. virReportSystemError(errno,
  249. _("cannot set mode of '%s' to %04o"),
  250. vol->target.path, vol->target.perms.mode);
  251. goto cleanup;
  252. }
  253. if (VIR_CLOSE(fd) < 0) {
  254. virReportSystemError(errno,
  255. _("cannot close file '%s'"),
  256. vol->target.path);
  257. goto cleanup;
  258. }
  259. fd = -1;
  260. ret = 0;
  261. cleanup:
  262. VIR_FORCE_CLOSE(fd);
  263. return ret;
  264. }
  265. static int
  266. createRawFile(int fd, virStorageVolDefPtr vol,
  267. virStorageVolDefPtr inputvol)
  268. {
  269. int ret = 0;
  270. unsigned long long remain;
  271. /* Seek to the final size, so the capacity is available upfront
  272. * for progress reporting */
  273. if (ftruncate(fd, vol->capacity) < 0) {
  274. ret = -errno;
  275. virReportSystemError(errno,
  276. _("cannot extend file '%s'"),
  277. vol->target.path);
  278. goto cleanup;
  279. }
  280. remain = vol->allocation;
  281. if (inputvol) {
  282. ret = virStorageBackendCopyToFD(vol, inputvol, fd, &remain, 1);
  283. if (ret < 0) {
  284. goto cleanup;
  285. }
  286. }
  287. if (remain) {
  288. if (track_allocation_progress) {
  289. while (remain) {
  290. /* Allocate in chunks of 512MiB: big-enough chunk
  291. * size and takes approx. 9s on ext3. A progress
  292. * update every 9s is a fair-enough trade-off
  293. */
  294. unsigned long long bytes = 512 * 1024 * 1024;
  295. if (bytes > remain)
  296. bytes = remain;
  297. if (safezero(fd, vol->allocation - remain, bytes) < 0) {
  298. ret = -errno;
  299. virReportSystemError(errno, _("cannot fill file '%s'"),
  300. vol->target.path);
  301. goto cleanup;
  302. }
  303. remain -= bytes;
  304. }
  305. } else { /* No progress bars to be shown */
  306. if (safezero(fd, 0, remain) < 0) {
  307. ret = -errno;
  308. virReportSystemError(errno, _("cannot fill file '%s'"),
  309. vol->target.path);
  310. goto cleanup;
  311. }
  312. }
  313. }
  314. if (fsync(fd) < 0) {
  315. ret = -errno;
  316. virReportSystemError(errno, _("cannot sync data to file '%s'"),
  317. vol->target.path);
  318. goto cleanup;
  319. }
  320. cleanup:
  321. return ret;
  322. }
  323. int
  324. virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
  325. virStoragePoolObjPtr pool,
  326. virStorageVolDefPtr vol,
  327. virStorageVolDefPtr inputvol,
  328. unsigned int flags)
  329. {
  330. int ret = -1;
  331. int fd = -1;
  332. int operation_flags;
  333. virCheckFlags(0, -1);
  334. if (vol->target.encryption != NULL) {
  335. virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
  336. "%s", _("storage pool does not support encrypted "
  337. "volumes"));
  338. goto cleanup;
  339. }
  340. operation_flags = VIR_FILE_OPEN_FORCE_MODE | VIR_FILE_OPEN_FORCE_OWNER;
  341. if (pool->def->type == VIR_STORAGE_POOL_NETFS)
  342. operation_flags |= VIR_FILE_OPEN_FORK;
  343. if ((fd = virFileOpenAs(vol->target.path,
  344. O_RDWR | O_CREAT | O_EXCL,
  345. vol->target.perms.mode,
  346. vol->target.perms.uid,
  347. vol->target.perms.gid,
  348. operation_flags)) < 0) {
  349. virReportSystemError(-fd,
  350. _("cannot create path '%s'"),
  351. vol->target.path);
  352. goto cleanup;
  353. }
  354. if ((ret = createRawFile(fd, vol, inputvol)) < 0)
  355. /* createRawFile already reported the exact error. */
  356. ret = -1;
  357. cleanup:
  358. VIR_FORCE_CLOSE(fd);
  359. return ret;
  360. }
  361. static int
  362. virStorageGenerateSecretUUID(virConnectPtr conn,
  363. unsigned char *uuid)
  364. {
  365. unsigned attempt;
  366. for (attempt = 0; attempt < 65536; attempt++) {
  367. virSecretPtr tmp;
  368. if (virUUIDGenerate(uuid) < 0) {
  369. virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
  370. _("unable to generate uuid"));
  371. return -1;
  372. }
  373. tmp = conn->secretDriver->lookupByUUID(conn, uuid);
  374. if (tmp == NULL)
  375. return 0;
  376. virSecretFree(tmp);
  377. }
  378. virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
  379. _("too many conflicts when generating an uuid"));
  380. return -1;
  381. }
  382. static int
  383. virStorageGenerateQcowEncryption(virConnectPtr conn,
  384. virStorageVolDefPtr vol)
  385. {
  386. virSecretDefPtr def = NULL;
  387. virBuffer buf = VIR_BUFFER_INITIALIZER;
  388. virStorageEncryptionPtr enc;
  389. virStorageEncryptionSecretPtr enc_secret = NULL;
  390. virSecretPtr secret = NULL;
  391. char *xml;
  392. unsigned char value[VIR_STORAGE_QCOW_PASSPHRASE_SIZE];
  393. int ret = -1;
  394. if (conn->secretDriver == NULL ||
  395. conn->secretDriver->lookupByUUID == NULL ||
  396. conn->secretDriver->defineXML == NULL ||
  397. conn->secretDriver->setValue == NULL) {
  398. virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
  399. _("secret storage not supported"));
  400. goto cleanup;
  401. }
  402. enc = vol->target.encryption;
  403. if (enc->nsecrets != 0) {
  404. virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
  405. _("secrets already defined"));
  406. goto cleanup;
  407. }
  408. if (VIR_ALLOC(enc_secret) < 0 || VIR_REALLOC_N(enc->secrets, 1) < 0 ||
  409. VIR_ALLOC(def) < 0) {
  410. virReportOOMError();
  411. goto cleanup;
  412. }
  413. def->ephemeral = 0;
  414. def->private = 0;
  415. if (virStorageGenerateSecretUUID(conn, def->uuid) < 0)
  416. goto cleanup;
  417. def->usage_type = VIR_SECRET_USAGE_TYPE_VOLUME;
  418. def->usage.volume = strdup(vol->target.path);
  419. if (def->usage.volume == NULL) {
  420. virReportOOMError();
  421. goto cleanup;
  422. }
  423. xml = virSecretDefFormat(def);
  424. virSecretDefFree(def);
  425. def = NULL;
  426. if (xml == NULL)
  427. goto cleanup;
  428. secret = conn->secretDriver->defineXML(conn, xml, 0);
  429. if (secret == NULL) {
  430. VIR_FREE(xml);
  431. goto cleanup;
  432. }
  433. VIR_FREE(xml);
  434. if (virStorageGenerateQcowPassphrase(value) < 0)
  435. goto cleanup;
  436. if (conn->secretDriver->setValue(secret, value, sizeof(value), 0) < 0)
  437. goto cleanup;
  438. enc_secret->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE;
  439. memcpy(enc_secret->uuid, secret->uuid, VIR_UUID_BUFLEN);
  440. enc->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
  441. enc->secrets[0] = enc_secret; /* Space for secrets[0] allocated above */
  442. enc_secret = NULL;
  443. enc->nsecrets = 1;
  444. ret = 0;
  445. cleanup:
  446. if (secret != NULL) {
  447. if (ret != 0 &&
  448. conn->secretDriver->undefine != NULL)
  449. conn->secretDriver->undefine(secret);
  450. virSecretFree(secret);
  451. }
  452. virBufferFreeAndReset(&buf);
  453. virSecretDefFree(def);
  454. VIR_FREE(enc_secret);
  455. return ret;
  456. }
  457. struct hookdata {
  458. virStorageVolDefPtr vol;
  459. bool skip;
  460. };
  461. static int virStorageBuildSetUIDHook(void *data) {
  462. struct hookdata *tmp = data;
  463. virStorageVolDefPtr vol = tmp->vol;
  464. if (tmp->skip)
  465. return 0;
  466. if (virSetUIDGID(vol->target.perms.uid, vol->target.perms.gid) < 0)
  467. return -1;
  468. return 0;
  469. }
  470. static int virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
  471. virStorageVolDefPtr vol,
  472. virCommandPtr cmd) {
  473. struct stat st;
  474. gid_t gid;
  475. uid_t uid;
  476. int filecreated = 0;
  477. struct hookdata data = {vol, false};
  478. if ((pool->def->type == VIR_STORAGE_POOL_NETFS)
  479. && (((getuid() == 0)
  480. && (vol->target.perms.uid != -1)
  481. && (vol->target.perms.uid != 0))
  482. || ((vol->target.perms.gid != -1)
  483. && (vol->target.perms.gid != getgid())))) {
  484. virCommandSetPreExecHook(cmd, virStorageBuildSetUIDHook, &data);
  485. if (virCommandRun(cmd, NULL) == 0) {
  486. /* command was successfully run, check if the file was created */
  487. if (stat(vol->target.path, &st) >=0)
  488. filecreated = 1;
  489. }
  490. }
  491. data.skip = true;
  492. if (!filecreated) {
  493. if (virCommandRun(cmd, NULL) < 0) {
  494. return -1;
  495. }
  496. if (stat(vol->target.path, &st) < 0) {
  497. virReportSystemError(errno,
  498. _("failed to create %s"), vol->target.path);
  499. return -1;
  500. }
  501. }
  502. uid = (vol->target.perms.uid != st.st_uid) ? vol->target.perms.uid : -1;
  503. gid = (vol->target.perms.gid != st.st_gid) ? vol->target.perms.gid : -1;
  504. if (((uid != -1) || (gid != -1))
  505. && (chown(vol->target.path, uid, gid) < 0)) {
  506. virReportSystemError(errno,
  507. _("cannot chown %s to (%u, %u)"),
  508. vol->target.path, uid, gid);
  509. return -1;
  510. }
  511. if (chmod(vol->target.path, vol->target.perms.mode) < 0) {
  512. virReportSystemError(errno,
  513. _("cannot set mode of '%s' to %04o"),
  514. vol->target.path, vol->target.perms.mode);
  515. return -1;
  516. }
  517. return 0;
  518. }
  519. enum {
  520. QEMU_IMG_BACKING_FORMAT_NONE = 0,
  521. QEMU_IMG_BACKING_FORMAT_FLAG,
  522. QEMU_IMG_BACKING_FORMAT_OPTIONS,
  523. };
  524. static int virStorageBackendQEMUImgBackingFormat(const char *qemuimg)
  525. {
  526. char *help = NULL;
  527. char *start;
  528. char *end;
  529. char *tmp;
  530. int ret = -1;
  531. int exitstatus;
  532. virCommandPtr cmd = virCommandNewArgList(qemuimg, "-h", NULL);
  533. virCommandAddEnvString(cmd, "LC_ALL=C");
  534. virCommandSetOutputBuffer(cmd, &help);
  535. virCommandClearCaps(cmd);
  536. /* qemuimg doesn't return zero exit status on -h,
  537. * therefore we need to provide pointer for storing
  538. * exit status, although we don't parse it any later */
  539. if (virCommandRun(cmd, &exitstatus) < 0)
  540. goto cleanup;
  541. if ((start = strstr(help, " create ")) == NULL ||
  542. (end = strstr(start, "\n")) == NULL) {
  543. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  544. _("unable to parse qemu-img output '%s'"),
  545. help);
  546. goto cleanup;
  547. }
  548. if (((tmp = strstr(start, "-F fmt")) && tmp < end) ||
  549. ((tmp = strstr(start, "-F backing_fmt")) && tmp < end))
  550. ret = QEMU_IMG_BACKING_FORMAT_FLAG;
  551. else if ((tmp = strstr(start, "[-o options]")) && tmp < end)
  552. ret = QEMU_IMG_BACKING_FORMAT_OPTIONS;
  553. else
  554. ret = QEMU_IMG_BACKING_FORMAT_NONE;
  555. cleanup:
  556. virCommandFree(cmd);
  557. VIR_FREE(help);
  558. return ret;
  559. }
  560. static int
  561. virStorageBackendCreateQemuImg(virConnectPtr conn,
  562. virStoragePoolObjPtr pool,
  563. virStorageVolDefPtr vol,
  564. virStorageVolDefPtr inputvol,
  565. unsigned int flags)
  566. {
  567. int ret = -1;
  568. char *create_tool;
  569. int imgformat = -1;
  570. virCommandPtr cmd = NULL;
  571. bool do_encryption = (vol->target.encryption != NULL);
  572. unsigned long long int size_arg;
  573. virCheckFlags(0, -1);
  574. const char *type = virStorageFileFormatTypeToString(vol->target.format);
  575. const char *backingType = vol->backingStore.path ?
  576. virStorageFileFormatTypeToString(vol->backingStore.format) : NULL;
  577. const char *inputBackingPath = (inputvol ? inputvol->backingStore.path
  578. : NULL);
  579. const char *inputPath = inputvol ? inputvol->target.path : NULL;
  580. /* Treat input block devices as 'raw' format */
  581. const char *inputType = inputPath ?
  582. virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ?
  583. VIR_STORAGE_FILE_RAW :
  584. inputvol->target.format) :
  585. NULL;
  586. if (type == NULL) {
  587. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  588. _("unknown storage vol type %d"),
  589. vol->target.format);
  590. return -1;
  591. }
  592. if (inputvol && inputType == NULL) {
  593. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  594. _("unknown storage vol type %d"),
  595. inputvol->target.format);
  596. return -1;
  597. }
  598. if (vol->backingStore.path) {
  599. int accessRetCode = -1;
  600. char *absolutePath = NULL;
  601. /* XXX: Not strictly required: qemu-img has an option a different
  602. * backing store, not really sure what use it serves though, and it
  603. * may cause issues with lvm. Untested essentially.
  604. */
  605. if (inputvol &&
  606. (!inputBackingPath ||
  607. STRNEQ(inputBackingPath, vol->backingStore.path))) {
  608. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  609. "%s", _("a different backing store cannot "
  610. "be specified."));
  611. return -1;
  612. }
  613. if (backingType == NULL) {
  614. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  615. _("unknown storage vol backing store type %d"),
  616. vol->backingStore.format);
  617. return -1;
  618. }
  619. /* Convert relative backing store paths to absolute paths for access
  620. * validation.
  621. */
  622. if ('/' != *(vol->backingStore.path) &&
  623. virAsprintf(&absolutePath, "%s/%s", pool->def->target.path,
  624. vol->backingStore.path) < 0) {
  625. virReportOOMError();
  626. return -1;
  627. }
  628. accessRetCode = access(absolutePath ? absolutePath
  629. : vol->backingStore.path, R_OK);
  630. VIR_FREE(absolutePath);
  631. if (accessRetCode != 0) {
  632. virReportSystemError(errno,
  633. _("inaccessible backing store volume %s"),
  634. vol->backingStore.path);
  635. return -1;
  636. }
  637. }
  638. if (do_encryption) {
  639. virStorageEncryptionPtr enc;
  640. if (vol->target.format != VIR_STORAGE_FILE_QCOW &&
  641. vol->target.format != VIR_STORAGE_FILE_QCOW2) {
  642. virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
  643. _("qcow volume encryption unsupported with "
  644. "volume format %s"), type);
  645. return -1;
  646. }
  647. enc = vol->target.encryption;
  648. if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW &&
  649. enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT) {
  650. virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
  651. _("unsupported volume encryption format %d"),
  652. vol->target.encryption->format);
  653. return -1;
  654. }
  655. if (enc->nsecrets > 1) {
  656. virStorageReportError(VIR_ERR_XML_ERROR, "%s",
  657. _("too many secrets for qcow encryption"));
  658. return -1;
  659. }
  660. if (enc->format == VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT ||
  661. enc->nsecrets == 0) {
  662. if (virStorageGenerateQcowEncryption(conn, vol) < 0)
  663. return -1;
  664. }
  665. }
  666. /* Size in KB */
  667. size_arg = VIR_DIV_UP(vol->capacity, 1024);
  668. /* KVM is usually ahead of qemu on features, so try that first */
  669. create_tool = virFindFileInPath("kvm-img");
  670. if (!create_tool)
  671. create_tool = virFindFileInPath("qemu-img");
  672. if (!create_tool) {
  673. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  674. "%s", _("unable to find kvm-img or qemu-img"));
  675. return -1;
  676. }
  677. imgformat = virStorageBackendQEMUImgBackingFormat(create_tool);
  678. if (imgformat < 0)
  679. goto cleanup;
  680. cmd = virCommandNew(create_tool);
  681. if (inputvol) {
  682. virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type,
  683. inputPath, vol->target.path, NULL);
  684. if (do_encryption) {
  685. if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) {
  686. virCommandAddArgList(cmd, "-o", "encryption=on", NULL);
  687. } else {
  688. virCommandAddArg(cmd, "-e");
  689. }
  690. }
  691. } else if (vol->backingStore.path) {
  692. virCommandAddArgList(cmd, "create", "-f", type,
  693. "-b", vol->backingStore.path, NULL);
  694. switch (imgformat) {
  695. case QEMU_IMG_BACKING_FORMAT_FLAG:
  696. virCommandAddArgList(cmd, "-F", backingType, vol->target.path,
  697. NULL);
  698. virCommandAddArgFormat(cmd, "%lluK", size_arg);
  699. if (do_encryption)
  700. virCommandAddArg(cmd, "-e");
  701. break;
  702. case QEMU_IMG_BACKING_FORMAT_OPTIONS:
  703. virCommandAddArg(cmd, "-o");
  704. virCommandAddArgFormat(cmd, "backing_fmt=%s%s", backingType,
  705. do_encryption ? ",encryption=on" : "");
  706. virCommandAddArg(cmd, vol->target.path);
  707. virCommandAddArgFormat(cmd, "%lluK", size_arg);
  708. break;
  709. default:
  710. VIR_INFO("Unable to set backing store format for %s with %s",
  711. vol->target.path, create_tool);
  712. virCommandAddArg(cmd, vol->target.path);
  713. virCommandAddArgFormat(cmd, "%lluK", size_arg);
  714. if (do_encryption)
  715. virCommandAddArg(cmd, "-e");
  716. }
  717. } else {
  718. virCommandAddArgList(cmd, "create", "-f", type,
  719. vol->target.path, NULL);
  720. virCommandAddArgFormat(cmd, "%lluK", size_arg);
  721. if (do_encryption) {
  722. if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) {
  723. virCommandAddArgList(cmd, "-o", "encryption=on", NULL);
  724. } else {
  725. virCommandAddArg(cmd, "-e");
  726. }
  727. }
  728. }
  729. ret = virStorageBackendCreateExecCommand(pool, vol, cmd);
  730. cleanup:
  731. VIR_FREE(create_tool);
  732. virCommandFree(cmd);
  733. return ret;
  734. }
  735. /*
  736. * Xen removed the fully-functional qemu-img, and replaced it
  737. * with a partially functional qcow-create. Go figure ??!?
  738. */
  739. static int
  740. virStorageBackendCreateQcowCreate(virConnectPtr conn ATTRIBUTE_UNUSED,
  741. virStoragePoolObjPtr pool,
  742. virStorageVolDefPtr vol,
  743. virStorageVolDefPtr inputvol,
  744. unsigned int flags)
  745. {
  746. int ret;
  747. char *size;
  748. virCommandPtr cmd;
  749. virCheckFlags(0, -1);
  750. if (inputvol) {
  751. virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
  752. _("cannot copy from volume with qcow-create"));
  753. return -1;
  754. }
  755. if (vol->target.format != VIR_STORAGE_FILE_QCOW2) {
  756. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  757. _("unsupported storage vol type %d"),
  758. vol->target.format);
  759. return -1;
  760. }
  761. if (vol->backingStore.path != NULL) {
  762. virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
  763. _("copy-on-write image not supported with "
  764. "qcow-create"));
  765. return -1;
  766. }
  767. if (vol->target.encryption != NULL) {
  768. virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
  769. "%s", _("encrypted volumes not supported with "
  770. "qcow-create"));
  771. return -1;
  772. }
  773. /* Size in MB - yes different units to qemu-img :-( */
  774. if (virAsprintf(&size, "%llu",
  775. VIR_DIV_UP(vol->capacity, (1024 * 1024))) < 0) {
  776. virReportOOMError();
  777. return -1;
  778. }
  779. cmd = virCommandNewArgList("qcow-create", size, vol->target.path, NULL);
  780. ret = virStorageBackendCreateExecCommand(pool, vol, cmd);
  781. virCommandFree(cmd);
  782. VIR_FREE(size);
  783. return ret;
  784. }
  785. virStorageBackendBuildVolFrom
  786. virStorageBackendFSImageToolTypeToFunc(int tool_type)
  787. {
  788. switch (tool_type) {
  789. case TOOL_KVM_IMG:
  790. case TOOL_QEMU_IMG:
  791. return virStorageBackendCreateQemuImg;
  792. case TOOL_QCOW_CREATE:
  793. return virStorageBackendCreateQcowCreate;
  794. default:
  795. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  796. _("Unknown file create tool type '%d'."),
  797. tool_type);
  798. }
  799. return NULL;
  800. }
  801. int
  802. virStorageBackendFindFSImageTool(char **tool)
  803. {
  804. int tool_type = -1;
  805. char *tmp = NULL;
  806. if ((tmp = virFindFileInPath("kvm-img")) != NULL) {
  807. tool_type = TOOL_KVM_IMG;
  808. } else if ((tmp = virFindFileInPath("qemu-img")) != NULL) {
  809. tool_type = TOOL_QEMU_IMG;
  810. } else if ((tmp = virFindFileInPath("qcow-create")) != NULL) {
  811. tool_type = TOOL_QCOW_CREATE;
  812. }
  813. if (tool)
  814. *tool = tmp;
  815. else
  816. VIR_FREE(tmp);
  817. return tool_type;
  818. }
  819. virStorageBackendBuildVolFrom
  820. virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol,
  821. virStorageVolDefPtr inputvol)
  822. {
  823. int tool_type;
  824. if (!inputvol)
  825. return NULL;
  826. /* If either volume is a non-raw file vol, we need to use an external
  827. * tool for converting
  828. */
  829. if ((vol->type == VIR_STORAGE_VOL_FILE &&
  830. vol->target.format != VIR_STORAGE_FILE_RAW) ||
  831. (inputvol->type == VIR_STORAGE_VOL_FILE &&
  832. inputvol->target.format != VIR_STORAGE_FILE_RAW)) {
  833. if ((tool_type = virStorageBackendFindFSImageTool(NULL)) < 0) {
  834. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  835. "%s", _("creation of non-raw file images is "
  836. "not supported without qemu-img."));
  837. return NULL;
  838. }
  839. return virStorageBackendFSImageToolTypeToFunc(tool_type);
  840. }
  841. if (vol->type == VIR_STORAGE_VOL_BLOCK)
  842. return virStorageBackendCreateBlockFrom;
  843. else
  844. return virStorageBackendCreateRaw;
  845. }
  846. virStorageBackendPtr
  847. virStorageBackendForType(int type) {
  848. unsigned int i;
  849. for (i = 0; backends[i]; i++)
  850. if (backends[i]->type == type)
  851. return backends[i];
  852. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  853. _("missing backend for pool type %d"), type);
  854. return NULL;
  855. }
  856. /*
  857. * Allows caller to silently ignore files with improper mode
  858. *
  859. * Returns -1 on error, -2 if file mode is unexpected or the
  860. * volume is a dangling symbolic link.
  861. */
  862. int
  863. virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags)
  864. {
  865. int fd, mode = 0;
  866. struct stat sb;
  867. char *base = last_component(path);
  868. if (lstat(path, &sb) < 0) {
  869. virReportSystemError(errno,
  870. _("cannot stat file '%s'"),
  871. path);
  872. return -1;
  873. }
  874. if (S_ISFIFO(sb.st_mode)) {
  875. VIR_WARN("ignoring FIFO '%s'", path);
  876. return -2;
  877. } else if (S_ISSOCK(sb.st_mode)) {
  878. VIR_WARN("ignoring socket '%s'", path);
  879. return -2;
  880. }
  881. if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) {
  882. if ((errno == ENOENT || errno == ELOOP) &&
  883. S_ISLNK(sb.st_mode)) {
  884. VIR_WARN("ignoring dangling symlink '%s'", path);
  885. return -2;
  886. }
  887. virReportSystemError(errno,
  888. _("cannot open volume '%s'"),
  889. path);
  890. return -1;
  891. }
  892. if (fstat(fd, &sb) < 0) {
  893. virReportSystemError(errno,
  894. _("cannot stat file '%s'"),
  895. path);
  896. VIR_FORCE_CLOSE(fd);
  897. return -1;
  898. }
  899. if (S_ISREG(sb.st_mode))
  900. mode = VIR_STORAGE_VOL_OPEN_REG;
  901. else if (S_ISCHR(sb.st_mode))
  902. mode = VIR_STORAGE_VOL_OPEN_CHAR;
  903. else if (S_ISBLK(sb.st_mode))
  904. mode = VIR_STORAGE_VOL_OPEN_BLOCK;
  905. else if (S_ISDIR(sb.st_mode)) {
  906. mode = VIR_STORAGE_VOL_OPEN_DIR;
  907. if (STREQ(base, ".") ||
  908. STREQ(base, "..")) {
  909. VIR_FORCE_CLOSE(fd);
  910. VIR_INFO("Skipping special dir '%s'", base);
  911. return -2;
  912. }
  913. }
  914. if (!(mode & flags)) {
  915. VIR_FORCE_CLOSE(fd);
  916. VIR_INFO("Skipping volume '%s'", path);
  917. if (mode & VIR_STORAGE_VOL_OPEN_ERROR) {
  918. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  919. _("unexpected storage mode for '%s'"), path);
  920. return -1;
  921. }
  922. return -2;
  923. }
  924. return fd;
  925. }
  926. int virStorageBackendVolOpen(const char *path)
  927. {
  928. return virStorageBackendVolOpenCheckMode(path,
  929. VIR_STORAGE_VOL_OPEN_DEFAULT);
  930. }
  931. int
  932. virStorageBackendUpdateVolTargetInfo(virStorageVolTargetPtr target,
  933. unsigned long long *allocation,
  934. unsigned long long *capacity,
  935. unsigned int openflags)
  936. {
  937. int ret, fd;
  938. if ((ret = virStorageBackendVolOpenCheckMode(target->path,
  939. openflags)) < 0)
  940. return ret;
  941. fd = ret;
  942. ret = virStorageBackendUpdateVolTargetInfoFD(target,
  943. fd,
  944. allocation,
  945. capacity);
  946. VIR_FORCE_CLOSE(fd);
  947. return ret;
  948. }
  949. int
  950. virStorageBackendUpdateVolInfoFlags(virStorageVolDefPtr vol,
  951. int withCapacity,
  952. unsigned int openflags)
  953. {
  954. int ret;
  955. if ((ret = virStorageBackendUpdateVolTargetInfo(&vol->target,
  956. &vol->allocation,
  957. withCapacity ? &vol->capacity : NULL,
  958. openflags)) < 0)
  959. return ret;
  960. if (vol->backingStore.path &&
  961. (ret = virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
  962. NULL, NULL,
  963. VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
  964. return ret;
  965. return 0;
  966. }
  967. int virStorageBackendUpdateVolInfo(virStorageVolDefPtr vol,
  968. int withCapacity)
  969. {
  970. return virStorageBackendUpdateVolInfoFlags(vol, withCapacity,
  971. VIR_STORAGE_VOL_OPEN_DEFAULT);
  972. }
  973. /*
  974. * virStorageBackendUpdateVolTargetInfoFD:
  975. * @conn: connection to report errors on
  976. * @target: target definition ptr of volume to update
  977. * @fd: fd of storage volume to update, via virStorageBackendOpenVol*
  978. * @allocation: If not NULL, updated allocation information will be stored
  979. * @capacity: If not NULL, updated capacity info will be stored
  980. *
  981. * Returns 0 for success, -1 on a legitimate error condition.
  982. */
  983. int
  984. virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target,
  985. int fd,
  986. unsigned long long *allocation,
  987. unsigned long long *capacity)
  988. {
  989. struct stat sb;
  990. #if HAVE_SELINUX
  991. security_context_t filecon = NULL;
  992. #endif
  993. if (fstat(fd, &sb) < 0) {
  994. virReportSystemError(errno,
  995. _("cannot stat file '%s'"),
  996. target->path);
  997. return -1;
  998. }
  999. if (allocation) {
  1000. if (S_ISREG(sb.st_mode)) {
  1001. #ifndef WIN32
  1002. *allocation = (unsigned long long)sb.st_blocks *
  1003. (unsigned long long)DEV_BSIZE;
  1004. #else
  1005. *allocation = sb.st_size;
  1006. #endif
  1007. /* Regular files may be sparse, so logical size (capacity) is not same
  1008. * as actual allocation above
  1009. */
  1010. if (capacity)
  1011. *capacity = sb.st_size;
  1012. } else if (S_ISDIR(sb.st_mode)) {
  1013. *allocation = 0;
  1014. if (capacity)
  1015. *capacity = 0;
  1016. } else {
  1017. off_t end;
  1018. /* XXX this is POSIX compliant, but doesn't work for CHAR files,
  1019. * only BLOCK. There is a Linux specific ioctl() for getting
  1020. * size of both CHAR / BLOCK devices we should check for in
  1021. * configure
  1022. */
  1023. end = lseek(fd, 0, SEEK_END);
  1024. if (end == (off_t)-1) {
  1025. virReportSystemError(errno,
  1026. _("cannot seek to end of file '%s'"),
  1027. target->path);
  1028. return -1;
  1029. }
  1030. *allocation = end;
  1031. if (capacity)
  1032. *capacity = end;
  1033. }
  1034. }
  1035. target->perms.mode = sb.st_mode & S_IRWXUGO;
  1036. target->perms.uid = sb.st_uid;
  1037. target->perms.gid = sb.st_gid;
  1038. VIR_FREE(target->perms.label);
  1039. #if HAVE_SELINUX
  1040. /* XXX: make this a security driver call */
  1041. if (fgetfilecon(fd, &filecon) == -1) {
  1042. if (errno != ENODATA && errno != ENOTSUP) {
  1043. virReportSystemError(errno,
  1044. _("cannot get file context of '%s'"),
  1045. target->path);
  1046. return -1;
  1047. } else {
  1048. target->perms.label = NULL;
  1049. }
  1050. } else {
  1051. target->perms.label = strdup(filecon);
  1052. freecon(filecon);
  1053. if (target->perms.label == NULL) {
  1054. virReportOOMError();
  1055. return -1;
  1056. }
  1057. }
  1058. #else
  1059. target->perms.label = NULL;
  1060. #endif
  1061. return 0;
  1062. }
  1063. struct diskType {
  1064. int part_table_type;
  1065. unsigned short offset;
  1066. unsigned short length;
  1067. unsigned long long magic;
  1068. };
  1069. static struct diskType const disk_types[] = {
  1070. { VIR_STORAGE_POOL_DISK_LVM2, 0x218, 8, 0x31303020324D564CULL },
  1071. { VIR_STORAGE_POOL_DISK_GPT, 0x200, 8, 0x5452415020494645ULL },
  1072. { VIR_STORAGE_POOL_DISK_DVH, 0x0, 4, 0x41A9E50BULL },
  1073. { VIR_STORAGE_POOL_DISK_MAC, 0x0, 2, 0x5245ULL },
  1074. { VIR_STORAGE_POOL_DISK_BSD, 0x40, 4, 0x82564557ULL },
  1075. { VIR_STORAGE_POOL_DISK_SUN, 0x1fc, 2, 0xBEDAULL },
  1076. /*
  1077. * NOTE: pc98 is funky; the actual signature is 0x55AA (just like dos), so
  1078. * we can't use that. At the moment I'm relying on the "dummy" IPL
  1079. * bootloader data that comes from parted. Luckily, the chances of running
  1080. * into a pc98 machine running libvirt are approximately nil.
  1081. */
  1082. /*{ 0x1fe, 2, 0xAA55UL },*/
  1083. { VIR_STORAGE_POOL_DISK_PC98, 0x0, 8, 0x314C5049000000CBULL },
  1084. /*
  1085. * NOTE: the order is important here; some other disk types (like GPT and
  1086. * and PC98) also have 0x55AA at this offset. For that reason, the DOS
  1087. * one must be the last one.
  1088. */
  1089. { VIR_STORAGE_POOL_DISK_DOS, 0x1fe, 2, 0xAA55ULL },
  1090. { -1, 0x0, 0, 0x0ULL },
  1091. };
  1092. int
  1093. virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target,
  1094. int fd)
  1095. {
  1096. int i;
  1097. off_t start;
  1098. unsigned char buffer[1024];
  1099. ssize_t bytes;
  1100. /* make sure to set the target format "unknown" to begin with */
  1101. target->format = VIR_STORAGE_POOL_DISK_UNKNOWN;
  1102. start = lseek(fd, 0, SEEK_SET);
  1103. if (start < 0) {
  1104. virReportSystemError(errno,
  1105. _("cannot seek to beginning of file '%s'"),
  1106. target->path);
  1107. return -1;
  1108. }
  1109. bytes = saferead(fd, buffer, sizeof(buffer));
  1110. if (bytes < 0) {
  1111. virReportSystemError(errno,
  1112. _("cannot read beginning of file '%s'"),
  1113. target->path);
  1114. return -1;
  1115. }
  1116. for (i = 0; disk_types[i].part_table_type != -1; i++) {
  1117. if (disk_types[i].offset + disk_types[i].length > bytes)
  1118. continue;
  1119. if (memcmp(buffer+disk_types[i].offset, &disk_types[i].magic,
  1120. disk_types[i].length) == 0) {
  1121. target->format = disk_types[i].part_table_type;
  1122. break;
  1123. }
  1124. }
  1125. return 0;
  1126. }
  1127. /*
  1128. * Given a volume path directly in /dev/XXX, iterate over the
  1129. * entries in the directory pool->def->target.path and find the
  1130. * first symlink pointing to the volume path.
  1131. *
  1132. * If, the target.path is /dev/, then return the original volume
  1133. * path.
  1134. *
  1135. * If no symlink is found, then return the original volume path
  1136. *
  1137. * Typically target.path is one of the /dev/disk/by-XXX dirs
  1138. * with stable paths.
  1139. */
  1140. char *
  1141. virStorageBackendStablePath(virStoragePoolObjPtr pool,
  1142. const char *devpath)
  1143. {
  1144. DIR *dh;
  1145. struct dirent *dent;
  1146. char *stablepath;
  1147. int opentries = 0;
  1148. /* Short circuit if pool has no target, or if its /dev */
  1149. if (pool->def->target.path == NULL ||
  1150. STREQ(pool->def->target.path, "/dev") ||
  1151. STREQ(pool->def->target.path, "/dev/"))
  1152. goto ret_strdup;
  1153. /* Skip whole thing for a pool which isn't in /dev
  1154. * so we don't mess will filesystem/dir based pools
  1155. */
  1156. if (!STRPREFIX(pool->def->target.path, "/dev"))
  1157. goto ret_strdup;
  1158. /* Logical pools are under /dev but already have stable paths */
  1159. if (pool->def->type == VIR_STORAGE_POOL_LOGICAL)
  1160. goto ret_strdup;
  1161. /* We loop here because /dev/disk/by-{id,path} may not have existed
  1162. * before we started this operation, so we have to give it some time to
  1163. * get created.
  1164. */
  1165. reopen:
  1166. if ((dh = opendir(pool->def->target.path)) == NULL) {
  1167. opentries++;
  1168. if (errno == ENOENT && opentries < 50) {
  1169. usleep(100 * 1000);
  1170. goto reopen;
  1171. }
  1172. virReportSystemError(errno,
  1173. _("cannot read dir '%s'"),
  1174. pool->def->target.path);
  1175. return NULL;
  1176. }
  1177. /* The pool is pointing somewhere like /dev/disk/by-path
  1178. * or /dev/disk/by-id, so we need to check all symlinks in
  1179. * the target directory and figure out which one points
  1180. * to this device node
  1181. */
  1182. while ((dent = readdir(dh)) != NULL) {
  1183. if (dent->d_name[0] == '.')
  1184. continue;
  1185. if (virAsprintf(&stablepath, "%s/%s",
  1186. pool->def->target.path,
  1187. dent->d_name) == -1) {
  1188. virReportOOMError();
  1189. closedir(dh);
  1190. return NULL;
  1191. }
  1192. if (virFileLinkPointsTo(stablepath, devpath)) {
  1193. closedir(dh);
  1194. return stablepath;
  1195. }
  1196. VIR_FREE(stablepath);
  1197. }
  1198. closedir(dh);
  1199. ret_strdup:
  1200. /* Couldn't find any matching stable link so give back
  1201. * the original non-stable dev path
  1202. */
  1203. stablepath = strdup(devpath);
  1204. if (stablepath == NULL)
  1205. virReportOOMError();
  1206. return stablepath;
  1207. }
  1208. #ifndef WIN32
  1209. /*
  1210. * Run an external program.
  1211. *
  1212. * Read its output and apply a series of regexes to each line
  1213. * When the entire set of regexes has matched consecutively
  1214. * then run a callback passing in all the matches
  1215. */
  1216. int
  1217. virStorageBackendRunProgRegex(virStoragePoolObjPtr pool,
  1218. const char *const*prog,
  1219. int nregex,
  1220. const char **regex,
  1221. int *nvars,
  1222. virStorageBackendListVolRegexFunc func,
  1223. void *data, const char *prefix)
  1224. {
  1225. int fd = -1, err, ret = -1;
  1226. FILE *list = NULL;
  1227. regex_t *reg;
  1228. regmatch_t *vars = NULL;
  1229. char line[1024];
  1230. int maxReg = 0, i, j;
  1231. int totgroups = 0, ngroup = 0, maxvars = 0;
  1232. char **groups;
  1233. virCommandPtr cmd = NULL;
  1234. /* Compile all regular expressions */
  1235. if (VIR_ALLOC_N(reg, nregex) < 0) {
  1236. virReportOOMError();
  1237. return -1;
  1238. }
  1239. for (i = 0 ; i < nregex ; i++) {
  1240. err = regcomp(&reg[i], regex[i], REG_EXTENDED);
  1241. if (err != 0) {
  1242. char error[100];
  1243. regerror(err, &reg[i], error, sizeof(error));
  1244. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  1245. _("Failed to compile regex %s"), error);
  1246. for (j = 0 ; j <= i ; j++)
  1247. regfree(&reg[j]);
  1248. VIR_FREE(reg);
  1249. return -1;
  1250. }
  1251. totgroups += nvars[i];
  1252. if (nvars[i] > maxvars)
  1253. maxvars = nvars[i];
  1254. }
  1255. /* Storage for matched variables */
  1256. if (VIR_ALLOC_N(groups, totgroups) < 0) {
  1257. virReportOOMError();
  1258. goto cleanup;
  1259. }
  1260. if (VIR_ALLOC_N(vars, maxvars+1) < 0) {
  1261. virReportOOMError();
  1262. goto cleanup;
  1263. }
  1264. cmd = virCommandNewArgs(prog);
  1265. virCommandSetOutputFD(cmd, &fd);
  1266. if (virCommandRunAsync(cmd, NULL) < 0) {
  1267. goto cleanup;
  1268. }
  1269. if ((list = VIR_FDOPEN(fd, "r")) == NULL) {
  1270. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  1271. "%s", _("cannot read fd"));
  1272. goto cleanup;
  1273. }
  1274. while (fgets(line, sizeof(line), list) != NULL) {
  1275. char *p = NULL;
  1276. /* Strip trailing newline */
  1277. int len = strlen(line);
  1278. if (len && line[len-1] == '\n')
  1279. line[len-1] = '\0';
  1280. /* ignore any command prefix */
  1281. if (prefix)
  1282. p = STRSKIP(line, prefix);
  1283. if (!p)
  1284. p = line;
  1285. for (i = 0 ; i <= maxReg && i < nregex ; i++) {
  1286. if (regexec(&reg[i], p, nvars[i]+1, vars, 0) == 0) {
  1287. maxReg++;
  1288. if (i == 0)
  1289. ngroup = 0;
  1290. /* NULL terminate each captured group in the line */
  1291. for (j = 0 ; j < nvars[i] ; j++) {
  1292. /* NB vars[0] is the full pattern, so we offset j by 1 */
  1293. p[vars[j+1].rm_eo] = '\0';
  1294. if ((groups[ngroup++] =
  1295. strdup(p + vars[j+1].rm_so)) == NULL) {
  1296. virReportOOMError();
  1297. goto cleanup;
  1298. }
  1299. }
  1300. /* We're matching on the last regex, so callback time */
  1301. if (i == (nregex-1)) {
  1302. if (((*func)(pool, groups, data)) < 0)
  1303. goto cleanup;
  1304. /* Release matches & restart to matching the first regex */
  1305. for (j = 0 ; j < totgroups ; j++)
  1306. VIR_FREE(groups[j]);
  1307. maxReg = 0;
  1308. ngroup = 0;
  1309. }
  1310. }
  1311. }
  1312. }
  1313. ret = virCommandWait(cmd, NULL);
  1314. cleanup:
  1315. if (groups) {
  1316. for (j = 0 ; j < totgroups ; j++)
  1317. VIR_FREE(groups[j]);
  1318. VIR_FREE(groups);
  1319. }
  1320. VIR_FREE(vars);
  1321. for (i = 0 ; i < nregex ; i++)
  1322. regfree(&reg[i]);
  1323. VIR_FREE(reg);
  1324. virCommandFree(cmd);
  1325. VIR_FORCE_FCLOSE(list);
  1326. VIR_FORCE_CLOSE(fd);
  1327. return ret;
  1328. }
  1329. /*
  1330. * Run an external program and read from its standard output
  1331. * a stream of tokens from IN_STREAM, applying FUNC to
  1332. * each successive sequence of N_COLUMNS tokens.
  1333. * If FUNC returns < 0, stop processing input and return -1.
  1334. * Return -1 if N_COLUMNS == 0.
  1335. * Return -1 upon memory allocation error.
  1336. * If the number of input tokens is not a multiple of N_COLUMNS,
  1337. * then the final FUNC call will specify a number smaller than N_COLUMNS.
  1338. * If there are no input tokens (empty input), call FUNC with N_COLUMNS == 0.
  1339. */
  1340. int
  1341. virStorageBackendRunProgNul(virStoragePoolObjPtr pool,
  1342. const char **prog,
  1343. size_t n_columns,
  1344. virStorageBackendListVolNulFunc func,
  1345. void *data)
  1346. {
  1347. size_t n_tok = 0;
  1348. int fd = -1;
  1349. FILE *fp = NULL;
  1350. char **v;
  1351. int ret = -1;
  1352. int i;
  1353. virCommandPtr cmd = NULL;
  1354. if (n_columns == 0)
  1355. return -1;
  1356. if (VIR_ALLOC_N(v, n_columns) < 0) {
  1357. virReportOOMError();
  1358. return -1;
  1359. }
  1360. for (i = 0; i < n_columns; i++)
  1361. v[i] = NULL;
  1362. cmd = virCommandNewArgs(prog);
  1363. virCommandSetOutputFD(cmd, &fd);
  1364. if (virCommandRunAsync(cmd, NULL) < 0) {
  1365. goto cleanup;
  1366. }
  1367. if ((fp = VIR_FDOPEN(fd, "r")) == NULL) {
  1368. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  1369. "%s", _("cannot open file using fd"));
  1370. goto cleanup;
  1371. }
  1372. while (1) {
  1373. char *buf = NULL;
  1374. size_t buf_len = 0;
  1375. /* Be careful: even when it returns -1,
  1376. this use of getdelim allocates memory. */
  1377. ssize_t tok_len = getdelim (&buf, &buf_len, 0, fp);
  1378. v[n_tok] = buf;
  1379. if (tok_len < 0) {
  1380. /* Maybe EOF, maybe an error.
  1381. If n_tok > 0, then we know it's an error. */
  1382. if (n_tok && func (pool, n_tok, v, data) < 0)
  1383. goto cleanup;
  1384. break;
  1385. }
  1386. ++n_tok;
  1387. if (n_tok == n_columns) {
  1388. if (func (pool, n_tok, v, data) < 0)
  1389. goto cleanup;
  1390. n_tok = 0;
  1391. for (i = 0; i < n_columns; i++) {
  1392. VIR_FREE(v[i]);
  1393. }
  1394. }
  1395. }
  1396. if (feof (fp) < 0) {
  1397. virReportSystemError(errno,
  1398. _("read error on pipe to '%s'"), prog[0]);
  1399. goto cleanup;
  1400. }
  1401. ret = virCommandWait(cmd, NULL);
  1402. cleanup:
  1403. for (i = 0; i < n_columns; i++)
  1404. VIR_FREE(v[i]);
  1405. VIR_FREE(v);
  1406. virCommandFree(cmd);
  1407. VIR_FORCE_FCLOSE(fp);
  1408. VIR_FORCE_CLOSE(fd);
  1409. return ret;
  1410. }
  1411. #else /* WIN32 */
  1412. int
  1413. virStorageBackendRunProgRegex(virConnectPtr conn,
  1414. virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
  1415. const char *const*prog ATTRIBUTE_UNUSED,
  1416. int nregex ATTRIBUTE_UNUSED,
  1417. const char **regex ATTRIBUTE_UNUSED,
  1418. int *nvars ATTRIBUTE_UNUSED,
  1419. virStorageBackendListVolRegexFunc func ATTRIBUTE_UNUSED,
  1420. void *data ATTRIBUTE_UNUSED)
  1421. {
  1422. virStorageReportError(VIR_ERR_INTERNAL_ERROR,
  1423. _("%s not implemented on Win32"), __FUNCTION__

Large files files are truncated, but you can click here to view the full file