Bug 501889

Summary: write-file does not support strings containing ASCII NUL
Product: [Community] Virtualization Tools Reporter: Richard W.M. Jones <rjones>
Component: libguestfsAssignee: Richard W.M. Jones <rjones>
Status: CLOSED UPSTREAM QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: mbooth, rjones, virt-maint
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-07-14 19:09:43 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 592883    

Description Richard W.M. Jones 2009-05-21 08:46:57 UTC
The guestfs_write_file / write-file command uses an XDR
string type to pass the buffer content.  Unfortunately we
discovered after making this choice that XDR strings cannot
contain ASCII NUL characters, which means that write-file
cannot be used to write binary files.

Current workaround is to use the guestfs_upload command
instead to upload arbitrary binary files to the guest filesystem.

We need to implement BufferIn/Out parameters, as discussed
in the TODO file.

Comment 1 Mark McLoughlin 2009-05-25 14:49:58 UTC
Moving upstream, since it's a "known limitiation" with the API which has a workaround

Comment 2 Richard W.M. Jones 2010-05-17 10:35:00 UTC
I'll make an extended attempt at explaining what this bug
is all about, since it affects FUSE access (bug 592883).

In libguestfs there is a protocol which is used to send and
receive messages between the library and the daemon (which
runs inside qemu).  This protocol uses Sun XDR, the same basic
protocol as NFS, NIS etc.

In the protocol, we normally encode C 'char *' as the XDR
string type.  When we first implemented this we didn't realize
that these are C strings, terminated by \0 characters.  (This
is because at the protocol level, they _are_ sent as len word +
data, but the C-level XDR library has the limitation that it
works out the length word using strlen).

Anyway, we need to use the XDR 'opaque' type.  It's exactly
the same as 'string' at the wire level, but in the XDR library
it is encoded using an explicit length, and therefore it can
contain \0 bytes.

To avoid complicating existing string parameters, we need
to add to the generator a new arg type, BufferIn, which will
take a (const char *, size_t) pair and send an opaque value
over the wire.

This will allow us to fix write-file, and implement a pwrite
API.  (Currently it's not possible to implement the pwrite
call in the API because it would fail if the buffer being
written contained any \0 byte).

With a pwrite call, we could implement the FUSE write
system call.

Comment 3 Richard W.M. Jones 2010-05-18 21:06:22 UTC
Proposed fix posted upstream:
https://www.redhat.com/archives/libguestfs/2010-May/msg00108.html