[libvirt] [PATCH 3/6] Add vol-create-upload, vol-upload and vol-download commands to virsh

Eric Blake eblake at redhat.com
Mon Mar 21 21:23:24 UTC 2011


On 03/18/2011 10:36 AM, Daniel P. Berrange wrote:
> * tools/virsh.c: Add vol-create-upload, vol-upload
>   and vol-download commands

Another stale commit message.

s/vol-create-upload, //

> +static int
> +cmdVolUpload (vshControl *ctl, const vshCmd *cmd)
> +{
> +    const char *file = NULL;
> +    virStorageVolPtr vol = NULL;
> +    int ret = FALSE;
> +    int fd = -1;
> +    virStreamPtr st = NULL;
> +    const char *name = NULL;
> +    unsigned long long offset = 0, length = 0;
> +
> +    if (!vshConnectionUsability(ctl, ctl->conn))
> +        goto cleanup;
> +
> +    if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", &name))) {
> +        return FALSE;
> +    }
> +
> +    if (vshCommandOptULongLong(cmd, "offset", &offset) < 0)
> +        return FALSE;
> +
> +    if (vshCommandOptULongLong(cmd, "length", &length) < 0)
> +        return FALSE;

This returns FALSE without an error message, not to mention that it
leaks vol.  Should be:

if (vshCommandOptULongLong(cmd, "offset", &offset) < 0 ||
    vshCommandOptULongLong(cmd, "length", &length) < 0) {
    vshError(ctl, "%s", _("Unable to parse integer parameter"));
    goto cleanup;
}

> +    st = virStreamNew(ctl->conn, 0);
> +    if (virStorageVolUpload(vol, st, offset, length, 0) < 0) {
> +        vshError(ctl, "cannot upload to volume %s", name);
> +        goto cleanup;
> +    }

Oh.  I see - virStorageVolUpload _can't_ return how many bytes were
read.  It is the start of an asynchronous data transfer, and can only
return 0 if the stream was successfully tied to the volume...

> +
> +    if (virStreamSendAll(st, cmdVolUploadSource, &fd) < 0) {
> +        vshError(ctl, "cannot send data to volume %s", name);
> +        goto cleanup;
> +    }

...and it isn't until the virStreamSendAll runs that you know how many
bytes were transferred.  That impacts some of my comments to patch 2/6.

Do we need any protection that a volume can only be tied to one stream
at a time, so if an upload or download is already in progress, then
attempts to attach another stream will fail?

This is a potentially long-running transaction.  Should virsh be taught
how to do SIGINT interruption of the command, or even how to do a
progress indicator of how many bytes remain to pass through the stream?

> +    if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", &name))) {
> +        return FALSE;
> +    }
> +
> +    if (vshCommandOptULongLong(cmd, "offset", &offset) < 0)
> +        return FALSE;
> +
> +    if (vshCommandOptULongLong(cmd, "length", &length) < 0)
> +        return FALSE;

Same usage problem and leak of vol.

> +
> +    if (vshCommandOptString(cmd, "file", &file) < 0)
> +        goto cleanup;
> +
> +    if ((fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {

No optional --mode command for specifying the permissions to give to a
newly created file?

> +        vshError(ctl, "cannot create %s", file);
> +        goto cleanup;
> +    }
> +
> +    st = virStreamNew(ctl->conn, 0);
> +    if (virStorageVolDownload(vol, st, offset, length, 0) < 0) {
> +        vshError(ctl, "cannot download from volume %s", name);
> +        goto cleanup;
> +    }
> +
> +    if (virStreamRecvAll(st, cmdVolDownloadSink, &fd) < 0) {
> +        vshError(ctl, "cannot receive data from volume %s", name);
> +        goto cleanup;
> +    }
> +
> +    if (VIR_CLOSE(fd) < 0) {
> +        vshError(ctl, "cannot close file %s", file);
> +        virStreamAbort(st);
> +        goto cleanup;
> +    }
> +
> +    if (virStreamFinish(st) < 0) {
> +        vshError(ctl, "cannot close volume %s", name);
> +        goto cleanup;
> +    }
> +
> +    ret = TRUE;
> +
> +cleanup:
> +    if (ret == FALSE)
> +        unlink(file);

Is it wise to blindly unlink() the file even if we didn't create it?  If
you insist on blind unlink(), then I'd feel more comfortable with O_EXCL
on open(), but I don't know that we can justify forbidding to overwrite
existing files.

-- 
Eric Blake   eblake at redhat.com    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 619 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20110321/2d4259a4/attachment-0001.sig>


More information about the libvir-list mailing list