63b785c3291332a86a9bc473e68f08121368898bvboxsync/* $Id$ */
63b785c3291332a86a9bc473e68f08121368898bvboxsync/** @file
63b785c3291332a86a9bc473e68f08121368898bvboxsync * VBoxManage - The bandwidth control related commands.
63b785c3291332a86a9bc473e68f08121368898bvboxsync */
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync/*
9d2d1455bc5c13147de944c100ef3a334ee6c452vboxsync * Copyright (C) 2006-2014 Oracle Corporation
63b785c3291332a86a9bc473e68f08121368898bvboxsync *
63b785c3291332a86a9bc473e68f08121368898bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
63b785c3291332a86a9bc473e68f08121368898bvboxsync * available from http://www.virtualbox.org. This file is free software;
63b785c3291332a86a9bc473e68f08121368898bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
63b785c3291332a86a9bc473e68f08121368898bvboxsync * General Public License (GPL) as published by the Free Software
63b785c3291332a86a9bc473e68f08121368898bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
63b785c3291332a86a9bc473e68f08121368898bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
63b785c3291332a86a9bc473e68f08121368898bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
63b785c3291332a86a9bc473e68f08121368898bvboxsync */
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync#ifndef VBOX_ONLY_DOCS
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync/*******************************************************************************
63b785c3291332a86a9bc473e68f08121368898bvboxsync* Header Files *
63b785c3291332a86a9bc473e68f08121368898bvboxsync*******************************************************************************/
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <VBox/com/com.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <VBox/com/array.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <VBox/com/ErrorInfo.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <VBox/com/errorprint.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <VBox/com/VirtualBox.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <iprt/path.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <iprt/param.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <iprt/string.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <iprt/ctype.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <iprt/stream.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <iprt/getopt.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include <VBox/log.h>
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync#include "VBoxManage.h"
63b785c3291332a86a9bc473e68f08121368898bvboxsyncusing namespace com;
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync// funcs
63b785c3291332a86a9bc473e68f08121368898bvboxsync///////////////////////////////////////////////////////////////////////////////
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync
af7209255033c3b77816f81ef6293ff8070ee156vboxsync/**
af7209255033c3b77816f81ef6293ff8070ee156vboxsync * Parses a string in the following format "n[k|m|g|K|M|G]". Stores the value
af7209255033c3b77816f81ef6293ff8070ee156vboxsync * of n expressed in bytes to *pLimit. k meas kilobit, while K means kilobyte.
af7209255033c3b77816f81ef6293ff8070ee156vboxsync *
af7209255033c3b77816f81ef6293ff8070ee156vboxsync * @returns Error message or NULL if successful.
af7209255033c3b77816f81ef6293ff8070ee156vboxsync * @param pcszLimit The string to parse.
af7209255033c3b77816f81ef6293ff8070ee156vboxsync * @param pLimit Where to store the result.
af7209255033c3b77816f81ef6293ff8070ee156vboxsync */
bf6e1749c204524a18da77c1d90449b10440c53dvboxsyncstatic const char *parseLimit(const char *pcszLimit, int64_t *pLimit)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync{
af7209255033c3b77816f81ef6293ff8070ee156vboxsync int iMultiplier = _1M;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync char *pszNext = NULL;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync int rc = RTStrToInt64Ex(pcszLimit, &pszNext, 10, pLimit);
af7209255033c3b77816f81ef6293ff8070ee156vboxsync
af7209255033c3b77816f81ef6293ff8070ee156vboxsync switch (rc)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case VINF_SUCCESS:
af7209255033c3b77816f81ef6293ff8070ee156vboxsync break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case VWRN_NUMBER_TOO_BIG:
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return "Limit is too big\n";
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case VWRN_TRAILING_CHARS:
af7209255033c3b77816f81ef6293ff8070ee156vboxsync switch (*pszNext)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case 'G': iMultiplier = _1G; break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case 'M': iMultiplier = _1M; break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case 'K': iMultiplier = _1K; break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case 'g': iMultiplier = 125000000; break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case 'm': iMultiplier = 125000; break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case 'k': iMultiplier = 125; break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync default: return "Invalid unit suffix. Valid suffixes are: k, m, g, K, M, G\n";
af7209255033c3b77816f81ef6293ff8070ee156vboxsync }
af7209255033c3b77816f81ef6293ff8070ee156vboxsync break;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case VWRN_TRAILING_SPACES:
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return "Trailing spaces in limit!\n";
af7209255033c3b77816f81ef6293ff8070ee156vboxsync case VERR_NO_DIGITS:
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return "No digits in limit specifier\n";
af7209255033c3b77816f81ef6293ff8070ee156vboxsync default:
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return "Invalid limit specifier\n";
af7209255033c3b77816f81ef6293ff8070ee156vboxsync }
10b09c6100b7c788267d108dbb1c68dde55b053avboxsync if (*pLimit < 0)
10b09c6100b7c788267d108dbb1c68dde55b053avboxsync return "Limit cannot be negative\n";
af7209255033c3b77816f81ef6293ff8070ee156vboxsync if (*pLimit > INT64_MAX / iMultiplier)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return "Limit is too big\n";
af7209255033c3b77816f81ef6293ff8070ee156vboxsync *pLimit *= iMultiplier;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return NULL;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync}
af7209255033c3b77816f81ef6293ff8070ee156vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync/**
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * Handles the 'bandwidthctl myvm add' sub-command.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @returns Exit code.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param a The handler argument package.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param bwCtrl Reference to the bandwidth control interface.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsyncstatic RTEXITCODE handleBandwidthControlAdd(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
63b785c3291332a86a9bc473e68f08121368898bvboxsync{
63b785c3291332a86a9bc473e68f08121368898bvboxsync HRESULT rc = S_OK;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync static const RTGETOPTDEF g_aBWCtlAddOptions[] =
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync { "--type", 't', RTGETOPT_REQ_STRING },
af7209255033c3b77816f81ef6293ff8070ee156vboxsync { "--limit", 'l', RTGETOPT_REQ_STRING }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync };
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync Bstr name(a->argv[2]);
69dcdc2c08e261f2e2d66eab1801aeb3560440f3vboxsync if (name.isEmpty())
69dcdc2c08e261f2e2d66eab1801aeb3560440f3vboxsync {
69dcdc2c08e261f2e2d66eab1801aeb3560440f3vboxsync errorArgument("Bandwidth group name must not be empty!\n");
69dcdc2c08e261f2e2d66eab1801aeb3560440f3vboxsync return RTEXITCODE_FAILURE;
69dcdc2c08e261f2e2d66eab1801aeb3560440f3vboxsync }
69dcdc2c08e261f2e2d66eab1801aeb3560440f3vboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync const char *pszType = NULL;
3861e08759f6f18d064369799b5542bb00432992vboxsync int64_t cMaxBytesPerSec = INT64_MAX;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync int c;
63b785c3291332a86a9bc473e68f08121368898bvboxsync RTGETOPTUNION ValueUnion;
63b785c3291332a86a9bc473e68f08121368898bvboxsync RTGETOPTSTATE GetState;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RTGetOptInit(&GetState, a->argc, a->argv, g_aBWCtlAddOptions,
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RT_ELEMENTS(g_aBWCtlAddOptions), 3, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync while ( SUCCEEDED(rc)
63b785c3291332a86a9bc473e68f08121368898bvboxsync && (c = RTGetOpt(&GetState, &ValueUnion)))
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
63b785c3291332a86a9bc473e68f08121368898bvboxsync switch (c)
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync case 't': // bandwidth group type
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
63b785c3291332a86a9bc473e68f08121368898bvboxsync if (ValueUnion.psz)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync pszType = ValueUnion.psz;
63b785c3291332a86a9bc473e68f08121368898bvboxsync else
63b785c3291332a86a9bc473e68f08121368898bvboxsync rc = E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync break;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync case 'l': // limit
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync if (ValueUnion.psz)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync const char *pcszError = parseLimit(ValueUnion.psz, &cMaxBytesPerSec);
af7209255033c3b77816f81ef6293ff8070ee156vboxsync if (pcszError)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync errorArgument(pcszError);
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return RTEXITCODE_FAILURE;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync }
af7209255033c3b77816f81ef6293ff8070ee156vboxsync }
af7209255033c3b77816f81ef6293ff8070ee156vboxsync else
af7209255033c3b77816f81ef6293ff8070ee156vboxsync rc = E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync break;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync default:
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync rc = E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync break;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync BandwidthGroupType_T enmType;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync if (!RTStrICmp(pszType, "disk"))
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync enmType = BandwidthGroupType_Disk;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync else if (!RTStrICmp(pszType, "network"))
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync enmType = BandwidthGroupType_Network;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync else
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync errorArgument("Invalid bandwidth group type\n");
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync return RTEXITCODE_FAILURE;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync }
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync
3861e08759f6f18d064369799b5542bb00432992vboxsync CHECK_ERROR2_RET(bwCtrl, CreateBandwidthGroup(name.raw(), enmType, (LONG64)cMaxBytesPerSec), RTEXITCODE_FAILURE);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync return RTEXITCODE_SUCCESS;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync}
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync/**
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * Handles the 'bandwidthctl myvm set' sub-command.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @returns Exit code.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param a The handler argument package.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param bwCtrl Reference to the bandwidth control interface.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsyncstatic RTEXITCODE handleBandwidthControlSet(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync{
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync HRESULT rc = S_OK;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync static const RTGETOPTDEF g_aBWCtlAddOptions[] =
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync { "--limit", 'l', RTGETOPT_REQ_STRING }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync };
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync Bstr name(a->argv[2]);
3861e08759f6f18d064369799b5542bb00432992vboxsync int64_t cMaxBytesPerSec = INT64_MAX;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync int c;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RTGETOPTUNION ValueUnion;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RTGETOPTSTATE GetState;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RTGetOptInit(&GetState, a->argc, a->argv, g_aBWCtlAddOptions,
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RT_ELEMENTS(g_aBWCtlAddOptions), 3, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync while ( SUCCEEDED(rc)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync && (c = RTGetOpt(&GetState, &ValueUnion)))
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync switch (c)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync case 'l': // limit
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync if (ValueUnion.psz)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync const char *pcszError = parseLimit(ValueUnion.psz, &cMaxBytesPerSec);
af7209255033c3b77816f81ef6293ff8070ee156vboxsync if (pcszError)
af7209255033c3b77816f81ef6293ff8070ee156vboxsync {
af7209255033c3b77816f81ef6293ff8070ee156vboxsync errorArgument(pcszError);
af7209255033c3b77816f81ef6293ff8070ee156vboxsync return RTEXITCODE_FAILURE;
af7209255033c3b77816f81ef6293ff8070ee156vboxsync }
af7209255033c3b77816f81ef6293ff8070ee156vboxsync }
af7209255033c3b77816f81ef6293ff8070ee156vboxsync else
af7209255033c3b77816f81ef6293ff8070ee156vboxsync rc = E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync break;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync default:
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
63b785c3291332a86a9bc473e68f08121368898bvboxsync errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
63b785c3291332a86a9bc473e68f08121368898bvboxsync rc = E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync break;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
12cbe990234bb127e4e4d2ab6c98511304193889vboxsync
af7209255033c3b77816f81ef6293ff8070ee156vboxsync if (cMaxBytesPerSec != INT64_MAX)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync ComPtr<IBandwidthGroup> bwGroup;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync CHECK_ERROR2_RET(bwCtrl, GetBandwidthGroup(name.raw(), bwGroup.asOutParam()), RTEXITCODE_FAILURE);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync if (SUCCEEDED(rc))
3861e08759f6f18d064369799b5542bb00432992vboxsync CHECK_ERROR2_RET(bwGroup, COMSETTER(MaxBytesPerSec)((LONG64)cMaxBytesPerSec), RTEXITCODE_FAILURE);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync return RTEXITCODE_SUCCESS;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync}
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync/**
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * Handles the 'bandwidthctl myvm remove' sub-command.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @returns Exit code.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param a The handler argument package.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param bwCtrl Reference to the bandwidth control interface.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsyncstatic RTEXITCODE handleBandwidthControlRemove(HandlerArg *a, ComPtr<IBandwidthControl> &bwCtrl)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync{
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync Bstr name(a->argv[2]);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync CHECK_ERROR2_RET(bwCtrl, DeleteBandwidthGroup(name.raw()), RTEXITCODE_FAILURE);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync return RTEXITCODE_SUCCESS;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync}
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync/**
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * Handles the 'bandwidthctl myvm list' sub-command.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @returns Exit code.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param a The handler argument package.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param bwCtrl Reference to the bandwidth control interface.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsyncstatic RTEXITCODE handleBandwidthControlList(HandlerArg *pArgs, ComPtr<IBandwidthControl> &rptrBWControl)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync{
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync static const RTGETOPTDEF g_aOptions[] =
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync };
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync VMINFO_DETAILS enmDetails = VMINFO_STANDARD;
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync int c;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RTGETOPTUNION ValueUnion;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RTGETOPTSTATE GetState;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, g_aOptions, RT_ELEMENTS(g_aOptions), 2 /*iArg*/, 0 /*fFlags*/);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync while ((c = RTGetOpt(&GetState, &ValueUnion)))
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync switch (c)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
23777a84b3e56937722404214b6064a797daf7b6vboxsync case 'M':
23777a84b3e56937722404214b6064a797daf7b6vboxsync enmDetails = VMINFO_MACHINEREADABLE;
23777a84b3e56937722404214b6064a797daf7b6vboxsync break;
23777a84b3e56937722404214b6064a797daf7b6vboxsync default:
23777a84b3e56937722404214b6064a797daf7b6vboxsync return errorGetOpt(USAGE_BANDWIDTHCONTROL, c, &ValueUnion);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
19a8f3f76b1488b15da70c1ed3796778a415634bvboxsync if (FAILED(showBandwidthGroups(rptrBWControl, enmDetails)))
19a8f3f76b1488b15da70c1ed3796778a415634bvboxsync return RTEXITCODE_FAILURE;
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync return RTEXITCODE_SUCCESS;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync}
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync/**
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * Handles the 'bandwidthctl' command.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @returns Exit code.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync * @param a The handler argument package.
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsyncint handleBandwidthControl(HandlerArg *a)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync{
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync int c = VERR_INTERNAL_ERROR; /* initialized to shut up gcc */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync HRESULT rc = S_OK;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync ComPtr<IMachine> machine;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync ComPtr<IBandwidthControl> bwCtrl;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync if (a->argc < 2)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync return errorSyntax(USAGE_BANDWIDTHCONTROL, "Too few parameters");
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync else if (a->argc > 7)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync return errorSyntax(USAGE_BANDWIDTHCONTROL, "Too many parameters");
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync /* try to find the given machine */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync machine.asOutParam()), 1);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync /* open a session for the VM (new or shared) */
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync SessionType_T st;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync CHECK_ERROR_RET(a->session, COMGETTER(Type)(&st), 1);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync bool fRunTime = (st == SessionType_Shared);
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync /* get the mutable session machine */
63b785c3291332a86a9bc473e68f08121368898bvboxsync a->session->COMGETTER(Machine)(machine.asOutParam());
63b785c3291332a86a9bc473e68f08121368898bvboxsync rc = machine->COMGETTER(BandwidthControl)(bwCtrl.asOutParam());
63b785c3291332a86a9bc473e68f08121368898bvboxsync if (FAILED(rc)) goto leave;
63b785c3291332a86a9bc473e68f08121368898bvboxsync
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync if (!strcmp(a->argv[1], "add"))
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync if (fRunTime)
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync errorArgument("Bandwidth groups cannot be created while the VM is running\n");
63b785c3291332a86a9bc473e68f08121368898bvboxsync goto leave;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync rc = handleBandwidthControlAdd(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync else if (!strcmp(a->argv[1], "remove"))
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync if (fRunTime)
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync errorArgument("Bandwidth groups cannot be deleted while the VM is running\n");
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync goto leave;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync rc = handleBandwidthControlRemove(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync else if (!strcmp(a->argv[1], "set"))
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync rc = handleBandwidthControlSet(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync else if (!strcmp(a->argv[1], "list"))
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync rc = handleBandwidthControlList(a, bwCtrl) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync else
63b785c3291332a86a9bc473e68f08121368898bvboxsync {
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync errorSyntax(USAGE_BANDWIDTHCONTROL, "Invalid parameter '%s'", Utf8Str(a->argv[1]).c_str());
e67a57a63d60b971a077d325eb0872a3ccde94a4vboxsync rc = E_FAIL;
63b785c3291332a86a9bc473e68f08121368898bvboxsync }
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync /* commit changes */
63b785c3291332a86a9bc473e68f08121368898bvboxsync if (SUCCEEDED(rc))
63b785c3291332a86a9bc473e68f08121368898bvboxsync CHECK_ERROR(machine, SaveSettings());
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsyncleave:
63b785c3291332a86a9bc473e68f08121368898bvboxsync /* it's important to always close sessions */
63b785c3291332a86a9bc473e68f08121368898bvboxsync a->session->UnlockMachine();
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync return SUCCEEDED(rc) ? 0 : 1;
63b785c3291332a86a9bc473e68f08121368898bvboxsync}
63b785c3291332a86a9bc473e68f08121368898bvboxsync
63b785c3291332a86a9bc473e68f08121368898bvboxsync#endif /* !VBOX_ONLY_DOCS */
63b785c3291332a86a9bc473e68f08121368898bvboxsync