On Fri, Sep 13, 2013 at 1:31 AM, Michal Privoznik <mprivozn@xxxxxxxxxx> wrote: > This is just digging out important implementation from qemu > driver's qemuDomainGetDiskBlockInfo() API as this functionality > is going to be required in the next patch. > > Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > --- > src/qemu/qemu_domain.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_domain.h | 4 ++ > src/qemu/qemu_driver.c | 121 +++-------------------------------------------- > 3 files changed, 135 insertions(+), 114 deletions(-) > > diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c > index b5770c5..64cd278 100644 > --- a/src/qemu/qemu_domain.c > +++ b/src/qemu/qemu_domain.c > @@ -2501,3 +2501,127 @@ error: > path); > goto cleanup; > } > + > +int > +qemuDomainGetDiskBlockInfo(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + virDomainDiskDefPtr disk, > + virDomainBlockInfoPtr info) > +{ > + > + int ret = -1; > + virStorageFileMetadata *meta = NULL; > + virQEMUDriverConfigPtr cfg = NULL; cfg is NULL here.... > + int format; > + struct stat sb; > + int fd = -1; > + off_t end; > + const char *path; > + > + if (!disk->src) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("disk %s does not currently have a source assigned"), > + disk->info.alias); > + goto cleanup; > + } > + path = disk->src; > + > + /* The path is correct, now try to open it and get its size. */ > + fd = qemuOpenFile(driver, vm, path, O_RDONLY, NULL, NULL); > + if (fd == -1) > + goto cleanup; > + > + /* Probe for magic formats */ > + if (disk->format) { > + format = disk->format; > + } else { > + if (cfg->allowDiskFormatProbing) { and used here, without being set. I think you're missing a "cfg = virQEMUDriverGetConfig(driver);" somewhere above. > + if ((format = virStorageFileProbeFormat(disk->src, > + cfg->user, > + cfg->group)) < 0) > + goto cleanup; > + } else { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("no disk format for %s and probing is disabled"), > + disk->src); > + goto cleanup; > + } > + } > + > + if (!(meta = virStorageFileGetMetadataFromFD(path, fd, format))) > + goto cleanup; > + > + /* Get info for normal formats */ > + if (fstat(fd, &sb) < 0) { > + virReportSystemError(errno, > + _("cannot stat file '%s'"), path); > + goto cleanup; > + } > + > + if (S_ISREG(sb.st_mode)) { > +#ifndef WIN32 > + info->physical = (unsigned long long)sb.st_blocks * > + (unsigned long long)DEV_BSIZE; > +#else > + info->physical = sb.st_size; > +#endif > + /* Regular files may be sparse, so logical size (capacity) is not same > + * as actual physical above > + */ > + info->capacity = sb.st_size; > + } else { > + /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should > + * be 64 bits on all platforms. > + */ > + end = lseek(fd, 0, SEEK_END); > + if (end == (off_t)-1) { > + virReportSystemError(errno, > + _("failed to seek to end of %s"), path); > + goto cleanup; > + } > + info->physical = end; > + info->capacity = end; > + } > + > + /* If the file we probed has a capacity set, then override > + * what we calculated from file/block extents */ > + if (meta->capacity) > + info->capacity = meta->capacity; > + > + /* Set default value .. */ > + info->allocation = info->physical; > + > + /* ..but if guest is running & not using raw > + disk format and on a block device, then query > + highest allocated extent from QEMU */ > + if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK && > + format != VIR_STORAGE_FILE_RAW && > + S_ISBLK(sb.st_mode) && > + virDomainObjIsActive(vm)) { > + qemuDomainObjPrivatePtr priv = vm->privateData; > + > + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) > + goto cleanup; > + > + if (virDomainObjIsActive(vm)) { > + qemuDomainObjEnterMonitor(driver, vm); > + ret = qemuMonitorGetBlockExtent(priv->mon, > + disk->info.alias, > + &info->allocation); > + qemuDomainObjExitMonitor(driver, vm); > + } else { > + ret = 0; > + } > + > + if (!qemuDomainObjEndJob(driver, vm)) > + vm = NULL; > + } else { > + ret = 0; > + } > + > +cleanup: > + VIR_FORCE_CLOSE(fd); > + virStorageFileFreeMetadata(meta); > + virObjectUnref(cfg); > + return ret; > +} > diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h > index 50987a4..b6e6e33 100644 > --- a/src/qemu/qemu_domain.h > +++ b/src/qemu/qemu_domain.h > @@ -360,6 +360,10 @@ void qemuDomainCleanupRemove(virDomainObjPtr vm, > qemuDomainCleanupCallback cb); > void qemuDomainCleanupRun(virQEMUDriverPtr driver, > virDomainObjPtr vm); > +int qemuDomainGetDiskBlockInfo(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + virDomainDiskDefPtr disk, > + virDomainBlockInfoPtr info); > > extern virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks; > extern virDomainXMLNamespace virQEMUDriverDomainXMLNamespace; > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 70b587f..b3e120f 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -9556,29 +9556,23 @@ cleanup: > } > > > -static int qemuDomainGetBlockInfo(virDomainPtr dom, > - const char *path, > - virDomainBlockInfoPtr info, > - unsigned int flags) { > +static int > +qemuDomainGetBlockInfo(virDomainPtr dom, > + const char *path, > + virDomainBlockInfoPtr info, > + unsigned int flags) > +{ > virQEMUDriverPtr driver = dom->conn->privateData; > virDomainObjPtr vm; > int ret = -1; > - int fd = -1; > - off_t end; > - virStorageFileMetadata *meta = NULL; > virDomainDiskDefPtr disk = NULL; > - struct stat sb; > int idx; > - int format; > - virQEMUDriverConfigPtr cfg = NULL; > > virCheckFlags(0, -1); > > if (!(vm = qemuDomObjFromDomain(dom))) > goto cleanup; > > - cfg = virQEMUDriverGetConfig(driver); > - > if (virDomainGetBlockInfoEnsureACL(dom->conn, vm->def) < 0) > goto cleanup; > > @@ -9595,113 +9589,12 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom, > goto cleanup; > } > disk = vm->def->disks[idx]; > - if (!disk->src) { > - virReportError(VIR_ERR_INVALID_ARG, > - _("disk %s does not currently have a source assigned"), > - path); > - goto cleanup; > - } > - path = disk->src; > - > - /* The path is correct, now try to open it and get its size. */ > - fd = qemuOpenFile(driver, vm, path, O_RDONLY, NULL, NULL); > - if (fd == -1) > - goto cleanup; > - > - /* Probe for magic formats */ > - if (disk->format) { > - format = disk->format; > - } else { > - if (cfg->allowDiskFormatProbing) { > - if ((format = virStorageFileProbeFormat(disk->src, > - cfg->user, > - cfg->group)) < 0) > - goto cleanup; > - } else { > - virReportError(VIR_ERR_INTERNAL_ERROR, > - _("no disk format for %s and probing is disabled"), > - disk->src); > - goto cleanup; > - } > - } > - > - if (!(meta = virStorageFileGetMetadataFromFD(path, fd, format))) > - goto cleanup; > - > - /* Get info for normal formats */ > - if (fstat(fd, &sb) < 0) { > - virReportSystemError(errno, > - _("cannot stat file '%s'"), path); > - goto cleanup; > - } > > - if (S_ISREG(sb.st_mode)) { > -#ifndef WIN32 > - info->physical = (unsigned long long)sb.st_blocks * > - (unsigned long long)DEV_BSIZE; > -#else > - info->physical = sb.st_size; > -#endif > - /* Regular files may be sparse, so logical size (capacity) is not same > - * as actual physical above > - */ > - info->capacity = sb.st_size; > - } else { > - /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should > - * be 64 bits on all platforms. > - */ > - end = lseek(fd, 0, SEEK_END); > - if (end == (off_t)-1) { > - virReportSystemError(errno, > - _("failed to seek to end of %s"), path); > - goto cleanup; > - } > - info->physical = end; > - info->capacity = end; > - } > - > - /* If the file we probed has a capacity set, then override > - * what we calculated from file/block extents */ > - if (meta->capacity) > - info->capacity = meta->capacity; > - > - /* Set default value .. */ > - info->allocation = info->physical; > - > - /* ..but if guest is running & not using raw > - disk format and on a block device, then query > - highest allocated extent from QEMU */ > - if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK && > - format != VIR_STORAGE_FILE_RAW && > - S_ISBLK(sb.st_mode) && > - virDomainObjIsActive(vm)) { > - qemuDomainObjPrivatePtr priv = vm->privateData; > - > - if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) > - goto cleanup; > - > - if (virDomainObjIsActive(vm)) { > - qemuDomainObjEnterMonitor(driver, vm); > - ret = qemuMonitorGetBlockExtent(priv->mon, > - disk->info.alias, > - &info->allocation); > - qemuDomainObjExitMonitor(driver, vm); > - } else { > - ret = 0; > - } > - > - if (!qemuDomainObjEndJob(driver, vm)) > - vm = NULL; > - } else { > - ret = 0; > - } > + ret = qemuDomainGetDiskBlockInfo(driver, vm, disk, info); > > cleanup: > - virStorageFileFreeMetadata(meta); > - VIR_FORCE_CLOSE(fd); > if (vm) > virObjectUnlock(vm); > - virObjectUnref(cfg); > return ret; > } > > -- > 1.8.1.5 > > -- > libvir-list mailing list > libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- Doug Goldstein -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list