mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
Added convenience virsh command for creating pools/volumes without XML
This commit is contained in:
parent
816fd02876
commit
f43e709842
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
Wed Feb 20 10:23:27 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* src/virsh.c: Added convenience methods for creating pools
|
||||||
|
and volumes without XML
|
||||||
|
* src/buf.c, src/buf.h, src/libvirt_sym.version: Export the
|
||||||
|
virBuffer* methods to virsh
|
||||||
|
* src/xend_internal.c, src/xm_intenral.c, src/xml.c,
|
||||||
|
src/qemu_conf.c
|
||||||
|
* src/util.c, src/util.h: Export virStrToLong_ull to virsh
|
||||||
|
|
||||||
Wed Feb 20 10:22:27 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
Wed Feb 20 10:22:27 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* src/virsh.c: Added commands for all storage APIs
|
* src/virsh.c: Added commands for all storage APIs
|
||||||
|
11
src/buf.c
11
src/buf.c
@ -61,7 +61,7 @@ virBufferGrow(virBufferPtr buf, unsigned int len)
|
|||||||
* Returns 0 successful, -1 in case of internal or API error.
|
* Returns 0 successful, -1 in case of internal or API error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virBufferAdd(virBufferPtr buf, const char *str, int len)
|
__virBufferAdd(virBufferPtr buf, const char *str, int len)
|
||||||
{
|
{
|
||||||
unsigned int needSize;
|
unsigned int needSize;
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ virBufferAdd(virBufferPtr buf, const char *str, int len)
|
|||||||
* Returns 0 if successful, -1 in the case of error.
|
* Returns 0 if successful, -1 in the case of error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virBufferAddChar (virBufferPtr buf, char c)
|
__virBufferAddChar (virBufferPtr buf, char c)
|
||||||
{
|
{
|
||||||
unsigned int needSize;
|
unsigned int needSize;
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ virBufferContentAndFree (virBufferPtr buf)
|
|||||||
* Returns 0 successful, -1 in case of internal or API error.
|
* Returns 0 successful, -1 in case of internal or API error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virBufferVSprintf(virBufferPtr buf, const char *format, ...)
|
__virBufferVSprintf(virBufferPtr buf, const char *format, ...)
|
||||||
{
|
{
|
||||||
int size, count, grow_size;
|
int size, count, grow_size;
|
||||||
va_list locarg, argptr;
|
va_list locarg, argptr;
|
||||||
@ -198,6 +198,11 @@ virBufferVSprintf(virBufferPtr buf, const char *format, ...)
|
|||||||
if ((format == NULL) || (buf == NULL)) {
|
if ((format == NULL) || (buf == NULL)) {
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buf->size == 0 &&
|
||||||
|
virBufferGrow(buf, 100) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
size = buf->size - buf->use - 1;
|
size = buf->size - buf->use - 1;
|
||||||
va_start(argptr, format);
|
va_start(argptr, format);
|
||||||
va_copy(locarg, argptr);
|
va_copy(locarg, argptr);
|
||||||
|
12
src/buf.h
12
src/buf.h
@ -29,15 +29,19 @@ struct _virBuffer {
|
|||||||
virBufferPtr virBufferNew(unsigned int size);
|
virBufferPtr virBufferNew(unsigned int size);
|
||||||
void virBufferFree(virBufferPtr buf);
|
void virBufferFree(virBufferPtr buf);
|
||||||
char *virBufferContentAndFree(virBufferPtr buf);
|
char *virBufferContentAndFree(virBufferPtr buf);
|
||||||
int virBufferAdd(virBufferPtr buf, const char *str, int len);
|
int __virBufferAdd(virBufferPtr buf, const char *str, int len);
|
||||||
int virBufferAddChar(virBufferPtr buf, char c);
|
int __virBufferAddChar(virBufferPtr buf, char c);
|
||||||
int virBufferVSprintf(virBufferPtr buf, const char *format, ...)
|
int __virBufferVSprintf(virBufferPtr buf, const char *format, ...)
|
||||||
ATTRIBUTE_FORMAT(printf, 2, 3);
|
ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||||
int virBufferStrcat(virBufferPtr buf, ...);
|
int virBufferStrcat(virBufferPtr buf, ...);
|
||||||
int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str);
|
int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str);
|
||||||
int virBufferURIEncodeString (virBufferPtr buf, const char *str);
|
int virBufferURIEncodeString (virBufferPtr buf, const char *str);
|
||||||
|
|
||||||
#define virBufferAddLit(buf_, literal_string_) \
|
#define virBufferAddLit(buf_, literal_string_) \
|
||||||
virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)
|
__virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)
|
||||||
|
|
||||||
|
#define virBufferAdd(b,s,l) __virBufferAdd((b),(s),(l))
|
||||||
|
#define virBufferAddChar(b,c) __virBufferAddChar((b),(c))
|
||||||
|
#define virBufferVSprintf(b,f,...) __virBufferVSprintf((b),(f), __VA_ARGS__)
|
||||||
|
|
||||||
#endif /* __VIR_BUFFER_H__ */
|
#endif /* __VIR_BUFFER_H__ */
|
||||||
|
@ -178,6 +178,11 @@
|
|||||||
|
|
||||||
__virFileReadAll;
|
__virFileReadAll;
|
||||||
__virStrToLong_i;
|
__virStrToLong_i;
|
||||||
|
__virStrToLong_ull;
|
||||||
|
|
||||||
|
__virBufferVSprintf;
|
||||||
|
__virBufferAdd;
|
||||||
|
__virBufferAddChar;
|
||||||
|
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
@ -2818,7 +2818,7 @@ char *qemudGenerateXML(virConnectPtr conn,
|
|||||||
if (virBufferAddLit(buf, " <readonly/>\n") < 0)
|
if (virBufferAddLit(buf, " <readonly/>\n") < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
if (virBufferVSprintf(buf, " </disk>\n") < 0)
|
if (virBufferAddLit(buf, " </disk>\n") < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
disk = disk->next;
|
disk = disk->next;
|
||||||
@ -2889,7 +2889,7 @@ char *qemudGenerateXML(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virBufferVSprintf(buf, " </interface>\n") < 0)
|
if (virBufferAddLit(buf, " </interface>\n") < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
net = net->next;
|
net = net->next;
|
||||||
@ -2974,7 +2974,7 @@ char *qemudGenerateNetworkXML(virConnectPtr conn,
|
|||||||
if (!buf)
|
if (!buf)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
if (virBufferVSprintf(buf, "<network>\n") < 0)
|
if (virBufferAddLit(buf, "<network>\n") < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
if (virBufferVSprintf(buf, " <name>%s</name>\n", def->name) < 0)
|
if (virBufferVSprintf(buf, " <name>%s</name>\n", def->name) < 0)
|
||||||
|
@ -613,7 +613,7 @@ virStrToLong_ll(char const *s, char **end_ptr, int base, long long *result)
|
|||||||
|
|
||||||
/* Just like virStrToLong_i, above, but produce an "unsigned long long" value. */
|
/* Just like virStrToLong_i, above, but produce an "unsigned long long" value. */
|
||||||
int
|
int
|
||||||
virStrToLong_ull(char const *s, char **end_ptr, int base, unsigned long long *result)
|
__virStrToLong_ull(char const *s, char **end_ptr, int base, unsigned long long *result)
|
||||||
{
|
{
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -70,9 +70,10 @@ int virStrToLong_ll(char const *s,
|
|||||||
char **end_ptr,
|
char **end_ptr,
|
||||||
int base,
|
int base,
|
||||||
long long *result);
|
long long *result);
|
||||||
int virStrToLong_ull(char const *s,
|
int __virStrToLong_ull(char const *s,
|
||||||
char **end_ptr,
|
char **end_ptr,
|
||||||
int base,
|
int base,
|
||||||
unsigned long long *result);
|
unsigned long long *result);
|
||||||
|
#define virStrToLong_ull(s,e,b,r) __virStrToLong_ull((s),(e),(b),(r))
|
||||||
|
|
||||||
#endif /* __VIR_UTIL_H__ */
|
#endif /* __VIR_UTIL_H__ */
|
||||||
|
347
src/virsh.c
347
src/virsh.c
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "buf.h"
|
||||||
|
|
||||||
static char *progname;
|
static char *progname;
|
||||||
|
|
||||||
@ -240,6 +241,9 @@ static vshCmdOpt *vshCommandOpt(vshCmd * cmd, const char *name);
|
|||||||
static int vshCommandOptInt(vshCmd * cmd, const char *name, int *found);
|
static int vshCommandOptInt(vshCmd * cmd, const char *name, int *found);
|
||||||
static char *vshCommandOptString(vshCmd * cmd, const char *name,
|
static char *vshCommandOptString(vshCmd * cmd, const char *name,
|
||||||
int *found);
|
int *found);
|
||||||
|
#if 0
|
||||||
|
static int vshCommandOptStringList(vshCmd * cmd, const char *name, char ***data);
|
||||||
|
#endif
|
||||||
static int vshCommandOptBool(vshCmd * cmd, const char *name);
|
static int vshCommandOptBool(vshCmd * cmd, const char *name);
|
||||||
|
|
||||||
#define VSH_BYID (1 << 1)
|
#define VSH_BYID (1 << 1)
|
||||||
@ -2851,6 +2855,100 @@ cmdPoolCreate(vshControl * ctl, vshCmd * cmd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "pool-create-as" command
|
||||||
|
*/
|
||||||
|
static vshCmdInfo info_pool_create_as[] = {
|
||||||
|
{"syntax", "pool-create-as <name> <type>"},
|
||||||
|
{"help", gettext_noop("create a pool from a set of args")},
|
||||||
|
{"desc", gettext_noop("Create a pool.")},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static vshCmdOptDef opts_pool_create_as[] = {
|
||||||
|
{"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name of the pool")},
|
||||||
|
{"type", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("type of the pool")},
|
||||||
|
{"source-host", VSH_OT_DATA, 0, gettext_noop("source-host for underlying storage")},
|
||||||
|
{"source-path", VSH_OT_DATA, 0, gettext_noop("source path for underlying storage")},
|
||||||
|
{"source-dev", VSH_OT_DATA, 0, gettext_noop("source device for underlying storage")},
|
||||||
|
{"target", VSH_OT_DATA, 0, gettext_noop("target for underlying storage")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdPoolCreateAs(vshControl * ctl, vshCmd * cmd)
|
||||||
|
{
|
||||||
|
virStoragePoolPtr pool;
|
||||||
|
int found;
|
||||||
|
char *name, *type, *srcHost, *srcPath, *srcDev, *target;
|
||||||
|
virBuffer buf;
|
||||||
|
|
||||||
|
memset(&buf, 0, sizeof(buf));
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
name = vshCommandOptString(cmd, "name", &found);
|
||||||
|
if (!found)
|
||||||
|
goto cleanup;
|
||||||
|
type = vshCommandOptString(cmd, "type", &found);
|
||||||
|
if (!found)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
srcHost = vshCommandOptString(cmd, "source-host", &found);
|
||||||
|
srcPath = vshCommandOptString(cmd, "source-path", &found);
|
||||||
|
srcDev = vshCommandOptString(cmd, "source-dev", &found);
|
||||||
|
target = vshCommandOptString(cmd, "target", &found);
|
||||||
|
|
||||||
|
if (virBufferVSprintf(&buf, "<pool type='%s'>\n", type) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferVSprintf(&buf, " <name>%s</name>\n", name) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcHost || srcPath || srcDev) {
|
||||||
|
if (virBufferAddLit(&buf, " <source>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcHost &&
|
||||||
|
virBufferVSprintf(&buf, " <host name='%s'>\n", srcHost) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcPath &&
|
||||||
|
virBufferVSprintf(&buf, " <dir path='%s'/>\n", srcPath) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcDev &&
|
||||||
|
virBufferVSprintf(&buf, " <device path='%s'/>\n", srcDev) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virBufferAddLit(&buf, " </source>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (target) {
|
||||||
|
if (virBufferAddLit(&buf, " <target>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferVSprintf(&buf, " <path>%s</path>\n", target) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferAddLit(&buf, " </target>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (virBufferAddLit(&buf, "</pool>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
pool = virStoragePoolCreateXML(ctl->conn, buf.content, 0);
|
||||||
|
free (buf.content);
|
||||||
|
|
||||||
|
if (pool != NULL) {
|
||||||
|
vshPrint(ctl, _("Pool %s created\n"), name);
|
||||||
|
virStoragePoolFree(pool);
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
vshError(ctl, FALSE, _("Failed to create pool %s"), name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(buf.content);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "pool-define" command
|
* "pool-define" command
|
||||||
@ -2900,6 +2998,101 @@ cmdPoolDefine(vshControl * ctl, vshCmd * cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "pool-define-as" command
|
||||||
|
*/
|
||||||
|
static vshCmdInfo info_pool_define_as[] = {
|
||||||
|
{"syntax", "pool-define-as <name> <type>"},
|
||||||
|
{"help", gettext_noop("define a pool from a set of args")},
|
||||||
|
{"desc", gettext_noop("Define a pool.")},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static vshCmdOptDef opts_pool_define_as[] = {
|
||||||
|
{"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name of the pool")},
|
||||||
|
{"type", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("type of the pool")},
|
||||||
|
{"source-host", VSH_OT_DATA, 0, gettext_noop("source-host for underlying storage")},
|
||||||
|
{"source-path", VSH_OT_DATA, 0, gettext_noop("source path for underlying storage")},
|
||||||
|
{"source-dev", VSH_OT_DATA, 0, gettext_noop("source device for underlying storage")},
|
||||||
|
{"target", VSH_OT_DATA, 0, gettext_noop("target for underlying storage")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdPoolDefineAs(vshControl * ctl, vshCmd * cmd)
|
||||||
|
{
|
||||||
|
virStoragePoolPtr pool;
|
||||||
|
int found;
|
||||||
|
char *name, *type, *srcHost, *srcPath, *srcDev, *target;
|
||||||
|
virBuffer buf;
|
||||||
|
|
||||||
|
memset(&buf, 0, sizeof(buf));
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
name = vshCommandOptString(cmd, "name", &found);
|
||||||
|
if (!found)
|
||||||
|
goto cleanup;
|
||||||
|
type = vshCommandOptString(cmd, "type", &found);
|
||||||
|
if (!found)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
srcHost = vshCommandOptString(cmd, "source-host", &found);
|
||||||
|
srcPath = vshCommandOptString(cmd, "source-path", &found);
|
||||||
|
srcDev = vshCommandOptString(cmd, "source-dev", &found);
|
||||||
|
target = vshCommandOptString(cmd, "target", &found);
|
||||||
|
|
||||||
|
if (virBufferVSprintf(&buf, "<pool type='%s'>\n", type) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferVSprintf(&buf, " <name>%s</name>\n", name) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcHost || srcPath || srcDev) {
|
||||||
|
if (virBufferAddLit(&buf, " <source>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcHost &&
|
||||||
|
virBufferVSprintf(&buf, " <host>%s</host>\n", srcHost) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcPath &&
|
||||||
|
virBufferVSprintf(&buf, " <path>%s</path>\n", srcPath) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (srcDev &&
|
||||||
|
virBufferVSprintf(&buf, " <device>%s</device>\n", srcDev) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virBufferAddLit(&buf, " </source>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (target) {
|
||||||
|
if (virBufferAddLit(&buf, " <target>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferVSprintf(&buf, " <path>%s</path>\n", target) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferAddLit(&buf, " </target>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (virBufferAddLit(&buf, "</pool>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
pool = virStoragePoolDefineXML(ctl->conn, buf.content, 0);
|
||||||
|
free (buf.content);
|
||||||
|
|
||||||
|
if (pool != NULL) {
|
||||||
|
vshPrint(ctl, _("Pool %s defined\n"), name);
|
||||||
|
virStoragePoolFree(pool);
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
vshError(ctl, FALSE, _("Failed to define pool %s"), name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(buf.content);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "pool-build" command
|
* "pool-build" command
|
||||||
*/
|
*/
|
||||||
@ -3391,6 +3584,131 @@ cmdPoolStart(vshControl * ctl, vshCmd * cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "vol-create-as" command
|
||||||
|
*/
|
||||||
|
static vshCmdInfo info_vol_create_as[] = {
|
||||||
|
{"syntax", "create-as <pool> <name> <capacity>"},
|
||||||
|
{"help", gettext_noop("create a vol from a set of as")},
|
||||||
|
{"desc", gettext_noop("Create a vol.")},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static vshCmdOptDef opts_vol_create_as[] = {
|
||||||
|
{"pool", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("pool name")},
|
||||||
|
{"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("name of the vol")},
|
||||||
|
{"capacity", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("size of the vol with optional k,M,G,T suffix")},
|
||||||
|
{"allocation", VSH_OT_DATA, 0, gettext_noop("initial allocation size with optional k,M,G,T suffix")},
|
||||||
|
{"format", VSH_OT_DATA, 0, gettext_noop("file format type raw,bochs,qcow,qcow2,vmdk")},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cmdVolSize(const char *data, unsigned long long *val)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
if (virStrToLong_ull(data, &end, 10, val) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (end && *end) {
|
||||||
|
/* Delibrate fallthrough cases here :-) */
|
||||||
|
switch (*end) {
|
||||||
|
case 'T':
|
||||||
|
*val *= 1024;
|
||||||
|
case 'G':
|
||||||
|
*val *= 1024;
|
||||||
|
case 'M':
|
||||||
|
*val *= 1024;
|
||||||
|
case 'k':
|
||||||
|
*val *= 1024;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
end++;
|
||||||
|
if (*end)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdVolCreateAs(vshControl * ctl, vshCmd * cmd)
|
||||||
|
{
|
||||||
|
virStoragePoolPtr pool;
|
||||||
|
virStorageVolPtr vol;
|
||||||
|
int found;
|
||||||
|
char *name, *capacityStr, *allocationStr, *format;
|
||||||
|
unsigned long long capacity, allocation = 0;
|
||||||
|
virBuffer buf;
|
||||||
|
|
||||||
|
memset(&buf, 0, sizeof(buf));
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL,
|
||||||
|
VSH_BYNAME)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
name = vshCommandOptString(cmd, "name", &found);
|
||||||
|
if (!found)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
capacityStr = vshCommandOptString(cmd, "capacity", &found);
|
||||||
|
if (!found)
|
||||||
|
goto cleanup;
|
||||||
|
if (cmdVolSize(capacityStr, &capacity) < 0)
|
||||||
|
vshError(ctl, FALSE, _("Malformed size %s"), capacityStr);
|
||||||
|
|
||||||
|
allocationStr = vshCommandOptString(cmd, "allocation", &found);
|
||||||
|
if (allocationStr &&
|
||||||
|
cmdVolSize(allocationStr, &allocation) < 0)
|
||||||
|
vshError(ctl, FALSE, _("Malformed size %s"), allocationStr);
|
||||||
|
|
||||||
|
format = vshCommandOptString(cmd, "format", &found);
|
||||||
|
|
||||||
|
if (virBufferAddLit(&buf, "<volume>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferVSprintf(&buf, " <name>%s</name>\n", name) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferVSprintf(&buf, " <capacity>%llu</capacity>\n", capacity) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (allocationStr &&
|
||||||
|
virBufferVSprintf(&buf, " <allocation>%llu</allocation>\n", allocation) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (format) {
|
||||||
|
if (virBufferAddLit(&buf, " <target>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (format)
|
||||||
|
if (virBufferVSprintf(&buf, " <format type='%s'/>\n",format) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
if (virBufferAddLit(&buf, " </target>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (virBufferAddLit(&buf, "</volume>\n") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
vol = virStorageVolCreateXML(pool, buf.content, 0);
|
||||||
|
free (buf.content);
|
||||||
|
virStoragePoolFree(pool);
|
||||||
|
|
||||||
|
if (vol != NULL) {
|
||||||
|
vshPrint(ctl, _("Vol %s created\n"), name);
|
||||||
|
virStorageVolFree(vol);
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
vshError(ctl, FALSE, _("Failed to create vol %s"), name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(buf.content);
|
||||||
|
virStoragePoolFree(pool);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "pool-undefine" command
|
* "pool-undefine" command
|
||||||
*/
|
*/
|
||||||
@ -4802,7 +5120,9 @@ static vshCmdDef commands[] = {
|
|||||||
{"pool-autostart", cmdPoolAutostart, opts_pool_autostart, info_pool_autostart},
|
{"pool-autostart", cmdPoolAutostart, opts_pool_autostart, info_pool_autostart},
|
||||||
{"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build},
|
{"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build},
|
||||||
{"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create},
|
{"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create},
|
||||||
|
{"pool-create-as", cmdPoolCreateAs, opts_pool_create_as, info_pool_create_as},
|
||||||
{"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define},
|
{"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define},
|
||||||
|
{"pool-define-as", cmdPoolDefineAs, opts_pool_define_as, info_pool_define_as},
|
||||||
{"pool-destroy", cmdPoolDestroy, opts_pool_destroy, info_pool_destroy},
|
{"pool-destroy", cmdPoolDestroy, opts_pool_destroy, info_pool_destroy},
|
||||||
{"pool-delete", cmdPoolDelete, opts_pool_delete, info_pool_delete},
|
{"pool-delete", cmdPoolDelete, opts_pool_delete, info_pool_delete},
|
||||||
{"pool-dumpxml", cmdPoolDumpXML, opts_pool_dumpxml, info_pool_dumpxml},
|
{"pool-dumpxml", cmdPoolDumpXML, opts_pool_dumpxml, info_pool_dumpxml},
|
||||||
@ -4831,6 +5151,7 @@ static vshCmdDef commands[] = {
|
|||||||
{"uri", cmdURI, NULL, info_uri},
|
{"uri", cmdURI, NULL, info_uri},
|
||||||
|
|
||||||
{"vol-create", cmdVolCreate, opts_vol_create, info_vol_create},
|
{"vol-create", cmdVolCreate, opts_vol_create, info_vol_create},
|
||||||
|
{"vol-create-as", cmdVolCreateAs, opts_vol_create_as, info_vol_create_as},
|
||||||
{"vol-delete", cmdVolDelete, opts_vol_delete, info_vol_delete},
|
{"vol-delete", cmdVolDelete, opts_vol_delete, info_vol_delete},
|
||||||
{"vol-dumpxml", cmdVolDumpXML, opts_vol_dumpxml, info_vol_dumpxml},
|
{"vol-dumpxml", cmdVolDumpXML, opts_vol_dumpxml, info_vol_dumpxml},
|
||||||
{"vol-info", cmdVolInfo, opts_vol_info, info_vol_info},
|
{"vol-info", cmdVolInfo, opts_vol_info, info_vol_info},
|
||||||
@ -5071,6 +5392,32 @@ vshCommandOptString(vshCmd * cmd, const char *name, int *found)
|
|||||||
return arg && arg->data && *arg->data ? arg->data : NULL;
|
return arg && arg->data && *arg->data ? arg->data : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int
|
||||||
|
vshCommandOptStringList(vshCmd * cmd, const char *name, char ***data)
|
||||||
|
{
|
||||||
|
vshCmdOpt *arg = cmd->opts;
|
||||||
|
char **val = NULL;
|
||||||
|
int nval = 0;
|
||||||
|
|
||||||
|
while (arg) {
|
||||||
|
if (arg->def && STREQ(arg->def->name, name)) {
|
||||||
|
char **tmp = realloc(val, sizeof(*tmp) * (nval+1));
|
||||||
|
if (!tmp) {
|
||||||
|
free(val);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val = tmp;
|
||||||
|
val[nval++] = arg->data;
|
||||||
|
}
|
||||||
|
arg = arg->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = val;
|
||||||
|
return nval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns TRUE/FALSE if the option exists
|
* Returns TRUE/FALSE if the option exists
|
||||||
*/
|
*/
|
||||||
|
@ -1440,7 +1440,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
|
|||||||
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", tmp);
|
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", tmp);
|
||||||
} else if (sexpr_has(root, "domain/bootloader")) {
|
} else if (sexpr_has(root, "domain/bootloader")) {
|
||||||
bootloader = 1;
|
bootloader = 1;
|
||||||
virBufferVSprintf(&buf, " <bootloader/>\n");
|
virBufferAddLit(&buf, " <bootloader/>\n");
|
||||||
}
|
}
|
||||||
tmp = sexpr_node(root, "domain/bootloader_args");
|
tmp = sexpr_node(root, "domain/bootloader_args");
|
||||||
if (tmp != NULL && bootloader) {
|
if (tmp != NULL && bootloader) {
|
||||||
@ -1464,12 +1464,12 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
|
|||||||
max_mem = cur_mem;
|
max_mem = cur_mem;
|
||||||
virBufferVSprintf(&buf, " <memory>%d</memory>\n", max_mem);
|
virBufferVSprintf(&buf, " <memory>%d</memory>\n", max_mem);
|
||||||
if ((cur_mem >= MIN_XEN_GUEST_SIZE) && (cur_mem != max_mem))
|
if ((cur_mem >= MIN_XEN_GUEST_SIZE) && (cur_mem != max_mem))
|
||||||
virBufferVSprintf(&buf, " <currentMemory>%d</currentMemory>\n",
|
virBufferVSprintf(&buf, " <currentMemory>%d</currentMemory>\n",
|
||||||
cur_mem);
|
cur_mem);
|
||||||
|
|
||||||
virBufferVSprintf(&buf, " <vcpu");
|
virBufferAddLit(&buf, " <vcpu");
|
||||||
if (cpus != NULL) {
|
if (cpus != NULL) {
|
||||||
virBufferVSprintf(&buf, " cpuset='%s'", cpus);
|
virBufferVSprintf(&buf, " cpuset='%s'", cpus);
|
||||||
}
|
}
|
||||||
virBufferVSprintf(&buf, ">%d</vcpu>\n",
|
virBufferVSprintf(&buf, ">%d</vcpu>\n",
|
||||||
sexpr_int(root, "domain/vcpus"));
|
sexpr_int(root, "domain/vcpus"));
|
||||||
@ -1646,7 +1646,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* This case is the cdrom device only */
|
/* This case is the cdrom device only */
|
||||||
virBufferVSprintf(&buf, " <disk device='cdrom'>\n");
|
virBufferAddLit(&buf, " <disk device='cdrom'>\n");
|
||||||
}
|
}
|
||||||
virBufferVSprintf(&buf, " <target dev='%s'/>\n", dst);
|
virBufferVSprintf(&buf, " <target dev='%s'/>\n", dst);
|
||||||
|
|
||||||
@ -1654,9 +1654,9 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
|
|||||||
/* XXX should we force mode == r, if cdrom==1, or assume
|
/* XXX should we force mode == r, if cdrom==1, or assume
|
||||||
xend has already done this ? */
|
xend has already done this ? */
|
||||||
if ((mode != NULL) && (!strcmp(mode, "r")))
|
if ((mode != NULL) && (!strcmp(mode, "r")))
|
||||||
virBufferVSprintf(&buf, " <readonly/>\n");
|
virBufferAddLit(&buf, " <readonly/>\n");
|
||||||
else if ((mode != NULL) && (!strcmp(mode, "w!")))
|
else if ((mode != NULL) && (!strcmp(mode, "w!")))
|
||||||
virBufferVSprintf(&buf, " <shareable/>\n");
|
virBufferAddLit(&buf, " <shareable/>\n");
|
||||||
virBufferAddLit(&buf, " </disk>\n");
|
virBufferAddLit(&buf, " </disk>\n");
|
||||||
|
|
||||||
bad_parse:
|
bad_parse:
|
||||||
@ -1667,12 +1667,12 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
|
|||||||
tmp2 = sexpr_node(node, "device/vif/script");
|
tmp2 = sexpr_node(node, "device/vif/script");
|
||||||
tmp = sexpr_node(node, "device/vif/bridge");
|
tmp = sexpr_node(node, "device/vif/bridge");
|
||||||
if ((tmp2 && strstr(tmp2, "bridge")) || tmp) {
|
if ((tmp2 && strstr(tmp2, "bridge")) || tmp) {
|
||||||
virBufferVSprintf(&buf, " <interface type='bridge'>\n");
|
virBufferAddLit(&buf, " <interface type='bridge'>\n");
|
||||||
if (tmp != NULL)
|
if (tmp != NULL)
|
||||||
virBufferVSprintf(&buf, " <source bridge='%s'/>\n",
|
virBufferVSprintf(&buf, " <source bridge='%s'/>\n",
|
||||||
tmp);
|
tmp);
|
||||||
} else {
|
} else {
|
||||||
virBufferVSprintf(&buf, " <interface type='ethernet'>\n");
|
virBufferAddLit(&buf, " <interface type='ethernet'>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = sexpr_node(node, "device/vif/vifname");
|
tmp = sexpr_node(node, "device/vif/vifname");
|
||||||
|
@ -667,7 +667,7 @@ char *xenXMDomainFormatXML(virConnectPtr conn, virConfPtr conf) {
|
|||||||
val = MIN_XEN_GUEST_SIZE * 2;
|
val = MIN_XEN_GUEST_SIZE * 2;
|
||||||
virBufferVSprintf(buf, " <memory>%ld</memory>\n", val * 1024);
|
virBufferVSprintf(buf, " <memory>%ld</memory>\n", val * 1024);
|
||||||
|
|
||||||
virBufferVSprintf(buf, " <vcpu");
|
virBufferAddLit(buf, " <vcpu");
|
||||||
if (xenXMConfigGetString(conf, "cpus", &str) == 0) {
|
if (xenXMConfigGetString(conf, "cpus", &str) == 0) {
|
||||||
char *ranges;
|
char *ranges;
|
||||||
|
|
||||||
|
@ -1298,11 +1298,11 @@ virDomainParseXMLDiskDesc(virConnectPtr conn, xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ro == 1)
|
if (ro == 1)
|
||||||
virBufferVSprintf(buf, "(mode 'r')");
|
virBufferAddLit(buf, "(mode 'r')");
|
||||||
else if (shareable == 1)
|
else if (shareable == 1)
|
||||||
virBufferVSprintf(buf, "(mode 'w!')");
|
virBufferAddLit(buf, "(mode 'w!')");
|
||||||
else
|
else
|
||||||
virBufferVSprintf(buf, "(mode 'w')");
|
virBufferAddLit(buf, "(mode 'w')");
|
||||||
|
|
||||||
virBufferAddLit(buf, ")");
|
virBufferAddLit(buf, ")");
|
||||||
virBufferAddLit(buf, ")");
|
virBufferAddLit(buf, ")");
|
||||||
@ -1617,7 +1617,7 @@ virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name,
|
|||||||
free(str);
|
free(str);
|
||||||
} else if (virXPathNumber("count(/domain/bootloader)", ctxt, &f) == 0
|
} else if (virXPathNumber("count(/domain/bootloader)", ctxt, &f) == 0
|
||||||
&& (f > 0)) {
|
&& (f > 0)) {
|
||||||
virBufferVSprintf(&buf, "(bootloader)");
|
virBufferAddLit(&buf, "(bootloader)");
|
||||||
/*
|
/*
|
||||||
* if using a bootloader, the kernel and initrd strings are not
|
* if using a bootloader, the kernel and initrd strings are not
|
||||||
* significant and should be discarded
|
* significant and should be discarded
|
||||||
|
Loading…
Reference in New Issue
Block a user