Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vboxwrapper]Enable vboxwrapper to use multiattach mode disk images #4603

Merged
merged 18 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 73 additions & 10 deletions samples/vboxwrapper/vbox_vboxmanage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.

#ifdef _WIN32
#include <algorithm>
#include "boinc_win.h"
#include "win_util.h"
#else
Expand Down Expand Up @@ -500,18 +501,80 @@ namespace vboxmanage {

// Adding virtual hard drive to VM
//
vboxlog_msg("Adding virtual disk drive to VM. (%s)", image_filename.c_str());
string command_fix_part;

command_fix_part = "storageattach \"" + vm_name + "\" ";
command_fix_part += "--storagectl \"Hard Disk Controller\" ";
command_fix_part += "--port 0 ";
command_fix_part += "--device 0 ";
command_fix_part += "--type hdd ";

if (!multiattach_vdi_file.size()) {
// the traditional method:
// copy the vdi file from the projects dir to the slots dir and rename it vm_image.vdi
// each copy must get a new (random) UUID
//
vboxlog_msg("Adding virtual disk drive to VM. (%s)", image_filename.c_str());
command = command_fix_part;
command += "--setuuid \"\" ";
command += "--medium \"" + virtual_machine_slot_directory + "/" + image_filename + "\" ";

command = "storageattach \"" + vm_name + "\" ";
command += "--storagectl \"Hard Disk Controller\" ";
command += "--port 0 ";
command += "--device 0 ";
command += "--type hdd ";
command += "--setuuid \"\" ";
command += "--medium \"" + virtual_machine_slot_directory + "/" + image_filename + "\" ";
retval = vbm_popen(command, output, "storage attach (fixed disk)");
if (retval) return retval;
} else {
// Use MultiAttach mode and differencing images
// See: https://www.virtualbox.org/manual/ch05.html#hdimagewrites
// https://www.virtualbox.org/manual/ch05.html#diffimages
// the vdi file downloaded to the projects dir becomes the parent (read only)
// "--setuid" must not be used
// each task gets it's own differencing image (writable)
// differencing images are written to the VM's snapshot folder
//
string medium_file = aid.project_dir;
medium_file += "/" + multiattach_vdi_file;

#ifdef _WIN32
replace(medium_file.begin(), medium_file.end(), '\\', '/');
#endif

vboxlog_msg("Adding virtual disk drive to VM. (%s)", multiattach_vdi_file.c_str());
command = "list hdds";

retval = vbm_popen(command, output, "check if parent hdd is registered", false, false);
if (retval) return retval;

#ifdef _WIN32
replace(output.begin(), output.end(), '\\', '/');
#endif

if (output.find(medium_file) == string::npos) {
// parent hdd is not registered
// vdi files can't be registered and set to multiattach mode within 1 step.
// They must first be attached to a VM in normal mode, then detached from the VM
//
command = command_fix_part;
command += "--medium \"" + medium_file + "\" ";

retval = vbm_popen(command, output, "register parent hdd", false, false);
if (retval) return retval;

command = command_fix_part;
command += "--medium none ";

retval = vbm_popen(command, output, "detach parent vdi", false, false);
if (retval) return retval;
// the vdi file is now registered and ready to be attached in multiattach mode
//
}

command = command_fix_part;
command += "--mtype multiattach ";
command += "--medium \"" + medium_file + "\" ";

retval = vbm_popen(command, output, "storage attach (fixed disk - multiattach mode)");
if (retval) return retval;
}

retval = vbm_popen(command, output, "storage attach (fixed disk)");
if (retval) return retval;

// Add guest additions to the VM
//
Expand Down
2 changes: 2 additions & 0 deletions samples/vboxwrapper/vboxjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ void VBOX_JOB::clear() {
heartbeat_filename.clear();
completion_trigger_file.clear();
temporary_exit_trigger_file.clear();
multiattach_vdi_file.clear();
enable_cern_dataformat = false;
enable_shared_directory = false;
enable_scratch_directory = false;
Expand Down Expand Up @@ -170,6 +171,7 @@ int VBOX_JOB::parse() {
else if (xp.parse_string("heartbeat_filename", heartbeat_filename)) continue;
else if (xp.parse_string("completion_trigger_file", completion_trigger_file)) continue;
else if (xp.parse_string("temporary_exit_trigger_file", temporary_exit_trigger_file)) continue;
else if (xp.parse_string("multiattach_vdi_file", multiattach_vdi_file)) continue;
else if (xp.parse_bool("enable_cern_dataformat", enable_cern_dataformat)) continue;
else if (xp.parse_bool("enable_network", enable_network)) continue;
else if (xp.parse_bool("network_bridged_mode", network_bridged_mode)) continue;
Expand Down
4 changes: 4 additions & 0 deletions samples/vboxwrapper/vboxjob.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ class VBOX_JOB {
// File can optionally contain is_notice bool (second line)
// and stderr text (subsequent lines).
// Addresses a problem where VM doesn't shut down properly

std::string multiattach_vdi_file;
// Name of the vdi file (without path) to be attached in multiattach mode.
// The file is expected to be in the project's base directory.
};

#endif