<div dir="ltr">Hi, everyone, My name is Taowei Luo. I'm one of the students working for GSoC this summer. My project is rewriting the vbox driver.<div><br></div><div>Before coding, I really need some discussions about how to implement it. Here I post my first version of plan. I had show as much details as I thought about in this plan. If anyone have ideas or suggestions about my work, I would like to hear. My nick name in #virt IRC channel is uaedante (or dante I used before). If I am offline in IRC, please contract me with my email address <a href="mailto:uaedante@gmail.com" target="_blank">uaedante@gmail.com</a>.</div>


<div><br></div><div>Regards,</div><div>Taowei.<br></div><div><br></div><div><br></div><div><p class="MsoNormal"><span lang="EN-US">Plan to rewrite vbox driver</span></p>

<p class="MsoNormal"><br></p>

<p class="MsoNormal"><span lang="EN-US">Introduction:</span></p>

<p class="MsoNormal"><span lang="EN-US">The existing vbox driver codes use vbox API
directly. But the vbox API is incompatible between different versions. To
support all vbox API versions, the vbox_tmpl.c file provides a template to
implement all vbox drivers. Each specified version of vbox driver includes the
vbox_tmpl.c file, with the definition in the corresponding head file, they work
well. As the vbox API defined in head files is conflict between different versions,
even some behavior of vbox APIs are changed. The vbox_tmpl.c contains lots of
codes such as “#if VBOX_API_VERSION < 4001000”. These codes is hard to
manage or adding new features.</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">Plan:</span></p>

<p class="MsoNormal"><span lang="EN-US">The core idea of my rewriting work is to add
a middle layer to uniform the API changes. This modification will not change any
functions’ behavior or sematic.</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">The middle layer has a global structure which
contains API changes. Like this:</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">struct vboxUniformedAPI {</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">A (*funcA)(A1 a,
….);</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">B (*funcB)(B1 a,
….);</span></p>

<p class="MsoNormal"><span lang="EN-US">}</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">If there is a code segment:</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">#if VBOX_API_VERSION < 4001000</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">adapter->vtbl->GetHostInterface(adapter,
&hostIntUtf16);</span></p>

<p class="MsoNormal"><span lang="EN-US">#else /* VBOX_API_VERSION >= 4001000 */</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">adapter->vtbl->GetBridgedInterface(adapter,
&hostIntUtf16);</span></p>

<p class="MsoNormal"><span lang="EN-US">#endif /* VBOX_API_VERSION >= 4001000 */</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">This will result to a variable in vboxUniformedAPI
structure:</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">RetType
(*GetInterface)(INetworkAdapter *a, PRUnichar *b)</span></p>

<p class="MsoNormal"><span lang="EN-US">When using the vbox under 4.1, this
variable will points to a function that calls GetHostInterface. When using the
vbox later than 4.1 and the variable will points to a function which calls GetBridgedInterface.</span></p>

<p class="MsoNormal"><span lang="EN-US">When replace these code segments with a
single function, we need to do living variable analyze and find out what is
used and what is changed in these codes. I plan to do these analyze manually.</span></p>

<p class="MsoNormal"><span lang="EN-US">All conflict in function prototype or function
implementation will be fixed up though this method.</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">When meeting a conflict in variable type, like:</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">#if VBOX_API_VERSION < 4001000</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">TypeA var;</span></p>

<p class="MsoNormal"><span lang="EN-US">#else /* VBOX_API_VERSION >= 4001000 */</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">TypeB var;</span></p>

<p class="MsoNormal"><span lang="EN-US">#endif /* VBOX_API_VERSION >= 4001000 */</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">I will add a union like this:</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">Union TypeC{</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">TypeA a;// used
in some versions</span></p>

<p class="MsoNormal" style="text-indent:21pt"><span lang="EN-US">TypeB b;// used
in some other versions</span></p>

<p class="MsoNormal"><span lang="EN-US">}</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">If there is any operation using variables
with such a union type (or functions use it as an argument or return value), I
will add a new function in vboxUniformedAPI to handle this operation. These
functions use TypeC as parameter type, dispatch it depends on the vbox version and
return TypeC value to conceal type conflict.</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">We still have another kind of conflict. There
are some versions have more variables, operations or function calls than other versions.
I will reserve all variables even though they may not be used in some
situation. And put an empty function if they have nothing to do in the specified
function step. (I have a backup solution here. That is adding some flags to indicate
whether the procession is necessary in the API version and prevent upper layer
from calling a nonexistent function.)</span></p>

<p class="MsoNormal"><span lang="EN-US"> </span></p>

<p class="MsoNormal"><span lang="EN-US">Expected result:</span></p>

<p class="MsoNormal"><span lang="EN-US">After rewriting with the rules above, we
will have a new vbox_tmpl.c. It gathers version specified code and common code respectively.
The common codes use stable vbox API or functions in vboxUniformedAPI. A function
named InstallvboxUnifromedAPI will fill the vboxUniformedAPI structure depends
on the current vbox API version. In final step, I will put all vbox APIs into the </span>vboxUniformedAPI and make the vbox driver codes use my API only. If this is done, the vbox driver will not be complied for each version anymore.</p>


<p class="MsoNormal"><br></p>

<p class="MsoNormal"><span lang="EN-US">Implementation:</span></p>

<p class="MsoNormal"><span lang="EN-US">First, define the vboxUniformedAPI
structure in vbox_tmpl.c, and write the InstallvboxUnifromedAPI function for
every vbox API version.</span></p>

<p class="MsoNormal"><span lang="EN-US">Next, rewrite the functions which have
conflict codes one by one. Each time rewrite a new function, we can do some
tests (here, I am not sure what kind of tests is enough). When rewriting one
function in vbox_tmpl.c, the others will not change.</span></p>

<p class="MsoNormal" align="left" style="background-image:initial;background-repeat:initial"><span lang="EN-US">At this point, there will split version
specified codes and common codes But we still need to build the whole
vbox_tmpl.c for each vbox API version.</span></p>

<p class="MsoNormal" align="left" style="background-image:initial;background-repeat:initial"><span lang="EN-US">If we want a single object file be generated
by vbox_tmpl.c, we need to prevent vbox_tmpl.c from calling vbox API directly. This
could be done by putting all of the vbox API calls into the middle
vboxUniformedAPI layer, and moving common codes into vbox_common.c. The
vbox_common.c should only use APIs in vboxUniformedAPI and will be complied
only once.</span></p></div></div>