From b64c353863d171e078da512b88b19f3458775c6b Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 25 Jan 2006 09:46:22 +0000 Subject: [PATCH] add xshandle checks, fix virsh grammar --- ChangeLog | 6 ++ docs/APIchunk0.html | 2 +- docs/APIchunk1.html | 2 +- docs/APIchunk2.html | 2 +- docs/APIconstructors.html | 2 +- docs/APIfiles.html | 2 +- docs/APIfunctions.html | 2 +- docs/APIsymbols.html | 2 +- docs/html/book1.html | 2 +- docs/html/index.html | 2 +- docs/html/libvir-lib.html | 2 +- docs/html/libvir-libvir.html | 4 +- docs/index.html | 3 +- src/libvir.c | 55 ++++++++-------- src/libvir_sym.version | 2 + src/virsh.c | 117 +++++++++++++++++++++++++---------- 16 files changed, 135 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c9016a407..67b1137f0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Jan 24 11:44:53 CET 2006 Karel Zak + + * src/libvir_sym.version: add virDeomainRestore and virDomainSave + * src/virsh.c: support '=' in options, fix command grammar + * src/libvir.c: add conn->xshandle checks + Tue Jan 24 14:09:37 CET 2006 Daniel Veillard * src/libvir.c: Karel pointed out handle was lost in diff --git a/docs/APIchunk0.html b/docs/APIchunk0.html index 0e4e12d153..373d5d78ef 100644 --- a/docs/APIchunk0.html +++ b/docs/APIchunk0.html @@ -1,6 +1,6 @@ -API Alphabetic Index A-f for libvir

API Alphabetic Index A-f for libvir

A-f +API Alphabetic Index A-f for libvir

API Alphabetic Index A-f for libvir

A-f g-r s-z

Letter A:

ABI
_virDomainInfo
diff --git a/docs/APIchunk1.html b/docs/APIchunk1.html index 769fd43a61..e1628cbb7c 100644 --- a/docs/APIchunk1.html +++ b/docs/APIchunk1.html @@ -1,6 +1,6 @@ -API Alphabetic Index g-r for libvir

API Alphabetic Index g-r for libvir

A-f +API Alphabetic Index g-r for libvir

API Alphabetic Index g-r for libvir

A-f g-r s-z

Letter g:

general
virDomainShutdown
diff --git a/docs/APIchunk2.html b/docs/APIchunk2.html index 43e4e64dd1..e87e8c1658 100644 --- a/docs/APIchunk2.html +++ b/docs/APIchunk2.html @@ -1,6 +1,6 @@ -API Alphabetic Index s-z for libvir

API Alphabetic Index s-z for libvir

A-f +API Alphabetic Index s-z for libvir

API Alphabetic Index s-z for libvir

A-f g-r s-z

Letter s:

same
virDomainGetName
diff --git a/docs/APIconstructors.html b/docs/APIconstructors.html index 7874c394f6..fe3b2e18d6 100644 --- a/docs/APIconstructors.html +++ b/docs/APIconstructors.html @@ -1,6 +1,6 @@ -List of constructors for libvir

List of constructors for libvir

Type unsigned int:

virDomainGetID
+List of constructors for libvir

List of constructors for libvir

Type unsigned int:

virDomainGetID

Type unsigned long:

virDomainGetMaxMemory

Type virConnectPtr:

virConnectOpen
virConnectOpenReadOnly
diff --git a/docs/APIfiles.html b/docs/APIfiles.html index 12606aa564..04f2e9e76f 100644 --- a/docs/APIfiles.html +++ b/docs/APIfiles.html @@ -1,6 +1,6 @@ -List of Symbols per Module for libvir

List of Symbols per Module for libvir

Module libvir:

LIBVIR_VERSION_NUMBER
+List of Symbols per Module for libvir

List of Symbols per Module for libvir

Module libvir:

LIBVIR_VERSION_NUMBER
VIR_DEVICE_DEFAULT
VIR_DEVICE_RO
VIR_DEVICE_RW
diff --git a/docs/APIfunctions.html b/docs/APIfunctions.html index ddfd268a73..2d2d4aa7ec 100644 --- a/docs/APIfunctions.html +++ b/docs/APIfunctions.html @@ -1,6 +1,6 @@ -List of function manipulating types in libvir

List of function manipulating types in libvir

Type int *:

virConnectListDomains
+List of function manipulating types in libvir

List of function manipulating types in libvir

Type int *:

virConnectListDomains

Type unsigned int:

virDomainCreateLinux

Type unsigned long:

virDomainCreateLinux
virDomainSetMaxMemory
diff --git a/docs/APIsymbols.html b/docs/APIsymbols.html index 0102184f56..0758d2a51c 100644 --- a/docs/APIsymbols.html +++ b/docs/APIsymbols.html @@ -1,6 +1,6 @@ -Alphabetic List of Symbols in libvir

Alphabetic List of Symbols in libvir

Letter L:

LIBVIR_VERSION_NUMBER
+Alphabetic List of Symbols in libvir

Alphabetic List of Symbols in libvir

Letter L:

LIBVIR_VERSION_NUMBER

Letter V:

VIR_DEVICE_DEFAULT
VIR_DEVICE_RO
VIR_DEVICE_RW
diff --git a/docs/html/book1.html b/docs/html/book1.html index 60519eb0b3..b612a9dc14 100644 --- a/docs/html/book1.html +++ b/docs/html/book1.html @@ -1,3 +1,3 @@ -Reference Manual for libvir

Reference Manual for libvir

Table of Contents

  • libvir: core interfaces for the libvir library

+Reference Manual for libvir

Reference Manual for libvir

Table of Contents

  • libvir: core interfaces for the libvir library

diff --git a/docs/html/index.html b/docs/html/index.html index 60519eb0b3..b612a9dc14 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -1,3 +1,3 @@ -Reference Manual for libvir

Reference Manual for libvir

Table of Contents

  • libvir: core interfaces for the libvir library

+Reference Manual for libvir

Reference Manual for libvir

Table of Contents

  • libvir: core interfaces for the libvir library

diff --git a/docs/html/libvir-lib.html b/docs/html/libvir-lib.html index 60519eb0b3..b612a9dc14 100644 --- a/docs/html/libvir-lib.html +++ b/docs/html/libvir-lib.html @@ -1,3 +1,3 @@ -Reference Manual for libvir

Reference Manual for libvir

Table of Contents

  • libvir: core interfaces for the libvir library

+Reference Manual for libvir

Reference Manual for libvir

Table of Contents

  • libvir: core interfaces for the libvir library

diff --git a/docs/html/libvir-libvir.html b/docs/html/libvir-libvir.html index 3cca872e67..8b32257b35 100644 --- a/docs/html/libvir-libvir.html +++ b/docs/html/libvir-libvir.html @@ -1,6 +1,6 @@ -Module libvir from libvir

Module libvir from libvir

Provides the interfaces of the libvir library to handle Xen domains from a process running in domain 0

Table of Contents

#define LIBVIR_VERSION_NUMBER
Structure virConnect
struct _virConnect +Module libvir from libvir

Module libvir from libvir

Provides the interfaces of the libvir library to handle Xen domains from a process running in domain 0

Table of Contents

#define LIBVIR_VERSION_NUMBER
Structure virConnect
struct _virConnect The content of this structure is not made public by the API.
Typedef virConnect * virConnectPtr
 
Enum virDeviceMode
@@ -138,4 +138,4 @@ The content of this structure is not made public by the API.
 

Suspends an active domain, the process is frozen without further access to CPU resources and I/O but the memory used by the domain at the hypervisor level will stay allocated. Use virDomainResume() to reactivate the domain. This function may requires priviledged access.

domain:a domain object
Returns:0 in case of success and -1 in case of failure.

Function: virGetVersion

int	virGetVersion			(unsigned long * libVer, 
const char * type,
unsigned long * typeVer)

Provides two information back, @libVer is the version of the library while @typeVer will be the version of the hypervisor type @type against which the library was compiled. If @type is NULL, "Xen" is assumed, if @type is unknown or not availble, an error code will be returned and @typeVer will be 0.

-
libVer:return value for the library version (OUT)
type:hypervisor type
typeVer:return value for the version of the hypervisor (OUT)
Returns:-1 in case of failure, 0 otherwise, and values for @libVer and @typeVer have the format major * 1,000,000 + minor * 1,000 + release.

+
libVer:return value for the library version (OUT)
type:hypervisor type
typeVer:return value for the version of the hypervisor (OUT)
Returns:-1 in case of failure, 0 otherwise, and values for @libVer and @typeVer have the format major * 1,000,000 + minor * 1,000 + release.

diff --git a/docs/index.html b/docs/index.html index 53cdd03d09..d2c8a38864 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,7 +1,8 @@ - + + the virtualization API diff --git a/src/libvir.c b/src/libvir.c index 23ec2587b2..4fd1fe0a06 100644 --- a/src/libvir.c +++ b/src/libvir.c @@ -344,14 +344,12 @@ virConnectListDomains(virConnectPtr conn, int *ids, int maxids) { ret = -1; goto done; } - if (virConnectCheckStoreID(conn, (int) id) < 0) continue; ids[ret++] = (int) id; } } - done: if ((t != NULL) && (conn->xshandle != NULL)) xs_transaction_end(conn->xshandle, t, 0); @@ -602,6 +600,8 @@ virDomainGetVMInfo(virDomainPtr domain, const char *vm, if (!VIR_IS_CONNECTED_DOMAIN(domain)) return(NULL); + if (domain->conn->xshandle==NULL) + return(NULL); snprintf(s, 255, "%s/%s", vm, name); s[255] = 0; @@ -721,33 +721,34 @@ virDomainLookupByName(virConnectPtr conn, const char *name) { } /* then though the XenStore */ + if (conn->xshandle != NULL) { + t = xs_transaction_start(conn->xshandle); + if (t == NULL) + goto done; - t = xs_transaction_start(conn->xshandle); - if (t == NULL) - goto done; + idlist = xs_directory(conn->xshandle, t, "/local/domain", &num); + if (idlist == NULL) + goto done; - idlist = xs_directory(conn->xshandle, t, "/local/domain", &num); - if (idlist == NULL) - goto done; - - for (i = 0;i < num;i++) { - id = strtol(idlist[i], &endptr, 10); - if ((endptr == idlist[i]) || (*endptr != 0)) { - goto done; - } - if (virConnectCheckStoreID(conn, (int) id) < 0) - continue; - snprintf(prop, 199, "/local/domain/%s/name", idlist[i]); - prop[199] = 0; - tmp = xs_read(conn->xshandle, t, prop, &len); - if (tmp != NULL) { - found = !strcmp(name, tmp); - free(tmp); - if (found) - break; - } + for (i = 0;i < num;i++) { + id = strtol(idlist[i], &endptr, 10); + if ((endptr == idlist[i]) || (*endptr != 0)) { + goto done; + } + if (virConnectCheckStoreID(conn, (int) id) < 0) + continue; + snprintf(prop, 199, "/local/domain/%s/name", idlist[i]); + prop[199] = 0; + tmp = xs_read(conn->xshandle, t, prop, &len); + if (tmp != NULL) { + found = !strcmp(name, tmp); + free(tmp); + if (found) + break; + } + } + path = xs_get_domain_path(conn->xshandle, (unsigned int) id); } - path = xs_get_domain_path(conn->xshandle, (unsigned int) id); do_found: @@ -1128,6 +1129,8 @@ virDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) { return(-1); if (domain->conn->flags & VIR_CONNECT_RO) return(-1); + if (domain->conn->xshandle==NULL) + return(-1); ret = xenHypervisorSetMaxMemory(domain->conn->handle, domain->handle, memory); if (ret < 0) diff --git a/src/libvir_sym.version b/src/libvir_sym.version index 534e851537..271048892b 100644 --- a/src/libvir_sym.version +++ b/src/libvir_sym.version @@ -18,7 +18,9 @@ virDomainGetXMLDesc; virDomainLookupByID; virDomainLookupByName; + virDomainRestore; virDomainResume; + virDomainSave; virDomainSetMaxMemory; virDomainShutdown; virDomainSuspend; diff --git a/src/virsh.c b/src/virsh.c index 08ab7226bc..673fff234f 100644 --- a/src/virsh.c +++ b/src/virsh.c @@ -70,13 +70,10 @@ typedef enum { * int_option = --optionname * string_option = --optionname * - * keyword = [a-zA-Z] - * number = [0-9]+ - * string = [^[:blank:]] | "[[:alnum:]]"$ + * keyword = [a-zA-Z] + * number = [0-9]+ + * string = [^[:blank:]] | "[[:alnum:]]"$ * - * Note: only one token per command is supported. It means: - * "command aaa bbb" is unsupported and you have to use any option, like: - * "command --aaa bbb" or whatever. */ /* @@ -323,7 +320,7 @@ static vshCmdInfo info_dstate[] = { }; static vshCmdOptDef opts_dstate[] = { - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -359,7 +356,7 @@ static vshCmdInfo info_suspend[] = { }; static vshCmdOptDef opts_suspend[] = { - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -390,15 +387,15 @@ cmdSuspend(vshControl *ctl, vshCmd *cmd) { * "save" command */ static vshCmdInfo info_save[] = { - { "syntax", "save to " }, + { "syntax", "save " }, { "help", "save a domain state to a file" }, { "desc", "Save a running domain." }, { NULL, NULL } }; static vshCmdOptDef opts_save[] = { - { "file", VSH_OT_STRING, VSH_OFLAG_REQ, "where to save the data" }, - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "file", VSH_OT_DATA, VSH_OFLAG_REQ, "where to save the data" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -407,14 +404,12 @@ cmdSave(vshControl *ctl, vshCmd *cmd) { virDomainPtr dom; char *name; char *to; - int found; int ret = TRUE; if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) return FALSE; - to = vshCommandOptString(cmd, "file", &found); - if (!found) + if (!(to = vshCommandOptString(cmd, "file", NULL))) return FALSE; if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &name))) @@ -442,7 +437,7 @@ static vshCmdInfo info_restore[] = { }; static vshCmdOptDef opts_restore[] = { - { "file", VSH_OT_DATA, 0, "the state to restore" }, + { "file", VSH_OT_DATA, VSH_OFLAG_REQ, "the state to restore" }, { NULL, 0, 0, NULL } }; @@ -479,7 +474,7 @@ static vshCmdInfo info_resume[] = { }; static vshCmdOptDef opts_resume[] = { - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -517,7 +512,7 @@ static vshCmdInfo info_shutdown[] = { }; static vshCmdOptDef opts_shutdown[] = { - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -555,7 +550,7 @@ static vshCmdInfo info_destroy[] = { }; static vshCmdOptDef opts_destroy[] = { - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -593,7 +588,7 @@ static vshCmdInfo info_dinfo[] = { }; static vshCmdOptDef opts_dinfo[] = { - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -659,7 +654,7 @@ static vshCmdInfo info_dumpxml[] = { }; static vshCmdOptDef opts_dumpxml[] = { - { "domain", VSH_OT_DATA, 0, "domain name or id" }, + { "domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name or id" }, { NULL, 0, 0, NULL } }; @@ -697,7 +692,7 @@ static vshCmdInfo info_nameof[] = { }; static vshCmdOptDef opts_nameof[] = { - { "id", VSH_OT_DATA, 0, "domain Id" }, + { "id", VSH_OT_DATA, VSH_OFLAG_REQ, "domain Id" }, { NULL, 0, 0, NULL } }; @@ -733,7 +728,7 @@ static vshCmdInfo info_idof[] = { }; static vshCmdOptDef opts_idof[] = { - { "name", VSH_OT_DATA, 0, "domain name" }, + { "name", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name" }, { NULL, 0, 0, NULL } }; @@ -902,15 +897,54 @@ vshCmddefGetOption(vshCmdDef *cmd, const char *name) { } static vshCmdOptDef * -vshCmddefGetData(vshCmdDef *cmd) { +vshCmddefGetData(vshCmdDef *cmd, int data_ct) { vshCmdOptDef *opt; - for (opt = cmd->opts; opt && opt->name; opt++) - if (opt->type==VSH_OT_DATA) - return opt; + for (opt = cmd->opts; opt && opt->name; opt++) { + if (opt->type==VSH_OT_DATA) { + if (data_ct==0) + return opt; + else + data_ct--; + } + } return NULL; } +/* + * Checks for required options + */ +static int +vshCommandCheckOpts(vshControl *ctl, vshCmd *cmd) +{ + vshCmdDef *def = cmd->def; + vshCmdOptDef *d; + int err=0; + + for (d = def->opts; d && d->name; d++) { + if (d->flag & VSH_OFLAG_REQ) { + vshCmdOpt *o = cmd->opts; + int ok=0; + + while(o && ok==0) { + if (o->def == d) + ok=1; + o = o->next; + } + if (!ok) { + vshError(ctl, FALSE, + d->type == VSH_OT_DATA ? + "command '%s' requires <%s> option" : + "command '%s' requires --%s option", + def->name, d->name); + err = 1; + } + + } + } + return !err; +} + static vshCmdDef * vshCmddefSearch(const char *cmdname) { vshCmdDef *c; @@ -1040,7 +1074,8 @@ vshCommandOptString(vshCmd *cmd, const char *name, int *found) { vshCmdOpt *arg = vshCommandOpt(cmd, name); if (found) *found = arg ? TRUE : FALSE; - return arg ? arg->data : NULL; + + return arg && arg->data && *arg->data ? arg->data : NULL; } /* @@ -1051,6 +1086,7 @@ vshCommandOptBool(vshCmd *cmd, const char *name) { return vshCommandOpt(cmd, name) ? TRUE : FALSE; } + static virDomainPtr vshCommandOptDomain(vshControl *ctl, vshCmd *cmd, const char *optname, char **name) { virDomainPtr dom = NULL; @@ -1062,18 +1098,23 @@ vshCommandOptDomain(vshControl *ctl, vshCmd *cmd, const char *optname, char **na return NULL; } + vshPrint(ctl, VSH_DEBUG5, "%s: found option <%s>: %s\n", cmd->def->name, optname, n); + if (name) *name = n; /* try it by ID */ id = (int) strtol(n, &end, 10); - if (id >= 0 && end && *end=='\0') + if (id >= 0 && end && *end=='\0') { + vshPrint(ctl, VSH_DEBUG5, "%s: <%s> seems like domain ID\n", cmd->def->name, optname); dom = virDomainLookupByID(ctl->conn, id); + } /* try it by NAME */ - if (!dom) + if (!dom) { + vshPrint(ctl, VSH_DEBUG5, "%s: <%s> tring as domain NAME\n", cmd->def->name, optname); dom = virDomainLookupByName(ctl->conn, n); - + } if (!dom) vshError(ctl, FALSE, "failed to get domain '%s'", n); @@ -1143,7 +1184,13 @@ vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res) { /* end of token is blank space or ';' */ if ((quote==FALSE && isblank((unsigned char) *p)) || *p==';') break; - + + /* end of option name could be '=' */ + if (tk==VSH_TK_OPTION && *p=='=') { + p++; /* skip '=' */ + break; + } + if (tk==VSH_TK_NONE) { if (*p=='-' && *(p+1)=='-' && *(p+2) && isalnum((unsigned char) *(p+2))) { tk = VSH_TK_OPTION; @@ -1204,6 +1251,7 @@ vshCommandParse(vshControl *ctl, char *cmdstr) { vshCmdOpt *last = NULL; vshCmdDef *cmd = NULL; int tk = VSH_TK_NONE; + int data_ct = 0; first = NULL; @@ -1262,7 +1310,7 @@ vshCommandParse(vshControl *ctl, char *cmdstr) { } } } else if (tk==VSH_TK_DATA) { - if (!(opt = vshCmddefGetData(cmd))) { + if (!(opt = vshCmddefGetData(cmd, data_ct++))) { vshError(ctl, FALSE, "unexpected data '%s'", tkdata); @@ -1301,6 +1349,9 @@ vshCommandParse(vshControl *ctl, char *cmdstr) { c->def = cmd; c->next = NULL; + if (!vshCommandCheckOpts(ctl, c)) + goto syntaxError; + if (!ctl->cmd) ctl->cmd = c; if (clast) @@ -1619,7 +1670,7 @@ vshParseArgv(vshControl *ctl, int argc, char **argv) { if (argc < 2) return TRUE; - /* look for begin of command, for example: + /* look for begin of the command, for example: * ./virsh --debug 5 -q command --cmdoption * <--- ^ ---> * getopt() stuff | command suff