VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp@ 40469

Last change on this file since 40469 was 40469, checked in by vboxsync, 13 years ago

VBoxManage: bandwidthctl uses sub-commands instead of options (#5582)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1/* $Id: VBoxManageBandwidthControl.cpp 40469 2012-03-14 18:14:52Z vboxsync $ */
2/** @file
3 * VBoxManage - The bandwidth control related commands.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_ONLY_DOCS
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <VBox/com/com.h>
24#include <VBox/com/array.h>
25#include <VBox/com/ErrorInfo.h>
26#include <VBox/com/errorprint.h>
27#include <VBox/com/VirtualBox.h>
28
29#include <iprt/path.h>
30#include <iprt/param.h>
31#include <iprt/string.h>
32#include <iprt/ctype.h>
33#include <iprt/stream.h>
34#include <iprt/getopt.h>
35#include <VBox/log.h>
36
37#include "VBoxManage.h"
38using namespace com;
39
40
41// funcs
42///////////////////////////////////////////////////////////////////////////////
43
44
45/**
46 * Handles the 'bandwidthctl myvm add' sub-command.
47 * @returns Exit code.
48 * @param a The handler argument package.
49 * @param bwCtrl Reference to the bandwidth control interface.
50 */
51static RTEXITCODE handleBandwidthControlAdd(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
52{
53 HRESULT rc = S_OK;
54 static const RTGETOPTDEF g_aBWCtlAddOptions[] =
55 {
56 { "--type", 't', RTGETOPT_REQ_STRING },
57 { "--limit", 'l', RTGETOPT_REQ_UINT32 }
58 };
59
60
61 Bstr name(a->argv[2]);
62 const char *pszType = NULL;
63 ULONG cMaxMbPerSec = UINT32_MAX;
64
65 int c;
66 RTGETOPTUNION ValueUnion;
67 RTGETOPTSTATE GetState;
68 RTGetOptInit(&GetState, a->argc, a->argv, g_aBWCtlAddOptions,
69 RT_ELEMENTS(g_aBWCtlAddOptions), 3, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
70
71 while ( SUCCEEDED(rc)
72 && (c = RTGetOpt(&GetState, &ValueUnion)))
73 {
74 switch (c)
75 {
76 case 't': // bandwidth group type
77 {
78 if (ValueUnion.psz)
79 pszType = ValueUnion.psz;
80 else
81 rc = E_FAIL;
82 break;
83 }
84
85 case 'l': // limit
86 {
87 cMaxMbPerSec = ValueUnion.u32;
88 break;
89 }
90
91 default:
92 {
93 errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
94 rc = E_FAIL;
95 break;
96 }
97 }
98 }
99 RTPrintf("Adding bwgroup: name=%ls type=%s limit=%u\n", name.raw(), pszType, cMaxMbPerSec);
100
101 BandwidthGroupType_T enmType;
102
103 if (!RTStrICmp(pszType, "disk"))
104 enmType = BandwidthGroupType_Disk;
105 else if (!RTStrICmp(pszType, "network"))
106 enmType = BandwidthGroupType_Network;
107 else
108 {
109 errorArgument("Invalid bandwidth group type\n");
110 return RTEXITCODE_FAILURE;
111 }
112
113 CHECK_ERROR2_RET(bwCtrl, CreateBandwidthGroup(name.raw(), enmType, cMaxMbPerSec), RTEXITCODE_FAILURE);
114
115 return RTEXITCODE_SUCCESS;
116}
117
118/**
119 * Handles the 'bandwidthctl myvm set' sub-command.
120 * @returns Exit code.
121 * @param a The handler argument package.
122 * @param bwCtrl Reference to the bandwidth control interface.
123 */
124static RTEXITCODE handleBandwidthControlSet(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
125{
126 HRESULT rc = S_OK;
127 static const RTGETOPTDEF g_aBWCtlAddOptions[] =
128 {
129 { "--limit", 'l', RTGETOPT_REQ_UINT32 }
130 };
131
132
133 Bstr name(a->argv[2]);
134 ULONG cMaxMbPerSec = UINT32_MAX;
135
136 int c;
137 RTGETOPTUNION ValueUnion;
138 RTGETOPTSTATE GetState;
139 RTGetOptInit(&GetState, a->argc, a->argv, g_aBWCtlAddOptions,
140 RT_ELEMENTS(g_aBWCtlAddOptions), 3, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
141
142 while ( SUCCEEDED(rc)
143 && (c = RTGetOpt(&GetState, &ValueUnion)))
144 {
145 switch (c)
146 {
147 case 'l': // limit
148 {
149 cMaxMbPerSec = ValueUnion.u32;
150 break;
151 }
152
153 default:
154 {
155 errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
156 rc = E_FAIL;
157 break;
158 }
159 }
160 }
161 RTPrintf("Updating bwgroup: name=%ls limit=%u\n", name.raw(), cMaxMbPerSec);
162
163
164 if (cMaxMbPerSec != UINT32_MAX)
165 {
166 ComPtr<IBandwidthGroup> bwGroup;
167 CHECK_ERROR2_RET(bwCtrl, GetBandwidthGroup(name.raw(), bwGroup.asOutParam()), RTEXITCODE_FAILURE);
168 if (SUCCEEDED(rc))
169 CHECK_ERROR2_RET(bwGroup, COMSETTER(MaxMbPerSec)(cMaxMbPerSec), RTEXITCODE_FAILURE);
170 }
171
172 return RTEXITCODE_SUCCESS;
173}
174
175/**
176 * Handles the 'bandwidthctl myvm remove' sub-command.
177 * @returns Exit code.
178 * @param a The handler argument package.
179 * @param bwCtrl Reference to the bandwidth control interface.
180 */
181static RTEXITCODE handleBandwidthControlRemove(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
182{
183 Bstr name(a->argv[2]);
184 CHECK_ERROR2_RET(bwCtrl, DeleteBandwidthGroup(name.raw()), RTEXITCODE_FAILURE);
185 return RTEXITCODE_SUCCESS;
186}
187
188/**
189 * Converts bandwidth group type to a string.
190 * @returns String representation.
191 * @param enmType Bandwidth control group type.
192 */
193inline const char * typeToString(BandwidthGroupType_T enmType)
194{
195 switch (enmType)
196 {
197 case BandwidthGroupType_Disk: return "Disk";
198 case BandwidthGroupType_Network: return "Network";
199 }
200 return "unknown";
201}
202
203/**
204 * Handles the 'bandwidthctl myvm list' sub-command.
205 * @returns Exit code.
206 * @param a The handler argument package.
207 * @param bwCtrl Reference to the bandwidth control interface.
208 */
209static RTEXITCODE handleBandwidthControlList(HandlerArg *pArgs, ComPtr<IBandwidthControl> &rptrBWControl)
210{
211 static const RTGETOPTDEF g_aOptions[] =
212 {
213 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
214 };
215
216 VMINFO_DETAILS enmDetails = VMINFO_STANDARD;
217
218 int c;
219 RTGETOPTUNION ValueUnion;
220 RTGETOPTSTATE GetState;
221 RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, g_aOptions, RT_ELEMENTS(g_aOptions), 2 /*iArg*/, 0 /*fFlags*/);
222 while ((c = RTGetOpt(&GetState, &ValueUnion)))
223 {
224 switch (c)
225 {
226 case 'M': enmDetails = VMINFO_MACHINEREADABLE; break;
227 default: return errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
228 }
229 }
230
231 /* See showVMInfo. */
232 com::SafeIfaceArray<IBandwidthGroup> bwGroups;
233 CHECK_ERROR2_RET(rptrBWControl, GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups)), RTEXITCODE_FAILURE);
234 for (size_t i = 0; i < bwGroups.size(); i++)
235 {
236 Bstr strName;
237 ULONG cMaxMbPerSec;
238 BandwidthGroupType_T enmType;
239
240 CHECK_ERROR2_RET(bwGroups[i], COMGETTER(Name)(strName.asOutParam()), RTEXITCODE_FAILURE);
241 CHECK_ERROR2_RET(bwGroups[i], COMGETTER(Type)(&enmType), RTEXITCODE_FAILURE);
242 CHECK_ERROR2_RET(bwGroups[i], COMGETTER(MaxMbPerSec)(&cMaxMbPerSec), RTEXITCODE_FAILURE);
243
244 RTPrintf(enmDetails == VMINFO_MACHINEREADABLE ?
245 "Group=%ls\nType=%s\nLimit=%u\n\n" :
246 "%-30ls %-10s %u MBytes/sec\n",
247 strName.raw(),
248 typeToString(enmType),
249 cMaxMbPerSec);
250 }
251
252 return RTEXITCODE_SUCCESS;
253}
254
255
256/**
257 * Handles the 'bandwidthctl' command.
258 * @returns Exit code.
259 * @param a The handler argument package.
260 */
261int handleBandwidthControl(HandlerArg *a)
262{
263 int c = VERR_INTERNAL_ERROR; /* initialized to shut up gcc */
264 HRESULT rc = S_OK;
265 ComPtr<IMachine> machine;
266 ComPtr<IBandwidthControl> bwCtrl;
267
268 if (a->argc < 2)
269 return errorSyntax(USAGE_BANDWIDTHCONTROL, "Too few parameters");
270 else if (a->argc > 7)
271 return errorSyntax(USAGE_BANDWIDTHCONTROL, "Too many parameters");
272
273 /* try to find the given machine */
274 CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
275 machine.asOutParam()), 1);
276
277 /* open a session for the VM (new or shared) */
278 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
279 SessionType_T st;
280 CHECK_ERROR_RET(a->session, COMGETTER(Type)(&st), 1);
281 bool fRunTime = (st == SessionType_Shared);
282
283 /* get the mutable session machine */
284 a->session->COMGETTER(Machine)(machine.asOutParam());
285 rc = machine->COMGETTER(BandwidthControl)(bwCtrl.asOutParam());
286 if (FAILED(rc)) goto leave;
287
288 if (!strcmp(a->argv[1], "add"))
289 {
290 if (fRunTime)
291 {
292 errorArgument("Bandwidth groups cannot be created while the VM is running\n");
293 goto leave;
294 }
295 rc = handleBandwidthControlAdd(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
296 }
297 else if (!strcmp(a->argv[1], "remove"))
298 {
299 if (fRunTime)
300 {
301 errorArgument("Bandwidth groups cannot be deleted while the VM is running\n");
302 goto leave;
303 }
304 rc = handleBandwidthControlRemove(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
305 }
306 else if (!strcmp(a->argv[1], "set"))
307 rc = handleBandwidthControlSet(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
308 else if (!strcmp(a->argv[1], "list"))
309 rc = handleBandwidthControlList(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
310 else
311 {
312 errorSyntax(USAGE_BANDWIDTHCONTROL, "Invalid parameter '%s'", Utf8Str(a->argv[1]).c_str());
313 rc = E_FAIL;
314 }
315
316 /* commit changes */
317 if (SUCCEEDED(rc))
318 CHECK_ERROR(machine, SaveSettings());
319
320leave:
321 /* it's important to always close sessions */
322 a->session->UnlockMachine();
323
324 return SUCCEEDED(rc) ? 0 : 1;
325}
326
327#endif /* !VBOX_ONLY_DOCS */
328
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette